Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
46a4ca1089
commit
9d0dc0e202
@@ -141,6 +141,8 @@ function InvoiceDetail() {
|
||||
|
||||
const canEdit = isAdmin || invoice.created_by === user?.id;
|
||||
const isDraft = invoice.status === "draft";
|
||||
// Line items, notes, and tax can be edited on any non-void invoice (not just drafts).
|
||||
const canModify = canEdit && invoice.status !== "void";
|
||||
const balance = Number(invoice.total) - Number(invoice.amount_paid);
|
||||
|
||||
const setStatus = async (status: string) => {
|
||||
@@ -420,7 +422,7 @@ function InvoiceDetail() {
|
||||
<th className="text-right px-3 py-2 font-medium w-[80px]">Qty</th>
|
||||
<th className="text-right px-3 py-2 font-medium w-[100px]">Rate</th>
|
||||
<th className="text-right px-3 py-2 font-medium w-[110px]">Amount</th>
|
||||
{canEdit && isDraft && <th className="w-[40px]" />}
|
||||
{canModify && <th className="w-[40px]" />}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -433,13 +435,13 @@ function InvoiceDetail() {
|
||||
<td className="px-3 py-1.5 text-right tabular-nums text-xs font-semibold text-muted-foreground">
|
||||
{sub.billable ? formatCurrency(sub.subtotal) : "—"}
|
||||
</td>
|
||||
{canEdit && isDraft && <td />}
|
||||
{canModify && <td />}
|
||||
</tr>
|
||||
{sub.items.map((it) => (
|
||||
<tr key={it.id} className={`border-t ${!sub.billable ? "text-muted-foreground" : ""}`}>
|
||||
<td className="px-3 py-2 text-xs">{it.work_date ? formatDate(it.work_date) : "—"}</td>
|
||||
<td className="px-3 py-2 align-top">
|
||||
{canEdit && isDraft ? (
|
||||
{canModify ? (
|
||||
<Input className="h-8" defaultValue={it.description}
|
||||
onBlur={(e) => e.target.value !== it.description && updateItem(it.id, { description: e.target.value })} />
|
||||
) : (
|
||||
@@ -454,13 +456,13 @@ function InvoiceDetail() {
|
||||
)}
|
||||
</td>
|
||||
<td className="px-3 py-2 text-right tabular-nums">
|
||||
{canEdit && isDraft ? (
|
||||
{canModify ? (
|
||||
<Input className="h-8 text-right tabular-nums" defaultValue={Number(it.quantity)}
|
||||
onBlur={(e) => Number(e.target.value) !== Number(it.quantity) && updateItem(it.id, { quantity: Number(e.target.value) })} />
|
||||
) : Number(it.quantity).toFixed(2)}
|
||||
</td>
|
||||
<td className="px-3 py-2 text-right tabular-nums">
|
||||
{canEdit && isDraft ? (
|
||||
{canModify ? (
|
||||
<Input className="h-8 text-right tabular-nums" defaultValue={Number(it.rate)}
|
||||
onBlur={(e) => Number(e.target.value) !== Number(it.rate) && updateItem(it.id, { rate: Number(e.target.value) })} />
|
||||
) : formatCurrency(it.rate)}
|
||||
@@ -468,7 +470,7 @@ function InvoiceDetail() {
|
||||
<td className="px-3 py-2 text-right tabular-nums font-medium">
|
||||
{sub.billable ? formatCurrency(it.amount) : "—"}
|
||||
</td>
|
||||
{canEdit && isDraft && (
|
||||
{canModify && (
|
||||
<td className="px-2 py-2 text-right">
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-muted-foreground hover:text-destructive" onClick={() => removeItem(it.id)}>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
@@ -481,7 +483,7 @@ function InvoiceDetail() {
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
{canEdit && isDraft && (
|
||||
{canModify && (
|
||||
<div className="border-t px-3 py-2 bg-muted/20">
|
||||
<Button variant="ghost" size="sm" onClick={() => addManualItem(g.caseRow?.id ?? null)} disabled={savingItem}>
|
||||
<Plus className="h-3.5 w-3.5 mr-1.5" /> Add line to {g.caseRow?.case_number ?? "this group"}
|
||||
@@ -492,7 +494,7 @@ function InvoiceDetail() {
|
||||
</Card>
|
||||
))}
|
||||
|
||||
{canEdit && isDraft && groups.length === 0 && (
|
||||
{canModify && groups.length === 0 && (
|
||||
<Button variant="outline" onClick={() => addManualItem(null)}>
|
||||
<Plus className="h-4 w-4 mr-2" /> Add first line item
|
||||
</Button>
|
||||
@@ -501,7 +503,7 @@ function InvoiceDetail() {
|
||||
<Card className="border-border/60">
|
||||
<CardContent className="p-4 space-y-2">
|
||||
<Label className="text-xs uppercase tracking-wider text-muted-foreground">Notes</Label>
|
||||
{canEdit && isDraft ? (
|
||||
{canModify ? (
|
||||
<Textarea defaultValue={invoice.notes ?? ""} rows={3} placeholder="Payment terms, thank-you message…"
|
||||
onBlur={(e) => updateNotes(e.target.value)} />
|
||||
) : (
|
||||
@@ -519,7 +521,7 @@ function InvoiceDetail() {
|
||||
<Row label="Subtotal" value={formatCurrency(invoice.subtotal)} />
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-muted-foreground">Tax</span>
|
||||
{canEdit && isDraft ? (
|
||||
{canModify ? (
|
||||
<div className="flex items-center gap-1">
|
||||
<Input className="h-7 w-16 text-right tabular-nums" type="number" step="0.01"
|
||||
defaultValue={invoice.subtotal > 0 ? ((Number(invoice.tax) / Number(invoice.subtotal)) * 100).toFixed(2) : "0"}
|
||||
|
||||
Reference in New Issue
Block a user