11import useGetZone from 'api/getZone' ;
22import HorizontalDivider from 'components/HorizontalDivider' ;
33import { useEffect , useState } from 'react' ;
4- import { FiAlertTriangle } from 'react-icons/fi' ;
5-
6- interface ZoneAlert {
7- message : string ;
8- start_time : string ;
9- end_time : string | null ;
10- alert_type : 'action' | 'informational' | string ;
11- }
4+ import { FiAlertTriangle , FiInfo } from 'react-icons/fi' ;
5+ import { ZoneMessage } from 'types' ;
126
137interface ZoneDetail {
14- zoneMessage : ZoneAlert | null ;
8+ zoneMessage : ZoneMessage | null ;
159}
1610
11+ // format date function to format date strings
12+ const formatDate = ( dateString ?: string ) => {
13+ if ( ! dateString ) {
14+ return 'N/A' ;
15+ }
16+ const date = new Date ( dateString ) ;
17+ return new Intl . DateTimeFormat ( 'en-US' , {
18+ dateStyle : 'medium' ,
19+ timeStyle : 'short' ,
20+ } ) . format ( date ) ;
21+ } ;
22+
23+ // Configuration for icons and colors based on alert type
24+ const alertTypeConfig : Record <
25+ string ,
26+ {
27+ icon : JSX . Element ;
28+ colorClass : string ;
29+ }
30+ > = {
31+ action : {
32+ icon : < FiAlertTriangle className = "inline" /> ,
33+ colorClass : 'bg-warning/10' ,
34+ } ,
35+ informational : {
36+ icon : < FiInfo className = "inline" /> ,
37+ colorClass : 'text-neutral-600 dark:text-neutral-400' ,
38+ } ,
39+ default : {
40+ icon : < FiInfo className = "inline" /> ,
41+ colorClass : 'text-neutral-600' ,
42+ } ,
43+ } ;
44+
1745export default function CurrentGridAlertsCard ( ) {
1846 const [ zoneDetails , setZoneDetails ] = useState < ZoneDetail [ ] > ( [ ] ) ;
1947 const [ loading , setLoading ] = useState ( true ) ;
2048
49+ // Fetch zone details using the custom hook
2150 const { data, isLoading : isZoneLoading } = useGetZone ( ) ;
2251
2352 useEffect ( ( ) => {
@@ -29,12 +58,7 @@ export default function CurrentGridAlertsCard() {
2958 setLoading ( true ) ;
3059 try {
3160 const zoneMessage = data . zoneMessage || null ;
32-
33- if ( zoneMessage ) {
34- setZoneDetails ( [ { zoneMessage } ] ) ;
35- } else {
36- setZoneDetails ( [ ] ) ;
37- }
61+ setZoneDetails ( zoneMessage ? [ { zoneMessage } ] : [ ] ) ;
3862 } catch ( error ) {
3963 console . error ( 'Error fetching grid state or zone details:' , error ) ;
4064 setZoneDetails ( [ ] ) ;
@@ -48,28 +72,37 @@ export default function CurrentGridAlertsCard() {
4872
4973 const isLoading = loading || isZoneLoading ;
5074
51- // Return nothing if not loading and no alerts
75+ // Nothing to show
5276 if ( ! isLoading && zoneDetails . length === 0 ) {
5377 return null ;
5478 }
5579
56- // If there are alerts, show the card
80+ // At least one alert action type
81+ const isAction = zoneDetails . some ( ( z ) => z . zoneMessage ?. alert_type === 'action' ) ;
82+
5783 return (
5884 < section >
5985 < div
6086 className = { `mb-2 rounded-2xl border ${
61- zoneDetails . some ( ( z ) => z . zoneMessage ?. alert_type === 'action' )
87+ isAction
6288 ? 'border-warning bg-warning/10 dark:border-warning/60 dark:bg-warning/20'
6389 : 'border-neutral-200 bg-white/60 dark:border-neutral-700/80 dark:bg-neutral-800/60'
6490 } p-0`}
6591 >
6692 < div className = "flex flex-col items-center gap-2 rounded-2xl bg-sunken p-4 dark:bg-sunken-dark" >
6793 { isLoading ? (
6894 < p className = "text-center text-xs" > Loading grid alerts...</ p >
69- ) : ( zoneDetails . length === 0 ? null : ( // Nothing shown when no alerts, or you can add a placeholder if you want
95+ ) : (
7096 < ul className = "w-full" >
71- { zoneDetails . map ( ( { zoneMessage } , index ) =>
72- zoneMessage ? (
97+ { zoneDetails . map ( ( { zoneMessage } , index ) => {
98+ if ( ! zoneMessage ) {
99+ return null ;
100+ }
101+
102+ const alertConfig = alertTypeConfig [ zoneMessage . alert_type ?? 'default' ] ;
103+ const [ title , ...rest ] = zoneMessage . message . split ( '\n' ) ;
104+
105+ return (
73106 < li
74107 key = { `${ zoneMessage . start_time } -${
75108 zoneMessage . end_time ?? 'no-end'
@@ -90,8 +123,10 @@ export default function CurrentGridAlertsCard() {
90123 wordWrap : 'break-word' ,
91124 } }
92125 >
93- < FiAlertTriangle className = "inline" /> { ' ' }
94- { zoneMessage . message . split ( '\n' ) [ 0 ] }
126+ { alertConfig . icon } { ' ' }
127+ < span className = { `font-semibold ${ alertConfig . colorClass } ` } >
128+ { title }
129+ </ span >
95130 </ div >
96131 < div
97132 style = { {
@@ -101,12 +136,14 @@ export default function CurrentGridAlertsCard() {
101136 fontSize : 12 ,
102137 fontFamily : 'Inter' ,
103138 fontWeight : '400' ,
104- lineHeight : 4 ,
139+ lineHeight : 2 ,
105140 wordWrap : 'break-word' ,
106141 } }
107142 >
108- From: { zoneMessage . start_time }
109- { zoneMessage . end_time && < > — To: { zoneMessage . end_time } </ > }
143+ From: { formatDate ( zoneMessage . start_time ) }
144+ { zoneMessage . end_time && (
145+ < > — To: { formatDate ( zoneMessage . end_time ) } </ >
146+ ) }
110147 </ div >
111148 < div className = "flex items-center justify-between font-bold" >
112149 < span className = "text-xs uppercase opacity-70" >
@@ -126,13 +163,13 @@ export default function CurrentGridAlertsCard() {
126163 wordWrap : 'break-word' ,
127164 } }
128165 >
129- { zoneMessage . message . split ( '\n' ) . slice ( 1 ) . join ( '\n' ) }
166+ { rest . join ( '\n' ) }
130167 </ div >
131168 </ li >
132- ) : null
133- ) }
169+ ) ;
170+ } ) }
134171 </ ul >
135- ) ) }
172+ ) }
136173 </ div >
137174 </ div >
138175 </ section >
0 commit comments