'use client'; import { FunctionComponent, useState } from 'react'; import { useSearchParams } from 'next/navigation'; import { APP_ROLES, RETURN_URL_PARAM, type AppRole } from '@/constants'; import { OTP_RESEND_FALLBACK_SECONDS } from '@/services/auth/constants'; import AuthCard from './AuthCard'; import PhoneStep from './PhoneStep'; import OtpStep from './OtpStep'; import RoleRouter from './RoleRouter'; type Step = 'phone' | 'otp' | 'routing'; /** * The single login stack for both actors (A1/A2 customer, B1/B2 nurse). One OTP mechanism, * parameterised by `intendedRole` (seeded from `?role=nurse`) — no forked login trees. After a * successful verify it hands off to the role router. * @component LoginFlow */ const LoginFlow: FunctionComponent = () => { const searchParams = useSearchParams(); const [intendedRole, setIntendedRole] = useState( searchParams.get('role') === APP_ROLES.NURSE ? APP_ROLES.NURSE : APP_ROLES.CUSTOMER, ); const [step, setStep] = useState('phone'); const [phone, setPhone] = useState(''); const [resendSeconds, setResendSeconds] = useState(OTP_RESEND_FALLBACK_SECONDS); // Carried from middleware.ts's redirect-to-login so a deep link survives the auth round trip. const next = searchParams.get(RETURN_URL_PARAM); if (step === 'routing') { return ; } return ( {step === 'phone' ? ( setIntendedRole((role) => role === APP_ROLES.NURSE ? APP_ROLES.CUSTOMER : APP_ROLES.NURSE, ) } onSent={(nextPhone, result) => { setPhone(nextPhone); setResendSeconds(result.resendAvailableInSeconds); setStep('otp'); }} /> ) : ( setStep('routing')} onChangeNumber={() => setStep('phone')} /> )} ); }; export default LoginFlow;