mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-31 10:47:38 +00:00
- Added detailed logging for socket connection events in useBookingWindowSocket. - Introduced new notification types for contract status and schedule updates. - Updated notification visuals to include new icons for contract status. - Enhanced notification href resolution for contract status and schedule updates. - Implemented booking lifecycle notifier service for customer and staff notifications. - Created contract notifier service for managing contract lifecycle notifications. - Added end-to-end tests for booking window socket functionality.
74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
import { NotificationType } from "@edr/types";
|
|
import type { NotificationItemData, NotificationVisual } from "@edr/ui-common";
|
|
import { Bell, ClipboardCheck, FileSignature, Inbox, Wallet } from "lucide-react";
|
|
|
|
const ICON_SIZE = 17;
|
|
|
|
/**
|
|
* Backoffice notification registry. Maps a notification `type` → icon + Mantine
|
|
* color, and `type`/`data` → an in-app deep link. This is the single place to
|
|
* customize how each staff-facing notification looks and where it goes.
|
|
*/
|
|
export function resolveNotificationVisual(
|
|
item: NotificationItemData,
|
|
): NotificationVisual {
|
|
switch (item.type) {
|
|
case NotificationType.REQUEST_SUBMITTED:
|
|
return { icon: <Inbox size={ICON_SIZE} />, color: "blue" };
|
|
case NotificationType.PAYMENT_RECEIVED:
|
|
return { icon: <Wallet size={ICON_SIZE} />, color: "teal" };
|
|
case NotificationType.CLEARANCE_REVIEW:
|
|
return { icon: <ClipboardCheck size={ICON_SIZE} />, color: "orange" };
|
|
case NotificationType.CONTRACT_STATUS:
|
|
return { icon: <FileSignature size={ICON_SIZE} />, color: "indigo" };
|
|
default:
|
|
return { icon: <Bell size={ICON_SIZE} />, color: "edr-green" };
|
|
}
|
|
}
|
|
|
|
function asId(value: unknown): string | undefined {
|
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
}
|
|
|
|
/**
|
|
* Resolve where clicking a notification navigates. Prefers an explicit
|
|
* server-provided `link`, else derives a `/dashboard/*` route from `type` +
|
|
* `data`. Returns `null` when there's nowhere sensible to go.
|
|
*/
|
|
export function resolveNotificationHref(
|
|
item: NotificationItemData,
|
|
): string | null {
|
|
if (item.link) return item.link;
|
|
const data = item.data ?? {};
|
|
switch (item.type) {
|
|
case NotificationType.REQUEST_SUBMITTED: {
|
|
const bookingId = asId(data.bookingId);
|
|
if (bookingId) return `/dashboard/booking-requests/${bookingId}`;
|
|
const contractId = asId(data.contractId);
|
|
if (contractId) return `/dashboard/contract-requests/${contractId}`;
|
|
return "/dashboard/booking-requests";
|
|
}
|
|
case NotificationType.PAYMENT_RECEIVED: {
|
|
const bookingId = asId(data.bookingId);
|
|
if (bookingId) return `/dashboard/bookings/${bookingId}/clearance`;
|
|
const id = asId(data.customerId);
|
|
return id ? `/dashboard/customers/${id}` : "/dashboard/customers";
|
|
}
|
|
case NotificationType.CLEARANCE_REVIEW: {
|
|
const bookingId = asId(data.bookingId);
|
|
if (bookingId) return `/dashboard/bookings/${bookingId}/clearance`;
|
|
const contractId = asId(data.contractId);
|
|
if (contractId) return `/dashboard/contracts/clearance/${contractId}`;
|
|
return "/dashboard/arrival-queue";
|
|
}
|
|
case NotificationType.CONTRACT_STATUS: {
|
|
const contractId = asId(data.contractId);
|
|
return contractId
|
|
? `/dashboard/contract-requests/${contractId}`
|
|
: "/dashboard/contract-requests";
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|