'use client'; import { useState } from 'react'; interface Props { token: string; defaultScopes: string[]; defaultRetentionDays: number; } type Step = 'phone' | 'code' | 'done'; export function OnboardingForm({ token, defaultScopes, defaultRetentionDays }: Props) { const [step, setStep] = useState('phone'); const [phone, setPhone] = useState(''); const [challengeId, setChallengeId] = useState(null); const [code, setCode] = useState(''); const [retentionDays, setRetentionDays] = useState(defaultRetentionDays); const [scopes, setScopes] = useState(defaultScopes); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); async function requestOtp() { setError(null); setBusy(true); try { const res = await fetch(`${process.env['NEXT_PUBLIC_API_URL'] ?? 'http://localhost:3001'}/public/auth/request-otp`, { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json' }, body: JSON.stringify({ onboardingToken: token, phone }), }); if (!res.ok) { const body = (await res.json().catch(() => ({}))) as { message?: string }; setError(body.message ?? 'Failed to send code'); return; } const data = (await res.json()) as { challengeId: string }; setChallengeId(data.challengeId); setStep('code'); } finally { setBusy(false); } } async function verifyOtp() { setError(null); setBusy(true); try { const res = await fetch('/api/onboard/verify-otp', { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json' }, body: JSON.stringify({ onboardingToken: token, challengeId, phone, code, scopes, retentionDays, }), }); if (!res.ok) { const body = (await res.json().catch(() => ({}))) as { message?: string }; setError(body.message ?? 'Verification failed'); return; } setStep('done'); } finally { setBusy(false); } } if (step === 'done') { return (

You're verified. Your session is set.

Go to your portal →
); } if (step === 'phone') { return (
{error &&

{error}

}

We'll DM a 6-digit code to your WhatsApp.

); } return (
Scopes {['INGEST', 'ARCHIVE', 'REPLICATE', 'DISPLAY'].map((s) => ( ))}
{error &&

{error}

}
); }