50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
'use client';
|
|
|
|
import {VStack, HStack} from '@astryxdesign/core/Layout';
|
|
import {Text} from '@astryxdesign/core/Text';
|
|
import {Badge} from '@astryxdesign/core/Badge';
|
|
import {Timestamp} from '@astryxdesign/core/Timestamp';
|
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
import {AsyncBoundary} from '@/shared/components/data/AsyncBoundary';
|
|
import {SkeletonRows} from '@/shared/components/patterns/LoadingState';
|
|
import {EmptyPanel} from '@/shared/components/patterns/EmptyPanel';
|
|
import {useCustomerHistory} from '@/features/customers/hooks/useCustomers';
|
|
|
|
/** Their visits, newest first — the one that enrolled them is marked. */
|
|
export function CustomerHistory({customerId}: {customerId: string}) {
|
|
const history = useCustomerHistory(customerId);
|
|
|
|
return (
|
|
<AsyncBoundary
|
|
resource={history}
|
|
loading={<SkeletonRows count={4} height={28} />}
|
|
empty={
|
|
<EmptyPanel
|
|
icon="visitors"
|
|
title="No visits recorded"
|
|
description="Visits appear here once a camera recognises them."
|
|
/>
|
|
}
|
|
>
|
|
{(visits) => (
|
|
<VStack gap={2}>
|
|
{visits.map((v, i) => (
|
|
<VStack key={v.id} gap={2}>
|
|
{i > 0 ? <Divider /> : null}
|
|
<HStack gap={2} vAlign="center" hAlign="between">
|
|
<VStack gap={0}>
|
|
<Timestamp value={v.occurredAt} format="date_time" />
|
|
<Text size="xsm" color="secondary">
|
|
{v.siteName}
|
|
</Text>
|
|
</VStack>
|
|
{v.isNewVisitor ? <Badge variant="neutral" label="First visit" /> : null}
|
|
</HStack>
|
|
</VStack>
|
|
))}
|
|
</VStack>
|
|
)}
|
|
</AsyncBoundary>
|
|
);
|
|
}
|