finilize gl

This commit is contained in:
marshal
2026-07-02 12:06:17 +03:00
parent 9c18d086d7
commit 4fefe4f827
50 changed files with 5150 additions and 1793 deletions

View File

@@ -0,0 +1,52 @@
import { Alert, Badge, Group, Stack, Text } from "@mantine/core";
import { Boxes } from "lucide-react";
import { useContractCapacity } from "@/hooks/contracts/useContracts";
export function ContractCapacityNotice({
contractId,
isContainer,
}: {
contractId: string;
isContainer: boolean;
}) {
const { data: lines = [] } = useContractCapacity(contractId);
if (lines.length === 0) return null;
const allFull = lines.every((l) => l.remaining === 0);
const unit = isContainer ? "" : " tons";
return (
<Alert
color={allFull ? "red" : "edr-green"}
variant="light"
radius="md"
icon={<Boxes size={16} />}
title={allFull ? "Contract capacity reached" : "Remaining contract capacity"}
>
{allFull ? (
<Text fz={13}>
This contract has been fully booked. No further shipments can be created
against it.
</Text>
) : (
<Stack gap={6} mt={4}>
{lines.map((l, i) => (
<Group key={i} justify="space-between" wrap="nowrap">
<Text fz={13}>{l.containerSize ?? "Bulk"}</Text>
<Badge
color={l.remaining === 0 ? "red" : "edr-green"}
variant="light"
radius="sm"
>
{l.remaining}
{unit} of {l.cap} left
</Badge>
</Group>
))}
</Stack>
)}
</Alert>
);
}

View File

@@ -0,0 +1,93 @@
import { Box, Group, Paper, Text, Title } from "@mantine/core";
import type { ReactNode } from "react";
const INK = "#10202F";
const MUTED = "#6B7C8E";
const BORDER = "#E6ECF2";
const GREEN_DARK = "#0A6F4D";
export const fieldStyles = {
label: { fontWeight: 600, fontSize: 13, color: INK, marginBottom: 6 },
input: {
borderRadius: 12,
minHeight: 46,
height: 46,
fontSize: 14,
borderColor: BORDER,
},
};
export function StepLabel({ children }: { children: ReactNode }) {
return (
<Text
fz={11}
fw={700}
tt="uppercase"
c={MUTED}
style={{ letterSpacing: "0.07em" }}
>
{children}
</Text>
);
}
export function StepCard({
children,
eyebrow,
}: {
children: ReactNode;
eyebrow?: ReactNode;
}) {
return (
<Paper
radius={20}
p={{ base: "lg", sm: 28 }}
withBorder
bg="white"
style={{ borderColor: BORDER, boxShadow: "0 2px 14px rgba(16,24,40,0.04)" }}
>
{eyebrow}
{children}
</Paper>
);
}
export function StepHeader({
title,
description,
icon,
}: {
title: string;
description: string;
icon?: ReactNode;
}) {
return (
<Group gap={14} align="flex-start" wrap="nowrap" mb={22}>
{icon ? (
<Box
style={{
flexShrink: 0,
width: 44,
height: 44,
borderRadius: 13,
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "linear-gradient(135deg, #ECF6F1, #E4F3EC)",
color: GREEN_DARK,
}}
>
{icon}
</Box>
) : null}
<Box>
<Title order={3} fz={20} fw={800} c={INK} style={{ letterSpacing: "-0.01em" }}>
{title}
</Title>
<Text size="sm" c={MUTED} mt={4} style={{ lineHeight: 1.5 }}>
{description}
</Text>
</Box>
</Group>
);
}