Skip to content

App Shell (Navigation, Search, Assistant Sidebar)

This document defines the shared application shell used across authenticated ConversionIQ surfaces.

Scope:

  • Layout regions common to most in-app pages (left navigation, top bar, profile menu)
  • Shared footer region for authenticated app pages
  • Global platform search behavior (contract-level, UI details may evolve)
  • Chatti Live assistant sidebar behavior (show/hide rules)

Out of scope:

  • Page-specific business logic (belongs in docs/domains/**)
  • Route-specific composition details (belongs in docs/routes/**)

References:


Provide a consistent enterprise-grade shell that:

  • Preserves org/workspace context and isolation cues
  • Offers predictable navigation across apps
  • Enables global search without permission leakage
  • Provides an assistant entry point (Chatti Live sidebar) without disrupting primary workflows

Responsibilities:

  • Primary navigation between top-level app sections.
  • Secondary navigation for the selected section.

Presentation states:

  • Default (expanded): icons + labels + section group headings.
  • Narrowed: icon-only rail (labels hidden; discovery behavior is TBD such as tooltips).

Expected groups (sitemap-aligned):

  • Get started
  • Account
  • Comment Responder
  • Chatti Live

Account menu order (main nav):

  1. Dashboard
  2. Workspaces
  3. Knowledge bases
  4. Channels
  5. Agents
  6. My profile
  7. Settings

Note: Agents is presented under the Account group in the left nav menu.

The Workspace detail page (/account/workspaces/[workspaceId]) opens a full-screen bottom sheet for the node view — a visual graph of the workspace’s resource structure. The sheet header contains:

  • Workspace selectorDropdownMenu at the leading edge of the sheet header (before connection toggles). With 2+ workspaces, choosing an item updates the in-sheet workspace without closing the sheet; with one workspace, shows a non-interactive label + avatar.
  • KB connections toggleSwitch labeled “KB connections”. Toggles visibility of all dashed KB-connection edges (agent→KB and channel→KB) in the graph. Default: on. Session-local (not persisted).

See Workspace – Node View for the full node view specification.

Get Started progress indicator (onboarding)

Section titled “Get Started progress indicator (onboarding)”

The Get started navigation item includes a 3-segment circular progress indicator representing onboarding progress:

  • Segment 1: Step 1 — Select channels
  • Segment 2: Step 2 — Connect channels
  • Segment 3: Step 3 — Train ConversionIQ AI

Visual rule:

  • Completed segment: solid (white)
  • Incomplete segment: semi-transparent

Visibility:

  • The progress indicator is shown in both left-nav presentation states:
    • Default (expanded)
    • Narrowed (icon-only)
  • The entire Get started navigation item is shown only while onboarding is incomplete AND not persistently hidden.
    • The nav item is hidden/removed when any of these is true:
      • Step 3 is completed (onboarding complete).
      • persistentlyHidden is true (user toggled “Don’t show Get Started automatically” in the overlay header).

Source of truth:

  • Segment completion must be derived from onboarding progress state (see Get Started – Stepper (3 steps)), not a client-only flag.
    • Onboarding is complete only after Step 3 is completed.

Notes:

  • Navigation must remain consistent with Sitemap (ConversionIQ) and docs/routes/**/README.md.
  • Items must be hidden/disabled if the user lacks required permissions (TBD exact gating rules per route doc).

Required elements:

  • Breadcrumbs (reflect current active page)
    • Purpose: communicate the current location within the app hierarchy.
    • Format: {Top-level section} > {Active page}
      • Example: Account > Dashboard
      • Example: Account > Channels
      • Example: Account > Profile
    • Rules:
      • Breadcrumbs must always reflect the current active page.
      • The active page crumb must match the route’s page title (sitemap-aligned).
      • Color rule (required for consistency):
        • All breadcrumb levels except the last (current) use the muted text color (same as the 1st level; e.g. #999).
        • Only the last (current) breadcrumb item uses the dark text color (e.g. #0d0d0d or #333).
        • Example: Account (muted) > Workspaces (muted when there is a 3rd level) > Acme Workspace (dark/current).
      • Workspace detail (top bar):
        • On /account/workspaces/[workspaceId], the breadcrumb trail is: Account > Workspaces (link to the workspaces list) > workspace name (last/current crumb).
        • The workspace name crumb is a dropdown/select when the account has more than one workspace (lists all workspaces; selection navigates to /account/workspaces/[id]).
        • The workspace name crumb is a plain (non-interactive) label when there is only one workspace.
        • The workspace name crumb uses the dark/foreground text color (it is the last/current crumb). Account and Workspaces use muted color per the standard color rule.
        • There is no workspace switcher placed before the section label — the workspace name lives only at the end of the breadcrumb trail.
      • Knowledge base detail breadcrumb (workspace-scoped entry):
        • When opening a KB detail from a workspace KB list, breadcrumb must be:
          • Account > Workspaces > [Workspace name] > [KB name]
        • [Workspace name] links back to /account/workspaces/[workspaceId].
        • [KB name] is the active crumb and becomes a dropdown/select when the workspace has 2+ KBs:
          • Trigger label shows the current KB name (truncated if needed).
          • Dropdown lists KBs from that workspace only.
          • Selecting a KB navigates to /account/knowledge-bases/[kbId] while preserving workspace breadcrumb context.
      • The My profile surface (including Billing and Activity log tabs) is part of the Account section for breadcrumbs (e.g., Account > My profile).
      • Separator style (e.g., chevrons) is UI-level; semantics must be clear for accessibility.
    • A toggle control (icon) in the breadcrumb area toggles the left navigation rail between Default and Narrowed states. This control is shown for all top-level sections (Account, Comment Responder, Chatti Live), not only Account.
    • The last breadcrumb item (active page) is a dropdown when the current section has 2 or more pages:
      • Clicking it opens that section’s submenu (secondary navigation for the current section).
      • Selecting an item navigates within the section and updates breadcrumbs accordingly.
      • If the section has only 1 page, the last breadcrumb item is rendered as a plain, non-interactive span.
  • Global platform search input
  • Conditional assistant toggle (see Chatti Live section)
  • Page title and page-specific content region.
  • The shell does not add padding around the main content area; each page is responsible for its own layout.
  • Account-section pages use a standard top section with px-6 py-5 and a single outer border-b.
  • For simple pages, this top section may contain only the page title / supporting copy.
  • For list pages with filters, the title/meta row and the filter toolbar live inside the same bordered top section with internal spacing between them and no divider between header and filters.
  • Count rule for list pages:
    • The page-level title badge shows the total number of entities on that page and must not change when table/list filters are applied.
    • Any table/list section header count inside the page shows the currently visible filtered dataset for that section.
  • Overview/dashboard checklist for Account-style operator pages:
    • Lead with the most decision-critical information first; detail belongs below summary.
    • Keep the initial screen scannable; avoid equally loud competing metrics.
    • Tab or category label counts show stable totals for that category and do not change with filters.
    • Filters should refine or prioritize the content below without destroying the high-level overview.
    • Reuse shared top-section, filter, tabs, section-header, and table-control patterns across sibling pages.
    • Use keyboard-only visible focus states for controls; mouse selection should not leave prominent focus halos.
    • Scrollbars and supporting chrome must inherit the active light/dark theme.
    • When local/context data already exists, prefer immediate render with background refresh over blocking the page behind loading skeletons.
  • The shell must not impose domain rules; it provides composition only.

4) Right sidebar: Chatti Live assistant (conditional)

Section titled “4) Right sidebar: Chatti Live assistant (conditional)”

When shown:

  • Docked sidebar on the right
  • Header: Chatti Live with overflow actions and close control
  • Content area (assistant messages + recommended actions)
  • Input dock: “Ask your question”

When hidden:

  • Sidebar is absent
  • A Chatti Live toggle button appears next to the global search input
  • A shared footer is pinned below the main content area in the authenticated shell.
  • The footer provides lightweight secondary navigation and support/legal entry points.
  • Current footer actions:
    • Security
    • Help
    • Contact
    • Components
    • Legal
  • Components links to /account/components.
  • The footer is not part of the primary left navigation and should be treated as secondary utility navigation.

  • Hidden state: show Chatti Live button in the top bar (next to search).
  • Shown state: hide the top-bar button (sidebar header provides controls).
  • Closing the sidebar returns to hidden state.

The assistant sidebar may be gated by:

  • Feature flag / plan entitlement (TBD)
  • Role/permission checks (TBD)

If not available:

  • Do not show the top-bar toggle
  • Do not render the sidebar

The assistant is intended to be a Gemini-backed assistant in a Chrome browser context. Details (auth, data access, tool boundaries) must comply with Security & Compliance and must be documented before implementation.


Search is global across the platform, but must respect:

  • org scope (org_id)
  • workspace scope (workspace_id) where applicable
  • RBAC permissions for each result type

Search must not leak:

  • existence of entities the user cannot access
  • cross-workspace or cross-org data

All result rendering must be permission-filtered (no “UI-only security”).

  • Result grouping by entity type (routes, KBs, channels, conversations, etc.) is TBD.
  • Keyboard navigation and accessibility requirements are required (TBD component contracts).

This control is profile-only (not a workspace switcher).

Expected menu items (sitemap-aligned):

  • My profile — links to /account/my-profile?tab=profile
  • Billing — links to /account/my-profile?tab=billing
  • Activity log — links to /account/my-profile?tab=activity
  • Log out

The menu may display user identity summary (name/email). My profile, Billing, and Activity log all target the same My profile page with the appropriate tab selected via the tab query parameter.


Shell-level UI states that must be supported across pages:

  • Left nav: default (expanded) / narrowed
  • Profile menu: closed / open
  • Global search: idle / querying / empty / error (TBD)
  • Assistant sidebar: hidden / shown
  • Get Started onboarding overlay: inactive / active (fullscreen overlay; see Get Started – Stepper (3 steps))

Overlay interaction expectations (MVP):

  • When onboarding overlay is active, it covers the shell (navigation/search/assistant are not the primary surface) (TBD exact interaction lock).
  • Closing/dismissing the overlay navigation rule:
    • If the user was on /get-started (i.e. they navigated there directly): redirect to Account → Dashboard after dismissal.
    • If the user was on any other account page (e.g. /account/channels, /account/workspaces): do not navigate. Simply dismiss the overlay and refresh setup state. The user stays on the page they were already viewing.
    • Rationale: the overlay is a layer on top of the shell; closing it should not disrupt the user’s current context unless they have no underlying page to return to.
  • The overlay is shown on every authenticated entry until onboarding is complete or persistently hidden.
  • Onboarding is considered complete only after the user completes Step 3: Train ConversionIQ AI.
  • Persistent hide: When persistentlyHidden is true, the overlay never auto-opens and the Get started nav item is removed. Restore path: Chatti Live only.

Filter triggers and select-like controls that use the shared SELECT_TRIGGER_BASE_CLASSNAME contract must follow a single state model across the app:

  • Use the violet ring for focus-visible only.
  • Do not reuse that ring as an “open” indicator on click.
  • Open-state affordance, when needed, should be subtle and consistent across controls (for example chevron direction, border tint, or surface tint), but must not conflict with the accessibility focus treatment.

This applies to toolbar filters such as All workspaces, All groups, status selects, and similar trigger controls on other pages.

All tab triggers across the app must use the shared TabsTrigger component from @/components/ui/tabs (Radix TabsPrimitive.Trigger wrapper).

Standard padding: py-1 px-2 (4 px vertical, 8 px horizontal)

  • This is baked into the shared component’s default className and must not be overridden at the call site.
  • Do not pass px-* or py-* overrides to <TabsTrigger className="..."> — doing so breaks visual consistency across all tab instances.
  • If a page needs a visually distinct tab style, discuss and update the shared component; do not patch it locally.

Reference implementation: src/components/ui/tabs.tsx


  • Navigation items must be gated by route permissions (see each route doc).
  • Search must filter results to the user’s authorized scope.
  • Assistant must not access cross-workspace data unless explicitly authorized and documented.

Reference: Roles & Permissions Model


  • Do not emit/store PII or message content in analytics.
  • Mask secrets in all UI surfaces (including assistant).
  • Prevent cross-tenant leakage via navigation, search, or assistant context.

Reference: Security & Compliance


Minimum expectations:

  • Shell load / route view events remain page-owned (e.g., account.dashboard.viewed)
  • Search/assistant interaction events are TBD and must not include PII or message content

Reference: Analytics Events (MVP)