From 5b31a252e4f11c264c8614730145c551eb6775db Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:29:51 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/components/cases/time-tab.tsx | 124 ++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/src/components/cases/time-tab.tsx b/src/components/cases/time-tab.tsx index d0e73a6..7f2a4d4 100644 --- a/src/components/cases/time-tab.tsx +++ b/src/components/cases/time-tab.tsx @@ -62,6 +62,7 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) { const [selectedFeeId, setSelectedFeeId] = useState(""); const [showNewFee, setShowNewFee] = useState(false); const [showImport, setShowImport] = useState(false); + const [editEntry, setEditEntry] = useState(null); useEffect(() => { (async () => { @@ -355,6 +356,7 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) { )} {!e.invoice_id && } + {!e.invoice_id && } @@ -394,6 +396,14 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) { clientId={caseRecord.client_id ?? null} onImported={load} /> + + setEditEntry(null)} + onSaved={() => { setEditEntry(null); load(); }} + /> ); } @@ -406,3 +416,117 @@ function Stat({ label, value }: { label: string; value: string }) { ); } + +function EditTimeEntryDialog({ + entry, + staff, + currentUserId, + onClose, + onSaved, +}: { + entry: any | null; + staff: Array<{ id: string; full_name: string | null; email: string | null; hourly_rate: number | null }>; + currentUserId: string; + onClose: () => void; + onSaved: () => void; +}) { + const [form, setForm] = useState({ + work_date: "", + user_id: "", + hours: "", + hourly_rate: "", + description: "", + billable: true, + }); + const [saving, setSaving] = useState(false); + + useEffect(() => { + if (entry) { + setForm({ + work_date: entry.work_date ?? "", + user_id: entry.user_id ?? currentUserId, + hours: String(entry.hours ?? ""), + hourly_rate: String(entry.hourly_rate ?? ""), + description: entry.description ?? "", + billable: !!entry.billable, + }); + } + }, [entry, currentUserId]); + + const save = async () => { + if (!entry) return; + const hours = roundToTenth(parseFloat(form.hours || "0") || 0); + const rate = parseFloat(form.hourly_rate || "0") || 0; + if (hours <= 0) { toast.error("Hours must be greater than 0"); return; } + if (!form.description.trim()) { toast.error("Description required"); return; } + setSaving(true); + const { error } = await supabase + .from("time_entries") + .update({ + work_date: form.work_date, + user_id: form.user_id, + hours, + hourly_rate: rate, + description: form.description.trim(), + billable: form.billable, + }) + .eq("id", entry.id); + setSaving(false); + if (error) { toast.error(error.message); return; } + toast.success("Time entry updated"); + onSaved(); + }; + + return ( + { if (!o) onClose(); }}> + + Edit time entry +
+
+
+ + setForm({ ...form, work_date: e.target.value })} /> +
+
+ + +
+
+
+
+ + setForm({ ...form, hours: e.target.value })} /> +
+
+ + setForm({ ...form, hourly_rate: e.target.value })} /> +
+
+
+ +