// Main app: backend data loading + layout + page routing. const { useState, useReducer, useEffect, useCallback } = React; const { ToastProvider, useToast } = window.UI; const EMPTY_TRAFFIC = { metrics: {}, requests: [], series: Array.from({ length: 60 }, (_, t) => ({ t, total: 0, success: 0, errors: 0, p95: 0 })), }; function emptyState() { return { pools: [], fingerprints: [], regionGroups: [], traffic: EMPTY_TRAFFIC, stats: null, auth: window.PG_API.getTokenMeta(), loading: true, booted: false, authRequired: false, error: "", }; } function rebuildRegionGroups(pools) { return window.PG.buildRegionGroups(pools || []); } function reducer(state, action) { switch (action.type) { case "setData": return { ...state, ...action.data, regionGroups: action.data.regionGroups || rebuildRegionGroups(action.data.pools), loading: false, booted: true, authRequired: false, error: "", }; case "setTraffic": return { ...state, traffic: action.traffic || EMPTY_TRAFFIC }; case "setLoading": return { ...state, loading: action.loading, error: action.error || state.error }; case "setError": return { ...state, loading: false, error: action.error || "" }; case "setAuthRequired": return { ...state, loading: false, authRequired: true, auth: null, error: action.error || "", }; case "setLoggedOut": return { ...emptyState(), loading: false, authRequired: true }; case "toggleNodeLocal": { const pools = state.pools.map(p => ({ ...p, nodes: (p.nodes || []).map(n => n.id === action.id ? { ...n, enabled: action.enabled } : n), })); return { ...state, pools, regionGroups: rebuildRegionGroups(pools) }; } case "togglePoolLocal": { const pools = state.pools.map(p => p.name === action.name ? { ...p, enabled: action.enabled } : p); return { ...state, pools, regionGroups: rebuildRegionGroups(pools) }; } default: return state; } } function findPool(pools, name) { return (pools || []).find(p => p.name === name); } function findNodeById(pools, id) { for (const pool of pools || []) { for (const node of pool.nodes || []) { if (node.id === id) return { pool, node }; } } return null; } const NAV = [ { id: "overview", label: "Overview", icon: "dashboard" }, { id: "egress", label: "Egress", icon: "globe" }, { id: "subscriptions", label: "Subscriptions", icon: "rss" }, { id: "templates", label: "Templates", icon: "tpl" }, { id: "tls", label: "TLS Profiles", icon: "shield" }, { id: "traffic", label: "Traffic", icon: "activity" }, { id: "system", label: "System", icon: "cog" }, ]; function pageFromPath(pathname) { const slug = String(pathname || "/").replace(/^\/+|\/+$/g, ""); if (!slug || slug === "login") return slug === "login" ? null : "overview"; return NAV.some(item => item.id === slug) ? slug : "overview"; } function pathForPage(page) { return page === "overview" ? "/" : `/${page}`; } function replacePath(path) { if (window.location.pathname !== path) { window.history.replaceState({}, "", path); } } function Sidebar({ page, setPage, state }) { const counts = { egress: state.pools.flatMap(p => p.nodes || []).length, subscriptions: state.pools.filter(p => p.source === "subscription").length, templates: state.pools.filter(p => p.source === "template").length, tls: state.fingerprints.length, traffic: state.traffic.requests.length, }; return (
Chijie
Console
{NAV.map(n => { const Icon = window.Ic[n.icon]; return (
setPage(n.id)}> {n.label} {counts[n.id] != null && {counts[n.id]}}
); })}
Admin API
{state.error ? "attention required" : "connected"}
); } function fmtToken(seconds) { if (!seconds) return "JWT"; if (seconds < 60) return `JWT · ${seconds}s`; if (seconds < 3600) return `JWT · ${Math.round(seconds / 60)}m`; return `JWT · ${Math.round(seconds / 3600)}h`; } function Topbar({ page, state, onRefresh, onLogout, busy }) { const label = NAV.find(n => n.id === page)?.label || ""; return (
Console/ {label}
/api/{page === "overview" ? "stats" : page}
AD
admin
{fmtToken(state.auth?.seconds)}
); } function ShellMessage({ title, message, action }) { return (
Chijie

{title}

{message &&

{message}

} {action}
); } function LoginScreen({ onLogin, error }) { const [password, setPassword] = useState(""); const [busy, setBusy] = useState(false); const [localError, setLocalError] = useState(""); const submit = async (event) => { event.preventDefault(); setBusy(true); setLocalError(""); const ok = await onLogin(password); if (!ok) setLocalError("Login failed"); setBusy(false); }; return (
Chijie

Admin Login

Enter the admin password from gateway.yaml.

setPassword(e.target.value)} />
{(error || localError) &&
{error || localError}
}
); } function App() { const [state, baseDispatch] = useReducer(reducer, null, emptyState); const [page, setPageState] = useState(() => pageFromPath(window.location.pathname) || "overview"); const [trafficLimit, setTrafficLimit] = useState(200); const [busy, setBusy] = useState(false); const toast = useToast(); const setPage = useCallback((nextPage) => { setPageState(nextPage); const nextPath = pathForPage(nextPage); if (window.location.pathname !== nextPath) { window.history.pushState({ page: nextPage }, "", nextPath); } }, []); const refreshData = useCallback(async (quiet = true) => { try { const next = await window.PG_API.loadState({ trafficLimit }); baseDispatch({ type: "setData", data: next }); if (!quiet) toast("Data refreshed"); return next; } catch (err) { if (err.authRequired || err.status === 401) { baseDispatch({ type: "setAuthRequired", error: err.message }); } else { baseDispatch({ type: "setError", error: err.message }); } return null; } }, [toast, trafficLimit]); useEffect(() => { refreshData(true); }, [refreshData]); useEffect(() => { const onPopState = () => { const nextPage = pageFromPath(window.location.pathname); if (nextPage) setPageState(nextPage); }; window.addEventListener("popstate", onPopState); return () => window.removeEventListener("popstate", onPopState); }, []); useEffect(() => { if (state.authRequired || !state.booted) return undefined; const timer = setInterval(() => refreshData(true), 10000); return () => clearInterval(timer); }, [state.authRequired, state.booted, refreshData]); useEffect(() => { if (state.authRequired) { replacePath("/login"); return; } if (state.booted && window.location.pathname === "/login") { replacePath(pathForPage(page)); } }, [state.authRequired, state.booted, page]); const dispatch = useCallback(async (action) => { const api = window.PG_API; setBusy(true); try { switch (action.type) { case "refreshData": return await refreshData(false); case "toggleNode": { const found = findNodeById(state.pools, action.id); if (!found) throw new Error("node not found"); const enabled = !found.node.enabled; baseDispatch({ type: "toggleNodeLocal", id: action.id, enabled }); const result = await api.setNodeEnabled({ pool: found.pool.name, node: found.node.name, enabled }); await refreshData(true); toast(enabled ? `Enabled ${found.node.name}` : `Disabled ${found.node.name}`); return result; } case "togglePool": { const pool = findPool(state.pools, action.name); if (!pool) throw new Error("pool not found"); const enabled = !pool.enabled; baseDispatch({ type: "togglePoolLocal", name: action.name, enabled }); const result = await api.setPoolEnabled(pool, enabled); await refreshData(true); toast(enabled ? `Enabled ${pool.name}` : `Disabled ${pool.name}`); return result; } case "addStaticNode": { const pool = findPool(state.pools, action.pool); if (!pool) throw new Error("static pool not found"); const result = await api.addStaticNode(pool, action.node); await refreshData(true); toast(`Added ${action.node.name}`); return result; } case "deleteNode": { const result = await api.deleteNode({ pool: action.pool, node: action.node }); await refreshData(true); toast(`Deleted ${action.node}`); return result; } case "refreshSub": { const result = await api.refreshSubscription(action.name); await refreshData(true); toast(`Refreshed ${action.name}`); return result; } case "addPool": { const result = await api.addPool(action.name, action.config); await refreshData(true); toast(`Created ${action.name}`); return result; } case "updatePoolConfig": { const pool = findPool(state.pools, action.pool); if (!pool) throw new Error("pool not found"); const result = await api.updatePoolConfig(pool, action.patch, action.newName); await refreshData(true); toast(`Saved ${action.newName || action.pool}`); return result; } case "deletePool": { const result = await api.deletePool(action.pool); await refreshData(true); toast(`Deleted ${action.pool}`); return result; } case "updateSubscriptionNode": { const result = await api.updateSubscriptionNode(action.payload); await refreshData(true); toast(`Saved ${action.payload.node}`); return result; } case "updateStaticNode": { const result = await api.updateStaticNode({ pool: action.pool, node: action.node, updatedNode: action.updatedNode, }); await refreshData(true); toast(`Saved ${action.updatedNode.name}`); return result; } case "testNode": { const result = await api.testNode({ pool: action.pool, node: action.node }); await refreshData(true); return result; } case "testTemplate": return await api.testTemplate({ pool: action.pool, region: action.region, url: action.url }); case "loadMoreTraffic": { const nextLimit = Math.min(1000, Math.max(200, trafficLimit + 200)); const traffic = await api.getTraffic(nextLimit); setTrafficLimit(nextLimit); baseDispatch({ type: "setTraffic", traffic }); return traffic; } case "addFingerprint": { const result = await api.addFingerprint({ name: action.name, config: action.config, configText: action.configText }); await refreshData(true); toast(`Created ${action.name}`); return result; } case "deleteFingerprint": { const result = await api.deleteFingerprint(action.name); await refreshData(true); toast(`Deleted ${action.name}`); return result; } case "testFingerprint": return await api.testFingerprint({ fingerprint: action.fingerprint, url: action.url }); case "reload": { const result = await api.reload(); await refreshData(true); toast("Config reloaded"); return result; } default: return null; } } catch (err) { if (err.status === 401) { baseDispatch({ type: "setAuthRequired", error: err.message }); } else { baseDispatch({ type: "setError", error: err.message }); } toast(err.message); await refreshData(true); return null; } finally { setBusy(false); } }, [state.pools, trafficLimit, refreshData, toast]); const login = async (password) => { try { await window.PG_API.login(password); await refreshData(true); replacePath(pathForPage(page)); toast("Signed in"); return true; } catch (err) { baseDispatch({ type: "setAuthRequired", error: err.message }); return false; } }; const logout = () => { window.PG_API.logout(); replacePath("/login"); baseDispatch({ type: "setLoggedOut" }); }; if (state.authRequired) { return ; } if (state.loading && !state.booted) { return ; } if (!state.booted && state.error) { return refreshData(false)}> Retry} />; } return (
dispatch({ type: "refreshData" })} onLogout={logout} busy={busy} /> {state.error &&
{state.error}
} {page === "overview" && } {page === "egress" && } {page === "subscriptions" && } {page === "templates" && } {page === "tls" && } {page === "traffic" && } {page === "system" && }
); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render();