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

@@ -8,7 +8,7 @@
<script>
// Global variables (fallback if Constants not loaded)
window.API_URL = window.API_URL || 'http://localhost:3002/api/departures';
window.REFRESH_INTERVAL = window.REFRESH_INTERVAL || 5000;
window.REFRESH_INTERVAL = window.REFRESH_INTERVAL || 30000;
</script>
<!-- Leaflet.js for map functionality -->
@@ -19,18 +19,8 @@
<link rel="stylesheet" href="public/css/main.css">
<link rel="stylesheet" href="public/css/components.css">
<!-- Utility scripts (must load first) -->
<script src="public/js/utils/constants.js"></script>
<script src="public/js/utils/logger.js"></script>
<!-- Component scripts (load in dependency order) -->
<script src="public/js/components/ConfigManager.js"></script>
<script src="public/js/components/Clock.js"></script>
<script src="public/js/components/WeatherManager.js"></script>
<script src="public/js/components/DeparturesManager.js"></script>
<!-- Main application script -->
<script src="public/js/main.js"></script>
<!-- Main application script (ES module - imports all dependencies) -->
<script type="module" src="public/js/main.js"></script>
<!-- Inline styles removed - now in external CSS files -->
</head>
@@ -69,6 +59,9 @@
</div>
</div>
<div class="temperature">7.1 °C</div>
<div class="sun-times">
☀️ Sunrise: 06:45 AM | 🌙 Sunset: 05:32 PM
</div>
</div>
<div class="forecast">
<div class="forecast-hour">
@@ -121,16 +114,113 @@
<div class="temp">5.5 °C</div>
</div>
</div>
<div class="sun-times">
☀️ Sunrise: 06:45 AM | 🌙 Sunset: 05:32 PM
</div>
</div> <!-- End of weather-section -->
<div class="last-updated" id="last-updated"></div>
<!-- Daylight Hours Bar -->
<div id="daylight-hours-bar">
<div class="daylight-bar-background"></div>
<div class="daylight-bar-indicator">
<span class="sun-icon">☀️</span>
</div>
</div>
</div> <!-- End of content-wrapper -->
<!-- Last updated - positioned next to gear icon -->
<div class="last-updated" id="last-updated"></div>
<!-- Config Modal Template -->
<template id="config-modal-template">
<div class="config-modal-content">
<div class="config-modal-header">
<h2>Settings</h2>
<span class="config-modal-close">&times;</span>
</div>
<div class="config-tabs">
<button class="config-tab active" data-tab="display">Display</button>
<button class="config-tab" data-tab="appearance">Appearance</button>
<button class="config-tab" data-tab="content">Content</button>
<button class="config-tab" data-tab="options">Options</button>
</div>
<div class="config-modal-body">
<!-- Display Tab -->
<div class="config-tab-content active" id="tab-display">
<div class="config-option">
<label for="orientation-select">Screen Orientation:</label>
<select id="orientation-select">
<option value="normal">Normal (0°)</option>
<option value="vertical">Vertical (90°)</option>
<option value="upsidedown">Upside Down (180°)</option>
<option value="vertical-reverse">Vertical Reverse (270°)</option>
<option value="landscape">Landscape (2-column)</option>
</select>
</div>
<div class="config-option">
<label for="dark-mode-select">Dark Mode:</label>
<select id="dark-mode-select">
<option value="auto">Automatic (Sunset/Sunrise)</option>
<option value="on">Always On</option>
<option value="off">Always Off</option>
</select>
<div class="sun-times" id="sun-times">
<small>Sunrise: <span id="sunrise-time">--:--</span> | Sunset: <span id="sunset-time">--:--</span></small>
</div>
</div>
</div>
<!-- Appearance Tab -->
<div class="config-tab-content" id="tab-appearance">
<div class="config-option">
<label for="background-image-url">Background Image:</label>
<input type="text" id="background-image-url" placeholder="Enter image URL">
<div class="config-flex-row">
<button id="test-image-button" class="config-btn-sm">Use Test Image</button>
<label for="local-image-input" class="config-file-label">Select Local Image</label>
<input type="file" id="local-image-input" accept="image/*" class="config-file-input-hidden">
</div>
<div class="background-preview" id="background-preview">
<div class="no-image">No image selected</div>
</div>
</div>
<div class="config-option">
<label for="background-opacity">Background Opacity: <span id="opacity-value">30%</span></label>
<input type="range" id="background-opacity" min="0" max="1" step="0.05" value="0.3">
</div>
</div>
<!-- Content Tab -->
<div class="config-tab-content" id="tab-content">
<div class="config-option">
<label>Transit Sites:</label>
<div style="margin-bottom: 15px;">
<div class="config-flex-row-mb">
<input type="text" id="site-search-input" placeholder="Search for transit stop..." class="config-search-input">
<button id="search-site-button">Search</button>
<button id="select-from-map-button">Select from Map</button>
</div>
<div id="site-search-results" class="config-search-results"></div>
</div>
<div id="sites-container"></div>
<div class="config-sites-add">
<button id="add-site-button" class="config-btn-sm">Add Site Manually</button>
</div>
</div>
</div>
<!-- Options Tab -->
<div class="config-tab-content" id="tab-options">
<div class="config-option">
<label for="combine-directions">
<input type="checkbox" id="combine-directions">
Combine departures going in the same direction
</label>
</div>
</div>
</div>
<div class="config-modal-footer">
<button id="config-save-button">Save</button>
<button id="config-cancel-button">Cancel</button>
</div>
</div>
</template>