mirror of
https://github.com/MrUnknownDE/utools.git
synced 2026-05-06 06:16:04 +02:00
87 lines
3.7 KiB
JavaScript
87 lines
3.7 KiB
JavaScript
import { page as homePage } from './pages/home.js';
|
||
import { page as subnetPage } from './pages/subnet.js';
|
||
import { page as dnsPage } from './pages/dns.js';
|
||
import { page as whoisPage } from './pages/whois.js';
|
||
import { page as macPage } from './pages/mac.js';
|
||
import { page as asnPage } from './pages/asn.js';
|
||
|
||
const routes = {
|
||
'/': homePage,
|
||
'/subnet': subnetPage,
|
||
'/dns': dnsPage,
|
||
'/whois': whoisPage,
|
||
'/mac': macPage,
|
||
'/asn': asnPage,
|
||
};
|
||
|
||
const app = document.getElementById('app');
|
||
let currentCleanup = null;
|
||
|
||
function setActiveNav(path) {
|
||
document.querySelectorAll('nav a').forEach(a => {
|
||
try {
|
||
const p = new URL(a.href).pathname;
|
||
a.classList.toggle('active-link', p === path);
|
||
} catch {}
|
||
});
|
||
}
|
||
|
||
async function navigate(path, { push = true, search = '' } = {}) {
|
||
const route = routes[path] ?? routes['/'];
|
||
|
||
// ── leave animation ──────────────────────────────────────────
|
||
app.classList.add('page-leaving');
|
||
if (currentCleanup) { try { currentCleanup(); } catch {} currentCleanup = null; }
|
||
await new Promise(r => setTimeout(r, 200));
|
||
|
||
// ── swap content ─────────────────────────────────────────────
|
||
app.innerHTML = route.template();
|
||
document.title = route.title ? `${route.title} – uTools` : 'uTools – Network Suite';
|
||
setActiveNav(path);
|
||
|
||
const fullUrl = path + (search ? (search.startsWith('?') ? search : '?' + search) : '');
|
||
if (push) history.pushState({ path }, '', fullUrl);
|
||
|
||
// ── enter animation ──────────────────────────────────────────
|
||
app.classList.remove('page-leaving');
|
||
app.classList.add('page-entering');
|
||
setTimeout(() => app.classList.remove('page-entering'), 300);
|
||
|
||
// ── init page ────────────────────────────────────────────────
|
||
const cleanup = await route.init(search);
|
||
currentCleanup = typeof cleanup === 'function' ? cleanup : null;
|
||
}
|
||
|
||
// ── Intercept same-origin link clicks ───────────────────────────
|
||
document.addEventListener('click', e => {
|
||
const a = e.target.closest('a[href]');
|
||
if (!a) return;
|
||
let url;
|
||
try { url = new URL(a.href); } catch { return; }
|
||
if (url.origin !== location.origin) return;
|
||
if (!(url.pathname in routes)) return;
|
||
e.preventDefault();
|
||
navigate(url.pathname, { push: true, search: url.search });
|
||
});
|
||
|
||
window.addEventListener('popstate', () => {
|
||
navigate(location.pathname, { push: false, search: location.search });
|
||
});
|
||
|
||
// ── Expose for programmatic navigation ──────────────────────────
|
||
window._router = {
|
||
navigate(path, searchObj = {}) {
|
||
const s = new URLSearchParams(searchObj).toString();
|
||
navigate(path, { push: true, search: s ? '?' + s : '' });
|
||
}
|
||
};
|
||
|
||
// ── Fetch version once ───────────────────────────────────────────
|
||
fetch('/api/version')
|
||
.then(r => r.json())
|
||
.then(d => { const el = document.getElementById('commit-sha'); if (el) el.textContent = d.commitSha || 'unknown'; })
|
||
.catch(() => { const el = document.getElementById('commit-sha'); if (el) el.textContent = 'error'; });
|
||
|
||
// ── Initial render ───────────────────────────────────────────────
|
||
navigate(location.pathname, { push: false, search: location.search });
|