Added staff selector to T&E

X-Lovable-Edit-ID: edt-e676f091-6e79-40e5-871c-5996593faa74
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-27 23:46:56 +00:00
co-authored by renee-png
+31 -1
View File
@@ -42,6 +42,8 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
const [showForm, setShowForm] = useState(false);
const [submitting, setSubmitting] = useState(false);
const [profileRate, setProfileRate] = useState<number | null>(null);
const [staff, setStaff] = useState<Array<{ id: string; full_name: string | null; email: string | null; hourly_rate: number | null }>>([]);
const [enteredById, setEnteredById] = useState<string>("");
const [form, setForm] = useState({
work_date: new Date().toISOString().slice(0, 10),
hours: "",
@@ -60,6 +62,20 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
const [showNewFee, setShowNewFee] = useState(false);
const [showImport, setShowImport] = useState(false);
useEffect(() => {
(async () => {
const { data } = await supabase
.from("profiles")
.select("id, full_name, email, hourly_rate")
.order("full_name");
setStaff((data ?? []) as any);
})();
}, []);
useEffect(() => {
if (user?.id && !enteredById) setEnteredById(user.id);
}, [user?.id, enteredById]);
const load = async () => {
const { data, error } = await supabase
.from("time_entries")
@@ -112,10 +128,11 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
if (!hours || hours <= 0) { toast.error("Time must be greater than 0"); return; }
if (!form.description.trim()) { toast.error("Description required"); return; }
if (!user?.id) { toast.error("Not signed in"); return; }
const userIdForEntry = enteredById || user.id;
setSubmitting(true);
const { error } = await supabase.from("time_entries").insert({
case_id: caseRecord.id,
user_id: user.id,
user_id: userIdForEntry,
work_date: form.work_date,
hours,
hourly_rate: rate,
@@ -242,6 +259,19 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
<Label className="text-xs">Date</Label>
<Input type="date" value={form.work_date} onChange={(e) => setForm({ ...form, work_date: e.target.value })} required />
</div>
<div className="space-y-1.5">
<Label className="text-xs">Entered by</Label>
<Select value={enteredById} onValueChange={setEnteredById}>
<SelectTrigger><SelectValue placeholder="Select staff…" /></SelectTrigger>
<SelectContent>
{staff.map((s) => (
<SelectItem key={s.id} value={s.id}>
{(s.full_name || s.email || "Unknown") + (s.id === user?.id ? " (me)" : "")}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-1.5">
<Label className="text-xs">Hours</Label>
<Input type="number" step="1" min="0" placeholder="0" value={form.hours} onChange={(e) => setForm({ ...form, hours: e.target.value })} />