'use client'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; const API_BASE = process.env['NEXT_PUBLIC_API_URL'] ?? 'http://localhost:3001'; type Step = 'phone' | 'code'; export default function MemberLoginPage() { const router = useRouter(); const [step, setStep] = useState('phone'); const [phone, setPhone] = useState(''); const [challengeId, setChallengeId] = useState(''); const [code, setCode] = useState(''); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); async function requestOtp() { setError(null); setBusy(true); try { const res = await fetch(`${API_BASE}/public/auth/member-login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone }), }); const data = (await res.json().catch(() => ({}))) as { challengeId?: string; message?: string }; if (!res.ok) { setError(data.message ?? 'Failed to send code'); return; } setChallengeId(data.challengeId ?? ''); setStep('code'); } finally { setBusy(false); } } async function verifyOtp() { setError(null); setBusy(true); try { const res = await fetch('/api/my/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ challengeId, phone, code }), }); const data = (await res.json().catch(() => ({}))) as { message?: string }; if (!res.ok) { setError(data.message ?? 'Verification failed'); return; } router.push('/my'); } finally { setBusy(false); } } return (
🏠

Sign in to your portal

{step === 'phone' ? 'Enter your WhatsApp number and we\'ll send you a code.' : `We sent a 6-digit code to ${phone} on WhatsApp.`}

{step === 'phone' && (
setPhone(e.target.value)} placeholder="+91 98765 43210" autoFocus 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" /> {error &&

{error}

}

First time?{' '} Use your invite link

)} {step === 'code' && (
setCode(e.target.value.replace(/\D/g, ''))} placeholder="000000" autoFocus 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" /> {error &&

{error}

}
)}
); }