DocumentationarchitectureOnboarding Wizard

Onboarding Wizard

The onboarding wizard guides new users through their first interactions with CredDAO.

Overview

The wizard consists of 4 steps:

  1. Connect Wallet - User connects their Solana wallet
  2. Get FairScore - System fetches on-chain reputation
  3. See Voting Power - Display voting power breakdown
  4. Explore Proposals - Redirect to proposals page

Implementation

Provider Hook

import { useOnboarding } from '@/components/onboarding/OnboardingWizard'
 
function App() {
  const { showOnboarding, completeOnboarding, skipOnboarding } = useOnboarding()
  
  return (
    <>
      {/* Main app content */}
      {showOnboarding && (
        <OnboardingWizard 
          onComplete={completeOnboarding} 
          onSkip={skipOnboarding} 
        />
      )}
    </>
  )
}

LocalStorage Persistence

// Check if onboarding was completed
const completed = localStorage.getItem('creddao_onboarding_completed')
 
// Values:
// - 'true' - User completed wizard
// - 'skipped' - User skipped wizard
// - null - New user, show wizard

Customization

Skip Steps

Modify the steps array to customize:

const [steps, setSteps] = useState<OnboardingStep[]>([
  { id: 'connect', title: 'Connect Wallet', description: '...', completed: false },
  { id: 'score', title: 'Get Your FairScore', description: '...', completed: false },
  // Add custom steps
  { id: 'delegate', title: 'Find Delegates', description: '...', completed: false },
  { id: 'explore', title: 'Start Governing', description: '...', completed: false },
])

Custom Styling

<OnboardingWizard
  onComplete={completeOnboarding}
  onSkip={skipOnboarding}
  className="custom-wizard"
  headerClassName="bg-gradient-to-r from-green-500 to-teal-500"
/>

Step Details

Step 1: Connect Wallet

  • Displays wallet connection prompt
  • Auto-advances when connected becomes true
  • Shows success checkmark on completion
// Auto-advance logic
useEffect(() => {
  if (connected && currentStep === 0) {
    advanceStep()
  }
}, [connected, currentStep])

Step 2: Get FairScore

  • Shows loading spinner while fetching
  • Displays score and tier when loaded
  • Auto-advances on successful fetch
useEffect(() => {
  if (scoreData && currentStep === 1) {
    advanceStep()
  }
}, [scoreData, currentStep])

Step 3: See Voting Power

  • Interactive token balance input
  • Real-time voting power calculation
  • Shows formula breakdown
// User can test different scenarios
const [tokenBalance, setTokenBalance] = useState(1000)
const power = calculateVotingPower(tokenBalance, scoreData.fairscore)

Step 4: Explore Proposals

  • Final step with CTA button
  • Redirects to proposals page
  • Marks onboarding as complete

Hook API

interface UseOnboardingReturn {
  showOnboarding: boolean      // Whether to show wizard
  completeOnboarding: () => void  // Mark as completed
  skipOnboarding: () => void   // Mark as skipped
  resetOnboarding: () => void  // Show wizard again
}

Manual Control

const { showOnboarding, resetOnboarding } = useOnboarding()
 
// Show wizard again (e.g., in settings)
<button onClick={resetOnboarding}>
  Replay Onboarding
</button>

User Experience

Progress Indicator

Visual progress bar shows completion:

<div className="flex gap-2 mt-3">
  {steps.map((step, index) => (
    <div
      key={step.id}
      className={`h-1.5 flex-1 rounded-full ${
        step.completed ? 'bg-white' : 
        index === currentStep ? 'bg-white/50' : 'bg-white/20'
      }`}
    />
  ))}
</div>

Skip Option

Users can skip onboarding at any time:

<button onClick={onSkip} className="text-white/80 hover:text-white text-sm">
  Skip
</button>

Mobile Responsive

Wizard adapts to mobile screens:

  • Full-screen modal on mobile
  • Centered modal on desktop
  • Touch-friendly buttons

Analytics Integration

Track onboarding completion:

const completeOnboarding = () => {
  localStorage.setItem('creddao_onboarding_completed', 'true')
  setShowOnboarding(false)
  
  // Track event
  analytics.track('Onboarding Completed', {
    steps: steps.filter(s => s.completed).length,
    totalTime: Date.now() - startTime,
    skipped: false
  })
}

Best Practices

  1. Don’t force completion - Always offer skip option
  2. Show progress - Visual indicator reduces drop-off
  3. Auto-advance - Don’t make users click “next” unnecessarily
  4. Provide value - Show useful info (score, power) during flow
  5. Remember choice - Don’t show again after completion