import { Card, Descriptions, Tabs, Table, Tag, Typography, Button, Space, Spin, Result } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { ArrowLeftOutlined } from '@ant-design/icons';
import { useQuery } from '@tanstack/react-query';
import { useNavigate, useParams } from 'react-router-dom';
import {
fetchFleetCustomerDetail, type FleetSite, type FleetDevice,
type FleetRecentMeasurement, type FleetIngestEvent,
} from '../api/fleet';
const { Text } = Typography;
export function AdminCustomerDetailPage() {
const { id = '' } = useParams<{ id: string }>();
const navigate = useNavigate();
const { data, isLoading, error } = useQuery({
queryKey: ['fleet-customer', id],
queryFn: () => fetchFleetCustomerDetail(id),
refetchInterval: 30_000,
});
if (isLoading) return
;
if (error || !data) {
return navigate('/admin/customers')}>Back} />;
}
const siteCols: ColumnsType = [
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Address', dataIndex: 'address', key: 'addr', render: v => v ?? — },
{ title: 'Active', dataIndex: 'isActive', key: 'a', render: (v: boolean) => v ? Active : Inactive },
];
const deviceCols: ColumnsType = [
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'External ID', dataIndex: 'externalId', key: 'ext', render: v => {v} },
{ title: 'Description', dataIndex: 'description', key: 'desc', render: v => v ?? — },
{ title: 'Active', dataIndex: 'isActive', key: 'a', render: (v: boolean) => v ? Active : Inactive },
];
const measCols: ColumnsType = [
{ title: 'Time (UTC)', dataIndex: 'time', key: 't', render: (v: string) => new Date(v).toISOString().replace('T', ' ').slice(0, 19) },
{ title: 'Device', dataIndex: 'deviceName', key: 'd' },
{ title: 'Active power (kW)', dataIndex: 'activePowerKw', key: 'p', render: (v: number) => v.toFixed(3) },
{ title: 'kWh imported (cumulative)', dataIndex: 'energyImportedKwh', key: 'e', render: (v: number | null) => v == null ? '—' : v.toFixed(2) },
];
const eventCols: ColumnsType = [
{ title: 'Received (UTC)', dataIndex: 'receivedAt', key: 'r', render: (v: string) => new Date(v).toISOString().replace('T', ' ').slice(0, 19) },
{ title: 'Type', dataIndex: 'batchType', key: 'bt' },
{ title: 'Accepted', dataIndex: 'rowsAccepted', key: 'a' },
{ title: 'Rejected', dataIndex: 'rowsRejected', key: 'rj', render: (v: number) => v > 0 ? {v} : v },
{ title: 'Bytes', dataIndex: 'batchBytes', key: 'b' },
{ title: 'Time spread', dataIndex: 'timeSpread', key: 'ts', render: (v: string | null) => v ?? '—' },
{ title: 'Error', dataIndex: 'error', key: 'e', render: (v: string | null) => v ? {v} : '—' },
];
return (
} onClick={() => navigate('/admin/customers')}>Customers
{data.code} · {data.name}
{data.isActive ? Active : Disabled}
{data.id}
{new Date(data.createdAt).toLocaleString()}
{data.firstSeenAt ? new Date(data.firstSeenAt).toLocaleString() : Never}
{data.lastSeenAt ? new Date(data.lastSeenAt).toLocaleString() : Never}
rowKey="receivedAt" columns={eventCols} dataSource={data.recentIngestEvents} pagination={false} size="small" />,
},
{
key: 'measurements',
label: `Recent measurements (${data.recentMeasurements.length})`,
children: rowKey={(r) => `${r.time}-${r.deviceId}`} columns={measCols} dataSource={data.recentMeasurements} pagination={false} size="small" />,
},
{
key: 'sites',
label: `Sites (${data.sites.length})`,
children: rowKey="id" columns={siteCols} dataSource={data.sites} pagination={false} size="small" />,
},
{
key: 'devices',
label: `Devices (${data.devices.length})`,
children: rowKey="id" columns={deviceCols} dataSource={data.devices} pagination={false} size="small" />,
},
]}
/>
);
}