"use client"; import { useState, Fragment, useEffect } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Skeleton } from "@/components/ui/skeleton"; import { ChevronDown, ChevronUp, Plane, PlaneLanding, PlaneTakeoff, Radio } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; interface Flight { callsign: string; type: 'Departure' | 'Arrival'; time: string; route: string; origin: string; destination: string; } interface Controller { callsign: string; frequency: string; facility: string; facilityLong: string; } interface MetarTableProps { data: any[]; loading: boolean; } export function MetarTable({ data, loading }: MetarTableProps) { const [expandedAirport, setExpandedAirport] = useState(null); const [flights, setFlights] = useState([]); const [loadingFlights, setLoadingFlights] = useState(false); const [controllers, setControllers] = useState>({}); // Fetch controller data useEffect(() => { async function fetchControllers() { try { const response = await fetch('/api/controllers'); const data = await response.json(); setControllers(data); } catch (error) { console.error('Failed to fetch controller data:', error); } } fetchControllers(); // Refresh controller data every minute const interval = setInterval(fetchControllers, 60000); return () => clearInterval(interval); }, []); const handleAirportClick = async (airport: string) => { if (expandedAirport === airport) { setExpandedAirport(null); return; } setExpandedAirport(airport); setLoadingFlights(true); try { const response = await fetch(`/api/vatsim/${airport}`); const data = await response.json(); setFlights(data); } catch (error) { console.error('Failed to fetch flights:', error); } finally { setLoadingFlights(false); } }; const getBadgeVariant = (facility: string) => { switch (facility) { case 'CTR': return "secondary"; case 'APP': return "default"; case 'TWR': return "default"; default: return "outline"; } }; if (loading) { return ; } return ( Airport Conditions RWY Wind (°/kts) Headwind (kts) Xwind (kts) Altimeter ATC METAR {data.map((row, index) => ( handleAirportClick(row.airport)} > {expandedAirport === row.airport ? ( ) : ( )} {row.airport} {row.flightRules} {row.bestRunway} {row.wind} {row.headwind} {row.crosswind} {row.altimeter} {controllers[row.airport] ? (
{controllers[row.airport].map((controller, i) => ( {controller.facility} {controller.frequency}

{controller.facilityLong}

{controller.callsign}

))}
) : ( Uncontrolled )}
{row.metar}
{expandedAirport === row.airport && ( {loadingFlights ? (
) : flights.length > 0 ? (

Active Flights

{flights.map((flight, i) => (
{flight.type === 'Departure' ? ( ) : ( )} {flight.callsign}

{flight.type}: {flight.time}Z

{flight.origin} → {flight.destination}

{flight.route}

))}
) : (

No active flights found for {row.airport}

)}
)}
))}
); } function LoadingSkeleton() { return (
{Array.from({ length: 5 }).map((_, i) => (
))}
); }