'use client'; import { useState } from 'react'; interface Props { token: string; groupName: string; tenantName: string; defaultScopes: string[]; defaultRetentionDays: number; } type Step = 'welcome' | 'phone' | 'consent' | 'code' | 'done'; const STEP_ORDER: Step[] = ['welcome', 'phone', 'consent', 'code', 'done']; interface ScopeMeta { key: string; label: string; description: string; } const SCOPE_META: ScopeMeta[] = [ { key: 'INGEST', label: 'Read group messages', description: 'Let TOWER read messages you send here so they can be organised and surfaced.', }, { key: 'ARCHIVE', label: 'Save to searchable archive', description: 'Keep a record of relevant messages so members can find them later.', }, { key: 'REPLICATE', label: 'Share across connected groups', description: 'Allow approved messages to be forwarded to connected sister groups.', }, { key: 'DISPLAY', label: 'Show in portal & digests', description: 'Let your contributions appear in the member portal and daily digests.', }, ]; export function OnboardingForm({ token, groupName, tenantName, defaultScopes, defaultRetentionDays }: Props) { const [step, setStep] = useState('welcome'); 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); const stepIndex = STEP_ORDER.indexOf(step); const progressPct = (stepIndex / (STEP_ORDER.length - 1)) * 100; async function requestOtp() { setError(null); setBusy(true); try { const res = await fetch('/api/onboard/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('consent'); } 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); } } function toggleScope(key: string, checked: boolean) { setScopes((prev) => (checked ? [...prev, key] : prev.filter((s) => s !== key))); } return (
{/* Progress bar */} {step !== 'welcome' && step !== 'done' && (

Step {stepIndex} of 3

)} {step === 'welcome' && (
👋

Welcome to {groupName}

Managed by {tenantName}

TOWER keeps your community's important messages organised, searchable, and shareable — while keeping you in control of your data. Let's get you set up. It takes about a minute.

)} {step === 'phone' && (

Your WhatsApp number

We'll send a 6-digit code to this number on WhatsApp.

setPhone(e.target.value)} placeholder="+91 98765 43210" className="w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500" autoFocus /> {error &&

{error}

}
)} {step === 'consent' && (

What you're agreeing to

You stay in control — change or revoke any of these anytime from your portal.

{SCOPE_META.map((s) => { const checked = scopes.includes(s.key); return ( ); })}
{error &&

{error}

}
)} {step === 'code' && (

Enter your code

We sent a 6-digit code to {phone} on WhatsApp.

setCode(e.target.value.replace(/\D/g, ''))} placeholder="000000" className="w-full rounded-lg border border-gray-300 px-3 py-2.5 text-center text-lg tracking-[0.3em] font-mono focus:outline-none focus:ring-2 focus:ring-indigo-500" autoFocus /> {error &&

{error}

}
)} {step === 'done' && (
✓

You're all set!

Welcome to {groupName}.

In your portal you can

  • 📋 Read daily digests of what matters
  • 📅 RSVP to community events
  • 🔒 Manage your privacy & consent anytime
Go to my portal →
)}
); }