Skip to content

Admin Dashboard

Most boilerplates stop at a marketing page. AI Web Launcher ships a working /dashboard route: a production admin shell with a collapsible sidebar, a command palette, six analytics charts, a settings form, modals, and toasts. Everything is driven by config and themed with the same Colorway C tokens as the rest of the app, so it looks like yours on day one.

What ships in the box

  • DashboardShell — collapsible sidebar + sticky top bar + ⌘K palette + toasts, wrapped around your page content.
  • DashboardSidebar — grouped, config-driven nav with badges, an active state that tracks the route, and an icon-rail collapse.
  • DashboardTopbar — search trigger, notifications menu with an unread count, user menu, and a slot for per-page actions.
  • CommandSearch — a grouped ⌘K / Ctrl-K palette wired to the router.
  • Six analytics charts — area, bar, line, stacked-bar, donut and radial, each driven by a single data prop.
  • AddItemDialog & SettingsForm — a create-modal pattern (validation + toast) and a full profile form you can wire to your API.

The shell is config, not markup

You never rebuild the chrome. Pass your brand, nav, user, notifications and search items as data, and drop your page body in as children.

Compose · DashboardShell
import { DashboardShell } from "@/components/dashboard";

<DashboardShell
  brand={<YourLogo />}
  sections={navSections}        // grouped nav items
  user={{ name, email }}        // top-right user menu
  notifications={notifications} // bell + unread count
  searchItems={searchItems}     // the ⌘K palette
  headerActions={<AddItemDialog />}
>
  {/* your page body */}
</DashboardShell>

The nav is a plain array of grouped items — add a section, add an item, set active on the current route, and the sidebar renders it (icon rail included).

Config · nav sections
const navSections = [
  {
    label: "Workspace",
    items: [
      { label: "Overview", icon: LayoutDashboard, href: "/dashboard", active: true },
      { label: "Apps", icon: Boxes, href: "/dashboard/apps", badge: 3 },
      { label: "Analytics", icon: BarChart3, href: "/dashboard/analytics" },
    ],
  },
  {
    label: "Account",
    items: [
      { label: "Billing", icon: CreditCard, href: "/dashboard/billing" },
      { label: "Settings", icon: Settings, href: "/dashboard/settings" },
    ],
  },
];

Six charts, one data prop each

The analytics page renders six reusable charts built on Recharts and themed to the brand accent. Each takes a single data prop, so the same set powers a real usage dashboard the moment you hand it your numbers.

Reuse · analytics charts
import {
  SessionsAreaChart,
  AcquisitionBarChart,
  CompletionLineChart,
  RetentionStackedBar,
  ComponentDonutChart,
  FeatureRadialChart,
} from "@/components/dashboard";

// Every chart takes a single `data` prop — swap the demo data for yours.
<SessionsAreaChart data={sessions} />

Public by default, gated in one line

The route is public so you can demo it immediately. To put it behind a signed-in user, guard the layout with the Supabase token that already ships in the boilerplate.

Gate · dashboard layout
// app/dashboard/layout.tsx — gate the whole route in one place
import { createClient } from "@/libs/supabase/server";
import { redirect } from "next/navigation";

export default async function DashboardLayout({ children }) {
  const supabase = createClient();
  const { data: { user } } = await supabase.auth.getUser();
  if (!user) redirect("/signin");
  return <DashboardChrome>{children}</DashboardChrome>;
}
It is already wired
The boilerplate's /signin flow and Supabase server client exist out of the box — gating the dashboard is a redirect, not a new integration.

Theming

Every surface reads the Colorway C design tokens — one accent used as a line, hairline structure, off-black and off-white neutrals, light and dark. Retarget the accent for a buyer in the design-system step and the whole dashboard moves with it. Nothing is hardcoded.