# Wild Central UI Refactor ## Core Insight Everything flows from the **service**. When a service is registered, Central lights up the components it needs: DNS records, proxy routes, TLS certs, DDNS records. The other pages aren't independent configuration surfaces — they're views into the effects of service registrations. This creates two clear sections: - **Services section** — the service-driven system. Everything here exists because services were registered (or because services need it to function). This is what Wild Cloud and Wild Works interact with. - **Central section** — the device itself. Firewall, VPN, security, DHCP. These exist whether or not any services are registered. This is the appliance config. ## Navigation ``` Services ├── Dashboard (default landing — health, warnings, at-a-glance status) ├── Cloudflare (THE setup page — token, zones, tunnel. Prerequisite for everything) ├── Services (registered services — the primary config surface) ├── DNS (complete DNS picture — internal + external resolution per service) └── Certificates (TLS status per service — what's provisioned, what's missing) Central ├── Firewall (nftables rules) ├── VPN (WireGuard server + peers) ├── CrowdSec (intrusion detection) └── DHCP (IP address assignment + leases) ``` ## Page Designs ### Dashboard The landing page. At-a-glance system health: - Daemon statuses: dnsmasq ✓, haproxy ✓, wireguard ✓, crowdsec ✓ - Registered services: 9 services (7 public, 2 internal) - Certificates: 2 valid, 1 missing — ⚠ warning - DDNS: synced, public IP 216.243.55.15 - Cloudflare: token valid ✓ - Warnings/actions: "wild-cloud.payne.io needs a TLS cert → Provision" If Cloudflare isn't configured, the dashboard shows a prominent setup prompt directing the user there first. ### Cloudflare The prerequisite page. Everything public depends on this: - API token management (set, verify, show accessible zones) - Tunnel status (cloudflared connection, connected services) - DDNS provider config (which records to sync, current public IP, last sync) This is the first page a new user configures. Without the token, public DNS and TLS certs don't work — the UI should make this dependency obvious. ### Services THE primary interaction surface. Every registered service in one table: | Domain | Backend | Type | Reach | DNS | TLS | DDNS | |--------|---------|------|-------|-----|-----|------| | cloud.payne.io | 192.168.8.240:443 | L4 passthrough | public | ✓ resolves | ✓ passthrough | ✓ A record | | *.cloud.payne.io | (same) | L4 wildcard | public | ✓ resolves | ✓ passthrough | — | | central.payne.io | 127.0.0.1:15055 | L7 proxy | internal | ✓ resolves | ✓ 88d left | — (internal) | | wild-cloud.payne.io | 127.0.0.1:5055 | L7 proxy | internal | ✓ resolves | ⚠ missing | — (internal) | | payne.io | 192.168.8.240:443 | L4 exact | public | ✓ resolves | ✓ passthrough | ✓ A record | Each row shows the **complete status** of one service — every effect Central provides for it. The user sees immediately: "wild-cloud.payne.io is missing a TLS cert." Click a row to see details or take action. Central's own domain (from config) appears in this table too — it's just another service from the user's perspective. The service detail view shows: - All the effects (DNS entry, proxy route, TLS cert, DDNS record) - The registration source (wild-cloud, wild-works, config) - Actions: provision cert, change reach, deregister HAProxy raw config, stats, and generate/restart move to a collapsible "Advanced" section at the bottom. ### DNS The **complete DNS picture** for all services. Not a configuration page — a status view showing how every domain resolves, from both inside and outside the network. For each service domain: | Domain | Internal (LAN) | External (Internet) | |--------|---------------|---------------------| | cloud.payne.io | 192.168.8.240 (direct to k8s LB) | 216.243.55.15 (via DDNS) | | central.payne.io | 192.168.8.151 (Central) | — (internal only) | | internal.cloud.payne.io | 192.168.8.240 (with local=/) | — (never forwarded) | Plus DNS server infrastructure status: - dnsmasq: running ✓, listening on 192.168.8.151 - Upstream forwarders: 1.1.1.1, 8.8.8.8 - DDNS sync: last checked 2m ago, public IP 216.243.55.15 This replaces the three overlapping DNS pages (dns, lan-dns, ddns) with one coherent view. ### Certificates TLS cert status for every service that needs Central to terminate TLS: | Domain | Status | Expires | Issuer | Action | |--------|--------|---------|--------|--------| | central.payne.io | ✓ valid | 88 days | Let's Encrypt | Renew | | wild-cloud.payne.io | ⚠ missing | — | — | Provision | Services with TLS passthrough (k8s instances) don't appear here — their backend handles TLS. "Provision" and "Renew All" buttons. "Add Wildcard" for opt-in wildcard certs. Requires Cloudflare token — if not configured, shows a prompt directing to Cloudflare page. ### Firewall, VPN, CrowdSec, DHCP These are Central's own infrastructure config. Not service-driven. Each is its own page under the "Central" sidebar section. No changes needed to their content — just the grouping. ## Key Design Principles 1. **Services are the entrypoint.** Every page in the Services section answers: "what did Central do (or need to do) because of the services registered with it?" 2. **Status over configuration.** DNS and Certificates pages are primarily status views — they show the effects of service registrations. The user configures services, not DNS entries directly. 3. **Dependencies are visible.** Dashboard warns if Cloudflare isn't configured. Certificates page warns if token is missing. Services page shows which effects are green vs red. 4. **Two sections, two concerns.** Services = outward-facing (what Central does for consumers). Central = inward-facing (what the device does for itself). ## Migration ### Pages to delete - `LanDnsPage.tsx` — duplicate - `DdnsPage.tsx` — folded into Cloudflare - `LanDnsComponent.tsx` — duplicate ### Pages to rename - `CentralPage.tsx` → `DashboardPage.tsx` - `IngressProxyPage.tsx` → `ServicesPage.tsx` - `IngressProxyComponent.tsx` → `ServicesComponent.tsx` - `CentralComponent.tsx` → `DashboardComponent.tsx` ### Pages to rewrite - `DashboardComponent` — new status dashboard (currently just operator email) - `ServicesComponent` — new service table with per-service effect status - `DnsComponent` — unified DNS view (internal + external per service) - `CloudflareComponent` — add DDNS management and tunnel status ### Sidebar changes - Two labeled groups: "Services" and "Central" - "Overview" → "Dashboard" - "Ingress Proxy" → "Services" - Remove DNS/LAN DNS/DDNS → replace with single "DNS" - Add DDNS content to Cloudflare page