Items 10-15: ES modules, inline style cleanup, template modal, code modernization

- Item 10: Convert to ES modules with import/export, single module entry point
- Item 11: Replace inline styles with CSS classes (background overlay, card
  animations, highlight effect, config modal form elements)
- Item 12: Move ConfigManager modal HTML from JS template literal to
  <template> element in index.html
- Item 13: Replace deprecated url.parse() with new URL() in server.js
  and update route handlers to use searchParams
- Item 14: Replace JSON.parse/stringify deep clone with structuredClone()
- Item 15: Remove dead JSON-fixing regex code from departures.js route

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 14:30:03 +01:00
parent 392a50b535
commit 1fdb3e48c7
12 changed files with 1883 additions and 1780 deletions

View File

@@ -23,62 +23,14 @@ function fetchDeparturesForSite(siteId) {
});
res.on('end', () => {
console.log('Raw API response:', data.substring(0, 200) + '...');
try {
try {
const parsedData = JSON.parse(data);
console.log('Successfully parsed as regular JSON');
resolve(parsedData);
return;
} catch (jsonError) {
console.log('Not valid JSON, trying to fix format...');
}
if (data.startsWith('departures":')) {
data = '{' + data;
} else if (data.includes('departures":')) {
const startIndex = data.indexOf('departures":');
if (startIndex > 0) {
data = '{' + data.substring(startIndex);
}
}
data = data.replace(/}{\s*"/g, '},{"');
data = data.replace(/"([^"]+)":\s*([^,{}\[\]]+)(?=")/g, '"$1": $2,');
data = data.replace(/,\s*}/g, '}').replace(/,\s*\]/g, ']');
try {
const parsedData = JSON.parse(data);
console.log('Successfully parsed fixed JSON');
if (parsedData && parsedData.departures && parsedData.departures.length > 0) {
console.log('Sample departure structure:', JSON.stringify(parsedData.departures[0], null, 2));
const sample = parsedData.departures[0];
console.log('Direction fields:', {
direction: sample.direction,
directionText: sample.directionText,
directionCode: sample.directionCode,
destination: sample.destination
});
}
resolve(parsedData);
} catch (parseError) {
console.error('Failed to parse even after fixing:', parseError);
// Return empty departures array instead of rejecting to be more resilient
resolve({
departures: [],
error: 'Failed to parse API response: ' + parseError.message
});
}
const parsedData = JSON.parse(data);
resolve(parsedData);
} catch (error) {
console.error('Error processing API response:', error);
// Return empty departures array instead of rejecting to be more resilient
console.error('Error parsing departures API response:', error);
resolve({
departures: [],
error: 'Error processing API response: ' + error.message
error: 'Failed to parse API response: ' + error.message
});
}
});