mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 10:28:59 +00:00
125 lines
3.7 KiB
TypeScript
125 lines
3.7 KiB
TypeScript
|
|
import { Link } from "react-router";
|
||
|
|
import { Text } from "@/components/ui/text";
|
||
|
|
import {
|
||
|
|
formatVendorPortalDateTime,
|
||
|
|
vendorPortalStatusClass,
|
||
|
|
} from "@/domain/vendor-portal/lib/status-helpers";
|
||
|
|
import type { VendorPortalDispatchDetail } from "@/domain/vendor-portal/types/vendor-portal";
|
||
|
|
import { DispatchStatusActions } from "@/app/v/[token]/dispatch/_components/dispatch-status-actions";
|
||
|
|
|
||
|
|
type DispatchSummaryCardProps = {
|
||
|
|
token: string;
|
||
|
|
data: VendorPortalDispatchDetail;
|
||
|
|
locked: boolean;
|
||
|
|
busy: boolean;
|
||
|
|
onAccept: () => void;
|
||
|
|
onStart: () => void;
|
||
|
|
onComplete: () => void;
|
||
|
|
onRequestCancel: () => void;
|
||
|
|
};
|
||
|
|
|
||
|
|
export function DispatchSummaryCard({
|
||
|
|
token,
|
||
|
|
data,
|
||
|
|
locked,
|
||
|
|
busy,
|
||
|
|
onAccept,
|
||
|
|
onStart,
|
||
|
|
onComplete,
|
||
|
|
onRequestCancel,
|
||
|
|
}: DispatchSummaryCardProps) {
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<Link to={`/v/${token}/dashboard`} className="vp-back-link">
|
||
|
|
← Back to dispatches
|
||
|
|
</Link>
|
||
|
|
|
||
|
|
<div className="vp-card">
|
||
|
|
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
|
||
|
|
<div>
|
||
|
|
<Text variant="title">{data.dispatchNumber}</Text>
|
||
|
|
<div className="vp-muted">{data.workOrder?.workerOrderTitle}</div>
|
||
|
|
</div>
|
||
|
|
<span className={vendorPortalStatusClass(data.status)}>{data.status}</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div style={{ marginTop: 12 }}>
|
||
|
|
{data.workOrder != null && Boolean(data.workOrder.internalWONumber) && (
|
||
|
|
<div className="vp-row">
|
||
|
|
<strong>WO #</strong>
|
||
|
|
<span>{data.workOrder.internalWONumber}</span>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
{Boolean(data.poNumber) && (
|
||
|
|
<div className="vp-row">
|
||
|
|
<strong>PO #</strong>
|
||
|
|
<span>{data.poNumber}</span>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
{data.nteAmount != null && (
|
||
|
|
<div className="vp-row">
|
||
|
|
<strong>NTE</strong>
|
||
|
|
<span>${Number(data.nteAmount).toFixed(2)}</span>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
<div className="vp-row">
|
||
|
|
<strong>Invoice</strong>
|
||
|
|
<span>
|
||
|
|
{data.invoiceStatus || "Not Submitted"}
|
||
|
|
{data.invoiceNumber ? ` · ${data.invoiceNumber}` : ""}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div className="vp-row">
|
||
|
|
<strong>Payment</strong>
|
||
|
|
<span>{data.paymentStatus || "Unavailable"}</span>
|
||
|
|
</div>
|
||
|
|
{Boolean(data.scheduledDate) && (
|
||
|
|
<div className="vp-row">
|
||
|
|
<strong>Scheduled</strong>
|
||
|
|
<span>{formatVendorPortalDateTime(data.scheduledDate)}</span>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{data.location != null && (
|
||
|
|
<>
|
||
|
|
<Text variant="heading" sx={{ marginTop: 2 }}>
|
||
|
|
Location
|
||
|
|
</Text>
|
||
|
|
<div>{data.location.name}</div>
|
||
|
|
<div className="vp-muted">
|
||
|
|
{[
|
||
|
|
data.location.address,
|
||
|
|
data.location.city,
|
||
|
|
data.location.state,
|
||
|
|
data.location.zipCode,
|
||
|
|
]
|
||
|
|
.filter(Boolean)
|
||
|
|
.join(", ")}
|
||
|
|
</div>
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{Boolean(data.description || data.workOrder?.description) && (
|
||
|
|
<>
|
||
|
|
<Text variant="heading" sx={{ marginTop: 2 }}>
|
||
|
|
Description
|
||
|
|
</Text>
|
||
|
|
<div>{data.description || data.workOrder?.description}</div>
|
||
|
|
</>
|
||
|
|
)}
|
||
|
|
|
||
|
|
<DispatchStatusActions
|
||
|
|
status={data.status}
|
||
|
|
locked={locked}
|
||
|
|
busy={busy}
|
||
|
|
onAccept={onAccept}
|
||
|
|
onStart={onStart}
|
||
|
|
onComplete={onComplete}
|
||
|
|
onRequestCancel={onRequestCancel}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|