Merge pull request #1114 from Tria-plc/freight_feature/usermanagement

always-on calendar, currency cards
This commit is contained in:
marshal
2026-08-05 10:05:45 +03:00
committed by GitHub
6 changed files with 229 additions and 115 deletions

View File

@@ -20,7 +20,6 @@ import {
Loader,
Modal,
Paper,
SegmentedControl,
Select,
Stack,
Switch,
@@ -49,7 +48,11 @@ import {
X,
} from "lucide-react";
import type { Freight } from "@edr/types";
import { ExportTrainPicker, OperationDatePicker } from "@edr/ui-common";
import {
CurrencySelector,
ExportTrainPicker,
OperationDatePicker,
} from "@edr/ui-common";
import { api } from "@/services/api";
import { PageContainer } from "@/components/page";
@@ -1713,47 +1716,42 @@ export default function GlCreateBookingForm() {
title="Schedule"
description="Pick the binding shipment day. Only days with an open train that has enough matching wagons for the cargo can be selected."
/>
{cargoQuery === null ? (
<Alert
color="yellow"
variant="light"
radius="md"
icon={<AlertCircle size={16} />}
>
Enter your cargo details first available shipment days depend
on the wagons your cargo needs.
</Alert>
) : (
<Box>
<StepLabel>Shipment day *</StepLabel>
<Box mt={10} w="100%">
<OperationDatePicker
fullWidth
availableDays={availableDays ?? []}
isLoading={daysLoading}
value={scheduledDate}
onChange={(d) => {
setScheduledDate(d);
// A new day invalidates the old train pick.
setTrainScheduleId("");
}}
/>
</Box>
{showErrors && dateError && (
<Text fz="xs" c="red" mt={6}>
{dateError}
</Text>
)}
{isExportPick && scheduledDate ? (
<ExportTrainPicker
options={exportTrainsQuery.data ?? []}
loading={exportTrainsQuery.isLoading}
value={trainScheduleId}
onChange={setTrainScheduleId}
/>
) : null}
<Box>
<StepLabel>Shipment day *</StepLabel>
<Box mt={10} w="100%">
{/* Calendar stays visible before cargo is entered — all days
disabled with a hint, since availability depends on cargo. */}
<OperationDatePicker
fullWidth
availableDays={cargoQuery === null ? [] : (availableDays ?? [])}
isLoading={cargoQuery !== null && daysLoading}
emptyMessage={
cargoQuery === null
? "Enter the cargo details first — available shipment days depend on the wagons the cargo needs."
: undefined
}
value={scheduledDate}
onChange={(d) => {
setScheduledDate(d);
// A new day invalidates the old train pick.
setTrainScheduleId("");
}}
/>
</Box>
)}
{showErrors && dateError && (
<Text fz="xs" c="red" mt={6}>
{dateError}
</Text>
)}
{isExportPick && scheduledDate ? (
<ExportTrainPicker
options={exportTrainsQuery.data ?? []}
loading={exportTrainsQuery.isLoading}
value={trainScheduleId}
onChange={setTrainScheduleId}
/>
) : null}
</Box>
</StepCard>
)}
@@ -1769,16 +1767,10 @@ export default function GlCreateBookingForm() {
? "Requested by the customer on their shipment request."
: "The contract is quoted in USD — pick the currency this shipment is invoiced in."}
</Text>
<SegmentedControl
<CurrencySelector
value={isIntercity ? "ETB" : paymentCurrency}
onChange={(v) => setPaymentCurrency(v as "USD" | "ETB")}
onChange={setPaymentCurrency}
disabled={isIntercity}
data={[
{ label: "USD", value: "USD" },
{ label: "ETB", value: "ETB" },
]}
color="edr-green"
radius={10}
/>
</Box>

View File

@@ -22,7 +22,6 @@ import {
Loader,
Modal,
Paper,
SegmentedControl,
Stack,
Switch,
Text,
@@ -50,7 +49,11 @@ import {
} from "lucide-react";
import type { Freight } from "@edr/types";
import { ExportTrainPicker, OperationDatePicker } from "@edr/ui-common";
import {
CurrencySelector,
ExportTrainPicker,
OperationDatePicker,
} from "@edr/ui-common";
import { api } from "@/services/api";
import {
contractsService,
@@ -1144,75 +1147,56 @@ function ScheduleStep({
Your contract is quoted in USD. Pick the currency this shipment is
invoiced in the total is converted for you.
</Text>
{/* Rendered unselected until the customer chooses: SegmentedControl
highlights whatever value it is given, so passing a fallback
here would look like a made choice. */}
<SegmentedControl
<CurrencySelector
value={field.value || ""}
onChange={(v) => field.onChange(v)}
data={[
{ label: "Select…", value: "", disabled: true },
{ label: "USD", value: "USD" },
{ label: "ETB", value: "ETB" },
]}
color="edr-green"
radius={10}
error={fieldState.error?.message}
/>
{fieldState.error && (
<Text fz={12.5} c="red.6" mt={6}>
{fieldState.error.message}
</Text>
)}
</Box>
)}
/>
{cargoQuery === null ? (
<Alert
color="yellow"
variant="light"
radius="md"
icon={<AlertCircle size={16} />}
>
Enter your cargo details first available shipment days depend on the
wagons your cargo needs.
</Alert>
) : (
<Controller
name="scheduledDate"
control={form.control}
render={({ field, fieldState }) => (
<Box>
<StepLabel>Shipment day *</StepLabel>
<Box mt={10} w="100%">
<OperationDatePicker
fullWidth
availableDays={availableDays ?? []}
isLoading={isLoading}
value={field.value ?? ""}
onChange={(d) => {
field.onChange(d);
// A new day invalidates the old train pick.
form.setValue("trainScheduleId", "");
}}
/>
</Box>
{fieldState.error?.message && (
<Text fz="xs" c="red" mt={6}>
{fieldState.error.message}
</Text>
)}
{isExportPick && scheduledDate ? (
<ExportTrainPicker
options={exportTrainsQuery.data ?? []}
loading={exportTrainsQuery.isLoading}
value={selectedTrainId ?? ""}
onChange={(id) => form.setValue("trainScheduleId", id)}
/>
) : null}
<Controller
name="scheduledDate"
control={form.control}
render={({ field, fieldState }) => (
<Box>
<StepLabel>Shipment day *</StepLabel>
<Box mt={10} w="100%">
{/* Calendar stays visible before cargo is entered — all days
disabled with a hint, since availability depends on cargo. */}
<OperationDatePicker
fullWidth
availableDays={cargoQuery === null ? [] : (availableDays ?? [])}
isLoading={cargoQuery !== null && isLoading}
emptyMessage={
cargoQuery === null
? "Enter your cargo details first — available shipment days depend on the wagons your cargo needs."
: undefined
}
value={field.value ?? ""}
onChange={(d) => {
field.onChange(d);
// A new day invalidates the old train pick.
form.setValue("trainScheduleId", "");
}}
/>
</Box>
)}
/>
)}
{fieldState.error?.message && (
<Text fz="xs" c="red" mt={6}>
{fieldState.error.message}
</Text>
)}
{isExportPick && scheduledDate ? (
<ExportTrainPicker
options={exportTrainsQuery.data ?? []}
loading={exportTrainsQuery.isLoading}
value={selectedTrainId ?? ""}
onChange={(id) => form.setValue("trainScheduleId", id)}
/>
) : null}
</Box>
)}
/>
</StepCard>
);
}