import { createFileRoute, Link } from "@tanstack/react-router"; import { useEffect, useState, useCallback } from "react"; import { ProtectedLayout } from "@/components/protected-layout"; import { PageContainer, PageHeader } from "@/components/app-shell"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { supabase } from "@/integrations/supabase/client"; import { ArrowLeft, FileText, Clock, DollarSign, Activity, Receipt, Scale, Users, Contact, Phone, Tag, Archive, ArchiveRestore } from "lucide-react"; import { ContactsLinkTab } from "@/components/contacts/contacts-link-tab"; import { CaseCallLogsTab } from "@/components/cases/call-logs-tab"; import { formatCurrency, formatDate, statusBadgeClass } from "@/lib/format"; import { CaseDocumentsTab } from "@/components/cases/documents-tab"; import { CaseTimeTab } from "@/components/cases/time-tab"; import { CaseExpensesTab } from "@/components/cases/expenses-tab"; import { CaseStatusTab } from "@/components/cases/status-tab"; import { CaseInvoicesTab } from "@/components/cases/invoices-tab"; import { CaseLitigationTab } from "@/components/cases/litigation-tab"; import { CaseCollectionsTab } from "@/components/cases/collections-tab"; import { CaseCustomFieldsTab } from "@/components/cases/custom-fields-tab"; import { setArchived } from "@/lib/archive"; import { toast } from "sonner"; import { useAuth } from "@/lib/auth"; export const Route = createFileRoute("/cases/$caseId")({ component: () => ( ), }); function CaseDetail() { const { caseId } = Route.useParams(); const { user, isAdmin } = useAuth(); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [users, setUsers] = useState([]); const load = useCallback(async () => { const [{ data: c, error }, { data: us }] = await Promise.all([ supabase .from("cases") .select("*, client:clients(id, name, client_type, annual_interest_rate), assignee:profiles!cases_assigned_attorney_id_fkey(id, full_name, email)") .eq("id", caseId) .maybeSingle(), supabase.from("profiles").select("id, full_name, email"), ]); if (error) toast.error("Failed to load case", { description: error.message }); setData(c); setUsers(us ?? []); setLoading(false); }, [caseId]); useEffect(() => { load(); }, [load]); const updateStatus = async (status: string) => { const { error } = await supabase .from("cases") .update({ status: status as "active" | "closed" | "closed_lost" | "closed_won" | "intake" | "on_hold", closed_at: status.startsWith("closed") ? new Date().toISOString().slice(0, 10) : null }) .eq("id", caseId); if (error) toast.error("Could not update", { description: error.message }); else { toast.success("Status updated"); load(); } }; const updateAssignee = async (assigned_attorney_id: string) => { const { error } = await supabase.from("cases").update({ assigned_attorney_id }).eq("id", caseId); if (error) toast.error(error.message); else { toast.success("Assignee updated"); load(); } }; if (loading) return Loading…; if (!data) { return ( Case not found or you don't have access. All cases ); } const canManage = isAdmin || data.assigned_attorney_id === user?.id || data.created_by === user?.id; return ( All cases {data.case_number} {data.status.replace("_", " ")} {data.title} {data.client.name} {" · "}{data.practice_area || "—"}{" · "}opened {formatDate(data.opened_at)} {canManage && ( {users.map((u) => {u.full_name || u.email})} Intake Active On hold Closed — won Closed — lost Closed )} {data.description && ( {data.description} )} ); } function CaseTabs({ data, caseId, canManage, load }: { data: any; caseId: string; canManage: boolean; load: () => void }) { const [tab, setTab] = useState("litigation"); return ( Litigation Status log Documents Contacts Time Expenses Invoices Calls Custom fields {(data.client?.client_type === "hoa" || data.client?.client_type === "condo") && ( Collections )} setTab("invoices")} /> {(data.client?.client_type === "hoa" || data.client?.client_type === "condo") && ( )} ); } function SmallStat({ label, value }: { label: string; value: string }) { return ( {label} {value} ); }
Loading…
Case not found or you don't have access.
{data.client.name} {" · "}{data.practice_area || "—"}{" · "}opened {formatDate(data.opened_at)}
{data.description}