// app/live/page.tsx // Live race view with track map and timing import { query } from '@/lib/db'; import { ActivityIcon } from '@/components/ui/icons'; import LiveSessionClient from '@/components/live/LiveSessionClient'; export const dynamic = "force-dynamic"; interface LiveData { server_id: number; server_name: string; server_track: string; server_config: string; connected_players: number; cars: any[]; } async function getLiveData(): Promise { const sql = ` SELECT s.server_id, s.server_name, s.server_track, s.server_config, s.connected_players FROM servers s WHERE s.connected_players > 0 ORDER BY s.connected_players DESC `; const servers = await query(sql); // For each server, get connected cars with their positions const liveData = await Promise.all( servers.map(async (server: any) => { const carsSql = ` SELECT u.driver_guid, u.driver_name, u.car_model, u.laps_completed FROM users u WHERE u.current_server = $1 AND u.is_connect = true ORDER BY u.user_rank ASC `; const cars = await query(carsSql, [server.server_id]); // Add mock data for positions (real data will come from telemetry stream) const carsWithPositions = cars.map((car: any, index: number) => ({ ...car, carID: index, position: index + 1, current_lap: car.laps_completed || 0, normalizedSplinePos: Math.random(), speed: 0, gear: 0, rpm: 0, last_lap_time: null, best_lap_time: null, })); return { ...server, cars: carsWithPositions, }; }) ); return liveData; } export default async function LivePage() { const liveData = await getLiveData(); return ( <> {/* Hero */}
LIVE TIMING

LIVE VIEW

Real-time race positions and telemetry from active servers

{/* Live Sessions */}
{liveData.length === 0 ? (

NO ACTIVE SESSIONS

Join a server to see live timing

) : ( liveData.map((session) => ( )) )}
{/* Info Box */}

ABOUT LIVE VIEW

• Data updates in real-time from UDP telemetry stream

• Track positions calculated from normalized spline position (0.0 - 1.0)

• Lap times and gaps updated every sector

); }