diff --git a/apps/edr-freight-web/portal/src/pages/MyPortalPage.tsx b/apps/edr-freight-web/portal/src/pages/MyPortalPage.tsx index 7b488bc7d..e05e3a503 100644 --- a/apps/edr-freight-web/portal/src/pages/MyPortalPage.tsx +++ b/apps/edr-freight-web/portal/src/pages/MyPortalPage.tsx @@ -438,7 +438,7 @@ export default function MyPortalPage() { - {!customer&& ( + {!customer && ( @@ -446,9 +446,10 @@ export default function MyPortalPage() { Setup your Company Profile - Complete your company information to unlock all features and start booking shipments. + Complete your company information to unlock all features and + start booking shipments. - + Complete Setup @@ -464,7 +465,6 @@ export default function MyPortalPage() { )} - {/* ── Stats Strip ───────────────────────────────────────────────────── */} diff --git a/apps/edr-freight-web/portal/src/pages/SettingsPage.tsx b/apps/edr-freight-web/portal/src/pages/SettingsPage.tsx index 755f85b45..71f9f7bc9 100644 --- a/apps/edr-freight-web/portal/src/pages/SettingsPage.tsx +++ b/apps/edr-freight-web/portal/src/pages/SettingsPage.tsx @@ -1,15 +1,39 @@ import { useSearchParams } from "react-router-dom"; -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { + AlertCircle, Building2, - User, Briefcase, - UserCheck, + CheckCircle2, FileCheck, + Loader2, + Save, + User, + UserCheck, + XCircle, } from "lucide-react"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; import { api } from "@/services/api"; -import { Badge } from "@edr/ui-common"; +import { + Badge, + Button, + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, + Field, + FieldError, + FieldGroup, + FieldLabel, + Input, +} from "@edr/ui-common"; import { cn } from "@/lib/utils"; +import PhoneInput from "@/components/auth/PhoneInput"; +import type { CreateCompanyPayload } from "@/services/companies.service"; import TabCompanyProfile from "./settings/TabCompanyProfile"; import TabContactPerson from "./settings/TabContactPerson"; import TabGeneralManager from "./settings/TabGeneralManager"; @@ -32,6 +56,7 @@ const TABS: { id: SettingsTab; label: string; icon: React.ReactNode }[] = [ ]; export default function SettingsPage() { + const queryClient = useQueryClient(); const [searchParams, setSearchParams] = useSearchParams(); const tab = (searchParams.get("tab") as SettingsTab) || "company"; const setTab = (t: SettingsTab) => { @@ -48,6 +73,54 @@ export default function SettingsPage() { const profile = profileQuery.data; + const createCompanyMutation = useMutation({ + mutationFn: (payload: CreateCompanyPayload) => + api.companies.create.call(payload), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: api.companies.getProfile.queryKey(), + }); + }, + }); + + const onboardingSchema = z.object({ + companyName: z.string().min(1, "Company name is required"), + companyEmail: z.string().email("Invalid email address"), + companyPhone: z.string().min(1, "Company phone is required"), + companyPhoneCountryCode: z.string().min(1, "Country code is required"), + companyLocation: z.string().min(1, "Location is required"), + companyAddress: z.string().min(1, "Address is required"), + tinNumber: z.string().length(10, "TIN must be exactly 10 digits"), + fanNumber: z.string().length(16, "FAN must be exactly 16 digits"), + }); + + type OnboardingFormData = z.infer; + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + resolver: zodResolver(onboardingSchema), + defaultValues: { + companyPhoneCountryCode: "+251", + }, + }); + + const onSubmitOnboarding = (data: OnboardingFormData) => { + const payload: CreateCompanyPayload = { + companyType: "customer", + companyName: data.companyName, + companyEmail: data.companyEmail, + companyPhone: `${data.companyPhoneCountryCode}${data.companyPhone}`, + companyLocation: data.companyLocation, + companyAddress: data.companyAddress, + tin: data.tinNumber, + fanNumber: data.fanNumber, + }; + createCompanyMutation.mutate(payload); + }; + if (profileQuery.isPending) { return (
@@ -56,14 +129,6 @@ export default function SettingsPage() { ); } - if (!profile) { - return ( -
-

No company profile found.

-
- ); - } - return (
@@ -75,9 +140,11 @@ export default function SettingsPage() { Manage your company profile, personnel, and documents

- - Verified - + {profile && ( + + Verified + + )}
{/* Tab Bar */} @@ -86,12 +153,16 @@ export default function SettingsPage() {
- {tab === "company" && } - {tab === "contact" && } - {tab === "gm" && } - {tab === "poa" && } - {tab === "documents" && } + {/* Tab Content */} + {!profile ? ( + <> + {tab === "company" ? ( + + + + + Company Profile + + + Enter your company registration details to get started + + +
+ + + + Company Name + + + + +
+ + Company Email + + + + + +
+ +
+ + Location + + + + + + Address + + + +
+ +
+ + TIN Number (10 digits) + + + + + + FAN Number (16 digits) + + + +
+
+
+ +
+ {createCompanyMutation.isSuccess && ( + + + Profile created successfully + + )} + {createCompanyMutation.isError && ( + + + Failed to create profile + + )} +
+ +
+
+
+ ) : ( + + +
+ +

+ Please complete the company profile first. +

+
+
+
+ )} + + ) : ( + <> + {tab === "company" && } + {tab === "contact" && } + {tab === "gm" && } + {tab === "poa" && } + {tab === "documents" && } + + )} ); }