Fixed time decimal rounding

X-Lovable-Edit-ID: edt-7be3c963-cec2-4b69-8a12-5b87d0b4a0cb
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-22 20:52:14 +00:00
co-authored by renee-png
+7 -7
View File
@@ -10,7 +10,7 @@ import { useAuth } from "@/lib/auth";
import { Plus, Trash2, Loader2, FilePlus, PlusCircle, CheckCircle2, Undo2, Download } from "lucide-react";
import { formatCurrency, formatDate } from "@/lib/format";
import { ensureMarkedInvoicedPlaceholder } from "@/lib/invoice-generation";
import { roundToSixth } from "@/lib/timer";
import { roundToTenth } from "@/lib/timer";
import { toast } from "sonner";
import { ImportUnbilledDialog } from "@/components/cases/import-unbilled-dialog";
import {
@@ -51,9 +51,9 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
billable: true,
});
// Compute total raw hours from hours + minutes inputs, then round UP to 1/6.
// Compute total raw hours from hours + minutes inputs, then round UP to 1/10 hr (6 min).
const rawHours = (parseFloat(form.hours || "0") || 0) + (parseFloat(form.minutes || "0") || 0) / 60;
const roundedHours = roundToSixth(rawHours);
const roundedHours = roundToTenth(rawHours);
const [fees, setFees] = useState<FeeItem[]>([]);
const [selectedFeeId, setSelectedFeeId] = useState<string>("");
@@ -125,7 +125,7 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
setSubmitting(false);
if (error) toast.error(error.message);
else {
toast.success(`Time entry added (${hours.toFixed(2)} hrs)`);
toast.success(`Time entry added (${hours.toFixed(1)} hrs)`);
setShowForm(false);
setForm({ ...form, hours: "", minutes: "", description: "" });
load();
@@ -173,7 +173,7 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
<div className="space-y-4">
<div className="flex flex-wrap gap-3 items-center justify-between">
<div className="flex gap-4 text-sm">
<Stat label="Hours" value={totals.hours.toFixed(2)} />
<Stat label="Hours" value={totals.hours.toFixed(1)} />
<Stat label="Billed total" value={formatCurrency(totals.billable)} />
<Stat label="Unbilled" value={formatCurrency(totals.unbilled)} />
</div>
@@ -251,7 +251,7 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
<Input type="number" step="1" min="0" placeholder="0" value={form.minutes} onChange={(e) => setForm({ ...form, minutes: e.target.value })} />
{rawHours > 0 && (
<p className="text-[11px] text-muted-foreground">
Billed as {roundedHours.toFixed(2)} hrs (1/6 hr)
Billed as {roundedHours.toFixed(1)} hrs (1/10 hr)
</p>
)}
</div>
@@ -302,7 +302,7 @@ export function CaseTimeTab({ caseRecord, onInvoice }: CaseTimeTabProps) {
<td className="px-4 py-3 text-muted-foreground whitespace-nowrap">{formatDate(e.work_date)}</td>
<td className="px-4 py-3 text-muted-foreground">{e.user?.full_name || e.user?.email}</td>
<td className="px-4 py-3 max-w-md">{e.description}</td>
<td className="px-4 py-3 text-right tabular-nums">{Number(e.hours).toFixed(2)}</td>
<td className="px-4 py-3 text-right tabular-nums">{Number(e.hours).toFixed(1)}</td>
<td className="px-4 py-3 text-right tabular-nums text-muted-foreground">{formatCurrency(e.hourly_rate)}</td>
<td className="px-4 py-3 text-right tabular-nums font-medium">{e.billable ? formatCurrency(Number(e.hours) * Number(e.hourly_rate)) : "—"}</td>
<td className="px-4 py-3 text-xs text-muted-foreground">{!e.billable ? "Non-billable" : e.invoice_id ? "Invoiced" : "Unbilled"}</td>