mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 08:20:58 +00:00
80 lines
2.0 KiB
TypeScript
80 lines
2.0 KiB
TypeScript
import type { BookingApprovalStep, BookingStatus } from "@/types/booking";
|
|
import { getNextPendingApprovalStep } from "@/features/bookings/booking-actions.config";
|
|
|
|
export interface ApprovalProgressSummary {
|
|
label: string;
|
|
detail: string;
|
|
complete: boolean;
|
|
}
|
|
|
|
/** Compact approval chain summary for list rows and badges. */
|
|
export function formatApprovalProgress(
|
|
status: BookingStatus | string,
|
|
steps?: BookingApprovalStep[] | null,
|
|
): ApprovalProgressSummary {
|
|
const sorted = [...(steps ?? [])].sort((a, b) => a.stepOrder - b.stepOrder);
|
|
|
|
if (sorted.length === 0) {
|
|
if (status === "SUBMITTED") {
|
|
return {
|
|
label: "Awaiting accept",
|
|
detail: "Staff must accept intake",
|
|
complete: false,
|
|
};
|
|
}
|
|
if (
|
|
status === "PENDING_APPROVAL" ||
|
|
status === "APPROVED_PENDING_SIGNATURE"
|
|
) {
|
|
return {
|
|
label: "No steps",
|
|
detail: "Approval chain not started",
|
|
complete: false,
|
|
};
|
|
}
|
|
if (
|
|
[
|
|
"APPROVED",
|
|
"CONTRACT_READY",
|
|
"SIGNED_CUSTOMER",
|
|
"FULLY_EXECUTED",
|
|
"PAID",
|
|
"COMPLETED",
|
|
].includes(status)
|
|
) {
|
|
return {
|
|
label: "Approved",
|
|
detail: "Internal approval complete",
|
|
complete: true,
|
|
};
|
|
}
|
|
return { label: "—", detail: "", complete: false };
|
|
}
|
|
|
|
const approved = sorted.filter((s) => s.status === "APPROVED").length;
|
|
const total = sorted.length;
|
|
const next = getNextPendingApprovalStep(sorted);
|
|
|
|
if (!next && approved === total) {
|
|
return {
|
|
label: `${approved}/${total} done`,
|
|
detail: sorted.map((s) => `${s.requiredRole} ✓`).join(" · "),
|
|
complete: true,
|
|
};
|
|
}
|
|
|
|
if (next) {
|
|
return {
|
|
label: `${approved}/${total}`,
|
|
detail: `Next: ${next.requiredRole} (step ${next.stepOrder})`,
|
|
complete: false,
|
|
};
|
|
}
|
|
|
|
return {
|
|
label: `${approved}/${total}`,
|
|
detail: sorted.map((s) => `${s.requiredRole}: ${s.status}`).join(" · "),
|
|
complete: approved === total,
|
|
};
|
|
}
|