import { useState } from "react"; import { useParams } from "react-router-dom"; import { AlertCircle, ArrowLeft, Loader2, MessagesSquare } from "lucide-react"; import { Alert, AlertDescription } from "../../../components/ui/alert.tsx"; import { Badge } from "../../../components/ui/badge.tsx"; import { EmptyState } from "../../../components/ui/empty-state.tsx"; import { usePatientSupportTicketThread, TICKET_STATUS_LABELS, TICKET_STATUS_VARIANT, type PatientSupportTicketEvent, } from "../../../hooks/usePatientSupportTickets"; import { formatDateTime } from "../../../utils/dateUtils"; /** * One problem a patient reported, the answer, and the reply that follows it. * * Two sides only. A patient's ticket belongs to Akashic from the moment it is raised and never moves * to a contractor, so there is no escalation, no hand-back and no third speaker to name. */ /** * Who spoke, in the reader's own terms - never an account id, and never guessed when it is blank. * The reader's own replies say "You" rather than their name: the name is stored on the ticket for * whoever answers, and reading it back tells them nothing while putting it on a shared screen. */ const speakerLabel = (event: PatientSupportTicketEvent): string => { if (event.side === "patient") return "You"; return event.authorName ? `${event.authorName} · Akashic support` : "Akashic support"; }; export const MySupportTicketDetail = () => { const { ticketId } = useParams<{ ticketId: string }>(); const { ticket, events, loading, error, notFound, reply, replying, replyError } = usePatientSupportTicketThread(ticketId); const [draft, setDraft] = useState(""); const submitReply = async (formEvent: React.FormEvent) => { formEvent.preventDefault(); if (!draft.trim() || replying) return; try { await reply(draft.trim()); setDraft(""); } catch { // `replyError` carries what to say. The draft stays: losing what somebody just wrote is // worse than making them press send again. } }; return (
{ticket.reference && `${ticket.reference} — `} Reported {formatDateTime(ticket.createdAt)}
{ticket.body}
{speakerLabel(item)} · {formatDateTime(item.at)}
{item.kind === "reply" ? ({item.body}
) : (Marked {item.status ? TICKET_STATUS_LABELS[item.status] : "updated"}.
)}