mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-05 17:43:39 +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.
83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
import { NotificationType } from "@edr/types";
|
|
import type { NotificationItemData, NotificationVisual } from "@edr/ui-common";
|
|
import {
|
|
BadgeCheck,
|
|
Bell,
|
|
CalendarClock,
|
|
FileSignature,
|
|
FileWarning,
|
|
Package,
|
|
Receipt,
|
|
} from "lucide-react";
|
|
|
|
const ICON_SIZE = 17;
|
|
|
|
/**
|
|
* Portal 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 notification looks and where clicking it goes.
|
|
*/
|
|
export function resolveNotificationVisual(
|
|
item: NotificationItemData,
|
|
): NotificationVisual {
|
|
switch (item.type) {
|
|
case NotificationType.CLEARANCE_DECISION:
|
|
return { icon: <BadgeCheck size={ICON_SIZE} />, color: "teal" };
|
|
case NotificationType.DOCUMENT_ACTION:
|
|
return { icon: <FileWarning size={ICON_SIZE} />, color: "orange" };
|
|
case NotificationType.BOOKING_STATUS:
|
|
return { icon: <Package size={ICON_SIZE} />, color: "blue" };
|
|
case NotificationType.CONTRACT_STATUS:
|
|
return { icon: <FileSignature size={ICON_SIZE} />, color: "indigo" };
|
|
case NotificationType.SCHEDULE_UPDATE:
|
|
return { icon: <CalendarClock size={ICON_SIZE} />, color: "cyan" };
|
|
case NotificationType.INVOICE_ISSUED:
|
|
return { icon: <Receipt size={ICON_SIZE} />, color: "violet" };
|
|
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 route from `type` + `data`.
|
|
* Returns `null` when there's nowhere sensible to go (item just marks read).
|
|
*/
|
|
export function resolveNotificationHref(
|
|
item: NotificationItemData,
|
|
): string | null {
|
|
if (item.link) return item.link;
|
|
const data = item.data ?? {};
|
|
switch (item.type) {
|
|
case NotificationType.INVOICE_ISSUED: {
|
|
const id = asId(data.invoiceId);
|
|
return id ? `/billing/${id}` : "/billing";
|
|
}
|
|
case NotificationType.BOOKING_STATUS: {
|
|
const id = asId(data.bookingId);
|
|
return id ? `/bookings/${id}` : null;
|
|
}
|
|
case NotificationType.CONTRACT_STATUS: {
|
|
const id = asId(data.contractId);
|
|
return id ? `/contracts/${id}` : "/contracts";
|
|
}
|
|
case NotificationType.SCHEDULE_UPDATE: {
|
|
const id = asId(data.bookingId);
|
|
return id ? `/bookings/${id}` : "/bookings/new";
|
|
}
|
|
case NotificationType.CLEARANCE_DECISION:
|
|
case NotificationType.DOCUMENT_ACTION: {
|
|
const bookingId = asId(data.bookingId);
|
|
if (bookingId) return `/bookings/${bookingId}`;
|
|
const id = asId(data.contractId);
|
|
return id ? `/contracts/${id}` : "/contracts";
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|