mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-06 10:03:38 +00:00
style: inter module integration
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { Badge } from "@mantine/core";
|
||||
|
||||
const STATUS_COLOR: Record<string, string> = {
|
||||
PENDING: "edr-green",
|
||||
ACCEPTED: "blue",
|
||||
REJECTED: "red",
|
||||
};
|
||||
|
||||
/** Status of a customer-submitted shipment (booking) request against a contract. */
|
||||
export function BookingRequestStatusBadge({ status }: { status: string }) {
|
||||
return (
|
||||
<Badge variant="light" radius="sm" color={STATUS_COLOR[status] ?? "gray"}>
|
||||
{status}
|
||||
</Badge>
|
||||
);
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import { clearanceWorkflowFileLabel } from "@edr/types";
|
||||
|
||||
import { SectionCard } from "@/components/bookings/detail/SectionCard";
|
||||
import { detailStyles } from "@/components/bookings/detail/booking-detail.styles";
|
||||
import { LinkedEntityCard } from "@/components/detail";
|
||||
import { customersService } from "@/services/customers.service";
|
||||
|
||||
type ContractFile = NonNullable<Freight.IContract["files"]>[number];
|
||||
@@ -141,25 +142,23 @@ export function ContractCustomerCard({
|
||||
|
||||
return (
|
||||
<Stack gap="lg">
|
||||
<SectionCard
|
||||
<LinkedEntityCard
|
||||
icon={Building2}
|
||||
title="Customer"
|
||||
subtitle={company.name}
|
||||
name={company.name ?? "Unnamed company"}
|
||||
to={`/dashboard/customers/${company.id}`}
|
||||
accent="blue"
|
||||
>
|
||||
<InfoRows
|
||||
rows={[
|
||||
{ icon: FileCheck, label: "TIN", value: company.tin },
|
||||
{ icon: Hash, label: "VAT number", value: company.vatNumber },
|
||||
{ icon: ShieldCheck, label: "FAN number", value: company.fanNumber },
|
||||
{ icon: Globe, label: "Country", value: company.country },
|
||||
{ icon: Mail, label: "Email", value: company.email },
|
||||
{ icon: Phone, label: "Phone", value: company.phone },
|
||||
{ icon: MapPin, label: "Address", value: company.address },
|
||||
{ icon: Globe, label: "Website", value: company.website },
|
||||
]}
|
||||
/>
|
||||
</SectionCard>
|
||||
rows={[
|
||||
{ icon: FileCheck, label: "TIN", value: company.tin },
|
||||
{ icon: Hash, label: "VAT number", value: company.vatNumber },
|
||||
{ icon: ShieldCheck, label: "FAN number", value: company.fanNumber },
|
||||
{ icon: Globe, label: "Country", value: company.country },
|
||||
{ icon: Mail, label: "Email", value: company.email },
|
||||
{ icon: Phone, label: "Phone", value: company.phone },
|
||||
{ icon: MapPin, label: "Address", value: company.address },
|
||||
{ icon: Globe, label: "Website", value: company.website },
|
||||
]}
|
||||
/>
|
||||
|
||||
<SectionCard icon={User} title="Contact person" accent="teal">
|
||||
<InfoRows
|
||||
|
||||
@@ -12,56 +12,14 @@ import {
|
||||
User,
|
||||
Warehouse,
|
||||
} from "lucide-react";
|
||||
import { Badge, Box, Divider, Group, Stack, Text } from "@mantine/core";
|
||||
import { Badge, Box, Group, Stack, Text } from "@mantine/core";
|
||||
import type { Freight } from "@edr/types";
|
||||
|
||||
import { SectionCard } from "@/components/bookings/detail/SectionCard";
|
||||
import { LinkedEntityCard } from "@/components/detail";
|
||||
|
||||
type ReqContract = NonNullable<Freight.IBookingRequest["contract"]>;
|
||||
|
||||
interface InfoRowProps {
|
||||
icon: LucideIcon;
|
||||
label: string;
|
||||
value?: string | null;
|
||||
}
|
||||
|
||||
function InfoRow({ icon: Icon, label, value }: InfoRowProps) {
|
||||
return (
|
||||
<Group justify="space-between" wrap="nowrap" py={6} gap="md">
|
||||
<Group gap="xs" wrap="nowrap">
|
||||
<Icon size={15} color="var(--mantine-color-gray-5)" />
|
||||
<Text size="sm" c="dimmed">
|
||||
{label}
|
||||
</Text>
|
||||
</Group>
|
||||
<Text size="sm" fw={600} ta="right" style={{ minWidth: 0 }} truncate>
|
||||
{value || "—"}
|
||||
</Text>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
function InfoRows({ rows }: { rows: InfoRowProps[] }) {
|
||||
const visible = rows.filter((r) => r.value);
|
||||
if (visible.length === 0) {
|
||||
return (
|
||||
<Text size="sm" c="dimmed">
|
||||
No details available.
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Stack gap={0}>
|
||||
{visible.map((row, i) => (
|
||||
<div key={row.label}>
|
||||
{i > 0 && <Divider color="var(--mantine-color-gray-2)" />}
|
||||
<InfoRow {...row} />
|
||||
</div>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
/** Customer (company) on the request's contract. */
|
||||
export function RequestCustomerCard({ contract }: { contract?: ReqContract | null }) {
|
||||
const company = contract?.company;
|
||||
@@ -75,23 +33,21 @@ export function RequestCustomerCard({ contract }: { contract?: ReqContract | nul
|
||||
);
|
||||
}
|
||||
return (
|
||||
<SectionCard
|
||||
<LinkedEntityCard
|
||||
icon={Building2}
|
||||
title="Customer"
|
||||
subtitle={company.name ?? undefined}
|
||||
name={company.name ?? "Unnamed company"}
|
||||
to={company.id ? `/dashboard/customers/${company.id}` : null}
|
||||
accent="blue"
|
||||
>
|
||||
<InfoRows
|
||||
rows={[
|
||||
{ icon: FileCheck, label: "TIN", value: company.tin },
|
||||
{ icon: Mail, label: "Email", value: company.email },
|
||||
{ icon: Phone, label: "Phone", value: company.phone },
|
||||
{ icon: MapPin, label: "Address", value: company.address },
|
||||
{ icon: User, label: "Contact", value: company.contactPersonName },
|
||||
{ icon: Phone, label: "Contact phone", value: company.contactPersonPhone },
|
||||
]}
|
||||
/>
|
||||
</SectionCard>
|
||||
rows={[
|
||||
{ icon: FileCheck, label: "TIN", value: company.tin },
|
||||
{ icon: Mail, label: "Email", value: company.email },
|
||||
{ icon: Phone, label: "Phone", value: company.phone },
|
||||
{ icon: MapPin, label: "Address", value: company.address },
|
||||
{ icon: User, label: "Contact", value: company.contactPersonName },
|
||||
{ icon: Phone, label: "Contact phone", value: company.contactPersonPhone },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -119,43 +75,41 @@ export function RequestContractSummaryCard({
|
||||
}) {
|
||||
if (!contract) return null;
|
||||
return (
|
||||
<SectionCard
|
||||
<LinkedEntityCard
|
||||
icon={FileText}
|
||||
title="Contract"
|
||||
subtitle={contract.reference}
|
||||
name={contract.reference}
|
||||
to={`/dashboard/contract-requests/${contract.id}`}
|
||||
accent="grape"
|
||||
>
|
||||
<InfoRows
|
||||
rows={[
|
||||
{
|
||||
icon: FileText,
|
||||
label: "Kind",
|
||||
value: contract.contractKind === "GENERAL" ? "General" : "One-time",
|
||||
},
|
||||
{
|
||||
icon: Package,
|
||||
label: "Cargo",
|
||||
value: contract.freightType === "CONTAINER" ? "Container" : "Bulk",
|
||||
},
|
||||
{ icon: Ship, label: "Trade", value: titleCase(contract.tradeDirection) },
|
||||
{ icon: FileCheck, label: "Currency", value: contract.paymentCurrency },
|
||||
{
|
||||
icon: FileCheck,
|
||||
label: "Customs",
|
||||
value: contract.customsClearingEnabled
|
||||
? "Included (Global Logistics)"
|
||||
: "Not included",
|
||||
},
|
||||
{
|
||||
icon: FileText,
|
||||
label: "Valid until",
|
||||
value: contract.contractValidUntil
|
||||
? fmtDate(contract.contractValidUntil)
|
||||
: "Not active yet",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionCard>
|
||||
rows={[
|
||||
{
|
||||
icon: FileText,
|
||||
label: "Kind",
|
||||
value: contract.contractKind === "GENERAL" ? "General" : "One-time",
|
||||
},
|
||||
{
|
||||
icon: Package,
|
||||
label: "Cargo",
|
||||
value: contract.freightType === "CONTAINER" ? "Container" : "Bulk",
|
||||
},
|
||||
{ icon: Ship, label: "Trade", value: titleCase(contract.tradeDirection) },
|
||||
{ icon: FileCheck, label: "Currency", value: contract.paymentCurrency },
|
||||
{
|
||||
icon: FileCheck,
|
||||
label: "Customs",
|
||||
value: contract.customsClearingEnabled
|
||||
? "Included (Global Logistics)"
|
||||
: "Not included",
|
||||
},
|
||||
{
|
||||
icon: FileText,
|
||||
label: "Valid until",
|
||||
value: contract.contractValidUntil
|
||||
? fmtDate(contract.contractValidUntil)
|
||||
: "Not active yet",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user