Files
baya-monorepo/client/src/components/auth/LoginFlow.tsx
T
2026-07-18 01:56:17 +03:30

65 lines
2.1 KiB
TypeScript

'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<AppRole>(
searchParams.get('role') === APP_ROLES.NURSE ? APP_ROLES.NURSE : APP_ROLES.CUSTOMER,
);
const [step, setStep] = useState<Step>('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 <RoleRouter intendedRole={intendedRole} next={next} />;
}
return (
<AuthCard>
{step === 'phone' ? (
<PhoneStep
intendedRole={intendedRole}
onSwitchRole={() =>
setIntendedRole((role) =>
role === APP_ROLES.NURSE ? APP_ROLES.CUSTOMER : APP_ROLES.NURSE,
)
}
onSent={(nextPhone, result) => {
setPhone(nextPhone);
setResendSeconds(result.resendAvailableInSeconds);
setStep('otp');
}}
/>
) : (
<OtpStep
phone={phone}
intendedRole={intendedRole}
resendSeconds={resendSeconds}
onVerified={() => setStep('routing')}
onChangeNumber={() => setStep('phone')}
/>
)}
</AuthCard>
);
};
export default LoginFlow;