Added billed time to cases
X-Lovable-Edit-ID: edt-d5bb0ae8-2204-4856-8b35-d2c2ae97bf3e Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,7 @@ import { supabase } from "@/integrations/supabase/client";
|
||||
import { ClientFormDialog } from "@/components/clients/client-form-dialog";
|
||||
import { useAuth } from "@/lib/auth";
|
||||
import { ArrowLeft, Edit, Plus, Building2, User, Briefcase as Building, MapPin, Mail, Phone, Users } from "lucide-react";
|
||||
import { formatDate, statusBadgeClass } from "@/lib/format";
|
||||
import { formatCurrency, formatDate, statusBadgeClass } from "@/lib/format";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export const Route = createFileRoute("/clients/$clientId")({
|
||||
@@ -36,8 +36,24 @@ function ClientDetail() {
|
||||
supabase.from("cases").select("id, case_number, title, status, opened_at").eq("client_id", clientId).order("opened_at", { ascending: false }),
|
||||
]);
|
||||
if (ce) toast.error("Failed to load client", { description: ce.message });
|
||||
const caseIds = (cs ?? []).map((x: any) => x.id);
|
||||
let totals: Record<string, { hours: number; amount: number }> = {};
|
||||
if (caseIds.length) {
|
||||
const { data: te } = await supabase
|
||||
.from("time_entries")
|
||||
.select("case_id, hours, hourly_rate, billable")
|
||||
.in("case_id", caseIds)
|
||||
.eq("billable", true);
|
||||
(te ?? []).forEach((t: any) => {
|
||||
const h = Number(t.hours) || 0;
|
||||
const r = Number(t.hourly_rate) || 0;
|
||||
if (!totals[t.case_id]) totals[t.case_id] = { hours: 0, amount: 0 };
|
||||
totals[t.case_id].hours += h;
|
||||
totals[t.case_id].amount += h * r;
|
||||
});
|
||||
}
|
||||
setClient(c);
|
||||
setCases(cs ?? []);
|
||||
setCases((cs ?? []).map((x: any) => ({ ...x, billed: totals[x.id] ?? { hours: 0, amount: 0 } })));
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
@@ -180,6 +196,9 @@ function ClientDetail() {
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{c.case_number} · opened {formatDate(c.opened_at)}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground mt-0.5">
|
||||
Billed: {c.billed.hours.toFixed(1)} hr · {formatCurrency(c.billed.amount)}
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user