Skip to content

Commit 1399cc6

Browse files
committed
Complete redesign of the dialogs
1 parent 8791c52 commit 1399cc6

File tree

5 files changed

+676
-599
lines changed

5 files changed

+676
-599
lines changed

src/components/AlertDetailsDialog.tsx

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AlertTriangle, OctagonX, Clock, MapPin } from 'lucide-react';
2-
import Dialog, { DialogHeader, DialogContent } from './Dialog';
2+
import Dialog, { DialogHeader, DialogContent, InfoCard, Badge } from './Dialog';
33
import { type Alert, getSeverityColors, formatHumanTime } from './types';
44

55
interface 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+
4253
export 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

Comments
 (0)