From da9f8799d8f687fed4367fb867d80e5c5675cc2a Mon Sep 17 00:00:00 2001 From: Zacheus Date: Tue, 2 Jun 2026 09:29:24 +0100 Subject: [PATCH 1/2] chore: implemented new UI changes across brifges reports and footer summary --- frontend/src/components/AssetStatusBadge.tsx | 157 ++++++++ frontend/src/components/BridgeNotesPanel.tsx | 325 ++++++++++++++++ frontend/src/components/BridgeStatusCard.tsx | 18 +- .../src/components/ReportQuickActions.tsx | 248 ++++++++++++ .../src/components/TableFooterSummary.tsx | 197 ++++++++++ frontend/src/hooks/useBridgeNotes.ts | 92 +++++ frontend/src/pages/Bridges.tsx | 9 + frontend/src/pages/Reports.tsx | 366 ++++++++++++++---- 8 files changed, 1316 insertions(+), 96 deletions(-) create mode 100644 frontend/src/components/AssetStatusBadge.tsx create mode 100644 frontend/src/components/BridgeNotesPanel.tsx create mode 100644 frontend/src/components/ReportQuickActions.tsx create mode 100644 frontend/src/components/TableFooterSummary.tsx create mode 100644 frontend/src/hooks/useBridgeNotes.ts diff --git a/frontend/src/components/AssetStatusBadge.tsx b/frontend/src/components/AssetStatusBadge.tsx new file mode 100644 index 00000000..15104bf4 --- /dev/null +++ b/frontend/src/components/AssetStatusBadge.tsx @@ -0,0 +1,157 @@ +/** + * AssetStatusBadge (#495) + * + * Standardised status badge for assets across all views. + * Variants : healthy | warning | critical | unknown | paused | syncing + * Sizes : sm | md | lg + * Dot mode : renders a coloured dot instead of a pill (dense tables) + */ + +export type AssetStatus = + | "healthy" + | "warning" + | "critical" + | "unknown" + | "paused" + | "syncing"; + +export type BadgeSize = "sm" | "md" | "lg"; + +export interface AssetStatusBadgeProps { + status: AssetStatus; + /** Override the default human-readable label */ + label?: string; + size?: BadgeSize; + /** Dot-only mode (useful in dense tables) */ + dot?: boolean; + className?: string; +} + +interface StatusConfig { + label: string; + colours: string; + dotColour: string; + ariaDescription: string; + animate?: boolean; +} + +const STATUS_CONFIG: Record = { + healthy: { + label: "Healthy", + colours: "bg-green-500/15 text-green-400 border-green-500/30", + dotColour: "bg-green-400", + ariaDescription: "Asset is healthy", + }, + warning: { + label: "Warning", + colours: "bg-yellow-500/15 text-yellow-400 border-yellow-500/30", + dotColour: "bg-yellow-400", + ariaDescription: "Asset requires attention", + }, + critical: { + label: "Critical", + colours: "bg-red-500/15 text-red-400 border-red-500/30", + dotColour: "bg-red-400", + ariaDescription: "Asset is in a critical state", + animate: true, + }, + unknown: { + label: "Unknown", + colours: "bg-gray-500/15 text-gray-400 border-gray-500/30", + dotColour: "bg-gray-500", + ariaDescription: "Asset status is unknown", + }, + paused: { + label: "Paused", + colours: "bg-blue-500/15 text-blue-400 border-blue-500/30", + dotColour: "bg-blue-400", + ariaDescription: "Asset monitoring is paused", + }, + syncing: { + label: "Syncing", + colours: "bg-purple-500/15 text-purple-400 border-purple-500/30", + dotColour: "bg-purple-400", + ariaDescription: "Asset is currently syncing", + animate: true, + }, +}; + +const SIZE_CLASSES: Record = { + sm: { badge: "gap-1 px-1.5 py-0.5 text-xs", dot: "h-1.5 w-1.5" }, + md: { badge: "gap-1.5 px-2.5 py-1 text-xs", dot: "h-2 w-2" }, + lg: { badge: "gap-2 px-3 py-1.5 text-sm", dot: "h-2.5 w-2.5" }, +}; + +export function AssetStatusBadge({ + status, + label, + size = "md", + dot = false, + className = "", +}: AssetStatusBadgeProps) { + const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.unknown; + const sizes = SIZE_CLASSES[size]; + const displayLabel = label ?? config.label; + + if (dot) { + return ( + + {config.animate && ( +