From 9994bbeaac24967b42ba73433ca192d029e9b354 Mon Sep 17 00:00:00 2001 From: Hermes Date: Thu, 9 Apr 2026 21:17:41 -0500 Subject: [PATCH] Complete visual redesign: solid dark cards, purple accent, iOS-like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - All pages use new design system (card, section-label, btn-accent) - No more glassmorphism — clean solid surfaces - Cron, Soul, Config, Skills detail all restyled - Consistent typography and spacing throughout --- app/config/page.tsx | 65 +++++++------------ app/cron/page.tsx | 125 ++++++++++++++++--------------------- app/skills/[name]/page.tsx | 49 ++++++--------- app/soul/page.tsx | 36 +++++------ 4 files changed, 112 insertions(+), 163 deletions(-) diff --git a/app/config/page.tsx b/app/config/page.tsx index ad17d83..5b00204 100644 --- a/app/config/page.tsx +++ b/app/config/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { Settings, Cpu, Globe, Wrench, Radio } from "lucide-react"; +import { Settings } from "lucide-react"; import { useConfig, useHealth } from "@/lib/hooks"; export default function ConfigPage() { @@ -9,7 +9,6 @@ export default function ConfigPage() { const online = health?.status === "ok"; const cfg = config?.config || {}; - const terminal = cfg.terminal as Record | undefined; const memory = cfg.memory as Record | undefined; const display = cfg.display as Record | undefined; @@ -17,52 +16,47 @@ export default function ConfigPage() { return (
-
- -

Config

-
-
- {online ? "Connected" : "Offline"} +
+

Config

+
+
+ + {online ? "Online" : "Offline"} +
{isLoading ? (
{[...Array(4)].map((_, i) => ( -
-
-
+
+
+
))}
) : (
- - - - - - -
)} @@ -70,28 +64,15 @@ export default function ConfigPage() { ); } -function ConfigSection({ - icon: Icon, - label, - color, - items, -}: { - icon: typeof Cpu; - label: string; - color: string; - items: [string, string][]; -}) { +function Section({ label, items }: { label: string; items: [string, string][] }) { return ( -
-
- - {label} -
-
+
+
{label}
+
{items.map(([k, v]) => ( -
- {k} - {v} +
+ {k} + {v}
))}
diff --git a/app/cron/page.tsx b/app/cron/page.tsx index 3b2b0bf..24fa7a9 100644 --- a/app/cron/page.tsx +++ b/app/cron/page.tsx @@ -1,8 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { Timer, Play, Pause, RefreshCw, ChevronRight } from "lucide-react"; -import Link from "next/link"; +import { Timer, Play, RefreshCw } from "lucide-react"; import { timeAgo } from "@/lib/utils"; interface CronJob { @@ -19,14 +18,15 @@ interface CronJob { run_count?: number; last_run?: string; next_run?: string; - created_at?: string; } export default function CronPage() { const [jobs, setJobs] = useState([]); const [loading, setLoading] = useState(true); + const [triggering, setTriggering] = useState(null); const load = () => { + setLoading(true); fetch("/cron/jobs") .then((r) => r.json()) .then((d) => setJobs(d.jobs || [])) @@ -37,8 +37,10 @@ export default function CronPage() { useEffect(() => { load(); }, []); const trigger = async (id: string) => { - await fetch(`/cron/jobs/${id}/run`, { method: "POST" }); - load(); + setTriggering(id); + await fetch("/cron/jobs/" + id + "/run", { method: "POST" }); + setTriggering(null); + setTimeout(load, 1000); }; const active = jobs.filter((j) => j.status === "active" || j.status === "enabled"); @@ -48,15 +50,8 @@ export default function CronPage() { return (
-
- -

Cron Jobs

-
-
@@ -64,81 +59,67 @@ export default function CronPage() { {loading ? (
{[...Array(3)].map((_, i) => ( -
-
-
+
+
+
))}
) : jobs.length === 0 ? ( -
- No cron jobs configured +
+ +

No cron jobs

) : ( -
- {active.length > 0 && ( -
- )} - {paused.length > 0 && ( -
- )} - {other.length > 0 && ( -
- )} +
+ {active.length > 0 && } + {paused.length > 0 && } + {other.length > 0 && }
)}
); } -function Section({ label, jobs, onTrigger }: { label: string; jobs: CronJob[]; onTrigger: (id: string) => void }) { +function JobSection({ label, jobs, onTrigger, triggering }: { label: string; jobs: CronJob[]; onTrigger: (id: string) => void; triggering: string | null }) { return (
-

- {label} ({jobs.length}) -

-
+
{label} ({jobs.length})
+
{jobs.map((j) => ( - onTrigger(j.id)} /> +
+
+
+
+ {j.name || j.prompt.slice(0, 60)} +
+
{j.schedule}
+
+
+
+ +
+
+
+ → {j.deliver} + {j.skills && j.skills.length > 0 && ( + {j.skills.join(", ")} + )} + {j.last_run && last: {timeAgo(new Date(j.last_run).getTime() / 1000)}} +
+
))}
); } - -function CronCard({ job, onTrigger }: { job: CronJob; onTrigger: () => void }) { - const isActive = job.status === "active" || job.status === "enabled"; - return ( -
-
-
-
- {job.name || job.prompt.slice(0, 60)} -
-
{job.schedule}
-
-
-
- -
-
-
- → {job.deliver} - {job.skills && job.skills.length > 0 && ( - {job.skills.join(", ")} - )} - {job.last_run && last: {timeAgo(new Date(job.last_run).getTime() / 1000)}} -
-
- ); -} diff --git a/app/skills/[name]/page.tsx b/app/skills/[name]/page.tsx index 9963a62..054cb0c 100644 --- a/app/skills/[name]/page.tsx +++ b/app/skills/[name]/page.tsx @@ -12,53 +12,42 @@ export default function SkillDetailPage({ params }: { params: Promise<{ name: st return (
- - + + -

{name}

+

{name}

{isLoading ? ( -
-
-
-
+
+
+
) : data ? ( <> - {/* Linked files */} {data.linked_files && Object.keys(data.linked_files).length > 0 && ( -
-
+
+
Linked Files
-
- {Object.entries(data.linked_files).map(([dir, files]) => - (files as string[]).map((f) => ( -
- - {dir}/{f} -
- )) - )} -
+ {Object.entries(data.linked_files).map(([dir, files]) => + (files as string[]).map((f) => ( +
+ + {dir}/{f} +
+ )) + )}
)} - - {/* Skill content */} -
-
+          
+
               {data.content}
             
) : ( -
- Skill not found -
+

Skill not found

)}
); diff --git a/app/soul/page.tsx b/app/soul/page.tsx index abe65ee..ba93a7c 100644 --- a/app/soul/page.tsx +++ b/app/soul/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { Sparkles, Save, RotateCcw } from "lucide-react"; +import { Save, RotateCcw } from "lucide-react"; export default function SoulPage() { const [content, setContent] = useState(""); @@ -36,46 +36,44 @@ export default function SoulPage() { return (
-
- -

SOUL.md

-
+

SOUL.md

{dirty && ( - )}
-

- Persona file loaded fresh each message. Edit to change how Hermes communicates. +

+ Persona file. Loaded fresh each message.

{loading ? ( -
-
-
-
+
+
+
) : (