11import { AlertTriangle , OctagonX , Clock , MapPin } from 'lucide-react' ;
2- import Dialog , { DialogHeader , DialogContent } from './Dialog' ;
2+ import Dialog , { DialogHeader , DialogContent , InfoCard , Badge } from './Dialog' ;
33import { type Alert , getSeverityColors , formatHumanTime } from './types' ;
44
55interface AlertDetailsDialogProps {
@@ -39,112 +39,128 @@ const formatDetails = (details: string): React.ReactNode => {
3939 } ) ;
4040} ;
4141
42+ const getSeverityBadgeVariant = ( severity : Alert [ 'severity' ] ) : 'warning' | 'critical' | 'info' => {
43+ switch ( severity ) {
44+ case 'CRITICAL' :
45+ return 'critical' ;
46+ case 'WARNING' :
47+ return 'warning' ;
48+ default :
49+ return 'info' ;
50+ }
51+ } ;
52+
4253export default function AlertDetailsDialog ( { alert, onClose } : AlertDetailsDialogProps ) {
4354 const colors = getSeverityColors ( alert . severity ) ;
4455 const isCritical = alert . severity === 'CRITICAL' ;
56+ const cardVariant = isCritical ? 'danger' : 'warning' ;
4557
4658 return (
4759 < Dialog onClose = { onClose } maxWidth = "2xl" >
4860 < DialogHeader onClose = { onClose } >
49- < div className = "flex items-center space-x-3" >
61+ < div
62+ className = { `${ isCritical ? 'bg-red-100' : 'bg-yellow-100' } rounded-lg w-11 h-11 flex items-center justify-center flex-shrink-0` }
63+ >
5064 { isCritical ? (
5165 < OctagonX className = { `h-6 w-6 ${ colors . icon } ` } />
5266 ) : (
5367 < AlertTriangle className = { `h-6 w-6 ${ colors . icon } ` } />
5468 ) }
55- < div className = "flex-1 min-w-0" >
56- < h2 className = "text-lg sm:text-xl font-semibold text-stone-800 leading-tight" >
57- { alert . title }
58- </ h2 >
59- < div className = "flex items-center flex-wrap gap-2 mt-1" >
60- < span
61- className = { `px-2 py-0.5 text-xs font-medium rounded-full border ${ colors . badge } ` }
62- >
63- { alert . severity . toLowerCase ( ) }
64- </ span >
65- { alert . impact && (
66- < span className = "px-2 py-0.5 text-xs font-medium rounded-full bg-stone-100 text-stone-700 border border-stone-200 capitalize" >
67- { alert . impact } impact
68- </ span >
69- ) }
70- { alert . type && (
71- < span className = "text-xs text-stone-500 capitalize" > { alert . type } alert</ span >
72- ) }
73- </ div >
69+ </ div >
70+ < div className = "flex-1 min-w-0" >
71+ < h2 className = "text-lg font-bold text-stone-800 leading-tight mb-2" > { alert . title } </ h2 >
72+ < div className = "flex items-center flex-wrap gap-2" >
73+ < Badge variant = { getSeverityBadgeVariant ( alert . severity ) } >
74+ { alert . severity . toLowerCase ( ) }
75+ </ Badge >
76+ { alert . impact && < Badge variant = "impact" > { alert . impact } impact</ Badge > }
77+ { alert . type && < Badge variant = "muted" > { alert . type } alert</ Badge > }
7478 </ div >
7579 </ div >
7680 </ DialogHeader >
7781
7882 < DialogContent >
79- < div className = "space-y-4 " >
83+ < div className = "space-y-3 " >
8084 { /* Main Description */ }
81- < div className = { `${ colors . bg } border ${ colors . border } rounded-lg p-4` } >
82- < div className = { `${ colors . text } text-sm leading-relaxed` } >
85+ < InfoCard variant = { cardVariant } >
86+ < div
87+ className = { `text-sm leading-relaxed ${ isCritical ? 'text-red-800' : 'text-yellow-800' } ` }
88+ >
8389 { alert . details ? formatDetails ( alert . details ) : alert . description }
8490 </ div >
85- </ div >
91+ </ InfoCard >
8692
8793 { /* Timing Information */ }
8894 { ( alert . startTime || alert . expectedEnd ) && (
89- < div className = "bg-stone-50 border border-stone-200 rounded-lg p-4" >
90- < div className = "flex items-start space-x-2 " >
91- < Clock className = "h-4 w-4 text-stone-500 mt-0.5 flex-shrink-0" />
95+ < InfoCard >
96+ < div className = "flex items-start gap-3 " >
97+ < Clock className = "h-5 w-5 text-stone-400 mt-0.5 flex-shrink-0" />
9298 < div className = "flex-1" >
93- < h3 className = "text-sm font-medium text-stone-700 mb-2" > Timing</ h3 >
99+ < div className = "text-[11px] font-semibold text-stone-500 uppercase tracking-wide mb-2" >
100+ Timing
101+ </ div >
94102 < div className = "grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm" >
95103 { alert . startTime && (
96104 < div >
97- < span className = "text-stone-500 text-xs uppercase tracking-wide block" >
105+ < span className = "text-stone-400 text-xs uppercase tracking-wide block mb-0.5 " >
98106 Started
99107 </ span >
100- < span className = "text-stone-700" > { formatHumanTime ( alert . startTime ) } </ span >
108+ < span className = "text-stone-800 font-medium" >
109+ { formatHumanTime ( alert . startTime ) }
110+ </ span >
101111 </ div >
102112 ) }
103113 { alert . expectedEnd && (
104114 < div >
105- < span className = "text-stone-500 text-xs uppercase tracking-wide block" >
115+ < span className = "text-stone-400 text-xs uppercase tracking-wide block mb-0.5 " >
106116 Expected End
107117 </ span >
108- < span className = "text-stone-700" > { formatHumanTime ( alert . expectedEnd ) } </ span >
118+ < span className = "text-stone-800 font-medium" >
119+ { formatHumanTime ( alert . expectedEnd ) }
120+ </ span >
109121 </ div >
110122 ) }
111123 </ div >
112124 </ div >
113125 </ div >
114- </ div >
126+ </ InfoCard >
115127 ) }
116128
117129 { /* Location Information */ }
118130 { ( alert . location || alert . locationDescription ) && (
119- < div className = "bg-stone-50 border border-stone-200 rounded-lg p-4" >
120- < div className = "flex items-start space-x-2 " >
121- < MapPin className = "h-4 w-4 text-stone-500 mt-0.5 flex-shrink-0" />
131+ < InfoCard >
132+ < div className = "flex items-start gap-3 " >
133+ < MapPin className = "h-5 w-5 text-stone-400 mt-0.5 flex-shrink-0" />
122134 < div className = "flex-1" >
123- < h3 className = "text-sm font-medium text-stone-700 mb-2" > Location</ h3 >
135+ < div className = "text-[11px] font-semibold text-stone-500 uppercase tracking-wide mb-2" >
136+ Location
137+ </ div >
124138 < div className = "space-y-2 text-sm" >
125139 { alert . locationDescription && (
126- < p className = "text-stone-700 " > { alert . locationDescription } </ p >
140+ < p className = "text-stone-800 font-medium " > { alert . locationDescription } </ p >
127141 ) }
128142 { alert . location && (
129143 < a
130144 href = { `https://www.google.com/maps/search/?api=1&query=${ encodeURIComponent ( alert . location ) } ` }
131145 target = "_blank"
132146 rel = "noopener noreferrer"
133- className = "text-blue-600 hover:text-blue-700 underline text-xs "
147+ className = "text-blue-600 hover:text-blue-700 text-sm inline-flex items-center gap-1 "
134148 >
135- View on map
149+ View on map →
136150 </ a >
137151 ) }
138152 </ div >
139153 </ div >
140154 </ div >
141- </ div >
155+ </ InfoCard >
142156 ) }
143157
144158 { /* Additional Metadata */ }
145159 { alert . metadata && Object . keys ( alert . metadata ) . length > 0 && (
146- < div className = "bg-stone-50 border border-stone-200 rounded-lg p-4" >
147- < h3 className = "text-sm font-medium text-stone-700 mb-2" > Additional Details</ h3 >
160+ < InfoCard >
161+ < div className = "text-[11px] font-semibold text-stone-500 uppercase tracking-wide mb-3" >
162+ Additional Details
163+ </ div >
148164 < div className = "grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm" >
149165 { Object . entries ( alert . metadata ) . map ( ( [ key , value ] ) => {
150166 if ( value === null || value === undefined || value === '' ) return null ;
@@ -155,15 +171,15 @@ export default function AlertDetailsDialog({ alert, onClose }: AlertDetailsDialo
155171 . replace ( / ^ \w / , ( c ) => c . toUpperCase ( ) ) ;
156172 return (
157173 < div key = { key } >
158- < span className = "text-stone-500 text-xs uppercase tracking-wide block" >
174+ < span className = "text-stone-400 text-xs uppercase tracking-wide block mb-0.5 " >
159175 { formattedKey }
160176 </ span >
161- < span className = "text-stone-700 " > { String ( value ) } </ span >
177+ < span className = "text-stone-800 font-medium " > { String ( value ) } </ span >
162178 </ div >
163179 ) ;
164180 } ) }
165181 </ div >
166- </ div >
182+ </ InfoCard >
167183 ) }
168184 </ div >
169185 </ DialogContent >
0 commit comments