docs: Final UI refactor — Dashboard + Services, 6 items
Dashboard: infrastructure health (router, cloudflare, DDNS, daemons). Services: every registered service with full status (DNS, proxy, TLS, DDNS) in expandable rows + custom TCP routes section. 9 sidebar items → 6. Seven old pages eliminated — their content lives in the two new pages where it belongs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,141 +6,183 @@ Everything flows from the **service**. When a service is registered, Central lig
|
|||||||
|
|
||||||
This creates two clear sections:
|
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.
|
- **Services section** — the service-driven system. Infrastructure health + registered services with their full status.
|
||||||
- **Central section** — the device itself. Firewall, VPN, security, DHCP. These exist whether or not any services are registered. This is the appliance config.
|
- **Central section** — the device itself. Firewall, VPN, security, DHCP. These exist whether or not any services are registered.
|
||||||
|
|
||||||
## Navigation
|
## Navigation
|
||||||
|
|
||||||
```
|
```
|
||||||
Services
|
Services
|
||||||
├── Dashboard (default landing — health, warnings, at-a-glance status)
|
├── Dashboard (infrastructure health: router, cloudflare, DDNS, daemons)
|
||||||
├── Cloudflare (THE setup page — token, zones, tunnel. Prerequisite for everything)
|
├── Services (registered services + custom TCP routes)
|
||||||
├── 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
|
Central
|
||||||
├── Firewall (nftables rules)
|
├── Firewall
|
||||||
├── VPN (WireGuard server + peers)
|
├── VPN
|
||||||
├── CrowdSec (intrusion detection)
|
├── CrowdSec
|
||||||
└── DHCP (IP address assignment + leases)
|
└── DHCP
|
||||||
```
|
```
|
||||||
|
|
||||||
## Page Designs
|
6 sidebar items (down from 9). Two labeled groups with clear separation.
|
||||||
|
|
||||||
### Dashboard
|
---
|
||||||
|
|
||||||
The landing page. At-a-glance system health:
|
## Dashboard
|
||||||
- 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.
|
The "is everything working" page. Shows the health of the infrastructure that Central depends on. If anything here is red, services won't work properly.
|
||||||
|
|
||||||
|
### Gateway Router
|
||||||
|
- Is the router forwarding DNS to Central (192.168.8.151)?
|
||||||
|
- Are the required ports forwarded? (443, 80, 51820/UDP)
|
||||||
|
- Instructions for common routers if not configured
|
||||||
|
|
||||||
### Cloudflare
|
### Cloudflare
|
||||||
|
- Is the API token configured and valid?
|
||||||
|
- What zones are accessible?
|
||||||
|
- Token setup inline if missing (don't send user to another page)
|
||||||
|
|
||||||
The prerequisite page. Everything public depends on this:
|
### Dynamic DNS
|
||||||
- API token management (set, verify, show accessible zones)
|
- Is the public IP current? When was it last checked?
|
||||||
- Tunnel status (cloudflared connection, connected services)
|
- Are all A records synced?
|
||||||
- DDNS provider config (which records to sync, current public IP, last sync)
|
- Record list with status (cloud.payne.io ✓, dev.payne.io ✓, etc.)
|
||||||
|
- These are infrastructure records, not per-service — they exist to make the public IP reachable
|
||||||
|
|
||||||
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.
|
### Daemon Status
|
||||||
|
- dnsmasq: running ✓ (listening on 192.168.8.151)
|
||||||
|
- haproxy: running ✓ (pid 12345)
|
||||||
|
- wireguard: running ✓ (2 peers connected)
|
||||||
|
- crowdsec: running ✓
|
||||||
|
- nats: running ✓
|
||||||
|
|
||||||
### Services
|
### Warnings
|
||||||
|
- "wild-cloud.payne.io needs a TLS cert → [Provision]"
|
||||||
|
- "Cloudflare token not set → [Configure]"
|
||||||
|
- "Port 443 not forwarded on router → [How to fix]"
|
||||||
|
|
||||||
THE primary interaction surface. Every registered service in one table:
|
---
|
||||||
|
|
||||||
| Domain | Backend | Type | Reach | DNS | TLS | DDNS |
|
## Services
|
||||||
|--------|---------|------|-------|-----|-----|------|
|
|
||||||
| 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.
|
THE page. Everything about every service in one place.
|
||||||
|
|
||||||
Central's own domain (from config) appears in this table too — it's just another service from the user's perspective.
|
### Service List
|
||||||
|
|
||||||
The service detail view shows:
|
Each service is a collapsed row showing summary status. Expand for full details.
|
||||||
- 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.
|
**Collapsed row:**
|
||||||
|
```
|
||||||
|
cloud.payne.io L4 passthrough public *.subdomains ✓✓✓✓
|
||||||
|
wild-cloud.payne.io L7 proxy internal ✓✓⚠—
|
||||||
|
payne.io L4 exact public ✓✓✓✓
|
||||||
|
```
|
||||||
|
|
||||||
### DNS
|
The four indicators are: DNS, Proxy, TLS, DDNS. Green/warning/missing/not-applicable.
|
||||||
|
|
||||||
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.
|
**Expanded row for cloud.payne.io:**
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ cloud.payne.io wild-cloud public│
|
||||||
|
│ L4 passthrough → 192.168.8.240:443 *.subdomains │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ DNS (LAN) address=/cloud.payne.io/192.168.8.240 ✓ │
|
||||||
|
│ DNS (Public) A record cloud.payne.io → 216.243.55.15 ✓ │
|
||||||
|
│ Proxy HAProxy L4 SNI + wildcard *.cloud.payne.io ✓ │
|
||||||
|
│ TLS passthrough (k8s traefik handles) ✓ │
|
||||||
|
│ │
|
||||||
|
│ Source: wild-cloud Registered: 2h ago │
|
||||||
|
│ [Change Reach] [Deregister] │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
For each service domain:
|
**Expanded row for wild-cloud.payne.io:**
|
||||||
| Domain | Internal (LAN) | External (Internet) |
|
```
|
||||||
|--------|---------------|---------------------|
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
| cloud.payne.io | 192.168.8.240 (direct to k8s LB) | 216.243.55.15 (via DDNS) |
|
│ wild-cloud.payne.io wild-cloud internal│
|
||||||
| central.payne.io | 192.168.8.151 (Central) | — (internal only) |
|
│ L7 reverse proxy → 127.0.0.1:5055 │
|
||||||
| internal.cloud.payne.io | 192.168.8.240 (with local=/) | — (never forwarded) |
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ DNS (LAN) local=/ + address=.../192.168.8.151 ✓ │
|
||||||
|
│ DNS (Public) (internal only — no public DNS record) — │
|
||||||
|
│ Proxy HAProxy L7 Host header routing ✓ │
|
||||||
|
│ TLS Central terminates — cert MISSING ⚠ │
|
||||||
|
│ └─ [Provision Certificate] │
|
||||||
|
│ │
|
||||||
|
│ Source: wild-cloud Registered: 2h ago │
|
||||||
|
│ [Change Reach] [Deregister] │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
Plus DNS server infrastructure status:
|
Central's own domain (from config) appears here too — it's just another row. Source shows "config" instead of a consumer name.
|
||||||
- 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.
|
### Custom TCP Routes
|
||||||
|
|
||||||
### Certificates
|
Below the service list, a separate section for manual TCP proxy rules that aren't domain-based service registrations:
|
||||||
|
|
||||||
TLS cert status for every service that needs Central to terminate TLS:
|
```
|
||||||
|
Custom TCP Routes
|
||||||
|
┌────────────────────────────────────────────────┐
|
||||||
|
│ civil_ssh port 2222 → 192.168.8.10:22 │
|
||||||
|
│ [Remove] │
|
||||||
|
├────────────────────────────────────────────────┤
|
||||||
|
│ [+ Add Custom Route] │
|
||||||
|
└────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
| Domain | Status | Expires | Issuer | Action |
|
These are from `cloud.haproxy.customRoutes` in the global config.
|
||||||
|--------|--------|---------|--------|--------|
|
|
||||||
| 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.
|
### Actions
|
||||||
|
|
||||||
"Provision" and "Renew All" buttons. "Add Wildcard" for opt-in wildcard certs.
|
- **Register new service** (manual registration form)
|
||||||
|
- **Provision certificate** (per-service, inline)
|
||||||
|
- **Change reach** (internal ↔ public, per-service)
|
||||||
|
- **Deregister** (per-service)
|
||||||
|
- **Add wildcard cert** (covers multiple services under same domain)
|
||||||
|
- **Generate & Apply HAProxy** (advanced, collapsed)
|
||||||
|
- **View raw HAProxy config** (advanced, collapsed)
|
||||||
|
|
||||||
Requires Cloudflare token — if not configured, shows a prompt directing to Cloudflare page.
|
---
|
||||||
|
|
||||||
### Firewall, VPN, CrowdSec, DHCP
|
## Central Section
|
||||||
|
|
||||||
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.
|
These pages are unchanged in content. They're Central's own infrastructure config — not driven by service registrations.
|
||||||
|
|
||||||
## Key Design Principles
|
### Firewall
|
||||||
|
nftables rules. Ports opened for HAProxy (443, 80), VPN (51820), SSH (22), plus any custom.
|
||||||
|
|
||||||
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?"
|
### VPN
|
||||||
|
WireGuard server config + peer management. Add/remove peers, view configs, QR codes.
|
||||||
|
|
||||||
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.
|
### CrowdSec
|
||||||
|
Intrusion detection. Alerts, decisions, machines, bouncers.
|
||||||
|
|
||||||
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.
|
### DHCP
|
||||||
|
dnsmasq DHCP config. IP ranges, lease times, static leases, active leases.
|
||||||
|
|
||||||
4. **Two sections, two concerns.** Services = outward-facing (what Central does for consumers). Central = inward-facing (what the device does for itself).
|
---
|
||||||
|
|
||||||
## Migration
|
## What Disappeared
|
||||||
|
|
||||||
### Pages to delete
|
The following pages are eliminated — their content lives elsewhere:
|
||||||
- `LanDnsPage.tsx` — duplicate
|
|
||||||
- `DdnsPage.tsx` — folded into Cloudflare
|
|
||||||
- `LanDnsComponent.tsx` — duplicate
|
|
||||||
|
|
||||||
### Pages to rename
|
| Old Page | Where It Went |
|
||||||
- `CentralPage.tsx` → `DashboardPage.tsx`
|
|----------|---------------|
|
||||||
- `IngressProxyPage.tsx` → `ServicesPage.tsx`
|
| Overview | → Dashboard (completely rewritten as infrastructure health) |
|
||||||
- `IngressProxyComponent.tsx` → `ServicesComponent.tsx`
|
| Cloudflare | → Dashboard (Cloudflare section) |
|
||||||
- `CentralComponent.tsx` → `DashboardComponent.tsx`
|
| DNS | → Services (per-service DNS status in expanded rows) |
|
||||||
|
| LAN DNS | → Services (per-service LAN DNS entries) |
|
||||||
|
| DDNS | → Dashboard (Dynamic DNS section — infrastructure health) |
|
||||||
|
| Ingress Proxy | → Services (proxy status in expanded rows, custom routes section) |
|
||||||
|
| Certificates | → Services (TLS status in expanded rows, provision inline) |
|
||||||
|
|
||||||
### 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
|
## Design Principles
|
||||||
- Two labeled groups: "Services" and "Central"
|
|
||||||
- "Overview" → "Dashboard"
|
1. **Services are the entrypoint.** The Services page is where you see, configure, and troubleshoot everything about what Central serves.
|
||||||
- "Ingress Proxy" → "Services"
|
|
||||||
- Remove DNS/LAN DNS/DDNS → replace with single "DNS"
|
2. **Dashboard is about infrastructure.** Is the foundation healthy? Router, Cloudflare, DDNS, daemons. If something here is red, fix it before worrying about individual services.
|
||||||
- Add DDNS content to Cloudflare page
|
|
||||||
|
3. **Everything about a service is in one place.** DNS, proxy, TLS, DDNS — all visible in the expanded service row. No hopping between pages to understand one service's status.
|
||||||
|
|
||||||
|
4. **Two sections, two concerns.** Services = what Central does for consumers. Central = what the device does for itself.
|
||||||
|
|
||||||
|
5. **6 items, not 9.** Less navigation, less confusion. The information isn't lost — it's better organized.
|
||||||
|
|||||||
Reference in New Issue
Block a user