App.TrackPicker = function TrackPicker({ selectedTrackConfigId, onSelect }) { const [tracks, setTracks] = React.useState([]); const [allConfigs, setAllConfigs] = React.useState([]); const [loading, setLoading] = React.useState(true); const [error, setError] = React.useState(''); const [search, setSearch] = React.useState(''); const [contentMode, setContentMode] = App.useContentFilter(); const [modalTrack, setModalTrack] = React.useState(null); React.useEffect(() => { Promise.all([ App.API.get('tracks'), App.API.get('track-configs'), ]).then(([tracksData, configsData]) => { setTracks(tracksData); setAllConfigs(configsData); setLoading(false); }).catch(err => { setError(err.message || 'Failed to load tracks'); setLoading(false); }); }, []); // Group configs by track_id const configsByTrack = React.useMemo(() => { const map = {}; allConfigs.forEach(cfg => { if (!map[cfg.track_id]) map[cfg.track_id] = []; map[cfg.track_id].push(cfg); }); return map; }, [allConfigs]); // Derive which track_id is selected from the selected config id const selectedTrackId = React.useMemo(() => { if (!selectedTrackConfigId) return null; const cfg = allConfigs.find(c => c.id == selectedTrackConfigId); return cfg ? cfg.track_id : null; }, [selectedTrackConfigId, allConfigs]); const handleTrackClick = (trackId) => { const configs = configsByTrack[trackId] || []; if (configs.length === 0) return; if (configs.length === 1) { // Auto-select the only config const cfg = configs[0]; const track = tracks.find(t => t.id == trackId); onSelect({ id: cfg.id, trackId: cfg.track_id, trackName: track ? track.name : '', configName: cfg.config_name, }); } else if (configs.length > 1) { const track = tracks.find(t => t.id == trackId); setModalTrack(track); } }; let filtered = search ? tracks.filter(t => t.name.toLowerCase().includes(search.toLowerCase())) : tracks; if (contentMode === 'included') { // Show tracks that have at least one free config filtered = filtered.filter(t => { const cfgs = configsByTrack[t.id] || []; return cfgs.some(c => c.is_free == 1); }); } if (loading) return ; if (error) return
{error}
; return (

Select Track

setSearch(e.target.value)} />
{filtered.map(track => ( ))}
{modalTrack && ( setModalTrack(null)} /> )}
); };