| import { DashboardProvider } from "@/lib/dashboard" | |
| import { Sidebar } from "@/components/layout/Sidebar" | |
| import { TopBar } from "@/components/layout/TopBar" | |
| import { Section } from "@/components/layout/Section" | |
| import { ModulePanel } from "@/components/layout/ModulePanel" | |
| import { Toaster } from "@/components/ui/sonner" | |
| import { SECTIONS, SPAN_CLASS, modulesForSection } from "@/modules/registry" | |
| export default function App() { | |
| let delay = 0 | |
| const nextDelay = () => `${(delay++ * 60).toString()}ms` | |
| return ( | |
| <DashboardProvider> | |
| <div className="flex min-h-screen"> | |
| <Sidebar /> | |
| <div className="flex min-w-0 flex-1 flex-col"> | |
| <TopBar /> | |
| <main className="mx-auto w-full max-w-[1500px] flex-1 space-y-10 px-4 py-8 sm:px-6"> | |
| {SECTIONS.sort((a, b) => a.order - b.order).map((section) => ( | |
| <Section key={section.id} section={section}> | |
| {modulesForSection(section.id).map((m) => ( | |
| <ModulePanel | |
| key={m.id} | |
| module={m} | |
| className={SPAN_CLASS[m.span]} | |
| style={{ animationDelay: nextDelay() }} | |
| /> | |
| ))} | |
| </Section> | |
| ))} | |
| <footer className="flex items-center justify-between border-t border-border/60 pt-4 font-mono text-[0.625rem] uppercase tracking-wider text-muted-foreground/50"> | |
| <span>tiny trigger · gradio.server backend</span> | |
| <span>rules are data, never code</span> | |
| </footer> | |
| </main> | |
| </div> | |
| </div> | |
| <Toaster /> | |
| </DashboardProvider> | |
| ) | |
| } | |