From 4500a1a45e1766744db1281d0295533536e39bca Mon Sep 17 00:00:00 2001 From: Paul Payne Date: Tue, 14 Jul 2026 12:18:07 +0000 Subject: [PATCH] Add certbot status to dashboard services and sidebar nav indicator - Add certbot to getDaemonStatus: checks binary availability and version - Dashboard: add Certificates card to services grid - Sidebar: show green/red status dot for certbot on Certificates nav item --- internal/api/v1/handlers.go | 14 ++++++++++++++ web/src/components/AppSidebar.tsx | 2 +- web/src/components/DashboardComponent.tsx | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/internal/api/v1/handlers.go b/internal/api/v1/handlers.go index 2bf8b18..a2de414 100644 --- a/internal/api/v1/handlers.go +++ b/internal/api/v1/handlers.go @@ -550,6 +550,20 @@ func getDaemonStatus() map[string]map[string]any { } result["nftables"] = nftEntry + // certbot is a CLI tool, not a daemon — check if installed + certbotEntry := map[string]any{"active": false} + if _, err := exec.LookPath("certbot"); err == nil { + certbotEntry["active"] = true + if out, verErr := exec.Command("certbot", "--version").Output(); verErr == nil { + // "certbot 2.11.0" + s := strings.TrimSpace(string(out)) + if _, after, found := strings.Cut(s, " "); found { + certbotEntry["version"] = after + } + } + } + result["certbot"] = certbotEntry + return result } diff --git a/web/src/components/AppSidebar.tsx b/web/src/components/AppSidebar.tsx index 58b7e78..b5e3dc5 100644 --- a/web/src/components/AppSidebar.tsx +++ b/web/src/components/AppSidebar.tsx @@ -105,7 +105,7 @@ export function AppSidebar() { { to: '/advanced/crowdsec', icon: ShieldAlert, label: 'CrowdSec', daemon: 'crowdsec' as const }, { to: '/advanced/authelia', icon: KeyRound, label: 'Authelia', daemon: 'authelia' as const }, { to: '/advanced/ddns', icon: Globe, label: 'DDNS', daemon: undefined }, - { to: '/advanced/certificates', icon: ShieldCheck, label: 'Certificates', daemon: undefined }, + { to: '/advanced/certificates', icon: ShieldCheck, label: 'Certificates', daemon: 'certbot' as const }, ]; return ( diff --git a/web/src/components/DashboardComponent.tsx b/web/src/components/DashboardComponent.tsx index aacd68f..765f338 100644 --- a/web/src/components/DashboardComponent.tsx +++ b/web/src/components/DashboardComponent.tsx @@ -8,7 +8,7 @@ import { Badge } from './ui/badge'; import { LayoutDashboard, Cloud, CheckCircle, XCircle, AlertCircle, Loader2, BookOpen, Globe, Router, RotateCw, Key, KeyRound, - Shield, Eye, ArrowLeftRight, Lock, + Shield, ShieldCheck, Eye, ArrowLeftRight, Lock, } from 'lucide-react'; import { useCloudflare } from '../hooks/useCloudflare'; import { useCentralStatus } from '../hooks/useCentralStatus'; @@ -23,6 +23,7 @@ const SERVICES = [ { key: 'wireguard', label: 'VPN', icon: Lock }, { key: 'crowdsec', label: 'CrowdSec', icon: Eye }, { key: 'authelia', label: 'Auth', icon: KeyRound }, + { key: 'certbot', label: 'Certificates', icon: ShieldCheck }, ]; function formatUptime(totalSeconds: number): string {