'use client' import { useState, useEffect, useCallback, useMemo } from 'react' import { XMarkIcon } from '@heroicons/react/24/outline' import axios from 'axios' import StationSelector, { Station } from '../StationSelector' import DirectionCard from './DirectionCard' import { StationConfig } from '@/types/config' interface Route { routeId: string arrival_times: number[] } interface StationData { stationId: string routes: Route[] } interface StationCardProps { configId: string initialConfig?: StationConfig availableLines: string[] onConfigChange?: (configId: string, config: StationConfig) => void onRemove?: () => void } export default function StationCard({ configId, initialConfig, availableLines, onConfigChange, onRemove }: StationCardProps) { const [selectedStation, setSelectedStation] = useState( initialConfig ? { id: initialConfig.stationId, name: initialConfig.stationName } : null ) const [showNorth, setShowNorth] = useState(initialConfig?.showNorth ?? true) const [showSouth, setShowSouth] = useState(initialConfig?.showSouth ?? true) const [selectedLines, setSelectedLines] = useState>( new Set(initialConfig?.selectedLines ?? availableLines) ) const [northData, setNorthData] = useState(null) const [southData, setSouthData] = useState(null) const notifyConfigChange = useCallback(() => { if (onConfigChange && selectedStation) { onConfigChange(configId, { id: configId, stationId: selectedStation.id, stationName: selectedStation.name, showNorth, showSouth, selectedLines: Array.from(selectedLines), }) } }, [configId, onConfigChange, selectedStation, showNorth, showSouth, selectedLines]) useEffect(() => { notifyConfigChange() }, [notifyConfigChange]) const fetchStationData = useCallback(async () => { if (!selectedStation) return if (showNorth) { try { const response = await axios.post(`/api/mta/${selectedStation.id}N`) setNorthData(response.data) } catch (err) { console.error('Error fetching north station data:', err) setNorthData(null) } } if (showSouth) { try { const response = await axios.post(`/api/mta/${selectedStation.id}S`) setSouthData(response.data) } catch (err) { console.error('Error fetching south station data:', err) setSouthData(null) } } }, [selectedStation, showNorth, showSouth]) // Clear old data when station changes to prevent showing stale data from previous station useEffect(() => { if (selectedStation) { setNorthData(null) setSouthData(null) } }, [selectedStation?.id]) useEffect(() => { if (selectedStation) { fetchStationData() const interval = setInterval(fetchStationData, 5000) return () => clearInterval(interval) } }, [selectedStation, fetchStationData]) const availableDirections = useMemo(() => { const directions = new Set() if (northData && northData.routes.length > 0) directions.add('North') if (southData && southData.routes.length > 0) directions.add('South') return directions }, [northData, southData]) const stationAvailableLines = useMemo(() => { const lines = new Set() if (northData) { northData.routes.forEach(route => { const lineId = route.routeId.replace('Route.', '') lines.add(lineId) }) } if (southData) { southData.routes.forEach(route => { const lineId = route.routeId.replace('Route.', '') lines.add(lineId) }) } return Array.from(lines).sort() }, [northData, southData]) const toggleLine = (line: string) => { const newSelected = new Set(selectedLines) if (newSelected.has(line)) { newSelected.delete(line) } else { newSelected.add(line) } setSelectedLines(newSelected) } const toggleDirection = (direction: 'North' | 'South') => { if (direction === 'North') { setShowNorth(!showNorth) } else { setShowSouth(!showSouth) } } const filterRoutes = (routes: Route[]): Route[] => { return routes.filter(route => { const lineId = route.routeId.replace('Route.', '') return selectedLines.has(lineId) }) } return (
) } interface HeaderProps { selectedStation: Station | null onSelectStation: (station: Station) => void showNorth: boolean showSouth: boolean selectedLines: Set availableDirections: Set availableLines: string[] onToggleDirection: (direction: 'North' | 'South') => void onToggleLine: (line: string) => void onRemove?: () => void } function Header({ selectedStation, onSelectStation, showNorth, showSouth, selectedLines, availableDirections, availableLines, onToggleDirection, onToggleLine, onRemove, }: HeaderProps) { const [showSearch, setShowSearch] = useState(false) return (
{/* Station Name Title and Search Row */}
{selectedStation && (

{selectedStation.name}

)} {/* Search Button */} {showSearch ? (
{ onSelectStation(station) setShowSearch(false) }} />
) : ( )}
{availableDirections.has('North') && ( )} {availableDirections.has('South') && ( )}
{availableLines.map(line => ( ))}
{onRemove && ( )}
) } interface ContentProps { selectedStation: Station | null showNorth: boolean showSouth: boolean northRoutes: Route[] southRoutes: Route[] availableDirections: Set } function Content({ selectedStation, showNorth, showSouth, northRoutes, southRoutes, availableDirections }: ContentProps) { if (!selectedStation) { return (
Select a station to view train arrivals
) } // Determine if this is an end-of-line station (only one direction available) const isEndOfLine = availableDirections.size === 1 // Only render directions that are both available AND selected const renderNorth = showNorth && availableDirections.has('North') const renderSouth = showSouth && availableDirections.has('South') return (
{renderNorth && (
)} {renderSouth && (
)}
) }