'use client'; import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts'; import { CardSkeleton } from '@/components/shared/loading-skeleton'; import { EmptyState } from '@/components/shared/empty-state'; import { ChartCard } from './chart-card'; import { useOccupancy } from './use-analytics'; import type { DateRange } from '@/lib/services/analytics.service'; import { rangeToSlug } from '@/lib/analytics/range'; interface Props { range: DateRange; } function shortDate(iso: string) { const d = new Date(`${iso}T00:00:00`); return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); } export function OccupancyTimelineChart({ range }: Props) { const { data, isLoading } = useOccupancy(range); const points = data?.points ?? []; const noBerths = points.length > 0 && points[0]?.total === 0; function toCsv(): string | null { if (!points.length) return null; const header = 'date,occupied,total,occupancy_pct'; const rows = points.map((p) => `${p.date},${p.occupied},${p.total},${p.occupancyPct}`); return [header, ...rows].join('\n'); } return ( {isLoading ? ( ) : noBerths ? ( ) : ( ({ ...p, label: shortDate(p.date) }))} margin={{ top: 8, right: 8, left: -16, bottom: 8 }} > `${v}%`} /> { const p = item?.payload as { occupied?: number; total?: number } | undefined; return [`${value}% (${p?.occupied ?? 0}/${p?.total ?? 0})`, 'Occupancy']; }} /> )} ); }