refactor(caddy): flatten routes to a plain array like bookings

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.
This commit is contained in:
Brückner
2026-06-08 14:08:57 +02:00
parent 1526d25144
commit d429b2d252
2 changed files with 14 additions and 10 deletions

View File

@ -1180,7 +1180,7 @@ async function startServer() {
app.get('/api/caddy/routes', requireAuth, (_req, res) => { app.get('/api/caddy/routes', requireAuth, (_req, res) => {
try { try {
res.json({ system: [], custom: getCaddyRoutes() }); res.json(getCaddyRoutes());
} catch (err: any) { } catch (err: any) {
res.status(500).json({ error: err.message }); res.status(500).json({ error: err.message });
} }

View File

@ -193,7 +193,7 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) {
const [caddyEnabled, setCaddyEnabled] = useState(false); const [caddyEnabled, setCaddyEnabled] = useState(false);
const [caddyAdminUrl, setCaddyAdminUrl] = useState('http://localhost:2019'); const [caddyAdminUrl, setCaddyAdminUrl] = useState('http://localhost:2019');
const [caddyStatus, setCaddyStatus] = useState<'unknown' | 'available' | 'unavailable'>('unknown'); 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<CaddyRoute[]>([]);
const [addingRoute, setAddingRoute] = useState(false); const [addingRoute, setAddingRoute] = useState(false);
const [newHostname, setNewHostname] = useState(''); const [newHostname, setNewHostname] = useState('');
const [newUpstream, setNewUpstream] = useState(''); const [newUpstream, setNewUpstream] = useState('');
@ -360,17 +360,15 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) {
} }
async function loadCaddyRoutes() { 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 { try {
const res = await authFetch('/api/caddy/routes'); const res = await authFetch('/api/caddy/routes');
if (res.ok) setCaddyRoutes(await res.json()); if (res.ok) setCaddyRoutes(await res.json());
} catch {} } 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() { async function handleAddRoute() {
@ -939,8 +937,14 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) {
</p> </p>
)} )}
{caddyRoutes.length === 0 && (
<p className="text-[11px] font-mono text-slate-500 mb-2">
No proxy routes configured yet.
</p>
)}
{/* Custom routes */} {/* Custom routes */}
{caddyRoutes?.custom.map(r => ( {caddyRoutes.map((r: CaddyRoute) => (
<div key={r.id} className="bg-slate-900/60 border border-slate-700/60 rounded-xl px-4 py-2.5"> <div key={r.id} className="bg-slate-900/60 border border-slate-700/60 rounded-xl px-4 py-2.5">
{editingRouteId === r.id ? ( {editingRouteId === r.id ? (
<div className="flex items-end gap-2"> <div className="flex items-end gap-2">