Files
buzz-sheet/components/commission/ticket-detail.tsx
T
gunshiz 3473b55768
CI / Verify (push) Successful in 1m48s
CI / Build immutable images and deploy (push) Successful in 2m47s
feat(commission) : add push notifications and unread ticket titles
2026-10-02 11:51:05 +07:00

44 lines
2.7 KiB
TypeScript

import { notFound } from "next/navigation";
import { getCommissionLabels } from "@/lib/commission/catalog";
import { getCommissionTicket } from "@/lib/commission/tickets";
import { publicMediaUrl } from "@/lib/media/storage";
import { HttpError } from "@/lib/security/http";
import { CommissionRequestSummary } from "./request-summary";
import { CommissionTicketChat } from "./ticket-chat";
import { CommissionTicketRename } from "./ticket-rename";
import { CommissionSlipDialog } from "./slip-dialog";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
export async function CommissionTicketDetail({ id, admin }: { id: string; admin: boolean }) {
let data: Awaited<ReturnType<typeof getCommissionTicket>>;
try {
data = await getCommissionTicket(id);
} catch (cause) {
if (cause instanceof HttpError && (cause.status === 401 || cause.status === 403 || cause.status === 404))
notFound();
throw cause;
}
const catalog = await getCommissionLabels(data.checkout.request);
return <div className="flex flex-col gap-6">
<header className="flex flex-wrap items-start justify-between gap-3">
<div className="min-w-0"><h1 className="wrap-anywhere font-heading text-3xl font-semibold">
{data.ticket.title || `Ticket #${data.ticket.id.slice(0, 8)}`}
</h1>
<p className="text-muted-foreground">{data.ticket.title ? `#${data.ticket.id.slice(0, 8)} - ` : ""}{data.customerName} - {data.ticket.status === "open" ? "เปิด" : "ปิด"}</p>
</div>
{admin && <CommissionTicketRename ticketId={id} title={data.ticket.title} />}
</header>
<div className="grid min-w-0 gap-6 lg:grid-cols-[minmax(0,300px)_minmax(0,1fr)]">
<Card className="h-fit lg:max-h-[78svh] lg:overflow-y-auto"><CardHeader><CardTitle>คำขอที่ชำระเงินแล้ว - ฿{data.checkout.amountBaht}</CardTitle></CardHeader>
<CardContent className="flex flex-col gap-3">{catalog && <CommissionRequestSummary request={data.checkout.request} catalog={catalog} amountBaht={data.checkout.amountBaht} />}
<p className="text-sm text-muted-foreground">การชำระเงิน: {data.payment.transRef} - {data.payment.transferredAt.toLocaleString("th-TH")}</p>
<CommissionSlipDialog src={publicMediaUrl(data.payment.slipObjectKey)} />
</CardContent></Card>
<CommissionTicketChat ticketId={id} ticketTitle={data.ticket.title || `Ticket #${id.slice(0, 8)}`}
userId={data.currentUserId} status={data.ticket.status}
messages={data.messages.map(({ imageObjectKey, ...message }) => ({ ...message,
imageUrl: imageObjectKey ? publicMediaUrl(imageObjectKey) : null }))} admin={admin} />
</div>
</div>;
}