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 ab00965fa..849ba50c5 100644 --- a/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx +++ b/apps/edr-freight-web/portal/src/components/onboarding/OnboardingWizardDialog.tsx @@ -286,9 +286,13 @@ export default function OnboardingWizardDialog({ }); }, [roles, nationality, startMutation]); - // Note: no "back to role selection" — once the draft is created the role(s) - // are fixed; the form's first-step Back is a no-op so progress never resets. - const handleBackToRoles = useCallback(() => { }, []); + // Back from the form's first step returns to nationality/role selection. + // Safe to re-enter: startOnboarding is idempotent — it reuses the existing + // draft, refreshes the nationality and creates only roles that don't exist yet. + const handleBackToRoles = useCallback(() => { + setStartError(null); + setPhase("nationality-role"); + }, []); // Save the current step's fields to the draft (PATCH /profile). Returns the // server error message on failure so the form can show it (e.g. duplicate TIN). @@ -359,7 +363,6 @@ export default function OnboardingWizardDialog({ // The active step across the whole journey, driving the header + progress pill. const activeStep: WizardStep = phase === "form" ? formStep : phase; const stepMeta = STEP_META[activeStep]; - console.log({ stepMeta, activeStep, STEP_META }); const activeIdx = WIZARD_STEPS.indexOf(activeStep); // Closing from the congratulations panel also clears the completed flag so a @@ -403,7 +406,6 @@ export default function OnboardingWizardDialog({ onSubmit: handleSubmit, isPending: finishMutation.isPending, onBack: handleBackToRoles, - hideFirstStepBack: true, initialStep: effectiveResumeStep, resyncOpen: opened, onStepChange: handleStepChange, 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 cc9f81a29..abfb61551 100644 --- a/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx +++ b/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx @@ -51,7 +51,6 @@ export default function CompanyProfileForm({ onBack, initialStep, resyncOpen, - hideFirstStepBack, onStepChange, onSaveStep, rehydrate, @@ -73,8 +72,6 @@ export default function CompanyProfileForm({ initialStep?: CompanyStep; /** When this flips true (dialog reopened), jump back to initialStep (furthest reached). */ resyncOpen?: boolean; - /** Hide the Back button on the first step (onboarding can't go back to role pick). */ - hideFirstStepBack?: boolean; /** Reports the active step so the parent can persist resume progress. */ onStepChange?: (step: CompanyStep) => void; /** Persist the current step's data before advancing; returns an error to show. */ @@ -514,10 +511,6 @@ export default function CompanyProfileForm({ else setStep(stepOrder[currentIdx - 1]); }; - // Back is hidden on the first step during onboarding (can't return to role - // selection); otherwise always available. - const showBack = !(hideFirstStepBack && step === "company"); - return ( <>
e.preventDefault()}> @@ -851,17 +844,13 @@ export default function CompanyProfileForm({ )} - {showBack ? ( - - ) : ( - - )} + + + + + + + + + + None of your profiles are active yet + + + + + Contracts can only be created under a profile EDR has + approved. You can continue, but every operation stays locked + until at least one profile is approved. + + + + {/* Summary strip */} @@ -378,7 +440,11 @@ export default function ContractsList() { - + No contracts yet. Create one from New Contract. @@ -400,154 +466,159 @@ export default function ContractsList() { const isOpen = expanded.has(c.id); return ( - navigate(`/contracts/${c.id}`)} - > - - { - e.stopPropagation(); - toggleExpanded(c.id); - }} - style={{ - display: "flex", - alignItems: "center", - justifyContent: "center", - width: 28, - height: 28, - borderRadius: 8, - border: `1px solid ${BORDER}`, - background: isOpen ? GREEN : "#FFFFFF", - color: isOpen ? "#FFFFFF" : MUTED, - cursor: "pointer", - transition: "all 140ms ease", - }} - > - navigate(`/contracts/${c.id}`)} + > + + { + e.stopPropagation(); + toggleExpanded(c.id); }} - /> - - - - - {c.reference} - - - {isContainer ? "Containerised" : "Bulk"} - - - - - {isGeneral ? "General" : "One-Time"} - - - - - {isContainer ? ( - - ) : ( - - )} - - {isContainer ? "Container" : "Bulk"} + style={{ + display: "flex", + alignItems: "center", + justifyContent: "center", + width: 28, + height: 28, + borderRadius: 8, + border: `1px solid ${BORDER}`, + background: isOpen ? GREEN : "#FFFFFF", + color: isOpen ? "#FFFFFF" : MUTED, + cursor: "pointer", + transition: "all 140ms ease", + }} + > + + + + + + {c.reference} - - - - - {origin}{" "} - - → - {" "} - {destination} - {count > 1 && ( - - {" "} - +{count - 1} + + {isContainer ? "Containerised" : "Bulk"} + + + + + {isGeneral ? "General" : "One-Time"} + + + + + {isContainer ? ( + + ) : ( + + )} + + {isContainer ? "Container" : "Bulk"} - )} - - - - - {tradeLabel} - - - - - {c.paymentCurrency ?? "—"} - - - - - {c.createdAt - ? new Date(c.createdAt).toLocaleDateString() - : "—"} - - - - - {c.contractValidUntil - ? new Date( + + + + + {origin}{" "} + + → + {" "} + {destination} + {count > 1 && ( + + {" "} + +{count - 1} + + )} + + + + + {tradeLabel} + + + + + {c.paymentCurrency ?? "—"} + + + + + {c.createdAt + ? new Date(c.createdAt).toLocaleDateString() + : "—"} + + + + + {c.contractValidUntil + ? new Date( c.contractValidUntil, ).toLocaleDateString() - : "—"} - - - - - - - - e.stopPropagation()} - /> - - - - - {isOpen && ( - - - + : "—"} + + + + + + + + e.stopPropagation()} + /> + + - )} + {isOpen && ( + + + + + + )} ); })} @@ -564,7 +635,10 @@ export default function ContractsList() { gap="md" px={20} py={14} - style={{ borderTop: `1px solid ${BORDER}`, background: "#FCFDFE" }} + style={{ + borderTop: `1px solid ${BORDER}`, + background: "#FCFDFE", + }} > @@ -574,8 +648,7 @@ export default function ContractsList() { data={["10", "25", "50"]} value={String(pagination.pageSize)} onChange={(v) => - v && - setPagination({ pageIndex: 0, pageSize: Number(v) }) + v && setPagination({ pageIndex: 0, pageSize: Number(v) }) } radius="md" size="xs"