Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b8944d0
chore(apollo-vertex): Add Layout menu item
petervachon Mar 20, 2026
c57705c
chore(apollo-vertex): General layout
petervachon Mar 20, 2026
0aa56c1
chore(apollo-vertex): Base setup for glow
petervachon Mar 21, 2026
5f84fda
chore(apollo-vertex): Devtool setup for canvas
petervachon Mar 22, 2026
30b0803
chore(apollo-vertex): Insight card config
petervachon Mar 22, 2026
e89878d
chore(apollo-vertex): Prompt card
petervachon Mar 22, 2026
c9dfee6
chore(apollo-vertex): OverviewCard
petervachon Mar 23, 2026
b57ab9c
chore(apollo-vertex): branchupdate
petervachon Mar 23, 2026
56c4be3
chore(apollo-vertex): Overview card updates
petervachon Mar 23, 2026
ed47e25
chore(apollo-vertex): Initial interaction insights
petervachon Mar 23, 2026
6c88e81
chore(apollo-vertex): Card interaction
petervachon Mar 23, 2026
e3a5444
chore(apollo-vertex): Experiment badge
petervachon Mar 23, 2026
fd91ddb
chore(apollo-vertex): update interaction
petervachon Mar 23, 2026
a186352
chore(apollo-vertex): Small adjustments
petervachon Mar 23, 2026
6f26b65
chore(apollo-vertex): Card cleanup
petervachon Mar 23, 2026
6c4cc11
chore(apollo-vertex): Flex adjustment
petervachon Mar 23, 2026
204ba52
chore(apollo-vertex): name change
petervachon Mar 23, 2026
80a7ba2
chore(apollo-vertex): chart glow
petervachon Mar 23, 2026
f1ded6f
chore(apollo-vertex): Responsive container
petervachon Apr 1, 2026
ab4eb07
chore(apollo-vertex): Compact view adjustments
petervachon Apr 1, 2026
fa41e28
chore(apollo-vertex): Compact mode updates
petervachon Apr 1, 2026
32370ba
chore(apollo-vertex): Componentize card content
petervachon Apr 1, 2026
5531d96
chore(apollo-vertex): Compact view
petervachon Apr 1, 2026
645eb62
chore(apollo-vertex): scroll behavior
petervachon Apr 1, 2026
d98860d
chore(apollo-vertex): Autopilot surface initial
petervachon Apr 1, 2026
e15556b
chore(apollo-vertex): Utility
petervachon Apr 1, 2026
22e83c6
chore(apollo-vertex): Dev tool for data
petervachon Apr 2, 2026
8a6086b
chore(apollo-vertex): Expanded card content
petervachon Apr 2, 2026
6cb26cd
chore(apollo-vertex): Expanded content
petervachon Apr 2, 2026
95d5541
chore(apollo-vertex): Small styles adjustments
petervachon Apr 2, 2026
038c114
chore(apollo-vertex): Expand cleanup
petervachon Apr 2, 2026
79e3999
chore(apollo-vertex): Color updates
petervachon Apr 2, 2026
a8e2f0a
chore(apollo-vertex): Clean up
petervachon Apr 2, 2026
d0f28b8
chore(apollo-vertex): Default dataset
petervachon Apr 2, 2026
185e5dc
chore(apollo-vertex): comment
petervachon Apr 2, 2026
dd22aa7
chore(apollo-vertex): clean up
petervachon Apr 2, 2026
3c71efe
chore(apollo-vertex): quick fix
petervachon Apr 2, 2026
8391de5
chore(apollo-vertex): cleanup
petervachon Apr 3, 2026
95b563f
chore(apollo-vertex): Rebase and linting
petervachon Apr 3, 2026
5e77663
chore(apollo-vertex): KPI card styles
petervachon Apr 3, 2026
ae9991e
chore(apollo-vertex): Expand load
petervachon Apr 3, 2026
fd95649
chore(apollo-vertex): Initial autopilot promptbar
petervachon Apr 3, 2026
d8a7700
chore(apollo-vertex): Prompt bar expand
petervachon Apr 3, 2026
0c6b972
chore(apollo-vertex): Documentation initial
petervachon Apr 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/apollo-vertex/app/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default {
dashboards: "Dashboards",
"data-querying": "Data Querying",
patterns: "Patterns",
layouts: "Layouts",
"shadcn-components": "Shadcn Components",
"vertex-components": "Vertex Components",
themes: "Themes",
Expand Down
2 changes: 2 additions & 0 deletions apps/apollo-vertex/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@import 'tailwindcss';
@source "../registry";
@source "../templates";

/* Optional: import Nextra theme styles */
@import 'nextra-theme-docs/style.css';
Expand Down
3 changes: 3 additions & 0 deletions apps/apollo-vertex/app/layouts/_meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
dashboard: "Dashboard",
};
149 changes: 149 additions & 0 deletions apps/apollo-vertex/app/layouts/dashboard/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { DashboardTemplate } from '@/templates/dashboard/DashboardTemplateDynamic';
import { PreviewFullScreen } from '@/app/components/preview-full-screen';

# Dashboard

A configurable dashboard template for building AI-assisted operational views. The dashboard is composed of named card regions with defined interaction patterns, designed to be data-driven and adaptable across verticals.

## Previews

### Sidebar Shell

<PreviewFullScreen title="Dashboard layout - sidebar shell">
<DashboardTemplate />
</PreviewFullScreen>

<a href="/preview/dashboard" target="_blank" className="text-sm text-primary hover:underline">Open standalone preview →</a>

### Minimal Header Shell

<PreviewFullScreen title="Dashboard layout - minimal shell">
<DashboardTemplate shellVariant="minimal" />
</PreviewFullScreen>

<a href="/preview/dashboard-minimal" target="_blank" className="text-sm text-primary hover:underline">Open standalone preview →</a>

---

## Anatomy

The dashboard is built from four semantic regions, each with a distinct role:

| Region | Description |
|---|---|
| **Overview Card** | The primary narrative area. Displays a greeting, headline, and subhead that summarize the current state. Occupies the top-left of the layout. |
| **Prompt Bar** | The AI input surface. Supports text entry, recommendation chips, and an expand interaction that opens an inline chat view. Anchored below the overview card. |
| **Insight Cards** | A grid of data cards on the right side. Each card has a type, a chart visualization, and an interaction pattern. Cards are arranged in rows of two. |
| **Autopilot Panel** | A slide-in panel that provides AI-generated analysis for a specific insight card. Triggered from the card's autopilot icon. |

## Card Types

Every insight card has a `type` that determines what it displays:

| Type | Renders | Example |
|---|---|---|
| `kpi` | A large number, badge, and description | "97.1%" with "+2.4%" badge |
| `chart` | A data visualization determined by `chartType` | Horizontal bars, stacked bars |

## Chart Types

Cards with `type: "chart"` use a `chartType` to select the visualization:

| Chart Type | Description |
|---|---|
| `horizontal-bars` | Ranked list of items with proportional bars and percentages |
| `stacked-bar` | Grouped bars with color-coded segments and a legend |
| `donut` | Circular progress indicator with a center label |
| `sparkline` | Compact line chart for trend indication |
| `area` | Filled area chart for volume over time |

## Card Sizes

Each card has a `size` that controls its column weight in the grid:

| Size | Grid Weight | Use Case |
|---|---|---|
| `sm` | `1fr` | KPI cards, compact metrics |
| `md` | `2fr` | Chart cards, detailed visualizations |
| `lg` | `1fr` | Full-width cards |

## Interaction Patterns

Cards support three interaction modes:

### Static

No interactive behavior. The card displays its content without any hover or click affordance. Used for simple KPIs that don't need drill-down.

### Navigate

On hover, an **arrow-up-right** icon appears in the card header. Clicking the card navigates to a detail page. Used for KPIs or summaries that link to a deeper view.

### Expand

On hover, a **maximize** icon appears in the card header. Clicking expands the card to fill the grid with a multi-phase animation:

1. **Width phase** — Card expands horizontally, sibling card collapses
2. **Height phase** — Card expands vertically, other rows collapse
3. **Full phase** — Expanded content fades in (drilldown tabs, autopilot prompts)

Clicking the **minimize** icon or another card collapses back to the grid.

For `horizontal-bars` cards, the expanded state includes **drilldown tabs** below the title for switching between data views.

## Prompt Bar

The prompt bar supports three ways to expand into the inline chat view:

| Trigger | Behavior |
|---|---|
| **Type + Enter / Submit** | Expands and passes the user's typed query |
| **Click a recommendation chip** | Expands and passes the chip text as the query |
| **Click the chat icon** | Expands and shows the current session conversation |

When expanded, the overview card collapses and the prompt bar grows to fill the left column. A **minimize** icon in the header collapses back to the default layout.

## Autopilot Panel

Each expandable card includes an **autopilot** icon alongside the expand icon. Clicking it slides in a panel from the right that provides AI-generated context for that card. The dashboard content shifts left to make room. Clicking the autopilot icon again or the close button dismisses the panel.

## Data Configuration

The dashboard is driven by a `DashboardDataset` object that defines all text and card content:

```ts
interface DashboardDataset {
name: string; // Dataset identifier
brandName: string; // Company name in header
brandLine: string; // Tagline in header
dashboardTitle: string; // Page title
badgeText: string; // Badge next to title
greeting: string; // Overview card greeting
headline: string; // Overview card headline
subhead: string; // Overview card description
promptPlaceholder: string; // Prompt bar placeholder text
promptSuggestions: string[]; // Recommendation chips
insightCards: [ // Exactly 4 insight cards
InsightCardData,
InsightCardData,
InsightCardData,
InsightCardData,
];
}
```

Each `InsightCardData` specifies its title, type, chart type, size, interaction, and the data for its visualization (KPI values, bar data, stacked segments, etc.).

## Layout Modes

The dashboard responds to container width:

| Mode | Breakpoint | Behavior |
|---|---|---|
| **Desktop** | ≥ 1100px | Two-column layout, full card grid |
| **Compact** | 800–1099px | Two-column layout, condensed card content |
| **Stacked** | < 800px | Single-column, vertically stacked |

## Theming

Card backgrounds, glow effects, and gradients are configurable through `CardConfig` and `GlowConfig` objects. The dashboard supports light and dark modes with independent styling for each. Color tokens and theme values should be updated in `registry.json`, not directly in CSS files.
3 changes: 3 additions & 0 deletions apps/apollo-vertex/app/preview/_meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
"*": { display: "hidden" },
};
16 changes: 16 additions & 0 deletions apps/apollo-vertex/app/preview/dashboard-minimal/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import dynamic from "next/dynamic";

const DashboardTemplate = dynamic(
() => import("@/templates/dashboard/DashboardTemplate").then((mod) => mod.DashboardTemplate),
{ ssr: false },
);

export default function DashboardMinimalPreviewPage() {
return (
<div className="fixed inset-0 z-50 bg-background not-prose">
<DashboardTemplate shellVariant="minimal" />
</div>
);
}
16 changes: 16 additions & 0 deletions apps/apollo-vertex/app/preview/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use client";

import dynamic from "next/dynamic";

const DashboardTemplate = dynamic(
() => import("@/templates/dashboard/DashboardTemplate").then((mod) => mod.DashboardTemplate),
{ ssr: false },
);

export default function DashboardPreviewPage() {
return (
<div className="fixed inset-0 z-50 bg-background not-prose">
<DashboardTemplate />
</div>
);
}
6 changes: 6 additions & 0 deletions apps/apollo-vertex/public/Autopilot_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions apps/apollo-vertex/public/Autopilot_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 31 additions & 1 deletion apps/apollo-vertex/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,17 @@
"color-sidebar-accent": "var(--sidebar-accent)",
"color-sidebar-accent-foreground": "var(--sidebar-accent-foreground)",
"color-sidebar-border": "var(--sidebar-border)",
"color-sidebar-ring": "var(--sidebar-ring)"
"color-sidebar-ring": "var(--sidebar-ring)",
"color-insight-50": "var(--insight-50)",
"color-insight-100": "var(--insight-100)",
"color-insight-200": "var(--insight-200)",
"color-insight-300": "var(--insight-300)",
"color-insight-400": "var(--insight-400)",
"color-insight-500": "var(--insight-500)",
"color-insight-600": "var(--insight-600)",
"color-insight-700": "var(--insight-700)",
"color-insight-800": "var(--insight-800)",
"color-insight-900": "var(--insight-900)"
},
"light": {
"background": "oklch(1 0 89.8800)",
Expand Down Expand Up @@ -118,6 +128,16 @@
"sidebar-accent-foreground": "oklch(0.1660 0.0283 203.3380)",
"sidebar-border": "oklch(0.9237 0.0133 262.3780)",
"sidebar-ring": "oklch(0.64 0.115 208)",
"insight-50": "oklch(0.96 0.03 277)",
"insight-100": "oklch(0.92 0.05 277)",
"insight-200": "oklch(0.86 0.09 277)",
"insight-300": "oklch(0.78 0.14 277)",
"insight-400": "oklch(0.70 0.19 277)",
"insight-500": "oklch(0.62 0.22 277)",
"insight-600": "oklch(0.56 0.20 277)",
"insight-700": "oklch(0.48 0.17 277)",
"insight-800": "oklch(0.38 0.13 278)",
"insight-900": "oklch(0.30 0.10 278)",
"font-sans": "Inter, ui-sans-serif, sans-serif, system-ui",
"font-serif": "IBM Plex Serif, ui-serif, serif",
"font-mono": "IBM Plex Mono, ui-monospace, monospace",
Expand Down Expand Up @@ -207,6 +227,16 @@
"sidebar-accent-foreground": "oklch(0.9525 0.0110 225.9830)",
"sidebar-border": "oklch(0.9525 0.0110 225.9830)",
"sidebar-ring": "oklch(0.69 0.112 207)",
"insight-50": "oklch(0.96 0.03 277)",
"insight-100": "oklch(0.92 0.05 277)",
"insight-200": "oklch(0.86 0.09 277)",
"insight-300": "oklch(0.78 0.14 277)",
"insight-400": "oklch(0.70 0.19 277)",
"insight-500": "oklch(0.62 0.22 277)",
"insight-600": "oklch(0.56 0.20 277)",
"insight-700": "oklch(0.48 0.17 277)",
"insight-800": "oklch(0.38 0.13 278)",
"insight-900": "oklch(0.30 0.10 278)",
"font-sans": "Inter, ui-sans-serif, sans-serif, system-ui",
"font-serif": "IBM Plex Serif, ui-serif, serif",
"font-mono": "IBM Plex Mono, ui-monospace, monospace",
Expand Down
2 changes: 1 addition & 1 deletion apps/apollo-vertex/registry/card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const GLASS_CLASSES = [
"dark:shadow-[0_2px_24px_2px_rgba(0,0,0,0.12),inset_0_1px_0_0_color-mix(in_srgb,var(--sidebar)_5%,transparent)]",
] as const;

const cardVariants = cva("flex flex-col text-card-foreground", {
const cardVariants = cva("flex flex-col gap-6 py-6 text-card-foreground", {
variants: {
variant: {
default: GLASS_CLASSES,
Expand Down
76 changes: 76 additions & 0 deletions apps/apollo-vertex/templates/dashboard/AutopilotInsight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"use client";

import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

interface AutopilotInsightProps {
onClose: () => void;
sourceCardTitle: string;
}

export function AutopilotInsight({
onClose,
sourceCardTitle,
}: AutopilotInsightProps) {
return (
<Card
variant="glass"
className="!bg-white/90 dark:!bg-card h-full overflow-hidden relative"
>
{/* Close button */}
<button
type="button"
onClick={onClose}
className="absolute top-5 right-5 z-20 size-7 rounded-md flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-all"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="size-4"
>
<path d="M18 6 6 18" />
<path d="m6 6 12 12" />
</svg>
</button>

<CardHeader className="!gap-2">
<div className="flex items-center gap-2">
<img
src="/Autopilot_dark.svg"
alt="Autopilot"
className="size-5 block dark:hidden"
/>
<img
src="/Autopilot_light.svg"
alt="Autopilot"
className="size-5 hidden dark:block"
/>
<CardTitle className="text-sm font-bold tracking-tight">
Autopilot Insight
</CardTitle>
</div>
<p className="text-xs text-muted-foreground">
Analyzing {sourceCardTitle}
</p>
</CardHeader>

<CardContent className="flex-1 flex flex-col">
{/* Placeholder for future chat UX responses */}
<div className="flex-1 border border-dashed border-muted-foreground/15 bg-muted/30 rounded-lg flex items-center justify-center">
<div className="text-center">
<p className="text-sm text-muted-foreground/60">
Autopilot response area
</p>
<p className="text-xs text-muted-foreground/40 mt-1">
Chat UX content will appear here
</p>
</div>
</div>
</CardContent>
</Card>
);
}
Loading
Loading