Files
edr-platform/apps/edr-freight-web/portal/src/features/notifications/notificationConfig.tsx
Marshal 05b13e84a8 enhance booking and contract notification systems
- 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.
2026-07-06 21:03:08 +00:00

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;
}
}