Nexus AI

Components Guide

The template ships 90+ components. They fall into a few groups under src/components/. The ui/ folder holds the shadcn/ui primitives; everything else is built on top of them.

Folder map

src/components/
├── ui/                shadcn/ui primitives (button, card, dialog, table,
│                      calendar, radio-group, toggle-group, …)
├── layout/            AppShell, Sidebar, Topbar, command palette, theme builder,
│                      notifications, logo, user menu
├── common/            StatCard, PageHeader, EmptyState, StatusBadge, ActivityFeed
├── charts/            Line / Area / Bar / Donut / Mixed wrappers + primitives
├── tables/            DataTable (TanStack Table + CSV/Excel export)
├── forms/             Date/range/time pickers, color picker, tags, multi-select,
│                      combobox, OTP, rating, stepper, range slider, phone,
│                      rich-text editor, image cropper, dropzone, form builder
├── ai/                ModelSelector, TokenCounter, UsageMeter, AgentStatus…
├── kanban/            Board, columns, cards, task & column dialogs
├── calendar/          Month / Week / Day views, time grid, event dialog
├── chat/              Chat view, message bubbles, streaming
├── notifications/     Notification item + full-page view
├── dashboard-builder/ Editable widget grid + widget renderer
├── audit/             Audit-log table view
├── integrations/      Connect/disconnect cards
├── onboarding/        Multi-step wizard
└── <page area>/       analytics, prompts, playground, users, billing, settings…

Common components

StatCard

src/components/common/stat-card.tsx — an animated metric card with optional trend, icon and sparkline.

import { Activity } from "lucide-react";
import { StatCard } from "@/components/common/stat-card";

<StatCard
  label="Total API Calls"
  value={2_418_902}
  change={14.2}            // % vs last period
  icon={Activity}
  sparkline={[12, 18, 14, 22, 30]}
  // invertTrend            // set when "down" is good (e.g. cost)
/>;

PageHeader

src/components/common/page-header.tsx — title, breadcrumbs and an actions slot. Used at the top of every page.

<PageHeader
  title="Users"
  description="Manage everyone in your workspace."
  breadcrumbs={[{ label: "Dashboard", href: "/dashboard" }, { label: "Users" }]}
  actions={<Button>Invite user</Button>}
/>

StatusBadge

src/components/common/status-badge.tsx — maps a status string (active, paused, paid, pro, admin, …) to a consistent color tone automatically.

<StatusBadge status="active" />     {/* green dot + label */}
<StatusBadge status="pro" dot={false} />

EmptyState / ActivityFeed

EmptyState (icon + message + CTA) for empty lists; ActivityFeed renders a vertical timeline of events.

Charts

All wrappers live in src/components/charts/ and use Recharts with shared theming. They accept a data array and a series config.

import { LineChart } from "@/components/charts/line-chart";

<LineChart
  data={apiUsageData}                       // [{ date, calls }, …]
  series={[{ key: "calls", label: "API calls" }]}
  valueFormatter={(v) => v.toLocaleString()}
/>;

Available: LineChart, AreaChart (stacked), StackedBarChart, CategoryBarChart, DonutChart (+ ChartLegend), MixedChart (bars + line). Colors come from the --chart-1…6 tokens; see Customization.

Charts render after mount (via the useMounted hook) to avoid Recharts' 0×0-size warning during server rendering — keep that pattern if you add new chart wrappers.

DataTable

src/components/tables/data-table.tsx — a TanStack Table v8 wrapper with sorting, pagination, column visibility, optional row selection, a bulk-action bar, and built-in CSV / Excel export (dependency-free).

import { DataTable } from "@/components/tables/data-table";

<DataTable
  columns={columns}            // TanStack ColumnDef[]
  data={rows}
  pageSize={10}
  enableRowSelection
  showExport                   // adds a CSV / Excel export menu
  exportFileName="users"
  onRowClick={(row) => router.push(`/users/${row.id}`)}
  renderBulkActions={(selected, clear) => (
    <Button onClick={() => { /* … */ clear(); }}>Delete {selected.length}</Button>
  )}
  toolbar={<Input placeholder="Search…" />}
/>;

Export respects current filters/sorting and only includes visible columns. Customize a column's exported output with meta.exportHeader / meta.exportValue, or skip it with meta.noExport. The export helpers live in src/lib/export.ts. See src/components/users/users-view.tsx and src/components/prompts/prompts-view.tsx for full column examples.

AI components

In src/components/ai/:

  • ModelSelector — dropdown of models with provider dot + per-1K cost.
  • TokenCounter — horizontal usage bar with limit and percentage.
  • UsageMeter — circular quota progress meter.
  • AgentStatusIndicator — colored status pill (active/paused/training/error).
  • CostMetric — currency value with trend.
  • ModelCard — model spec card with set-primary action.

Forms

Forms use React Hook Form + Zod. Pattern (from the auth pages):

const schema = z.object({ email: z.string().email() });
const { register, handleSubmit, formState: { errors } } = useForm({
  resolver: zodResolver(schema),
});

The Form Components page (/forms) showcases a large library of inputs in src/components/forms/, all controlled (value/onChange) so they drop straight into RHF via <Controller>:

  • Pickers: DatePicker, DateRangePicker, TimePicker, Calendar (a dependency-free month grid built on date-fns), ColorPicker.
  • Selection: MultiSelect, Combobox, TagInput, RadioGroup, ToggleGroup (segmented control).
  • Specialized: OTPInput, RatingInput, StepperInput, RangeSlider, PhoneInput, FileDropzone, RichTextEditor, ImageCropper, PasswordInput.
  • Form builder (dynamic-form-builder.tsx) — add / remove / reorder fields with a live preview.

Adding a component

Put shared UI in the closest matching folder (common/, ai/, charts/…), or a new <page-area>/ folder for page-specific views. Reuse the cn() helper from @/lib/utils for class merging, and keep client-only logic behind "use client".

Next: Mock Data →