garage-erp/apps/dashboard/modules/expenses/expense-items-section.tsx
2026-04-23 14:38:41 +03:00

134 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { ShoppingCartIcon } from "lucide-react"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/shared/components/ui/table"
import { formatCurrency } from "@/shared/utils/formatters"
type ExpenseItem = {
id?: number
expense_id?: number
expense_item_id?: number
quantity?: number | string
rate?: string | number
description?: string | null
expense_item?: {
id?: number
item_name?: string
name?: string
item_code?: string
sku?: string
}
}
type ExpenseItemsSectionProps = {
items?: ExpenseItem[]
discountType?: string | null
subTotal?: number | null
discountAmount?: number | null
taxAmount?: number | null
total?: number | null
taxLabel?: string | null
}
export function ExpenseItemsSection({
items,
discountType,
subTotal,
discountAmount,
taxAmount,
total,
taxLabel,
}: ExpenseItemsSectionProps) {
if (!items || items.length === 0) return null
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<ShoppingCartIcon className="size-4" />
Expense Items ({items.length})
</CardTitle>
</CardHeader>
<CardContent>
<div className="overflow-x-auto">
<Table>
<TableHeader>
<TableRow className="hover:bg-transparent">
<TableHead>Item</TableHead>
<TableHead>Description</TableHead>
<TableHead className="text-right w-20">Qty</TableHead>
<TableHead className="text-right w-28">Rate</TableHead>
<TableHead className="text-right w-28">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{items.map((item) => {
const qty = Number(item.quantity || 0)
const rate = Number(item.rate || 0)
const amount = qty * rate
const name = item.expense_item?.item_name || item.expense_item?.name || "—"
return (
<TableRow key={item.id}>
<TableCell className="font-medium">
<div>{name}</div>
{(item.expense_item?.sku || item.expense_item?.item_code) && (
<div className="text-xs text-muted-foreground font-mono">
{item.expense_item?.sku || item.expense_item?.item_code}
</div>
)}
</TableCell>
<TableCell className="text-sm text-muted-foreground">
{item.description || "—"}
</TableCell>
<TableCell className="text-right text-sm">{qty.toLocaleString()}</TableCell>
<TableCell className="text-right text-sm">{formatCurrency(rate)}</TableCell>
<TableCell className="text-right font-semibold">{formatCurrency(amount)}</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
</div>
{/* ── Totals summary ── */}
<div className="mt-4 flex justify-end">
<div className="w-64 space-y-1 text-sm">
{subTotal != null && (
<div className="flex justify-between">
<span className="text-muted-foreground">Subtotal</span>
<span className="font-medium">{formatCurrency(subTotal)}</span>
</div>
)}
{discountAmount != null && discountAmount > 0 && discountType !== "no" && (
<div className="flex justify-between text-destructive">
<span>Discount</span>
<span> {formatCurrency(discountAmount)}</span>
</div>
)}
{taxAmount != null && taxAmount > 0 && (
<div className="flex justify-between">
<span className="text-muted-foreground">{taxLabel || "Tax"}</span>
<span className="font-medium">{formatCurrency(taxAmount)}</span>
</div>
)}
{total != null && (
<div className="flex justify-between border-t pt-2 text-base font-semibold">
<span>Total</span>
<span>{formatCurrency(total)}</span>
</div>
)}
</div>
</div>
</CardContent>
</Card>
)
}