Merge branch 'freight_feature/profile' of github.com:Tria-plc/edr-platform into freight_feature/profile

This commit is contained in:
marshal
2026-06-25 06:17:38 +03:00
13 changed files with 439 additions and 246 deletions

View File

@@ -44,9 +44,9 @@ const STATUS_META: Record<
Freight.DocumentReviewStatus,
{ label: string; color: string }
> = {
APPROVED: { label: "Approved", color: "edr-blue" },
APPROVED: { label: "Approved", color: "edr-green" },
QUERIED: { label: "Queried", color: "red" },
PENDING: { label: "Pending", color: "edr-accent" },
PENDING: { label: "Pending", color: "gray" },
};
/**
@@ -142,7 +142,7 @@ export function ClearanceReviewSection({
if (isLoading || !clearance) {
return (
<Group justify="center" py="xl" gap={10}>
<Loader size="sm" color="edr-blue" />
<Loader size="sm" color="edr-green" />
<Text c="dimmed">Loading clearance</Text>
</Group>
);
@@ -165,15 +165,15 @@ export function ClearanceReviewSection({
<Box>
<Progress
value={stats.pct}
color="edr-blue"
color="edr-green"
radius="xl"
size="sm"
mb={6}
/>
<Group gap="lg">
<StatPill color="edr-blue" label="Approved" value={stats.approved} />
<StatPill color="edr-green" label="Approved" value={stats.approved} />
<StatPill color="red" label="Queried" value={stats.queried} />
<StatPill color="edr-accent" label="Pending" value={stats.pending} />
<StatPill color="gray" label="Pending" value={stats.pending} />
</Group>
</Box>
)}
@@ -219,13 +219,13 @@ export function ClearanceReviewSection({
icon={Upload}
title="Customs output documents"
subtitle="Upload the cleared/customs paperwork to hand back to the customer."
accent="edr-accent"
accent="edr-green"
>
<Stack gap={10}>
{glDocs.map((doc) => (
<Group key={doc.fileKey} justify="space-between" wrap="nowrap">
<Group gap={8} wrap="nowrap" style={{ minWidth: 0 }}>
<FileText size={16} color="var(--mantine-color-edr-accent-6)" />
<FileText size={16} color="var(--mantine-color-edr-green-6)" />
<Text fz="13px" c="edr-text" truncate>
{doc.label}
{doc.required ? " *" : ""}
@@ -239,7 +239,7 @@ export function ClearanceReviewSection({
href={doc.file.url}
target="_blank"
rel="noreferrer"
c="edr-accent"
c="edr-green"
style={{ display: "flex" }}
>
<Download size={15} />
@@ -261,7 +261,7 @@ export function ClearanceReviewSection({
{...props}
size="compact-xs"
variant="light"
color="edr-accent"
color="edr-green"
leftSection={<Upload size={13} />}
>
{outputFiles[doc.fileKey] ? "Selected" : "Upload"}
@@ -275,7 +275,7 @@ export function ClearanceReviewSection({
<Group justify="flex-end" mt="md">
<Button
variant="light"
color="edr-accent"
color="edr-green"
radius="md"
leftSection={<Upload size={15} />}
disabled={Object.keys(outputFiles).length === 0}
@@ -301,7 +301,7 @@ export function ClearanceReviewSection({
<Group gap={8} wrap="nowrap" style={{ minWidth: 0 }}>
<ThemeIcon
variant="light"
color={clearance.allApproved ? "edr-blue" : "gray"}
color={clearance.allApproved ? "edr-green" : "gray"}
radius="md"
size={28}
>
@@ -314,7 +314,7 @@ export function ClearanceReviewSection({
</Text>
</Group>
<Button
color="edr-blue"
color="edr-green"
radius="md"
leftSection={<CheckCircle2 size={16} />}
disabled={!clearance.allApproved}
@@ -391,7 +391,7 @@ function DocReviewCard({
status === "QUERIED"
? "var(--mantine-color-red-2)"
: status === "APPROVED"
? "var(--mantine-color-edr-blue-2)"
? "var(--mantine-color-edr-green-2)"
: "var(--mantine-color-edr-border-6)",
}}
>
@@ -399,7 +399,7 @@ function DocReviewCard({
<Group gap={12} wrap="nowrap" style={{ minWidth: 0 }}>
<ThemeIcon
variant="light"
color={hasFile ? "edr-blue" : "gray"}
color={hasFile ? "edr-green" : "gray"}
radius="md"
size={40}
>
@@ -471,7 +471,7 @@ function DocReviewCard({
</Button>
<Button
size="compact-sm"
color="edr-blue"
color="edr-green"
radius="md"
leftSection={<CheckCircle2 size={14} />}
disabled={busy}

View File

@@ -64,7 +64,7 @@ export default function DocumentClearanceDetailPage() {
return (
<PageContainer>
<Group justify="center" py={80} gap={10}>
<Loader color="edr-blue" />
<Loader color="edr-green" />
<Text c="dimmed">Loading clearance</Text>
</Group>
</PageContainer>
@@ -103,7 +103,7 @@ export default function DocumentClearanceDetailPage() {
clearance.allApproved ? (
<Badge
variant="light"
color="edr-blue"
color="edr-green"
radius="sm"
leftSection={<CheckCircle2 size={13} />}
>
@@ -112,7 +112,7 @@ export default function DocumentClearanceDetailPage() {
) : (
<Badge
variant="light"
color="edr-accent"
color="gray"
radius="sm"
leftSection={<Clock size={13} />}
>
@@ -133,13 +133,17 @@ export default function DocumentClearanceDetailPage() {
{/* RIGHT — sticky progress gauge */}
<Grid.Col span={{ base: 12, lg: 4 }}>
<Box style={{ position: "sticky", top: 24 }}>
<SectionCard icon={PackageCheck} title="Review progress" accent="blue">
<SectionCard
icon={PackageCheck}
title="Review progress"
accent="edr-green"
>
<Stack align="center" gap="sm">
<RingProgress
size={140}
thickness={12}
roundCaps
sections={[{ value: stats.pct, color: "edr-blue" }]}
sections={[{ value: stats.pct, color: "edr-green" }]}
label={
<Stack gap={0} align="center">
<Text fw={800} fz={26} lh={1}>
@@ -153,7 +157,7 @@ export default function DocumentClearanceDetailPage() {
/>
<Group gap="lg" justify="center">
<ProgressStat
color="edr-blue"
color="edr-green"
label="Approved"
value={stats.approved}
/>
@@ -163,7 +167,7 @@ export default function DocumentClearanceDetailPage() {
value={stats.queried}
/>
<ProgressStat
color="edr-accent"
color="gray"
label="Pending"
value={stats.pending}
/>
@@ -199,7 +203,7 @@ function ClearanceHero({
<Paper withBorder radius="md" p="lg">
<Group justify="space-between" align="flex-start" wrap="wrap" gap="lg">
<Group gap="md" wrap="nowrap" style={{ minWidth: 0 }}>
<ThemeIcon variant="light" color="edr-blue" radius="md" size={52}>
<ThemeIcon variant="light" color="edr-green" radius="md" size={52}>
<ShieldCheck size={26} />
</ThemeIcon>
<Box style={{ minWidth: 0 }}>
@@ -210,7 +214,7 @@ function ClearanceHero({
<Badge
size="sm"
variant="light"
color={direction === "IMPORT" ? "edr-blue" : "edr-accent"}
color={direction === "IMPORT" ? "edr-green" : "gray"}
radius="sm"
>
{direction}
@@ -219,7 +223,7 @@ function ClearanceHero({
<Badge
size="sm"
variant="light"
color="edr-accent"
color="edr-green"
radius="sm"
leftSection={<ShieldCheck size={12} />}
>
@@ -248,7 +252,7 @@ function ClearanceHero({
{stats.approved}/{stats.total}
</Text>
</Group>
<Progress value={stats.pct} color="edr-blue" radius="xl" size="md" />
<Progress value={stats.pct} color="edr-green" radius="xl" size="md" />
</Box>
</Group>
</Paper>

View File

@@ -15,6 +15,7 @@ import {
Text,
TextInput,
ThemeIcon,
Tooltip,
} from "@mantine/core";
import {
ArrowRight,
@@ -101,8 +102,29 @@ function formatDate(iso?: string): string {
});
}
function directionColor(direction: string): string {
return direction === "IMPORT" ? "edr-blue" : "edr-accent";
/**
* Icon-only chip for a booking's trade direction — Truck for import, ShipWheel
* for export — on a light background, matching the "awaiting review" badge
* styling. Keeps the cards within the white / light-gray / green palette and
* drops the text label in favour of a tooltip.
*/
function DirectionIcon({ direction }: { direction: string }) {
const isImport = direction === "IMPORT";
const Icon = isImport ? Truck : ShipWheel;
const label = isImport ? "Import" : direction === "EXPORT" ? "Export" : "—";
return (
<Tooltip label={label} withArrow>
<ThemeIcon
variant="light"
color={isImport ? "edr-green" : "gray"}
radius="md"
size={28}
aria-label={label}
>
<Icon size={15} strokeWidth={1.9} />
</ThemeIcon>
</Tooltip>
);
}
export default function DocumentClearanceListPage() {
@@ -204,15 +226,8 @@ export default function DocumentClearanceListPage() {
{r.destinationLabel}
</Text>
</Group>
<Group gap={6}>
<Badge
size="xs"
variant="light"
radius="sm"
color={directionColor(r.tradeDirection)}
>
{r.tradeDirection}
</Badge>
<Group gap={8} align="center">
<DirectionIcon direction={r.tradeDirection} />
<Badge size="xs" variant="default" radius="sm">
{r.freightType}
</Badge>
@@ -235,7 +250,7 @@ export default function DocumentClearanceListPage() {
id: "status",
header: () => <span className={bookingTable.headerCell}>Status</span>,
cell: () => (
<Badge size="sm" variant="light" color="edr-blue" radius="sm">
<Badge size="sm" variant="light" color="edr-green" radius="sm">
Under review
</Badge>
),
@@ -296,13 +311,13 @@ export default function DocumentClearanceListPage() {
label: "Import",
value: tabCounts.import,
icon: Truck,
color: "edr-blue",
color: "edr-green",
},
{
label: "Export",
value: tabCounts.export,
icon: ShipWheel,
color: "edr-accent",
color: "gray",
},
]}
/>
@@ -528,7 +543,7 @@ function ClearanceCard({
</Group>
</Box>
</Group>
<Badge size="sm" variant="light" color="edr-blue" radius="sm">
<Badge size="sm" variant="light" color="edr-green" radius="sm">
Under review
</Badge>
</Group>
@@ -554,28 +569,23 @@ function ClearanceCard({
</Box>
<Group justify="space-between" mt="md" wrap="nowrap">
<Group gap={6} wrap="nowrap">
<Badge
size="xs"
variant="light"
radius="sm"
color={directionColor(row.tradeDirection)}
>
{row.tradeDirection}
</Badge>
<Group gap={8} wrap="nowrap">
<DirectionIcon direction={row.tradeDirection} />
<Badge size="xs" variant="default" radius="sm">
{row.freightType}
</Badge>
{row.hasCustoms ? (
<Badge
size="xs"
variant="light"
color="edr-green"
radius="sm"
leftSection={<ShieldCheck size={11} />}
>
Customs
</Badge>
<Tooltip label="Customs clearance" withArrow>
<ThemeIcon
variant="light"
color="edr-green"
radius="md"
size={28}
aria-label="Customs clearance"
>
<ShieldCheck size={15} strokeWidth={1.9} />
</ThemeIcon>
</Tooltip>
) : null}
</Group>
<Group gap={4} wrap="nowrap">