All files / src/lib use-onboarding.ts

0% Statements 0/74
0% Branches 0/1
0% Functions 0/1
0% Lines 0/74

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129                                                                                                                                                                                                                                                                 
/**
 * useOnboarding - Hook for detecting and managing first-time user onboarding
 *
 * Determines if user needs to go through the onboarding wizard.
 * Stores completion status in localStorage.
 */
 
import { useState, useEffect, useCallback } from 'react';
 
const ONBOARDING_COMPLETED_KEY = 'zclaw-onboarding-completed';
const USER_PROFILE_KEY = 'zclaw-user-profile';
 
export interface UserProfile {
  userName: string;
  userRole?: string;
  completedAt: string;
}
 
export interface OnboardingState {
  isNeeded: boolean;
  isLoading: boolean;
  userProfile: UserProfile | null;
  markCompleted: (profile: Omit<UserProfile, 'completedAt'>) => void;
  resetOnboarding: () => void;
}
 
/**
 * Hook to manage first-time user onboarding
 *
 * Usage:
 * ```tsx
 * const { isNeeded, isLoading, markCompleted } = useOnboarding();
 *
 * if (isNeeded) {
 *   return <OnboardingWizard onComplete={markCompleted} />;
 * }
 * ```
 */
export function useOnboarding(): OnboardingState {
  const [isNeeded, setIsNeeded] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [userProfile, setUserProfile] = useState<UserProfile | null>(null);
 
  // Check onboarding status on mount
  useEffect(() => {
    try {
      const completed = localStorage.getItem(ONBOARDING_COMPLETED_KEY);
      const profileStr = localStorage.getItem(USER_PROFILE_KEY);
 
      if (completed === 'true' && profileStr) {
        const profile = JSON.parse(profileStr) as UserProfile;
        setUserProfile(profile);
        setIsNeeded(false);
      } else {
        // No onboarding record - first time user
        setIsNeeded(true);
      }
    } catch (err) {
      console.warn('[useOnboarding] Failed to check onboarding status:', err);
      setIsNeeded(true);
    } finally {
      setIsLoading(false);
    }
  }, []);
 
  // Mark onboarding as completed
  const markCompleted = useCallback((profile: Omit<UserProfile, 'completedAt'>) => {
    const fullProfile: UserProfile = {
      ...profile,
      completedAt: new Date().toISOString(),
    };
 
    try {
      localStorage.setItem(ONBOARDING_COMPLETED_KEY, 'true');
      localStorage.setItem(USER_PROFILE_KEY, JSON.stringify(fullProfile));
      setUserProfile(fullProfile);
      setIsNeeded(false);
      console.log('[useOnboarding] Onboarding completed for user:', profile.userName);
    } catch (err) {
      console.error('[useOnboarding] Failed to save onboarding status:', err);
    }
  }, []);
 
  // Reset onboarding (for testing or user request)
  const resetOnboarding = useCallback(() => {
    try {
      localStorage.removeItem(ONBOARDING_COMPLETED_KEY);
      localStorage.removeItem(USER_PROFILE_KEY);
      setUserProfile(null);
      setIsNeeded(true);
      console.log('[useOnboarding] Onboarding reset');
    } catch (err) {
      console.error('[useOnboarding] Failed to reset onboarding:', err);
    }
  }, []);
 
  return {
    isNeeded,
    isLoading,
    userProfile,
    markCompleted,
    resetOnboarding,
  };
}
 
/**
 * Get stored user profile without hook (for use outside React components)
 */
export function getStoredUserProfile(): UserProfile | null {
  try {
    const profileStr = localStorage.getItem(USER_PROFILE_KEY);
    if (profileStr) {
      return JSON.parse(profileStr) as UserProfile;
    }
  } catch (err) {
    console.warn('[useOnboarding] Failed to get user profile:', err);
  }
  return null;
}
 
/**
 * Check if onboarding is completed (for use outside React components)
 */
export function isOnboardingCompleted(): boolean {
  return localStorage.getItem(ONBOARDING_COMPLETED_KEY) === 'true';
}
 
export default useOnboarding;