Merge branch 'dev' into freight/nati-2

This commit is contained in:
Nathnael
2026-08-12 08:03:10 +00:00
95 changed files with 7755 additions and 859 deletions

View File

@@ -33,6 +33,8 @@ import { contractsService } from "@/services/contracts.service";
import { api } from "@/services/api";
import { extractApiError } from "@/utils/result";
import "./contract-sign-bar.css";
const CONSENT_TEXT = "I have read the entire contract and agree to its terms.";
/**
@@ -225,7 +227,7 @@ export default function ContractViewPage() {
return (
<Box
p={{ base: "md", md: "xl" }}
pb={data.canSignCustomer ? 120 : undefined}
pb={data.canSignCustomer ? { base: 220, sm: 160, md: 120 } : undefined}
>
<Box maw={920} mx="auto">
<Group justify="space-between" wrap="wrap" gap="sm" mb="md">
@@ -294,16 +296,19 @@ export default function ContractViewPage() {
style={{
position: "fixed",
bottom: 0,
left: 0,
left: "var(--sign-bar-left, 0px)",
right: 0,
zIndex: 100,
borderTop: "1px solid var(--mantine-color-gray-3)",
background: "var(--mantine-color-body)",
paddingBottom: 32,
paddingBottom: "max(env(safe-area-inset-bottom, 0px), 16px)",
maxHeight: "80vh",
overflowY: "auto",
}}
className="contract-sign-bar"
>
<Box maw={920} mx="auto">
<Stack gap="sm">
<Group justify="flex-start" align="flex-start" wrap="wrap" gap="sm">
<Checkbox
checked={agreedToTerms}
onChange={(e) => setAgreedToTerms(e.currentTarget.checked)}
@@ -315,17 +320,15 @@ export default function ContractViewPage() {
: "Read the full contract above before you can agree and sign."
}
/>
<Group justify="flex-end">
<Button
color="edr-green"
leftSection={<FileSignature size={16} />}
disabled={!canProceedToSign}
onClick={openSign}
>
{usingSaved ? "Approve & sign" : "Sign contract"}
</Button>
</Group>
</Stack>
<Button
color="edr-green"
leftSection={<FileSignature size={16} />}
disabled={!canProceedToSign}
onClick={openSign}
>
{usingSaved ? "Approve & sign" : "Sign contract"}
</Button>
</Group>
</Box>
</Paper>
)}

View File

@@ -87,6 +87,8 @@ export default function NewShipmentRequestPage() {
contract.contractKind === "GENERAL" &&
(contract.serviceType?.includesCustoms ?? contract.customsClearingEnabled);
const isIntercity = contract.tradeDirection === "DOMESTIC";
// Export shipments are invoiced in ETB only — USD is not offered.
const isExport = contract.tradeDirection === "EXPORT";
// Only the container sizes the contract was scoped for (20ft, 40ft, or both).
const SIZE_ORDER = ["20ft", "40ft"];
@@ -115,7 +117,7 @@ export default function NewShipmentRequestPage() {
const dto: Freight.CreateBookingRequestDto = {
contractRouteId: route?.id,
scheduledDate: hasCustoms ? undefined : scheduledDate || undefined,
paymentCurrency: isIntercity ? "ETB" : paymentCurrency,
paymentCurrency: isIntercity || isExport ? "ETB" : paymentCurrency,
notes: notes.trim() || undefined,
};
@@ -246,16 +248,22 @@ export default function NewShipmentRequestPage() {
<Text size="xs" c="dimmed" mb={8}>
{isIntercity
? "Intercity shipments are invoiced in ETB."
: "Your contract is quoted in USD. Global Logistics will book this shipment and invoice you in the currency you pick here."}
: isExport
? "Export shipments are invoiced in ETB."
: "Your contract is quoted in USD. Global Logistics will book this shipment and invoice you in the currency you pick here."}
</Text>
<SegmentedControl
value={isIntercity ? "ETB" : paymentCurrency}
value={isIntercity || isExport ? "ETB" : paymentCurrency}
onChange={(v) => setPaymentCurrency(v as "USD" | "ETB")}
disabled={isIntercity}
data={[
{ label: "USD", value: "USD" },
{ label: "ETB", value: "ETB" },
]}
disabled={isIntercity || isExport}
data={
isExport
? [{ label: "ETB", value: "ETB" }]
: [
{ label: "USD", value: "USD" },
{ label: "ETB", value: "ETB" },
]
}
color="teal"
radius={10}
/>

View File

@@ -0,0 +1,11 @@
/* Keeps the fixed sign bar confined to the content area (right of the
navbar) instead of spanning the full viewport and drifting off-center. */
.contract-sign-bar {
--sign-bar-left: 0px;
}
@media (min-width: 48em) {
.contract-sign-bar {
--sign-bar-left: 260px;
}
}