94 lines
2.8 KiB
TypeScript
94 lines
2.8 KiB
TypeScript
import { useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import {
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@/components/ui/table";
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import { formatDistanceToNow } from "date-fns";
|
|
|
|
interface ControllerTableProps {
|
|
data: any[];
|
|
loading: boolean;
|
|
}
|
|
|
|
export function ControllerTable({ data, loading }: ControllerTableProps) {
|
|
const router = useRouter();
|
|
|
|
const handleControllerClick = (cid: string) => {
|
|
router.push(`/controllers/${cid}`);
|
|
};
|
|
|
|
if (loading) {
|
|
return <LoadingSkeleton />;
|
|
}
|
|
|
|
return (
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Name</TableHead>
|
|
<TableHead>CID</TableHead>
|
|
<TableHead>Current Position</TableHead>
|
|
<TableHead>Airport</TableHead>
|
|
<TableHead>Frequency</TableHead>
|
|
<TableHead>Rating</TableHead>
|
|
<TableHead>Last Seen</TableHead>
|
|
<TableHead>Session Duration</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{data.map((controller) => (
|
|
<TableRow
|
|
key={controller.cid}
|
|
className="cursor-pointer hover:bg-muted/50"
|
|
onClick={() => handleControllerClick(controller.cid)}
|
|
>
|
|
<TableCell className="font-medium">{controller.name}</TableCell>
|
|
<TableCell>{controller.cid}</TableCell>
|
|
<TableCell>{controller.callsign}</TableCell>
|
|
<TableCell>{controller.airport}</TableCell>
|
|
<TableCell>{controller.frequency}</TableCell>
|
|
<TableCell>{controller.rating}</TableCell>
|
|
<TableCell>
|
|
{formatDistanceToNow(new Date(controller.lastSeen), { addSuffix: true })}
|
|
</TableCell>
|
|
<TableCell>
|
|
{formatSessionDuration(controller.logonTime, controller.lastSeen)}
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
);
|
|
}
|
|
|
|
function formatSessionDuration(start: string, end: string) {
|
|
const duration = new Date(end).getTime() - new Date(start).getTime();
|
|
const hours = Math.floor(duration / (1000 * 60 * 60));
|
|
const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60));
|
|
return `${hours}h ${minutes}m`;
|
|
}
|
|
|
|
function LoadingSkeleton() {
|
|
return (
|
|
<div className="space-y-3 p-4">
|
|
{Array.from({ length: 5 }).map((_, i) => (
|
|
<div key={i} className="flex gap-4">
|
|
<Skeleton className="h-4 w-[150px]" />
|
|
<Skeleton className="h-4 w-[100px]" />
|
|
<Skeleton className="h-4 w-[120px]" />
|
|
<Skeleton className="h-4 w-[80px]" />
|
|
<Skeleton className="h-4 w-[100px]" />
|
|
<Skeleton className="h-4 w-[80px]" />
|
|
<Skeleton className="h-4 w-[120px]" />
|
|
<Skeleton className="h-4 w-[100px]" />
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
} |