"use client"; import { useEffect, useState, useRef } from "react"; import { Plus, Trash2, RotateCcw, Save, ChevronDown, ChevronUp, Pencil } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { type Persona } from "@/lib/personas"; function uid() { return Math.random().toString(36).slice(2, 10); } // ── Confirm dialog ──────────────────────────────────────────────────────────── function ConfirmDialog({ trigger, title, description, confirmLabel = "Confirm", destructive = false, onConfirm, }: { trigger: React.ReactNode; title: string; description: string; confirmLabel?: string; destructive?: boolean; onConfirm: () => void; }) { const [open, setOpen] = useState(false); return ( {trigger} {title} {description} ); } // ── Per-persona card ────────────────────────────────────────────────────────── type SaveState = "idle" | "editing" | "saving" | "saved" | "error"; function PersonaCard({ persona, onSave, onDelete, }: { persona: Persona; onSave: (p: Persona) => Promise; onDelete: () => void; }) { const [open, setOpen] = useState(false); const [draft, setDraft] = useState(persona); const [state, setState] = useState("idle"); const [errorMsg, setErrorMsg] = useState(null); // Sync when parent updates (e.g. after reset) const prevId = useRef(persona.id); useEffect(() => { if (persona.id !== prevId.current || state === "idle") { setDraft(persona); prevId.current = persona.id; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [persona]); const isDirty = JSON.stringify(draft) !== JSON.stringify(persona); function change(field: keyof Persona, value: string) { setDraft((d) => ({ ...d, [field]: value })); setState("editing"); } async function save() { setState("saving"); setErrorMsg(null); try { await onSave(draft); setState("saved"); setTimeout(() => setState("idle"), 2500); } catch (e) { setErrorMsg((e as Error).message); setState("error"); } } return (
{/* Header row */}
} title="Delete persona" description={`Remove "${draft.name || "this persona"}" permanently? Students will no longer see it.`} confirmLabel="Delete" destructive onConfirm={onDelete} />
{/* Expandable fields */} {open && (
change("name", e.target.value)} placeholder="e.g. Socratic Tutor" />
change("description", e.target.value)} placeholder="One sentence shown in the dropdown" />