78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
import { Card, CardContent } from "@/components/ui/card";
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@/components/ui/table";
|
|
import { apiGet } from "@/lib/api";
|
|
import { useAuthStore } from "@/store/authStore";
|
|
import type { CustomerRow } from "@/lib/types";
|
|
import { formatDate } from "@/lib/format";
|
|
|
|
export function CustomersPage() {
|
|
const selectedPropertyId = useAuthStore((s) => s.selectedPropertyId);
|
|
const [rows, setRows] = useState<CustomerRow[]>([]);
|
|
|
|
useEffect(() => {
|
|
apiGet<{ data: CustomerRow[] }>("/customers").then((r) =>
|
|
setRows(r.data)
|
|
);
|
|
}, [selectedPropertyId]);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h1 className="text-2xl font-bold">Customers</h1>
|
|
<p className="text-sm text-muted-foreground">
|
|
Aggregated from bookings (read-only mock).
|
|
</p>
|
|
<Card className="rounded-2xl">
|
|
<CardContent className="pt-6">
|
|
<div className="hidden md:block">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Name</TableHead>
|
|
<TableHead>Email</TableHead>
|
|
<TableHead>Bookings</TableHead>
|
|
<TableHead>Last stay</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{rows.map((c) => (
|
|
<TableRow key={c.email}>
|
|
<TableCell className="font-medium">{c.name}</TableCell>
|
|
<TableCell className="text-sm text-muted-foreground">
|
|
{c.email}
|
|
</TableCell>
|
|
<TableCell>{c.bookingCount}</TableCell>
|
|
<TableCell>
|
|
{c.lastStay ? formatDate(c.lastStay) : "—"}
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
<div className="space-y-2 md:hidden">
|
|
{rows.map((c) => (
|
|
<div key={c.email} className="rounded-xl border p-3 text-sm">
|
|
<p className="font-medium">{c.name}</p>
|
|
<p className="text-muted-foreground">{c.email}</p>
|
|
<p className="mt-1 text-xs">
|
|
{c.bookingCount} bookings
|
|
{c.lastStay && ` · last ${formatDate(c.lastStay)}`}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|