mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 07:22:53 +00:00
chore: add company select to backoffice booking
This commit is contained in:
@@ -180,8 +180,10 @@ export default function NewBookingPage() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [isGovernment, setIsGovernment] = useState(false);
|
||||
const [governmentInstitution, setGovernmentInstitution] = useState("");
|
||||
const [companyId, setCompanyId] = useState<string | null>(null);
|
||||
// Government bookings bill to a real government company + an explicit profile.
|
||||
const [govCompanyId, setGovCompanyId] = useState<string | null>(null);
|
||||
const [govProfileId, setGovProfileId] = useState<string | null>(null);
|
||||
const [freightType, setFreightType] = useState<FreightType>("CONTAINER");
|
||||
const [originYardId, setOriginYardId] = useState<string | null>(null);
|
||||
const [destinationYardId, setDestinationYardId] = useState<string | null>(null);
|
||||
@@ -220,6 +222,42 @@ export default function NewBookingPage() {
|
||||
label: c.name || c.email || c.tin || c.id,
|
||||
}));
|
||||
|
||||
// Active government companies (kind=government) the booking can bill to.
|
||||
const { data: govCompaniesPage, isLoading: govCompaniesLoading } = useQuery({
|
||||
queryKey: ["companies", "government", "active"],
|
||||
queryFn: () =>
|
||||
customersService.list({
|
||||
page: 1,
|
||||
pageSize: 1000,
|
||||
kind: "government",
|
||||
status: "active",
|
||||
}),
|
||||
enabled: isGovernment,
|
||||
});
|
||||
|
||||
const govCompanies = govCompaniesPage?.items ?? [];
|
||||
const govCompanyOptions = govCompanies.map((c) => ({
|
||||
value: c.id,
|
||||
label: c.name || c.tin || c.id,
|
||||
}));
|
||||
|
||||
// Profiles (importer/exporter) of the chosen government company — the booking
|
||||
// must link to one explicitly.
|
||||
const selectedGovCompany = govCompanies.find((c) => c.id === govCompanyId);
|
||||
const govProfileOptions = (selectedGovCompany?.companyProfiles ?? [])
|
||||
.filter((p) => p.status === "active")
|
||||
.map((p) => ({
|
||||
value: p.id,
|
||||
label: `${p.type === "importer" ? "Import" : p.type === "exporter" ? "Export" : p.type}${
|
||||
p.reference ? ` — ${p.reference}` : ""
|
||||
}`,
|
||||
}));
|
||||
|
||||
// Reset the chosen profile when the government company changes.
|
||||
useEffect(() => {
|
||||
setGovProfileId(null);
|
||||
}, [govCompanyId]);
|
||||
|
||||
// Day-level pool: fetch only the days that have a departure on the route (no
|
||||
// train, no capacity). The batch engine assigns the train after booking.
|
||||
const { data: availableDays, isLoading: daysLoading } = useQuery(
|
||||
@@ -306,7 +344,7 @@ export default function NewBookingPage() {
|
||||
Boolean(tradeDirection) &&
|
||||
Boolean(serviceTypeId) &&
|
||||
departureSatisfied &&
|
||||
(isGovernment ? governmentInstitution.trim().length >= 2 : Boolean(companyId)) &&
|
||||
(isGovernment ? Boolean(govCompanyId && govProfileId) : Boolean(companyId)) &&
|
||||
(freightType === "BULK"
|
||||
? Boolean(cargoTypeId) && bulkWeight > 0
|
||||
: allLinesValid);
|
||||
@@ -320,8 +358,8 @@ export default function NewBookingPage() {
|
||||
mutationFn: () =>
|
||||
bookingsService.create({
|
||||
isGovernment,
|
||||
governmentInstitution: isGovernment ? governmentInstitution : undefined,
|
||||
companyId: isGovernment ? undefined : companyId || undefined,
|
||||
companyId: isGovernment ? govCompanyId || undefined : companyId || undefined,
|
||||
companyProfileId: isGovernment ? govProfileId || undefined : undefined,
|
||||
freightType,
|
||||
contractType: "NEW",
|
||||
equipmentReturn,
|
||||
@@ -390,18 +428,37 @@ export default function NewBookingPage() {
|
||||
<Stack gap="md">
|
||||
<Switch
|
||||
label="Government booking"
|
||||
description="No company required — institution name instead. Expedited to the scheduling queue."
|
||||
description="Bills to a government entity + profile. Expedited to the scheduling queue."
|
||||
checked={isGovernment}
|
||||
onChange={(e) => setIsGovernment(e.currentTarget.checked)}
|
||||
/>
|
||||
{isGovernment ? (
|
||||
<TextInput
|
||||
label="Government institution"
|
||||
placeholder="e.g. Ministry of Transport"
|
||||
value={governmentInstitution}
|
||||
onChange={(e) => setGovernmentInstitution(e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
<Group grow align="flex-start">
|
||||
<Select
|
||||
label="Government entity"
|
||||
placeholder="Select government company"
|
||||
data={govCompanyOptions}
|
||||
value={govCompanyId}
|
||||
onChange={setGovCompanyId}
|
||||
searchable
|
||||
required
|
||||
disabled={govCompaniesLoading}
|
||||
nothingFoundMessage="No active government companies"
|
||||
/>
|
||||
<Select
|
||||
label="Profile"
|
||||
placeholder={
|
||||
govCompanyId ? "Select import/export profile" : "Pick an entity first"
|
||||
}
|
||||
data={govProfileOptions}
|
||||
value={govProfileId}
|
||||
onChange={setGovProfileId}
|
||||
searchable
|
||||
required
|
||||
disabled={!govCompanyId}
|
||||
nothingFoundMessage="No active profiles for this entity"
|
||||
/>
|
||||
</Group>
|
||||
) : (
|
||||
<Select
|
||||
label="Customer"
|
||||
|
||||
@@ -18,6 +18,9 @@ export type CompanyType =
|
||||
/** Mirrors backend `CompanyStatus`. */
|
||||
export type CompanyStatus = "active" | "pending" | "suspended" | "blacklisted";
|
||||
|
||||
/** Mirrors backend `CompanyKind` — commercial customer vs. government entity. */
|
||||
export type CompanyKind = "commercial" | "government";
|
||||
|
||||
/** Mirrors backend `ProfileType` (the role a company plays). */
|
||||
export type ProfileType =
|
||||
| "importer"
|
||||
@@ -47,6 +50,7 @@ export interface Company {
|
||||
id: string;
|
||||
name: string;
|
||||
type: CompanyType;
|
||||
kind: CompanyKind;
|
||||
status: CompanyStatus;
|
||||
tin: string;
|
||||
vatNumber?: string | null;
|
||||
@@ -73,6 +77,7 @@ export interface CompanyListFilter {
|
||||
pageSize: number;
|
||||
search?: string;
|
||||
type?: CompanyType;
|
||||
kind?: CompanyKind;
|
||||
status?: CompanyStatus;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user