"use client" import { useEffect, useState } from "react" import { useRouter } from "next/navigation" import { toast } from "sonner" import { InvoiceStatus } from "@garage/api" import { confirm } from "@/shared/components/confirm-dialog" import { badgeVariants } from "@/shared/components/ui/badge" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/shared/components/ui/select" import { cn } from "@/shared/lib/utils" import { formatEnum } from "@/shared/utils/formatters" import { useAuthApi } from "@/shared/useApi" type InvoiceStatusValue = (typeof InvoiceStatus)[number] type InvoiceStatusBadgeProps = { invoice: { status?: string | null id: number | string } } const STATUS_TRIGGER_CLASS_NAMES: Record = { draft: "border-slate-200 bg-slate-100 text-slate-700 dark:border-slate-800 dark:bg-slate-900/70 dark:text-slate-200", open: "border-blue-200 bg-blue-100 text-blue-700 dark:border-blue-900 dark:bg-blue-950/70 dark:text-blue-200", over_due: "border-red-200 bg-red-100 text-red-700 dark:border-red-900 dark:bg-red-950/70 dark:text-red-200", paid: "border-emerald-200 bg-emerald-100 text-emerald-700 dark:border-emerald-900 dark:bg-emerald-950/70 dark:text-emerald-200", partially_paid: "border-amber-200 bg-amber-100 text-amber-700 dark:border-amber-900 dark:bg-amber-950/70 dark:text-amber-200", un_paid: "border-orange-200 bg-orange-100 text-orange-700 dark:border-orange-900 dark:bg-orange-950/70 dark:text-orange-200", } function isInvoiceStatus(value?: string | null): value is InvoiceStatusValue { return !!value && InvoiceStatus.includes(value as InvoiceStatusValue) } export default function InvoiceStatusBadge({ invoice }: InvoiceStatusBadgeProps) { const api = useAuthApi() const router = useRouter() const [isUpdating, setIsUpdating] = useState(false) const [status, setStatus] = useState( isInvoiceStatus(invoice.status) ? invoice.status : undefined, ) useEffect(() => { setStatus(isInvoiceStatus(invoice.status) ? invoice.status : undefined) }, [invoice.status]) const handleStatusChange = async (nextStatus: string) => { if (!isInvoiceStatus(nextStatus) || nextStatus === status || isUpdating) { return } const currentStatus = status const confirmed = await confirm({ title: "Change Invoice Status", description: currentStatus ? `Change invoice status from ${formatEnum(currentStatus)} to ${formatEnum(nextStatus)}?` : `Change invoice status to ${formatEnum(nextStatus)}?`, confirmLabel: "Update", }) if (!confirmed) { return } setIsUpdating(true) try { const promise = api.invoices.update(String(invoice.id), { status: nextStatus }) toast.promise(promise, { loading: `Updating invoice status to ${formatEnum(nextStatus)}...`, success: "Invoice status updated successfully.", error: "Failed to update invoice status.", }) await promise setStatus(nextStatus) router.refresh() } finally { setIsUpdating(false) } } return ( ) }