diff --git a/frontend/src/lib/components/PaymentBillComp.svelte b/frontend/src/lib/components/PaymentBillComp.svelte index a0d837b..2e4742d 100644 --- a/frontend/src/lib/components/PaymentBillComp.svelte +++ b/frontend/src/lib/components/PaymentBillComp.svelte @@ -10,15 +10,26 @@ }; export let monthFor: Date = new Date(); - let showDatePicker = false; - let selectedDate = ""; let paymentDate: string = ""; + let previousValidDate: string = ""; + let dateElement: HTMLElement | null = null; + let isEditing = false; $: { - if (paymentBill.payment && paymentBill.payment.paymentDate) { + if (!isEditing && paymentBill.payment && paymentBill.payment.paymentDate) { // @ts-ignore Yes split exists... The type is time.Time but it's actually a string - paymentDate = paymentBill.payment.paymentDate.split("T")[0]; - selectedDate = paymentDate; + const isoString = paymentBill.payment.paymentDate.split("T")[0]; + paymentDate = isoString; + previousValidDate = isoString; + if (dateElement) { + dateElement.textContent = isoString; + } + } else if (!isEditing) { + paymentDate = ""; + previousValidDate = ""; + if (dateElement) { + dateElement.textContent = ""; + } } } @@ -28,17 +39,43 @@ throw new Error(`failed setting paid for ${paymentBill.id} and month ${monthFor} with error ${res.error}`); } paymentBill.payment = res.data; - showDatePicker = false; } - async function doPaidWithDate() { - const dateObj = new Date(selectedDate + "T00:00:00"); + function handleDateFocus() { + isEditing = true; + } + + async function handleDateBlur(event: FocusEvent) { + isEditing = false; + const target = event.target as HTMLElement; + const newDate = target.textContent?.trim() || ""; + + if (!newDate) { + target.textContent = previousValidDate; + return; + } + + if (!/^\d{4}-\d{2}-\d{2}$/.test(newDate)) { + target.textContent = previousValidDate; + return; + } + + const isoDateString = newDate + "T00:00:00.000Z"; + const dateObj = new Date(isoDateString); + if (isNaN(dateObj.getTime())) { + target.textContent = previousValidDate; + return; + } + const res = await SetPaidWithDate(paymentBill.id, monthFor, dateObj); if (!res.success) { + target.textContent = previousValidDate; throw new Error(`failed setting paid for ${paymentBill.id} with custom date: ${res.error}`); } + paymentBill.payment = res.data; - showDatePicker = false; + previousValidDate = newDate; + paymentDate = newDate; } async function doUnmarkPaid() { @@ -49,40 +86,46 @@ paymentBill.payment = null; } - function openDatePicker() { - if (paymentBill.payment) { - showDatePicker = true; - } else { - doPaid(); - } - } diff --git a/service.go b/service.go index 3fc5db8..389bedb 100644 --- a/service.go +++ b/service.go @@ -118,7 +118,6 @@ INSERT INTO Payment (billid, monthFor, paymentDate) VALUES (?, date(strftime('%Y-%m-01', ?)), ?) ON CONFLICT(billid, monthFor) DO UPDATE SET paymentDate = excluded.paymentDate -WHERE Payment.paymentDate IS NULL `, billid, monthFor, when) if err != nil { return res, fmt.Errorf("failed upserting into payment with error: %w", err)