Architecture: UI Home Page — Dashboard Landing Experience
Date: 2026-03-03
Decision
Replace the / redirect with a proper dashboard-style home page that serves as the primary entry point. The page surfaces recent chats, shared conversations (by individual, team, and everyone), platform capability cards, and a personal insights widget. The page lives inside the (app) route group to inherit the global AppHeader layout.
Why a Home Page at /
The home page lives at / (not /dashboard or /home) because:
/is the natural entry point; the logo in AppHeader already links to/- It eliminates the redirect hop (better performance, no flash)
- It follows standard web application conventions
Why Inside the (app) Route Group
The page is at src/app/(app)/page.tsx rather than src/app/page.tsx because the (app) route group wraps children in a layout that renders AppHeader — the global navigation bar with Skills, Chat, Knowledge Bases, and Admin tabs. Placing the page outside this group would render it without navigation.
Alternatives Considered
| Alternative | Pros | Cons | Decision |
|---|---|---|---|
Dashboard home page at / (chosen) | Natural entry point, eliminates redirect, surfaces shared content and capabilities | New page to build and maintain | Selected |
Enhanced /skills page with dashboard widgets | No new route, incremental change | Conflates skill catalog with dashboard; skills page already has its own UX (gallery + runner); becomes cluttered | Rejected |
Separate /dashboard route, keep / redirect | Doesn't change existing flow | Extra redirect still exists; two "home" concepts confuse users; logo click goes to redirect, not dashboard | Rejected |
| Keep current redirect, add shared chats to sidebar | Minimal change | Sidebar is per-chat-page only; doesn't help new users orient; doesn't surface capabilities | Rejected |
Solution Architecture
Page Structure
┌──────────────────────────────────────────────────┐
│ AppHeader [Home] [Skills] [Chat] [KB] [Admin] │
├──────────────────────────────────────────────────┤
│ Welcome Banner │
│ "Welcome back, {firstName}" │
├──────────────────────────────────────────────────┤
│ Capability Cards (Chat | Skills | KB*) │
│ * Knowledge Bases shown only if RAG_ENABLED │
├──────────────────────────────────────────────────┤
│ Recent Chats (grid) │ Insights Widget* │
│ │ * MongoDB only │
├──────────────────────────────────────────────────┤
│ Shared Conversations* (tabbed) │
│ [With me] [Team] [Everyone] │
│ * MongoDB only │
├──────────────────────────────────────────────────┤
│ ⚡ Powered by caipe.io │
└──────────────────────────────────────────────────┘
Navigation Change
A "Home" pill was added as the first item in AppHeader's navigation pills. The getActiveTab() function was updated to return "home" when the pathname is exactly /.
Data Flow
ShareDialog Enhancement
The existing ShareDialog component (src/components/chat/ShareDialog.tsx) was updated to include a "Share with everyone" toggle (role="switch", data-testid="share-public-toggle") that sets sharing.is_public on the conversation. The backend field already existed; only the UI toggle was missing.
Graceful Degradation
When MongoDB is unavailable (storageMode !== 'mongodb'):
| Section | Behavior |
|---|---|
| Welcome Banner | Shown (uses session user name) |
| Capability Cards | Shown (static content, no API) |
| Recent Chats | Shown (loaded from localStorage via chat store) |
| Shared with me | Hidden (requires MongoDB) |
| Shared with team | Hidden (requires MongoDB) |
| Shared with everyone | Hidden (requires MongoDB) |
| Insights Widget | Hidden (requires MongoDB) |
| "Powered by" Footer | Shown (unconditional) |
Components Changed
New Components
| Component | Path | Purpose |
|---|---|---|
HomePage | src/app/(app)/page.tsx | Dashboard home page at / |
WelcomeBanner | src/components/home/WelcomeBanner.tsx | Personalized greeting with time-of-day awareness |
CapabilityCards | src/components/home/CapabilityCards.tsx | Chat / Skills / KB feature cards (KB conditional on RAG_ENABLED) |
RecentChats | src/components/home/RecentChats.tsx | Grid of recent conversation cards with "New Chat" link |
SharedConversations | src/components/home/SharedConversations.tsx | Tabbed view: with me / team / everyone |
InsightsWidget | src/components/home/InsightsWidget.tsx | Personal stats summary with "View all" link to /insights |
ConversationCard | src/components/home/ConversationCard.tsx | Reusable card for conversation entries with relative timestamps |
Modified Components
| Component | Path | Change |
|---|---|---|
AppHeader | src/components/layout/AppHeader.tsx | Added "Home" nav pill as first tab; updated getActiveTab() to detect / |
ShareDialog | src/components/chat/ShareDialog.tsx | Added data-testid="share-public-toggle" to the toggle (toggle itself merged in PR #891) |
Existing APIs Used (No Backend Changes)
| API | Client Method | Already Existed | Previously Used |
|---|---|---|---|
GET /api/chat/conversations | getConversations() | Yes | Yes (Sidebar) |
GET /api/chat/shared | getSharedConversations() | Yes | No (unused) |
GET /api/users/me/stats | getUserStats() | Yes | Yes (Insights page) |
POST /api/chat/conversations/:id/share | shareConversation() | Yes | Yes (ShareDialog) |
Related
- Spec: spec.md