From 2d71f24937af4880cdf174661c8ddb1d2aea5b69 Mon Sep 17 00:00:00 2001 From: Nathnael Date: Fri, 3 Jul 2026 11:08:57 +0000 Subject: [PATCH] chore: rm the verify step in onboarding --- .../onboarding/OnboardingWizardDialog.tsx | 7 - .../src/pages/accounts/CompanyProfileForm.tsx | 205 +----------------- .../accounts/companyProfileForm/schema.ts | 2 - 3 files changed, 1 insertion(+), 213 deletions(-) diff --git a/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx b/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx index 4d4c8664a..d6c965053 100644 --- a/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx +++ b/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx @@ -46,7 +46,6 @@ type FormStep = | "company" | "personnel" | "contact" - | "verify" | "poa" | "documents" | "additional"; @@ -54,7 +53,6 @@ const FORM_STEPS: FormStep[] = [ "company", "personnel", "contact", - "verify", "poa", "documents", "additional", @@ -95,11 +93,6 @@ const STEP_META: Record< title: "Contact Person", description: "Who should we reach out to about this account?", }, - verify: { - icon: , - title: "Verify Contact Person", - description: "Confirm the contact phone with a one-time SMS code.", - }, poa: { icon: , title: "Power of Attorney", diff --git a/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx b/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx index bfde5c43b..3c8ad0271 100644 --- a/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx +++ b/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx @@ -4,7 +4,6 @@ import { Divider, Group, Loader, - PinInput, SimpleGrid, Stack, Text, @@ -16,9 +15,6 @@ import { AlertCircle, ArrowLeft, ArrowRight, - CheckCircle2, - RotateCw, - Smartphone, UserCheck, } from "lucide-react"; import { useEffect, useRef, useState } from "react"; @@ -35,7 +31,6 @@ import RoleLicenseStep, { type RoleLicenseProfile, } from "@/components/onboarding/RoleLicenseStep"; import ETradeInfo from "@/components/onboarding/ETradeInfo"; -import { extractApiError } from "@/utils/result"; import { type CompanyStep, type FormData, @@ -44,8 +39,6 @@ import { } from "./companyProfileForm/schema"; import { buildPayload, - maskPhone, - samePhone, stepPayload, toFormValues, } from "./companyProfileForm/helpers"; @@ -350,85 +343,6 @@ export default function CompanyProfileForm({ } }; - // --- Contact-phone SMS OTP verification ----------------------------------- - // The phone we verify is the contact-person phone, normalised to E.164 so it - // matches what the backend persists as `contactVerifiedPhone`. - const contactPhoneE164 = toEthiopianE164(watch("contactPersonPhone") ?? ""); - // Source of truth for "already verified" comes from the onboarding/profile - // info (rehydrate) — so a refresh resumes the verify step's "done" state. - const [verifiedPhone, setVerifiedPhone] = useState( - rehydrate?.contactVerifiedPhone ?? null, - ); - useEffect(() => { - if (rehydrate?.contactVerifiedPhone) { - setVerifiedPhone(rehydrate.contactVerifiedPhone); - } - }, [rehydrate?.contactVerifiedPhone]); - const phoneVerified = samePhone(verifiedPhone, contactPhoneE164); - - const [otpSent, setOtpSent] = useState(false); - const [otpCode, setOtpCode] = useState(""); - const [sendingOtp, setSendingOtp] = useState(false); - const [verifyingOtp, setVerifyingOtp] = useState(false); - const [otpError, setOtpError] = useState(null); - const [resendIn, setResendIn] = useState(0); - - // Resend cooldown countdown (no Date.now needed — pure setTimeout ticks). - useEffect(() => { - if (resendIn <= 0) return; - const t = setTimeout(() => setResendIn((s) => s - 1), 1000); - return () => clearTimeout(t); - }, [resendIn]); - - // A changed contact phone invalidates any in-flight code entry (the previous - // code was for a different number). Verified state is handled separately via - // the phone comparison, so this only resets the send/enter UI. - useEffect(() => { - setOtpSent(false); - setOtpCode(""); - setOtpError(null); - }, [contactPhoneE164]); - - const sendContactOtp = async () => { - setOtpError(null); - if (!contactPhoneE164) { - setOtpError("Enter a valid contact phone number first."); - return; - } - setSendingOtp(true); - try { - await api.auth.sendOTP.call({ phone: contactPhoneE164 }); - setOtpSent(true); - setOtpCode(""); - setResendIn(60); - } catch (err) { - setOtpError(extractApiError(err).message); - } finally { - setSendingOtp(false); - } - }; - - const verifyContactOtp = async () => { - setOtpError(null); - if (otpCode.length !== 6) { - setOtpError("Enter the 6-digit code we sent you."); - return; - } - setVerifyingOtp(true); - try { - await api.auth.verifyOTP.call({ phone: contactPhoneE164, otp: otpCode }); - setVerifiedPhone(contactPhoneE164); - setOtpSent(false); - // Persist the verified phone so the step resumes as "done" after a refresh - // (best-effort — the OTP itself already succeeded server-side). - onSaveStep?.({ contactVerifiedPhone: contactPhoneE164 }).catch(() => { }); - } catch (err) { - setOtpError(extractApiError(err).message); - } finally { - setVerifyingOtp(false); - } - }; - const hasDocuments = Boolean(uploadSetting?.fields?.length); // The registration/license details come straight from the eTrade lookup and @@ -451,7 +365,6 @@ export default function CompanyProfileForm({ "company", "personnel", "contact", - "verify", "poa", "documents", "additional", @@ -495,20 +408,6 @@ export default function CompanyProfileForm({ handleSubmit((data) => onSubmit(buildPayload(data, user)))(); return; } - // Contact-phone verification gates advancing past the verify step. The - // verified phone is already persisted (on verify success), so there's - // nothing extra to save here. - if (step === "verify") { - if (!phoneVerified) { - setSaveError( - "Please verify the contact person's phone number to continue.", - ); - return; - } - setSaveError(null); - setStep(stepOrder[currentIdx + 1]); - return; - } // The documents step auto-uploads whatever the user selected as they // continue (partial uploads are allowed — required-doc completeness is // re-checked on resume). A failed upload holds them on the step. @@ -783,107 +682,6 @@ export default function CompanyProfileForm({ )} - {step === "verify" && ( - - - We'll text a one-time code to the contact person's phone to - confirm it's reachable. This is required before you continue. - - - {!contactPhoneE164 ? ( - } - > - Add a valid contact phone number on the previous step first. - - ) : phoneVerified ? ( - } - title="Phone verified" - > - {maskPhone(contactPhoneE164)} has been verified. - - ) : ( - - - - - {maskPhone(contactPhoneE164)} - - - - {!otpSent ? ( - - ) : ( - - - - - - - - )} - - {otpError && ( - } - > - {otpError} - - )} - - )} - - )} - {step === "poa" && ( <> @@ -1009,8 +807,7 @@ export default function CompanyProfileForm({ disabled={ isPending || saving || - (step === "documents" && !hasDocuments && loadingDocuments) || - (step === "verify" && !phoneVerified) + (step === "documents" && !hasDocuments && loadingDocuments) } loading={isPending || saving} rightSection={ diff --git a/apps/edr-freight-web/portal/src/pages/accounts/companyProfileForm/schema.ts b/apps/edr-freight-web/portal/src/pages/accounts/companyProfileForm/schema.ts index 31ee21ced..9a123e255 100644 --- a/apps/edr-freight-web/portal/src/pages/accounts/companyProfileForm/schema.ts +++ b/apps/edr-freight-web/portal/src/pages/accounts/companyProfileForm/schema.ts @@ -6,7 +6,6 @@ export type CompanyStep = | "company" | "personnel" | "contact" - | "verify" | "poa" | "documents" | "additional"; @@ -103,7 +102,6 @@ export const stepFields: Record = { "contactPersonEmail", "contactPersonPhone", ], - verify: [], poa: [], documents: [], additional: [],