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