Files
pragativeer-v2/src/components/AI/CollegePredictorCard.tsx

139 lines
6.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { useEffect, useState } from "react"
import { Card, CardContent } from "@/components/ui/card"
import { RefreshCw, TrendingUp, MapPin, Star } from "lucide-react"
import { useActiveUser } from "@/hooks/useActiveUser"
const MOCK_COLLEGES: Record<string, Array<{ rank: number; name: string; branch: string; match: number; location: string; type: string; starred?: boolean }>> = {
Reach: [
{ rank: 1, name: "IIT Bombay", branch: "Computer Science", match: 48, location: "Mumbai", type: "IIT", starred: true },
{ rank: 2, name: "IIT Delhi", branch: "Electrical Engineering", match: 52, location: "Delhi", type: "IIT" },
{ rank: 3, name: "IIT Madras", branch: "Mech. Engineering", match: 55, location: "Chennai", type: "IIT" },
{ rank: 4, name: "IIT Roorkee", branch: "Computer Science", match: 60, location: "Roorkee", type: "IIT", starred: true },
{ rank: 5, name: "IIT Kharagpur", branch: "Aerospace Engg.", match: 63, location: "Kharagpur", type: "IIT" },
],
Target: [
{ rank: 1, name: "NIT Trichy", branch: "Computer Science", match: 85, location: "Trichy", type: "NIT", starred: true },
{ rank: 2, name: "NIT Surathkal", branch: "Information Tech.", match: 78, location: "Surathkal", type: "NIT" },
{ rank: 3, name: "NIT Warangal", branch: "Electronics & Comm.", match: 74, location: "Warangal", type: "NIT" },
{ rank: 4, name: "BITS Pilani", branch: "Computer Science", match: 70, location: "Pilani", type: "BITS", starred: true },
{ rank: 5, name: "NIT Calicut", branch: "Computer Science", match: 68, location: "Calicut", type: "NIT" },
],
Safety: [
{ rank: 1, name: "IIIT Hyderabad", branch: "Computer Science", match: 94, location: "Hyderabad", type: "IIIT", starred: true },
{ rank: 2, name: "IIIT Allahabad", branch: "Information Tech.", match: 91, location: "Allahabad", type: "IIIT" },
{ rank: 3, name: "DTU Delhi", branch: "Software Engineering", match: 89, location: "Delhi", type: "State" },
{ rank: 4, name: "NSIT Delhi", branch: "Computer Engineering", match: 87, location: "Delhi", type: "State" },
{ rank: 5, name: "NIT Jamshedpur", branch: "Mech. Engineering", match: 84, location: "Jamshedpur", type: "NIT" },
],
}
const MATCH_COLOR = (match: number) => {
if (match >= 80) return "text-green-500 bg-green-500/10"
if (match >= 60) return "text-amber-500 bg-amber-500/10"
return "text-red-400 bg-red-400/10"
}
export function CollegePredictorCard() {
const [loading, setLoading] = useState(true)
const [activeTab, setActiveTab] = useState("Target")
const { userId, loading: userLoading } = useActiveUser()
useEffect(() => {
if (userLoading || !userId) return
async function fetchData() {
try {
const res = await fetch(`/api/ai-coach/readiness/${userId}`)
if (!res.ok) throw new Error("fallback")
} catch {
// Use mock data — no-op
} finally {
setLoading(false)
}
}
fetchData()
}, [userId, userLoading])
if (loading) {
return (
<Card className="border-border shadow-sm h-full flex items-center justify-center min-h-[150px]">
<RefreshCw className="animate-spin text-muted-foreground" />
</Card>
)
}
const colleges = MOCK_COLLEGES[activeTab] || []
const TAB_COLORS: Record<string, string> = {
Reach: "bg-purple-500/10 border-purple-500/20 text-purple-400",
Target: "bg-[#00F0FF]/10 border-[#00F0FF]/20 text-[#00F0FF]",
Safety: "bg-green-500/10 border-green-500/20 text-green-400",
}
const INACTIVE = "bg-white/5 border-transparent text-muted-foreground hover:bg-white/10"
return (
<Card className="border-border bg-card shadow-[0_4px_24px_rgba(0,0,0,0.3)] overflow-hidden group hover:border-[#00F0FF]/30 transition-colors">
<CardContent className="p-5 flex flex-col gap-4">
{/* Tabs */}
<div className="flex gap-1.5">
{["Reach", "Target", "Safety"].map((tab) => (
<button
key={tab}
onClick={() => setActiveTab(tab)}
className={`flex-1 py-2 text-xs font-bold rounded-lg border transition-all ${activeTab === tab ? TAB_COLORS[tab] : INACTIVE}`}
>
{tab}
</button>
))}
</div>
{/* Tab description */}
<div className="text-xs text-muted-foreground font-medium px-0.5">
{activeTab === "Reach" && "Colleges where your current score gives you a ~50–65% admission probability. Requires improvement."}
{activeTab === "Target" && "Colleges within strong reach. Your current trajectory suggests 68–90% match probability."}
{activeTab === "Safety" && "Colleges highly likely with your current score. Aim to convert all safety options."}
</div>
{/* College List */}
<div className="flex flex-col gap-2">
{colleges.map((col) => (
<div key={col.name} className="flex items-center gap-3 p-3 rounded-xl bg-white/5 border border-border hover:bg-white/10 transition-colors group/item">
<div className={`w-8 h-8 rounded-full flex items-center justify-center text-xs font-black shrink-0 ${activeTab === "Reach" ? "bg-purple-500/10 text-purple-400" : activeTab === "Target" ? "bg-[#00F0FF]/10 text-[#00F0FF]" : "bg-green-500/10 text-green-400"}`}>
#{col.rank}
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-1.5">
<span className="text-sm font-black text-primary truncate">{col.name}</span>
{col.starred && <Star size={11} className="text-yellow-400 fill-yellow-400 shrink-0" />}
</div>
<div className="flex items-center gap-2 text-xs text-muted-foreground font-semibold">
<span>{col.branch}</span>
<span className="opacity-40">·</span>
<span className="flex items-center gap-0.5">
<MapPin size={10} />{col.location}
</span>
<span className="opacity-40">·</span>
<span className="opacity-60">{col.type}</span>
</div>
</div>
<div className={`text-xs font-black px-2.5 py-1 rounded-md shrink-0 ${MATCH_COLOR(col.match)}`}>
{col.match}%
</div>
</div>
))}
</div>
{/* Bottom Tip */}
<div className="mt-1 p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-xl text-xs text-yellow-500 font-bold flex items-center gap-2">
<TrendingUp size={14} className="shrink-0" />
{activeTab === "Reach" && "Score +20 marks in Maths to convert IIT Roorkee from Reach to Target!"}
{activeTab === "Target" && "Just 15 more marks in Maths can upgrade you from NIT Trichy to IIT Roorkee!"}
{activeTab === "Safety" && "You're on track for all safety colleges. Focus your energy on converting Target colleges."}
</div>
</CardContent>
</Card>
)
}