"use client"; import { useState, useCallback, useEffect } from "react"; import { formatDate } from "@/lib/date-utils"; import { exportTaxReport, exportTaxByState, type TaxOrderRow, type TaxByStateRow, } from "@/lib/reports-export"; import { getTaxSummaryAction, getTaxableOrdersAction, type TaxSummaryData, } from "@/actions/tax"; import { AdminButton, AdminFilterTabs } from "@/components/admin/design-system"; type DatePreset = "month" | "quarter" | "this_year" | "custom"; type DateRange = { start: string; end: string }; function buildRange(preset: DatePreset, customStart?: string, customEnd?: string): DateRange { const now = new Date(); const toDateStr = (d: Date) => d.toISOString().slice(0, 10); const today = toDateStr(now); switch (preset) { case "month": { const start = new Date(now.getFullYear(), now.getMonth(), 1); return { start: toDateStr(start), end: today }; } case "quarter": { const q = Math.floor(now.getMonth() / 3); const start = new Date(now.getFullYear(), q * 3, 1); return { start: toDateStr(start), end: today }; } case "this_year": { const start = new Date(now.getFullYear(), 0, 1); return { start: toDateStr(start), end: today }; } case "custom": return { start: customStart ?? today, end: customEnd ?? today }; } } function quarterLabel(start: string, end: string): string { const s = new Date(start + "T00:00:00"); const q = Math.floor(s.getMonth() / 3) + 1; return `Q${q} ${s.getFullYear()}`; } type TaxSummaryDataLocal = TaxSummaryData; function SummaryCard({ label, value, prefix, suffix, highlight, }: { label: string; value: number; prefix?: string; suffix?: string; highlight?: boolean; }) { return (

{label}

{prefix ?? ""}{typeof value === "number" ? value.toLocaleString(undefined, { maximumFractionDigits: 2 }) : value}{suffix ?? ""}

); } function ExportBtn({ label, onClick }: { label: string; onClick: () => void }) { return ( Export CSV ); } function ReportTable({ headers, rows, renderRow }: { headers: string[]; rows: unknown[]; renderRow: (row: unknown, i: number) => React.ReactNode; }) { return (
{headers.map((h) => ( ))} {rows.length === 0 ? ( ) : ( rows.map((_, i) => renderRow(_, i)) )}
{h}
No data
); } const TABS = [ { value: "summary", label: "Tax Summary" }, { value: "orders", label: "Taxable Orders" }, ]; export default function TaxDashboard({ brands, initialBrandId, isPlatformAdmin, }: { brands: { id: string; name: string }[]; initialBrandId: string | null; isPlatformAdmin: boolean; }) { const [preset, setPreset] = useState("quarter"); const [customStart, setCustomStart] = useState(""); const [customEnd, setCustomEnd] = useState(""); const [selectedBrandId, setSelectedBrandId] = useState(initialBrandId ?? ""); const [activeTab, setActiveTab] = useState("summary"); const [summary, setSummary] = useState(null); const [orders, setOrders] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const range: DateRange = buildRange(preset, customStart, customEnd); const fetchTaxSummary = useCallback(async () => { if (!selectedBrandId) return; setLoading(true); setError(null); try { const result = await getTaxSummaryAction({ brandId: selectedBrandId, startDate: range.start, endDate: range.end, }); if (!result.success) throw new Error(result.error); setSummary(result.data); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load tax summary"); } finally { setLoading(false); } }, [selectedBrandId, range]); const fetchTaxableOrders = useCallback(async () => { if (!selectedBrandId) return; setLoading(true); setError(null); try { const result = await getTaxableOrdersAction({ brandId: selectedBrandId, startDate: range.start, endDate: range.end, }); if (!result.success) throw new Error(result.error); setOrders(result.data); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load orders"); } finally { setLoading(false); } }, [selectedBrandId, range]); function handleFetch() { if (activeTab === "summary") fetchTaxSummary(); else fetchTaxableOrders(); } // Auto-fetch when tab/brand/range changes — use useEffect to avoid render-time side effects useEffect(() => { const init = async () => { if (summary === null && activeTab === "summary" && selectedBrandId && !loading) { await fetchTaxSummary(); } }; init(); }, [summary, activeTab, selectedBrandId, loading, fetchTaxSummary]); useEffect(() => { const init = async () => { if (orders.length === 0 && activeTab === "orders" && selectedBrandId && !loading) { await fetchTaxableOrders(); } }; init(); }, [orders.length, activeTab, selectedBrandId, loading, fetchTaxableOrders]); function handleExportCSV() { if (activeTab === "summary" && summary) { const rows: TaxByStateRow[] = summary.tax_by_state.map((s) => ({ state: s.state, total_tax: s.total_tax, gross_sales: s.gross_sales, order_count: s.order_count, })); const csv = exportTaxByState(rows); downloadCSV(csv, `tax-by-state-${range.start}.csv`); } else if (activeTab === "orders" && orders.length > 0) { const csv = exportTaxReport(orders); downloadCSV(csv, `taxable-orders-${range.start}.csv`); } } function downloadCSV(csv: string, filename: string) { const blob = new Blob([csv], { type: "text/csv" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } const effectiveRate = summary && summary.total_gross_sales > 0 ? (summary.total_tax_collected / summary.total_gross_sales) * 100 : 0; return (
{error && (
{error}
)} {/* ── Filters ── */}
{(["month", "quarter", "this_year", "custom"] as DatePreset[]).map((p) => ( setPreset(p)} variant={preset === p ? "primary" : "secondary"} size="sm" > {p === "month" ? "This Month" : p === "quarter" ? "This Quarter" : p === "this_year" ? "This Year" : "Custom"} ))}
{preset === "custom" && (
setCustomStart(e.target.value)} className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs" /> to setCustomEnd(e.target.value)} className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs" />
)} {isPlatformAdmin && ( )} Refresh {preset === "quarter" ? quarterLabel(range.start, range.end) : preset === "this_year" ? `${new Date().getFullYear()} YTD` : `${range.start} → ${range.end}`}
{/* ── Tab bar ── */} {/* ── TAX SUMMARY TAB ── */} {activeTab === "summary" && (
{summary && ( <>

Tax by State

{summary.tax_by_state.length > 0 && ( )}
{ const r = row as { state: string; total_tax: number; gross_sales: number; order_count: number }; const rate = r.gross_sales > 0 ? (r.total_tax / r.gross_sales) * 100 : 0; return ( {r.state} ${r.total_tax.toFixed(2)} ${r.gross_sales.toFixed(2)} {r.order_count} {rate.toFixed(2)}% ); }} /> )} {!summary && !loading && (
Click Refresh to load tax summary
)}
)} {/* ── TAXABLE ORDERS TAB ── */} {activeTab === "orders" && (

Taxable Orders

{orders.length > 0 && ( )}
{ const r = row as TaxOrderRow; return ( {r.order_id.slice(0, 8)} {r.date} {r.customer_name} {r.city} {r.state} ${Number(r.taxable_amount).toFixed(2)} ${Number(r.tax_amount).toFixed(2)} {Number(r.tax_rate).toFixed(4)} {r.tax_location} ); }} />
)}
); }