Migrate frontend from monolithic app.js to vanilla ES modules
Build and Push Docker Image / build (push) Successful in 35s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 49s
CI / Security audit (push) Successful in 1m9s
CI / Tests & coverage (push) Successful in 1m23s

- Delete React files (App.jsx, main.jsx, App.css)
- Create modular vanilla JS structure in client/src/:
  - state.js (global state object)
  - api.js (all fetch calls)
  - sse.js (SSE connection management)
  - ui/auth.js (authentication UI)
  - ui/downloads.js (downloads rendering)
  - ui/history.js (history section)
  - ui/statusPanel.js (status panel)
  - ui/webhooks.js (webhook management)
  - ui/filters.js (download client filter)
  - ui/theme.js (theme switching)
  - ui/tabs.js (tab navigation)
  - utils/format.js (formatting utilities)
  - utils/storage.js (localStorage helpers)
  - main.js (DOMContentLoaded bootstrap)
- Update vite.config.js for vanilla build outputting to ../public/app.js
- Build succeeds: 14 modules, 43.88 kB output
This commit is contained in:
2026-05-20 23:30:24 +01:00
parent a38fc4a8ce
commit 8dc105ff3e
19 changed files with 2173 additions and 2854 deletions
+50
View File
@@ -0,0 +1,50 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
import { getActiveTab, saveActiveTab } from '../utils/storage.js';
import { loadHistory } from './history.js';
export function initTabs() {
const downloadsTab = document.getElementById('downloads-tab');
const historyTab = document.getElementById('history-tab');
const downloadsSection = document.getElementById('downloads-section');
const historySection = document.getElementById('history-section');
if (!downloadsTab || !historyTab) return;
// Load saved tab
const savedTab = getActiveTab();
if (savedTab === 'history') {
activateTab('history');
} else {
activateTab('downloads');
}
downloadsTab.addEventListener('click', () => activateTab('downloads'));
historyTab.addEventListener('click', () => activateTab('history'));
}
export function activateTab(tab) {
const downloadsTab = document.getElementById('downloads-tab');
const historyTab = document.getElementById('history-tab');
const downloadsSection = document.getElementById('downloads-section');
const historySection = document.getElementById('history-section');
if (tab === 'downloads') {
downloadsTab.classList.add('active');
historyTab.classList.remove('active');
downloadsSection.style.display = 'block';
historySection.style.display = 'none';
saveActiveTab('downloads');
} else if (tab === 'history') {
historyTab.classList.add('active');
downloadsTab.classList.remove('active');
historySection.style.display = 'block';
downloadsSection.style.display = 'none';
saveActiveTab('history');
loadHistory();
}
}
export function goHome() {
activateTab('downloads');
}