feat(web): add tenant user registration flow
This commit is contained in:
@@ -7,16 +7,18 @@ const PHONE_RE = /^\d{11}$/;
|
||||
|
||||
interface VerificationCodeButtonProps {
|
||||
phone: string;
|
||||
scene: 'reset_password';
|
||||
scene: 'reset_password' | 'register';
|
||||
tenantCode?: string;
|
||||
onChallenge: (challengeId: string) => void;
|
||||
onError: (message: string) => void;
|
||||
}
|
||||
|
||||
/** "获取验证码" button with resend countdown. Ported from the old app's VerificationButton. */
|
||||
export function VerificationCodeButton({ phone, scene, onChallenge, onError }: VerificationCodeButtonProps) {
|
||||
export function VerificationCodeButton({ phone, scene, tenantCode, onChallenge, onError }: VerificationCodeButtonProps) {
|
||||
const [seconds, setSeconds] = useState(0);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const timerRef = useRef<number | undefined>(undefined);
|
||||
const phoneRef = useRef(phone);
|
||||
|
||||
// Without this, navigating away mid-countdown (e.g. switching from register back to login)
|
||||
// leaves the interval running against an unmounted component indefinitely until it naturally
|
||||
@@ -27,6 +29,7 @@ export function VerificationCodeButton({ phone, scene, onChallenge, onError }: V
|
||||
// otherwise correcting a mistyped number mid-cooldown leaves the button stuck disabled (still
|
||||
// counting down for the old number) until the old timer happens to run out on its own.
|
||||
useEffect(() => {
|
||||
phoneRef.current = phone;
|
||||
window.clearInterval(timerRef.current);
|
||||
setSeconds(0);
|
||||
}, [phone]);
|
||||
@@ -55,12 +58,12 @@ export function VerificationCodeButton({ phone, scene, onChallenge, onError }: V
|
||||
const requestedPhone = phone;
|
||||
setBusy(true);
|
||||
try {
|
||||
const data = await requestVerificationCode(scene, requestedPhone);
|
||||
if (requestedPhone !== phone) return;
|
||||
const data = await requestVerificationCode(scene, requestedPhone, tenantCode);
|
||||
if (requestedPhone !== phoneRef.current) return;
|
||||
onChallenge(data.challenge_id);
|
||||
tick(data.resend_after_seconds || 60);
|
||||
} catch (err) {
|
||||
if (requestedPhone !== phone) return;
|
||||
if (requestedPhone !== phoneRef.current) return;
|
||||
onError(err instanceof ImApiError ? err.message : '获取验证码失败');
|
||||
// Rate-limited but a still-valid challenge already exists for this phone/scene -- reuse it.
|
||||
const details = err instanceof ImApiError ? (err.details as Record<string, unknown> | undefined) : undefined;
|
||||
|
||||
Reference in New Issue
Block a user