72 lines
2.3 KiB
Svelte
72 lines
2.3 KiB
Svelte
<script lang="ts">
|
|
import ExternalLinkIcon from '@lucide/svelte/icons/external-link';
|
|
import { resolve } from '$app/paths';
|
|
import { Badge, type BadgeVariant } from '$lib/components/ui/badge/index.js';
|
|
import * as Table from '$lib/components/ui/table/index.js';
|
|
import type { PageData } from './$types';
|
|
|
|
let {
|
|
data,
|
|
formatValue,
|
|
formatDate,
|
|
formatMoney,
|
|
relationLabel
|
|
}: {
|
|
data: Pick<PageData, 'records'>;
|
|
formatValue: (value: unknown) => string;
|
|
formatDate: (value: unknown) => string;
|
|
formatMoney: (value: unknown) => string;
|
|
relationLabel: (value: unknown, optionsKey: 'clients') => string;
|
|
} = $props();
|
|
|
|
function statusVariant(status: string): BadgeVariant {
|
|
if (status === 'paid') return 'default';
|
|
if (status === 'void') return 'destructive';
|
|
if (status === 'draft') return 'outline';
|
|
return 'secondary';
|
|
}
|
|
</script>
|
|
|
|
{#if data.records.length > 0}
|
|
<div class="overflow-hidden rounded-lg border border-border">
|
|
<Table.Root>
|
|
<Table.Header>
|
|
<Table.Row>
|
|
<Table.Head>Invoice #</Table.Head>
|
|
<Table.Head>Client</Table.Head>
|
|
<Table.Head>Status</Table.Head>
|
|
<Table.Head>Issued</Table.Head>
|
|
<Table.Head>Due</Table.Head>
|
|
<Table.Head>Total</Table.Head>
|
|
</Table.Row>
|
|
</Table.Header>
|
|
<Table.Body>
|
|
{#each data.records as record (record.id)}
|
|
<Table.Row>
|
|
<Table.Cell class="font-medium"
|
|
><a
|
|
class="inline-flex items-center gap-2 underline-offset-4 hover:text-primary hover:underline"
|
|
href={resolve('/dashboard/invoices/[id]', { id: record.id })}
|
|
>{formatValue(record.invoiceNumber)}<ExternalLinkIcon class="size-3.5" /></a
|
|
></Table.Cell
|
|
>
|
|
<Table.Cell class="">{relationLabel(record.clientId, 'clients')}</Table.Cell>
|
|
<Table.Cell
|
|
><Badge variant={statusVariant(record.status)} class="capitalize"
|
|
>{formatValue(record.status)}</Badge
|
|
></Table.Cell
|
|
>
|
|
<Table.Cell class="">{formatDate(record.issueDate)}</Table.Cell>
|
|
<Table.Cell class="">{formatDate(record.dueDate)}</Table.Cell>
|
|
<Table.Cell class="">{formatMoney(record.totalGbp)}</Table.Cell>
|
|
</Table.Row>
|
|
{/each}
|
|
</Table.Body>
|
|
</Table.Root>
|
|
</div>
|
|
{:else}
|
|
<div class="rounded-lg border p-8 text-center text-sm text-muted-foreground">
|
|
No invoices have been created yet.
|
|
</div>
|
|
{/if}
|