Skip to content

Repository files navigation

Sentra Onboarding Flow

A multi-step onboarding modal for new Sentra users. Built with Next.js 16, React 19, Tailwind CSS 4, and Radix UI primitives.


Quick Start

pnpm install
pnpm dev

Navigate to http://localhost:3000/onboarding to see the flow.


Architecture Overview

components/onboarding/
├── onboarding-modal.tsx      # Main orchestrator - manages step state & routing
├── step-asset-panel.tsx      # Left panel with contextual visuals per step
└── steps/
    ├── auth-step.tsx         # Email/password or Google OAuth
    ├── verification-step.tsx # Email verification (auto-advances)
    ├── permissions-step.tsx  # Mic + camera permissions
    ├── product-modes-step.tsx# Bot / Stealth / In-person mode selection
    ├── features-overview-step.tsx  # Feature carousel (4 sub-steps)
    ├── connections-step.tsx  # Calendar, Gmail, Slack, Linear integrations
    ├── workspace-step.tsx    # Team workspace creation (work emails only)
    └── trial-step.tsx        # Payment + success state

Onboarding Flow

Step Sequence

# Step Required Notes
1 Auth Google OAuth or email/password signup
2 Verification Auto-advances after simulated verification
3 Permissions Both mic + camera must be granted
4 Product Modes Choose default: Bot, Stealth, or In-person
5 Features Overview 4-step carousel explaining core features
6 Connections ⚠️ Calendar/Gmail recommended; Slack/Linear optional
7 Workspace 🔀 Only shown for work emails (not gmail.com, etc.)
8 Trial Payment form → success state → redirect

Conditional Logic

Work Email Detection (onboarding-modal.tsx:46-59)

function isWorkEmail(email: string): boolean {
  const personalDomains = [
    "gmail.com", "yahoo.com", "hotmail.com", "outlook.com",
    "icloud.com", "aol.com", "protonmail.com", "mail.com"
  ]
  const domain = email.split("@")[1]?.toLowerCase()
  return domain ? !personalDomains.includes(domain) : false
}
  • Work email → includes Workspace step, shows Slack/Linear integrations
  • Personal email → skips Workspace step, locks Slack/Linear behind "Available with workspaces"

Component Details

1. Auth Step (auth-step.tsx)

Purpose: Sign up or sign in with Google or email/password.

Props:

interface AuthStepProps {
  onComplete: (email: string) => void
}

Implementation Notes:

  • Currently mocks Google OAuth with hardcoded email
  • Toggle between sign-up and sign-in modes
  • Form validation is minimal (just checks non-empty)

TODO for production:

  • Integrate real OAuth provider (Google, etc.)
  • Add proper form validation with Zod
  • Password strength requirements
  • Error handling for failed auth

2. Verification Step (verification-step.tsx)

Purpose: Wait for email verification link click.

Props:

interface VerificationStepProps {
  email: string
  onComplete: () => void
}

Implementation Notes:

  • Auto-advances through states: sentverifyingverified
  • Timers simulate the verification flow (2s → 1.5s → 1s auto-advance)
  • "Resend email" button shown in sent state

TODO for production:

  • Real email verification via backend
  • Poll or websocket for verification status
  • Rate limiting on resend
  • Magic link alternative

3. Permissions Step (permissions-step.tsx)

Purpose: Request microphone and camera permissions for in-person recording.

Props:

interface PermissionsStepProps {
  onComplete: () => void
}

Implementation Notes:

  • Both permissions must be granted to continue
  • Currently mocks permission granting with 500ms delay

TODO for production:

  • Use navigator.mediaDevices.getUserMedia() for real permissions
  • Handle denied permissions gracefully
  • Store permission state in user preferences
  • Show system permission dialog

4. Product Modes Step (product-modes-step.tsx)

Purpose: Choose default meeting capture method.

Props:

interface ProductModesStepProps {
  onComplete: () => void
  onModeChange?: (mode: string) => void
}

Modes:

Mode ID Description
Meeting Bot bot Sentra joins as visible participant (recommended)
Stealth Mode stealth Records screen + audio without joining call
In-person inperson Device mic/camera for real-world meetings

Implementation Notes:

  • onModeChange callback updates the asset panel visualization
  • Selection persists via React state (not stored yet)

TODO for production:

  • Save preference to user profile
  • Show mode-specific setup instructions

5. Features Overview Step (features-overview-step.tsx)

Purpose: Carousel walkthrough of 4 core features.

Props:

interface FeaturesOverviewStepProps {
  onComplete: () => void
  onSubStepChange?: (index: number) => void
}

Features (sub-steps):

  1. Pre-meeting briefs
  2. Auto to-do extraction
  3. Autonomous CRM
  4. In-person recording

Implementation Notes:

  • Progress bar at bottom shows position
  • Users can click progress dots to jump
  • Asset panel updates per sub-step via onSubStepChange

6. Connections Step (connections-step.tsx)

Purpose: Connect calendar, email, and team tools.

Props:

interface ConnectionsStepProps {
  onComplete: () => void
  isWorkEmail?: boolean
}

Integrations:

Integration Priority Work Email Only
Google Calendar ✅ Required No
Gmail ✅ Required No
Slack Optional Yes
Linear Optional Yes

Implementation Notes:

  • At least one priority integration needed to enable "Continue"
  • "Skip for now" always available
  • Work email users see Slack/Linear; personal email users see them locked

TODO for production:

  • Real OAuth flows for each integration
  • Store connection status in database
  • Handle disconnection/reconnection
  • Add more integrations (Notion, HubSpot, etc.)

7. Workspace Step (workspace-step.tsx)

Purpose: Create team workspace and invite colleagues.

Props:

interface WorkspaceStepProps {
  email: string
  onComplete: () => void
}

Implementation Notes:

  • Only shown for work emails
  • Workspace name defaults to email domain (e.g., acme from user@acme.com)
  • Invite emails collected via tag input
  • Enter key or blur adds email to list

TODO for production:

  • Create workspace in backend
  • Send invitation emails
  • Handle existing workspace (join vs. create)
  • Role assignment for invitees

8. Trial Step (trial-step.tsx)

Purpose: Collect payment info and start 14-day free trial.

Props: None (final step)

States:

  1. Payment form - Card number, expiry, CVC
  2. Success state - Celebration animation → "Enter Sentra" button

Implementation Notes:

  • Card formatting: groups of 4 digits, MM/YY expiry
  • Validation: 16 digits, 5 char expiry (MM/YY), 3-4 digit CVC
  • Success redirects to / (main product)

TODO for production:

  • Integrate Stripe Elements or similar
  • Real payment processing
  • Trial tracking in backend
  • Handle payment failures
  • Add billing address if required

Shared Components

Step Asset Panel (step-asset-panel.tsx)

Left panel showing contextual visuals for each step.

Props:

interface StepAssetPanelProps {
  currentStep: OnboardingStep
  featureSubStep?: number  // For features-overview carousel
  selectedMode?: string    // For product-modes visualization
}

Each step has a corresponding asset component:

  • AuthAsset - Welcome message + feature bullets
  • VerificationAsset - Security messaging
  • PermissionsAsset - Mic/camera icons + waveform
  • ProductModesAsset - Interactive mode visualizations
  • FeaturesAsset - Feature-specific mock UIs
  • ConnectionsAsset - Integration benefits
  • WorkspaceAsset - Team collaboration messaging
  • TrialAsset - Trial benefits list

Styling & Theming

Custom CSS Variables (globals.css)

--sentra-blue: oklch(0.58 0.13 250);       /* Primary brand blue */
--sentra-blue-light: oklch(0.96 0.015 250); /* Light blue background */
--sentra-success: oklch(0.65 0.2 145);      /* Success green */
--sentra-success-light: oklch(0.95 0.03 145);

Step Animations

Each step has a unique entrance animation:

Step Animation Class Effect
auth animate-float-in Fade up + scale
verification animate-slide-in-right Slide from left
permissions animate-expand-in Scale in
product-modes animate-float-in Fade up + scale
features-overview animate-reveal-up Slide up + blur
connections animate-rotate-in Slight rotation
workspace animate-expand-in Scale in
trial animate-float-in Fade up + scale

State Management

Currently all state lives in OnboardingModal:

const [currentStep, setCurrentStep] = useState<OnboardingStep>("auth")
const [email, setEmail] = useState("")
const [hasWorkEmail, setHasWorkEmail] = useState(false)
const [mounted, setMounted] = useState(false)
const [featureSubStep, setFeatureSubStep] = useState(0)
const [selectedMode, setSelectedMode] = useState("bot")

For Production

Consider moving to:

  • URL-based step tracking (for back button support)
  • Zustand or similar for step state
  • Persist partial progress to localStorage/backend
  • Resume interrupted onboarding

Integration Points

Backend APIs Needed

Endpoint Purpose Step
POST /auth/signup Create account Auth
POST /auth/signin Sign in existing Auth
POST /auth/google Google OAuth Auth
POST /auth/verify Check verification status Verification
POST /auth/resend-verification Resend email Verification
POST /users/preferences Save mode preference Product Modes
POST /integrations/:provider/connect OAuth start Connections
GET /integrations/:provider/callback OAuth callback Connections
POST /workspaces Create workspace Workspace
POST /workspaces/:id/invites Send invites Workspace
POST /billing/subscribe Start trial Trial

Testing

Manual Test Cases

  1. Personal email flow (e.g., user@gmail.com)

    • Should skip Workspace step
    • Should show Slack/Linear as locked
  2. Work email flow (e.g., user@acme.com)

    • Should include Workspace step
    • Should show all integrations
  3. Permissions denied

    • Continue button should stay disabled
  4. Skip integrations

    • Should allow proceeding without connections
  5. Payment validation

    • Invalid card formats should be rejected

File Structure

app/
├── globals.css           # Theme + animations
├── layout.tsx            # Root layout with ThemeProvider
├── onboarding/
│   └── page.tsx          # Onboarding page (renders modal)
└── page.tsx              # Home (post-onboarding redirect target)

components/
├── onboarding/           # Onboarding-specific components
├── theme-provider.tsx    # next-themes provider
└── ui/                   # shadcn/ui components

lib/
└── utils.ts              # cn() utility for Tailwind classes

Dependencies

Key packages:

  • next@16 - App router, React Server Components
  • react@19 - Latest React with concurrent features
  • tailwindcss@4 - CSS framework
  • @radix-ui/* - Accessible UI primitives
  • lucide-react - Icon library
  • next-themes - Dark mode support
  • input-otp - OTP input (for future use)

Questions?

Reach out to the team if you need clarification on:

  • OAuth integration specifics
  • Backend API contracts
  • Design system tokens
  • Animation timing preferences

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages