import { Badge, Button, Group, Tooltip } from "@mantine/core"; import { useMutation } from "@tanstack/react-query"; import { api } from "@/services/api"; import type { CompanyProfile, CompanyStatus, CompanyType, CustomerBookingStatus, CustomerPaymentStatus, ProfileStatus, ProfileType, } from "@/types/customer"; import { humanize } from "./format"; const badgeStyle = { fontSize: "0.7rem", letterSpacing: "0.04em", whiteSpace: "nowrap" as const, }; /** Shared status palette — active/paid green, pending amber, terminal red. */ const STATUS_COLOR: Record = { active: "edr-green", pending: "yellow", suspended: "orange", blacklisted: "red", }; const COMPANY_TYPE_COLOR: Record = { customer: "edr-green", freight_forwarder: "blue", dj_freight_forwarder: "indigo", transporter: "grape", }; const PROFILE_TYPE_COLOR: Record = { importer: "teal", exporter: "cyan", freight_forwarder: "blue", dj_freight_forwarder: "indigo", transporter: "grape", }; export function CompanyStatusBadge({ status }: { status: CompanyStatus }) { return ( {status} ); } export function CompanyTypeBadge({ type }: { type: CompanyType }) { return ( {humanize(type)} ); } /** * Profile chips for a company row: one chip per role (Importer / Exporter / …) * carrying its reference code. Caps at three (a company has at most three * profiles); any extra collapse into a `+N` chip. */ export function ProfileChips({ profiles, max = 3, }: { profiles: CompanyProfile[]; max?: number; }) { if (!profiles.length) { return ( No profiles ); } const shown = profiles.slice(0, max); const extra = profiles.length - shown.length; return ( {shown.map((profile) => ( {humanize(profile.type)} · {profile.reference} ))} {extra > 0 ? ( +{extra} ) : null} ); } export function ProfileTypeBadge({ type }: { type: ProfileType }) { return ( {humanize(type)} ); } export function ProfileStatusBadge({ status }: { status: ProfileStatus }) { return ( {status} ); } const BOOKING_STATUS_COLOR: Record = { DRAFT: "gray", SUBMITTED: "yellow", PENDING_APPROVAL: "yellow", APPROVED: "cyan", PAID: "edr-green", IN_TRANSIT: "blue", COMPLETED: "indigo", REJECTED: "red", CANCELLED: "red", }; export function BookingStatusBadge({ status }: { status: CustomerBookingStatus }) { return ( {humanize(status)} ); } const PAYMENT_STATUS_COLOR: Record = { "action-required": "orange", processing: "yellow", success: "edr-green", failed: "red", canceled: "gray", refunded: "grape", }; export function PaymentStatusBadge({ status }: { status: CustomerPaymentStatus }) { return ( {humanize(status)} ); } /** * Inline approval action buttons for a profile row. * Transitions: pending → approve/reject | active → suspend | suspended → reactivate/blacklist | blacklisted → reinstate */ export function ProfileApprovalActions({ profileId, status, }: { profileId: string; status: ProfileStatus; }) { const { mutate, isPending } = useMutation( api.customers.setProfileStatus.mutationOptions(), ); const act = (next: ProfileStatus) => mutate({ profileId, status: next }); if (status === "pending") { return ( ); } if (status === "active") { return ( ); } if (status === "suspended") { return ( ); } if (status === "blacklisted") { return ( ); } return null; }