'use client' import { useState, useMemo } from 'react' import { trpc } from '@/lib/trpc/client' import { toast } from 'sonner' import { cn } from '@/lib/utils' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Checkbox } from '@/components/ui/checkbox' import { Loader2, ChevronDown, CheckCircle2, X } from 'lucide-react' export type RecommendationItem = { projectId: string rank: number score: number category: string strengths: string[] concerns: string[] recommendation: string } export type AIRecommendationsDisplayProps = { recommendations: { STARTUP: RecommendationItem[]; BUSINESS_CONCEPT: RecommendationItem[] } projectStates: any[] | undefined roundId: string onClear: () => void onApplied: () => void } export function AIRecommendationsDisplay({ recommendations, projectStates, roundId, onClear, onApplied, }: AIRecommendationsDisplayProps) { const [expandedId, setExpandedId] = useState(null) const [applying, setApplying] = useState(false) // Initialize selected with all recommended project IDs const allRecommendedIds = useMemo(() => { const ids = new Set() for (const item of recommendations.STARTUP) ids.add(item.projectId) for (const item of recommendations.BUSINESS_CONCEPT) ids.add(item.projectId) return ids }, [recommendations]) const [selectedIds, setSelectedIds] = useState>(() => new Set(allRecommendedIds)) // Build projectId → title map from projectStates const projectTitleMap = useMemo(() => { const map = new Map() if (projectStates) { for (const ps of projectStates) { if (ps.project?.id && ps.project?.title) { map.set(ps.project.id, ps.project.title) } } } return map }, [projectStates]) const transitionMutation = trpc.roundEngine.transitionProject.useMutation() const toggleProject = (projectId: string) => { setSelectedIds((prev) => { const next = new Set(prev) if (next.has(projectId)) next.delete(projectId) else next.add(projectId) return next }) } const selectedStartups = recommendations.STARTUP.filter((item) => selectedIds.has(item.projectId)).length const selectedConcepts = recommendations.BUSINESS_CONCEPT.filter((item) => selectedIds.has(item.projectId)).length const handleApply = async () => { setApplying(true) try { // Transition all selected projects to PASSED const promises = Array.from(selectedIds).map((projectId) => transitionMutation.mutateAsync({ projectId, roundId, newState: 'PASSED' }).catch(() => { // Project might already be PASSED — that's OK }) ) await Promise.all(promises) toast.success(`Marked ${selectedIds.size} project(s) as passed`) onApplied() } catch (error) { toast.error('Failed to apply recommendations') } finally { setApplying(false) } } const renderCategory = (label: string, items: RecommendationItem[], colorClass: string) => { if (items.length === 0) return (
No {label.toLowerCase()} projects evaluated
) return (
{items.map((item) => { const isExpanded = expandedId === `${item.category}-${item.projectId}` const isSelected = selectedIds.has(item.projectId) const projectTitle = projectTitleMap.get(item.projectId) || item.projectId return (
toggleProject(item.projectId)} className="shrink-0" />
{isExpanded && (

Strengths

    {item.strengths.map((s, i) =>
  • {s}
  • )}
{item.concerns.length > 0 && (

Concerns

    {item.concerns.map((c, i) =>
  • {c}
  • )}
)}

Recommendation

{item.recommendation}

)}
) })}
) } return (
AI Shortlist Recommendations Ranked independently per category — {selectedStartups} of {recommendations.STARTUP.length} startups, {selectedConcepts} of {recommendations.BUSINESS_CONCEPT.length} concepts selected

Startup ({recommendations.STARTUP.length})

{renderCategory('Startup', recommendations.STARTUP, 'bg-blue-500')}

Business Concept ({recommendations.BUSINESS_CONCEPT.length})

{renderCategory('Business Concept', recommendations.BUSINESS_CONCEPT, 'bg-purple-500')}
{/* Apply button */}

{selectedIds.size} project{selectedIds.size !== 1 ? 's' : ''} will be marked as Passed

) }