From d429b2d2528ba82d01308169628a1f116d7570fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Br=C3=BCckner?= Date: Mon, 8 Jun 2026 14:08:57 +0200 Subject: [PATCH] refactor(caddy): flatten routes to a plain array like bookings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET /api/caddy/routes now returns the route array directly instead of { system, custom }. Frontend state is CaddyRoute[] initialised to [], rendered with a simple .map() and an empty-state message — mirroring how bookings are loaded and displayed. --- server.ts | 2 +- src/components/Settings.tsx | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/server.ts b/server.ts index 1e9a9ea..fffbf9b 100644 --- a/server.ts +++ b/server.ts @@ -1180,7 +1180,7 @@ async function startServer() { app.get('/api/caddy/routes', requireAuth, (_req, res) => { try { - res.json({ system: [], custom: getCaddyRoutes() }); + res.json(getCaddyRoutes()); } catch (err: any) { res.status(500).json({ error: err.message }); } diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 4aa9b5c..d26ee85 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -193,7 +193,7 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) { const [caddyEnabled, setCaddyEnabled] = useState(false); const [caddyAdminUrl, setCaddyAdminUrl] = useState('http://localhost:2019'); const [caddyStatus, setCaddyStatus] = useState<'unknown' | 'available' | 'unavailable'>('unknown'); - const [caddyRoutes, setCaddyRoutes] = useState<{ system: { hostname: string; upstream: string }[]; custom: CaddyRoute[] } | null>(null); + const [caddyRoutes, setCaddyRoutes] = useState([]); const [addingRoute, setAddingRoute] = useState(false); const [newHostname, setNewHostname] = useState(''); const [newUpstream, setNewUpstream] = useState(''); @@ -360,17 +360,15 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) { } async function loadCaddyRoutes() { - // Status check is background — never blocks route display - authFetch('/api/caddy/status') - .then(res => res.ok ? res.json() : null) - .then(s => setCaddyStatus(s?.available ? 'available' : 'unavailable')) - .catch(() => setCaddyStatus('unavailable')); - - // Routes load immediately from DB try { const res = await authFetch('/api/caddy/routes'); if (res.ok) setCaddyRoutes(await res.json()); } catch {} + // Status check runs separately — purely informational, never blocks the list + authFetch('/api/caddy/status') + .then(res => res.ok ? res.json() : null) + .then(s => setCaddyStatus(s?.available ? 'available' : 'unavailable')) + .catch(() => setCaddyStatus('unavailable')); } async function handleAddRoute() { @@ -939,8 +937,14 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) {

)} + {caddyRoutes.length === 0 && ( +

+ No proxy routes configured yet. +

+ )} + {/* Custom routes */} - {caddyRoutes?.custom.map(r => ( + {caddyRoutes.map((r: CaddyRoute) => (
{editingRouteId === r.id ? (