"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { CalendarCheckIcon, CheckIcon, MinusIcon, XIcon } from "lucide-react"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Item, ItemContent, ItemHeader, ItemTitle } from "@/components/ui/item"; import { setMissionAttendance } from "@/app/(frontend)/intelligence/missions/actions"; type AttendanceResponse = "yes" | "no" | "tentative"; interface Attendee { id: number; name: string; } interface MissionAttendanceProps { missionId: number; currentUserId: number | null; currentResponse: AttendanceResponse | null; attendanceClosed?: boolean; yes: Attendee[]; no: Attendee[]; tentative: Attendee[]; } const stateMeta: Record< AttendanceResponse, { label: string; icon: typeof CheckIcon; color: string; active: string } > = { yes: { label: "Yes", icon: CheckIcon, color: "text-green-400", active: "border-green-500/60 bg-green-500/15 text-green-400 hover:bg-green-500/25", }, no: { label: "No", icon: XIcon, color: "text-red-400", active: "border-red-500/60 bg-red-500/15 text-red-400 hover:bg-red-500/25", }, tentative: { label: "Tentative", icon: MinusIcon, color: "text-amber-400", active: "border-amber-500/60 bg-amber-500/15 text-amber-400 hover:bg-amber-500/25", }, }; const states = Object.keys(stateMeta) as AttendanceResponse[]; export function MissionAttendance({ missionId, currentUserId, currentResponse, attendanceClosed = false, yes, no, tentative, }: MissionAttendanceProps) { const router = useRouter(); const [selected, setSelected] = useState(currentResponse); const [pending, setPending] = useState(null); const [error, setError] = useState(null); const groups: Record = { yes, no, tentative }; async function handleSet(response: AttendanceResponse) { setPending(response); setSelected(response); setError(null); const res = await setMissionAttendance({ missionId, response }); if (!res.success) { setSelected(currentResponse); setError(res.error ?? "Failed to update attendance."); } setPending(null); router.refresh(); } return (
Attendance
{currentUserId !== null && !attendanceClosed && (
{states.map((response) => { const meta = stateMeta[response]; const Icon = meta.icon; return ( ); })}
)} {currentUserId !== null && attendanceClosed && (

Attendance is closed for this mission.

)} {error &&

{error}

} {states.map((response) => { const meta = stateMeta[response]; const Icon = meta.icon; const people = groups[response] .slice() .sort((a, b) => a.name.localeCompare(b.name)); return (
{meta.label} ({people.length})
{people.length > 0 && (
    {people.map((person) => (
  • {person.name}
  • ))}
)}
); })}
); }