mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-03 02:13:22 +00:00
521 lines
14 KiB
TypeScript
521 lines
14 KiB
TypeScript
import type {
|
||
LocationOption,
|
||
VendorDropdownItem,
|
||
WorkOrderDetail,
|
||
WorkOrderUser,
|
||
} from "@/domain/work-orders/types/work-order";
|
||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||
import type { WorkOrdersListParams } from "@/domain/work-orders/types/work-order-list";
|
||
import { MOCK_DISPATCHER_USERS } from "@/domain/work-orders/mocks/dispatcher-filter-mock-data";
|
||
import {
|
||
MOCK_WO_WIZARD_LOCATIONS,
|
||
MOCK_WO_WIZARD_SERVICES,
|
||
MOCK_WO_WIZARD_VENDORS,
|
||
} from "@/domain/work-orders/mocks/wo-wizard-mock-data";
|
||
import { currentWeekMonday } from "@/domain/work-orders/utils/list-week-utils";
|
||
import { deriveDayFields, isDateInWeek } from "@/domain/work-orders/utils/table-day-utils";
|
||
import { enrichTableRow } from "@/domain/work-orders/utils/table-filter-utils";
|
||
import { addDaysIso, todayIso } from "@/domain/work-orders/utils/wizard-date-utils";
|
||
|
||
export const MOCK_WO_TABLE_USERS: WorkOrderUser[] = MOCK_DISPATCHER_USERS.map(({ id, name }) => ({
|
||
id,
|
||
name,
|
||
}));
|
||
|
||
function sched(iso: string): Pick<WorkOrderTableRow, "scheduledOn" | "dayGroup" | "dayLabel"> {
|
||
const { dayGroup, dayLabel } = deriveDayFields(iso);
|
||
return { scheduledOn: iso, dayGroup, dayLabel };
|
||
}
|
||
|
||
type RowSeed = {
|
||
id: string | number;
|
||
woNumber: string;
|
||
site: string;
|
||
location: string;
|
||
locationId: string | number;
|
||
type: WorkOrderTableRow["type"];
|
||
dispatcherId: string;
|
||
dispatcherName: string;
|
||
scheduledOn?: string;
|
||
targetWeek?: string;
|
||
dueDate: string;
|
||
pm: string;
|
||
company: string;
|
||
tech: string;
|
||
techPhone: string;
|
||
apptStart: string;
|
||
apptEnd: string;
|
||
apptTime: string;
|
||
status: WorkOrderTableRow["status"];
|
||
docStatus: WorkOrderTableRow["docStatus"];
|
||
pocName: string;
|
||
pocPhone: string;
|
||
pocNotes: string;
|
||
rescheduleCount: number;
|
||
carriedOver: number;
|
||
originalWeek: string;
|
||
originalDate: string;
|
||
scheduleWeekOnly: boolean;
|
||
mediaCount: number;
|
||
title?: string;
|
||
priority?: string;
|
||
};
|
||
|
||
function buildRow(seed: RowSeed): WorkOrderTableRow {
|
||
const scheduledOn = seed.scheduledOn ?? "";
|
||
const dayFields = scheduledOn ? sched(scheduledOn) : deriveDayFields("");
|
||
return enrichTableRow({
|
||
title: seed.title ?? `${seed.type || "Work Order"} — ${seed.site}`,
|
||
priority: seed.priority ?? "Sev 3",
|
||
...seed,
|
||
...dayFields,
|
||
scheduledOn,
|
||
targetWeek: seed.targetWeek ?? "",
|
||
isPastDue: false,
|
||
});
|
||
}
|
||
|
||
function buildMockRows(): WorkOrderTableRow[] {
|
||
const mon = currentWeekMonday();
|
||
const tue = addDaysIso(mon, 1);
|
||
const wed = addDaysIso(mon, 2);
|
||
const thu = addDaysIso(mon, 3);
|
||
const fri = addDaysIso(mon, 4);
|
||
const yesterday = addDaysIso(todayIso(), -1);
|
||
|
||
const sarah = MOCK_DISPATCHER_USERS[0];
|
||
const alyssa = MOCK_DISPATCHER_USERS[1];
|
||
const derek = MOCK_DISPATCHER_USERS[2];
|
||
const morgan = MOCK_DISPATCHER_USERS[3];
|
||
|
||
return [
|
||
buildRow({
|
||
id: "mock-wo-1",
|
||
woNumber: "20260623001",
|
||
site: "CHI-1042",
|
||
location: "Chicago Loop",
|
||
locationId: "mock-loc-1",
|
||
type: "PM",
|
||
dispatcherId: String(sarah.id),
|
||
dispatcherName: sarah.name,
|
||
...sched(mon),
|
||
dueDate: fri,
|
||
pm: "HVAC — Quarterly PM",
|
||
company: "Midwest HVAC Co.",
|
||
tech: "Mike Torres",
|
||
techPhone: "(312) 555-0198",
|
||
apptStart: "09:00",
|
||
apptEnd: "11:00",
|
||
apptTime: "09:00 – 11:00",
|
||
status: "Scheduled",
|
||
docStatus: "No",
|
||
pocName: "Maria Gonzalez",
|
||
pocPhone: "(312) 555-0142",
|
||
pocNotes: "Loading dock B",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-2",
|
||
woNumber: "20260623002",
|
||
site: "IND-2208",
|
||
location: "Indianapolis North",
|
||
locationId: "mock-loc-2",
|
||
type: "Emergency",
|
||
dispatcherId: String(alyssa.id),
|
||
dispatcherName: alyssa.name,
|
||
...sched(tue),
|
||
dueDate: tue,
|
||
pm: "Plumbing — Leak repair",
|
||
company: "Great Lakes Plumbing",
|
||
tech: "Jen Walsh",
|
||
techPhone: "(317) 555-4412",
|
||
apptStart: "08:00",
|
||
apptEnd: "",
|
||
apptTime: "08:00",
|
||
status: "On Site",
|
||
docStatus: "No",
|
||
pocName: "Chris Bennett",
|
||
pocPhone: "(317) 555-2208",
|
||
pocNotes: "",
|
||
rescheduleCount: 1,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 3,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-3",
|
||
woNumber: "20260623003",
|
||
site: "MIL-3315",
|
||
location: "Milwaukee West",
|
||
locationId: "mock-loc-3",
|
||
type: "Reactive",
|
||
dispatcherId: String(derek.id),
|
||
dispatcherName: derek.name,
|
||
...sched(wed),
|
||
dueDate: thu,
|
||
pm: "Electrical — Panel inspection",
|
||
company: "SparkLine Electric",
|
||
tech: "Pat Nguyen",
|
||
techPhone: "",
|
||
apptStart: "13:00",
|
||
apptEnd: "15:00",
|
||
apptTime: "13:00 – 15:00",
|
||
status: "In Progress",
|
||
docStatus: "Yes",
|
||
pocName: "Taylor Brooks",
|
||
pocPhone: "(414) 555-3315",
|
||
pocNotes: "Badge required at front desk",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-4",
|
||
woNumber: "20260623004",
|
||
site: "CHI-1042",
|
||
location: "Chicago Loop",
|
||
locationId: "mock-loc-1",
|
||
type: "Add-On",
|
||
dispatcherId: String(morgan.id),
|
||
dispatcherName: morgan.name,
|
||
...sched(thu),
|
||
dueDate: fri,
|
||
pm: "Roof — Membrane patch",
|
||
company: "Midwest HVAC Co.",
|
||
tech: "Mike Torres",
|
||
techPhone: "(312) 555-0198",
|
||
apptStart: "10:30",
|
||
apptEnd: "12:00",
|
||
apptTime: "10:30 – 12:00",
|
||
status: "Pending",
|
||
docStatus: "NN",
|
||
pocName: "Maria Gonzalez",
|
||
pocPhone: "(312) 555-0142",
|
||
pocNotes: "",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-5",
|
||
woNumber: "20260623005",
|
||
site: "IND-2208",
|
||
location: "Indianapolis North",
|
||
locationId: "mock-loc-2",
|
||
type: "PM",
|
||
dispatcherId: "",
|
||
dispatcherName: "",
|
||
...sched(fri),
|
||
dueDate: fri,
|
||
pm: "HVAC — Quarterly PM",
|
||
company: "",
|
||
tech: "",
|
||
techPhone: "",
|
||
apptStart: "",
|
||
apptEnd: "",
|
||
apptTime: "",
|
||
status: "Incomplete",
|
||
docStatus: "No",
|
||
pocName: "",
|
||
pocPhone: "",
|
||
pocNotes: "",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-6",
|
||
woNumber: "20260623006",
|
||
site: "MIL-3315",
|
||
location: "Milwaukee West",
|
||
locationId: "mock-loc-3",
|
||
type: "Overdue",
|
||
dispatcherId: String(sarah.id),
|
||
dispatcherName: sarah.name,
|
||
...sched(mon),
|
||
dueDate: yesterday,
|
||
pm: "Plumbing — Leak repair",
|
||
company: "Great Lakes Plumbing",
|
||
tech: "Jen Walsh",
|
||
techPhone: "(317) 555-4412",
|
||
apptStart: "07:00",
|
||
apptEnd: "09:00",
|
||
apptTime: "07:00 – 09:00",
|
||
status: "Scheduled",
|
||
docStatus: "No",
|
||
pocName: "Taylor Brooks",
|
||
pocPhone: "(414) 555-3315",
|
||
pocNotes: "",
|
||
rescheduleCount: 2,
|
||
carriedOver: 1,
|
||
originalWeek: "",
|
||
originalDate: yesterday,
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-7",
|
||
woNumber: "20260623007",
|
||
site: "CHI-1042",
|
||
location: "Chicago Loop",
|
||
locationId: "mock-loc-1",
|
||
type: "Reactive",
|
||
dispatcherId: String(alyssa.id),
|
||
dispatcherName: alyssa.name,
|
||
scheduledOn: "",
|
||
targetWeek: mon,
|
||
dueDate: wed,
|
||
pm: "Electrical — Panel inspection",
|
||
company: "SparkLine Electric",
|
||
tech: "Pat Nguyen",
|
||
techPhone: "",
|
||
apptStart: "",
|
||
apptEnd: "",
|
||
apptTime: "",
|
||
status: "Incomplete",
|
||
docStatus: "No",
|
||
pocName: "Maria Gonzalez",
|
||
pocPhone: "(312) 555-0142",
|
||
pocNotes: "Week-only target",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: mon,
|
||
originalDate: "",
|
||
scheduleWeekOnly: true,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-8",
|
||
woNumber: "20260623008",
|
||
site: "IND-2208",
|
||
location: "Indianapolis North",
|
||
locationId: "mock-loc-2",
|
||
type: "PM",
|
||
dispatcherId: String(derek.id),
|
||
dispatcherName: derek.name,
|
||
scheduledOn: "",
|
||
targetWeek: "",
|
||
dueDate: thu,
|
||
pm: "HVAC — Quarterly PM",
|
||
company: "Midwest HVAC Co.",
|
||
tech: "Mike Torres",
|
||
techPhone: "(312) 555-0198",
|
||
apptStart: "",
|
||
apptEnd: "",
|
||
apptTime: "",
|
||
status: "Pending",
|
||
docStatus: "No",
|
||
pocName: "Chris Bennett",
|
||
pocPhone: "(317) 555-2208",
|
||
pocNotes: "",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-9",
|
||
woNumber: "20260623009",
|
||
site: "MIL-3315",
|
||
location: "Milwaukee West",
|
||
locationId: "mock-loc-3",
|
||
type: "PM",
|
||
dispatcherId: String(morgan.id),
|
||
dispatcherName: morgan.name,
|
||
...sched(wed),
|
||
dueDate: fri,
|
||
pm: "Roof — Membrane patch",
|
||
company: "SparkLine Electric",
|
||
tech: "Pat Nguyen",
|
||
techPhone: "",
|
||
apptStart: "14:00",
|
||
apptEnd: "16:00",
|
||
apptTime: "14:00 – 16:00",
|
||
status: "En Route",
|
||
docStatus: "No",
|
||
pocName: "Taylor Brooks",
|
||
pocPhone: "(414) 555-3315",
|
||
pocNotes: "",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 0,
|
||
}),
|
||
buildRow({
|
||
id: "mock-wo-10",
|
||
woNumber: "20260623010",
|
||
site: "CHI-1042",
|
||
location: "Chicago Loop",
|
||
locationId: "mock-loc-1",
|
||
type: "Reactive",
|
||
dispatcherId: String(sarah.id),
|
||
dispatcherName: sarah.name,
|
||
...sched(tue),
|
||
dueDate: wed,
|
||
pm: "Plumbing — Leak repair",
|
||
company: "Great Lakes Plumbing",
|
||
tech: "Jen Walsh",
|
||
techPhone: "(317) 555-4412",
|
||
apptStart: "11:00",
|
||
apptEnd: "12:30",
|
||
apptTime: "11:00 – 12:30",
|
||
status: "Completed",
|
||
docStatus: "Yes",
|
||
pocName: "Maria Gonzalez",
|
||
pocPhone: "(312) 555-0142",
|
||
pocNotes: "",
|
||
rescheduleCount: 0,
|
||
carriedOver: 0,
|
||
originalWeek: "",
|
||
originalDate: "",
|
||
scheduleWeekOnly: false,
|
||
mediaCount: 2,
|
||
}),
|
||
];
|
||
}
|
||
|
||
let cachedRows: WorkOrderTableRow[] | null = null;
|
||
|
||
export function getMockWorkOrderTableRows(): WorkOrderTableRow[] {
|
||
if (!cachedRows) {
|
||
cachedRows = buildMockRows();
|
||
}
|
||
return cachedRows;
|
||
}
|
||
|
||
function rowMatchesSearch(row: WorkOrderTableRow, search: string): boolean {
|
||
const q = search.trim().toLowerCase();
|
||
if (!q) {
|
||
return true;
|
||
}
|
||
const haystack = [
|
||
row.site,
|
||
row.location,
|
||
row.woNumber,
|
||
row.type,
|
||
row.dispatcherName,
|
||
row.pm,
|
||
row.company,
|
||
row.tech,
|
||
row.status,
|
||
row.title,
|
||
]
|
||
.join(" ")
|
||
.toLowerCase();
|
||
return haystack.includes(q);
|
||
}
|
||
|
||
export function getMockWorkOrdersList(params: WorkOrdersListParams = {}): {
|
||
items: WorkOrderTableRow[];
|
||
totalCount: number;
|
||
page: number;
|
||
pageSize: number;
|
||
} {
|
||
let items = getMockWorkOrderTableRows();
|
||
|
||
if (params.search) {
|
||
items = items.filter((row) => rowMatchesSearch(row, params.search!));
|
||
}
|
||
|
||
if (params.type) {
|
||
items = items.filter((row) => row.type === params.type);
|
||
}
|
||
|
||
if (params.dateFrom && params.dateTo) {
|
||
const weekMonday = params.dateFrom;
|
||
items = items.filter((row) => {
|
||
if (row.scheduledOn) {
|
||
return row.scheduledOn >= params.dateFrom! && row.scheduledOn <= params.dateTo!;
|
||
}
|
||
if (row.targetWeek) {
|
||
return isDateInWeek(row.targetWeek, weekMonday);
|
||
}
|
||
return true;
|
||
});
|
||
}
|
||
|
||
const page = params.page ?? 1;
|
||
const pageSize = params.pageSize ?? items.length;
|
||
|
||
return {
|
||
items,
|
||
totalCount: items.length,
|
||
page,
|
||
pageSize,
|
||
};
|
||
}
|
||
|
||
export function getMockWorkOrderTableRow(id: string | number): WorkOrderTableRow | undefined {
|
||
return getMockWorkOrderTableRows().find((row) => String(row.id) === String(id));
|
||
}
|
||
|
||
export function buildMockWorkOrderDetailFromTableRow(row: WorkOrderTableRow): WorkOrderDetail {
|
||
return {
|
||
id: row.id,
|
||
internalWONumber: row.woNumber,
|
||
workOrderNumber: row.woNumber,
|
||
title: row.title,
|
||
location: row.location,
|
||
locationId: String(row.locationId),
|
||
locationZip: "",
|
||
assignedTo: row.dispatcherName,
|
||
dueDate: row.dueDate,
|
||
createdDate: addDaysIso(todayIso(), -7),
|
||
createdDateFull: new Date().toISOString(),
|
||
description: [
|
||
row.pocNotes && `POC notes: ${row.pocNotes}`,
|
||
row.pocName && `POC: ${row.pocName} · ${row.pocPhone}`,
|
||
row.apptTime && row.apptTime !== "—" && `Appt: ${row.apptTime}`,
|
||
row.company && `Vendor: ${row.company}`,
|
||
]
|
||
.filter(Boolean)
|
||
.join("\n"),
|
||
priority: row.priority,
|
||
status:
|
||
row.status === "Completed" ? "Done" : row.status === "Incomplete" ? "Open" : "In Progress",
|
||
po: "",
|
||
tt: "",
|
||
problem: row.pm,
|
||
trade: "",
|
||
subTrade: "",
|
||
vendorNTE: "",
|
||
scheduledDate: row.scheduledOn,
|
||
completedDate: row.status === "Completed" ? todayIso() : "",
|
||
source: row.type,
|
||
comments: [],
|
||
auditLog: [],
|
||
dispatches: [],
|
||
};
|
||
}
|
||
|
||
export function getMockWorkOrderLocations(): LocationOption[] {
|
||
return MOCK_WO_WIZARD_LOCATIONS;
|
||
}
|
||
|
||
export function getMockWorkOrderVendors(): VendorDropdownItem[] {
|
||
return MOCK_WO_WIZARD_VENDORS;
|
||
}
|
||
|
||
export function getMockPmTypes(): string[] {
|
||
return MOCK_WO_WIZARD_SERVICES.map((s) => s.value).filter(Boolean);
|
||
}
|