import { useState } from 'react' import { useNavigate } from 'react-router-dom' import { Loader2 } from 'lucide-react' import { useAuthStore } from '@/store/authStore' import { onboardingApi, type PrimaryPsa } from '@/api/onboarding' import { cn } from '@/lib/utils' const PSA_OPTIONS: { value: PrimaryPsa; label: string; description: string }[] = [ { value: 'connectwise', label: 'ConnectWise', description: 'Manage / PSA' }, { value: 'autotask', label: 'Autotask', description: 'Datto Autotask PSA' }, { value: 'halopsa', label: 'HaloPSA', description: 'Halo Service Solutions' }, { value: 'none', label: 'No PSA yet', description: "We'll add one later" }, ] /** * `/welcome/step-2` — second step of the welcome wizard. Captures the PSA the * shop primarily uses. Selecting a non-`none` tile splits the primary CTA * into "Connect now" (routes to `/account/integrations` after saving) * and "Connect later" (continues to step 3). Both paths persist the * `primary_psa` choice before navigating. */ export function WelcomeStep2() { const navigate = useNavigate() const fetchUser = useAuthStore((s) => s.fetchUser) const [primaryPsa, setPrimaryPsa] = useState(null) const [submitting, setSubmitting] = useState< 'continue' | 'connect-now' | 'skip' | 'dismiss' | null >(null) const [error, setError] = useState(null) const isBusy = submitting !== null const showConnectNow = primaryPsa !== null && primaryPsa !== 'none' const selectedPsaLabel = PSA_OPTIONS.find((o) => o.value === primaryPsa)?.label const handleContinue = async () => { if (isBusy) return setError(null) setSubmitting('continue') try { await onboardingApi.updateStep({ step: 2, action: 'complete', data: primaryPsa ? { primary_psa: primaryPsa } : undefined, }) await fetchUser() navigate('/welcome/step-3') } catch { setError('Could not save. Please try again.') setSubmitting(null) } } const handleConnectNow = async () => { if (isBusy || !showConnectNow) return setError(null) setSubmitting('connect-now') try { await onboardingApi.updateStep({ step: 2, action: 'complete', data: { primary_psa: primaryPsa! }, }) await fetchUser() navigate('/account/integrations') } catch { setError('Could not save. Please try again.') setSubmitting(null) } } const handleSkipStep = async () => { if (isBusy) return setError(null) setSubmitting('skip') try { await onboardingApi.updateStep({ step: 2, action: 'skip' }) await fetchUser() navigate('/welcome/step-3') } catch { setError('Could not save. Please try again.') setSubmitting(null) } } const handleDismissRest = async () => { if (isBusy) return setError(null) setSubmitting('dismiss') try { await onboardingApi.dismissRest() await fetchUser() navigate('/home') } catch { setError('Could not save. Please try again.') setSubmitting(null) } } return (

Step 2 of 3

Your PSA

Pick the PSA your team uses today. We'll wire it up later — no credentials needed yet.

{PSA_OPTIONS.map((opt) => { const selected = primaryPsa === opt.value return ( ) })}
{error && (

{error}

)}
{showConnectNow ? ( <> ) : ( )}
) } export default WelcomeStep2