2026-01-26 11:30:40 -05:00

129 lines
3.8 KiB
Svelte

<script lang="ts">
import ItemActions from '$lib/components/admin/ItemActions.svelte';
import { IconEdit, IconTrash } from '$lib/components/icons';
import { formatDate } from '$lib/utils/date';
interface Labor {
id: string;
amount: number | null;
startDate: string | null;
endDate: string | null;
}
interface Props {
labors: Labor[];
showHistory: boolean;
onAdd: () => void;
onEdit: (labor: Labor) => void;
onDelete: (laborId: string) => void;
onToggleHistory: () => void;
}
let { labors, showHistory, onAdd, onEdit, onDelete, onToggleHistory }: Props = $props();
let currentLabor = $derived(labors.find((l) => !l.endDate));
let historicalLabors = $derived(labors.filter((l) => l.endDate));
function formatCurrency(amount: number | null | undefined): string {
if (amount === null || amount === undefined) return '$0.00';
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount);
}
</script>
<div class="mt-3 border-t border-theme pt-3">
<div class="mb-2 flex items-center justify-between">
<p class="text-xs font-medium tracking-wide text-theme-muted uppercase">Labor</p>
<button
type="button"
onclick={onAdd}
class="text-xs font-medium text-primary-500 hover:text-primary-600"
>
+ Add
</button>
</div>
{#if currentLabor}
<div
class="rounded border-2 border-blue-200 bg-blue-50 p-2 text-sm dark:border-blue-800 dark:bg-blue-900/20"
>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<span class="font-bold text-blue-700 dark:text-blue-400">
{formatCurrency(currentLabor.amount)}
</span>
<span
class="rounded bg-blue-100 px-1.5 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-900/40 dark:text-blue-400"
>
Current
</span>
</div>
<div class="flex items-center gap-1">
<button
type="button"
onclick={() => onEdit(currentLabor)}
class="rounded p-1 text-blue-600 hover:bg-blue-100 dark:text-blue-400 dark:hover:bg-blue-900/40"
aria-label="Edit labor"
>
<IconEdit class="h-3.5 w-3.5" />
</button>
<button
type="button"
onclick={() => onDelete(currentLabor.id)}
class="rounded p-1 text-blue-600 hover:bg-red-50 hover:text-red-500 dark:text-blue-400 dark:hover:bg-red-900/20"
aria-label="Delete labor"
>
<IconTrash class="h-3.5 w-3.5" />
</button>
</div>
</div>
<p class="mt-1 text-xs text-blue-600 dark:text-blue-500">
As of {formatDate(currentLabor.startDate) || '—'}
</p>
</div>
{:else}
<p class="text-xs text-theme-muted">No current labor rate set.</p>
{/if}
{#if historicalLabors.length > 0}
<button
type="button"
onclick={onToggleHistory}
class="mt-2 flex w-full items-center justify-between text-xs text-theme-secondary hover:text-theme"
>
<span>History ({historicalLabors.length})</span>
<svg
class="h-3 w-3 transition-transform {showHistory ? 'rotate-180' : ''}"
style="fill: none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
{#if showHistory}
<div class="mt-2 space-y-1">
{#each historicalLabors as labor (labor.id)}
<div
class="flex items-center justify-between rounded border border-theme bg-theme-card p-2 text-xs"
>
<div>
<span class="font-medium text-theme">{formatCurrency(labor.amount)}</span>
<span class="text-theme-muted">
({formatDate(labor.startDate) || '—'} - {formatDate(labor.endDate) || 'Present'})
</span>
</div>
<ItemActions
size="sm"
editLabel="Edit labor"
deleteLabel="Delete labor"
onEdit={() => onEdit(labor)}
onDelete={() => onDelete(labor.id)}
/>
</div>
{/each}
</div>
{/if}
{/if}
</div>