import { useState } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Users, MessageCircle, CheckCircle, Clock, ArrowRight, } from "lucide-react"; export interface Applicant { id: string; user?: { id: string; name: string; avatar_url?: string; }; opportunity?: { id: string; title: string; }; status: "applied" | "interviewing" | "hired"; rating?: number; notes?: string; applied_at?: string; } interface ApplicantTrackerWidgetProps { applicants: Applicant[]; title?: string; description?: string; onViewProfile?: (applicantId: string) => void; onMessage?: (applicantId: string) => void; onUpdateStatus?: ( applicantId: string, newStatus: "applied" | "interviewing" | "hired", ) => void; accentColor?: "blue" | "purple" | "cyan" | "green"; } const statusColors = { applied: { bg: "bg-blue-950/40", border: "border-blue-500/20", badge: "bg-blue-600/50 text-blue-100", label: "Applied", icon: Clock, }, interviewing: { bg: "bg-purple-950/40", border: "border-purple-500/20", badge: "bg-purple-600/50 text-purple-100", label: "Interviewing", icon: MessageCircle, }, hired: { bg: "bg-green-950/40", border: "border-green-500/20", badge: "bg-green-600/50 text-green-100", label: "Hired", icon: CheckCircle, }, }; const nextStatusMap: Record = { applied: "interviewing", interviewing: "hired", hired: "applied", }; export function ApplicantTrackerWidget({ applicants, title = "Applicant Tracker", description = "Track applicants through your hiring pipeline", onViewProfile, onMessage, onUpdateStatus, accentColor = "blue", }: ApplicantTrackerWidgetProps) { const [draggedApplicant, setDraggedApplicant] = useState(null); const statusCounts = { applied: applicants.filter((a) => a.status === "applied").length, interviewing: applicants.filter((a) => a.status === "interviewing").length, hired: applicants.filter((a) => a.status === "hired").length, }; const allStatuses: Array<"applied" | "interviewing" | "hired"> = [ "applied", "interviewing", "hired", ]; const handleDragStart = (applicantId: string) => { setDraggedApplicant(applicantId); }; const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); }; const handleDrop = (status: "applied" | "interviewing" | "hired") => { if (draggedApplicant) { onUpdateStatus?.(draggedApplicant, status); setDraggedApplicant(null); } }; return ( {title} {description} {applicants.length === 0 ? (

No applicants yet

) : (
{allStatuses.map((status) => { const statusInfo = statusColors[status]; const StatusIcon = statusInfo.icon; const statusApplicants = applicants.filter( (a) => a.status === status, ); return (
handleDrop(status)} className={`p-4 rounded-lg border-2 border-dashed transition ${statusInfo.border} ${statusInfo.bg}`} > {/* Column Header */}
{statusInfo.label}

{statusApplicants.length}

{/* Applicants List */}
{statusApplicants.length === 0 ? (
Drag applicants here
) : ( statusApplicants.map((app) => (
handleDragStart(app.id)} className="p-3 bg-black/40 rounded-lg border border-gray-500/10 cursor-move hover:border-gray-500/30 hover:bg-black/50 transition space-y-2" > {/* Applicant Info */}
{app.user?.avatar_url && ( {app.user.name} )}

{app.user?.name || "Unknown"}

{app.opportunity?.title && (

{app.opportunity.title}

)}
{/* Rating */} {app.rating && (
{Array.from({ length: 5 }).map((_, i) => ( ))}
)} {/* Notes */} {app.notes && (

"{app.notes}"

)} {/* Actions */}
{onViewProfile && ( )} {onMessage && ( )}
{/* Applied Date */} {app.applied_at && (

{new Date(app.applied_at).toLocaleDateString()}

)}
)) )}
); })}
)}
); } export default ApplicantTrackerWidget;