@pfm-platform/alerts-ui-mui 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,528 @@
1
+ 'use strict';
2
+
3
+ var material = require('@mui/material');
4
+ var iconsMaterial = require('@mui/icons-material');
5
+ var alertsDataAccess = require('@pfm-platform/alerts-data-access');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var alertsFeature = require('@pfm-platform/alerts-feature');
8
+ var react = require('react');
9
+
10
+ // src/components/AlertList.tsx
11
+ function AlertList({
12
+ userId,
13
+ filterType,
14
+ filterSource,
15
+ title = "Alerts",
16
+ maxItems
17
+ }) {
18
+ const { data: alerts } = alertsDataAccess.useAlerts({ userId });
19
+ if (!alerts) {
20
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
21
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
22
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading alerts..." })
23
+ ] }) });
24
+ }
25
+ let filteredAlerts = alerts;
26
+ if (filterType) {
27
+ filteredAlerts = filteredAlerts.filter((alert) => alert.type === filterType);
28
+ }
29
+ if (filterSource) {
30
+ filteredAlerts = filteredAlerts.filter((alert) => alert.source_type === filterSource);
31
+ }
32
+ const displayAlerts = maxItems ? filteredAlerts.slice(0, maxItems) : filteredAlerts;
33
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
34
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
35
+ displayAlerts.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "No alerts found" }) : /* @__PURE__ */ jsxRuntime.jsx(material.List, { disablePadding: true, children: displayAlerts.map((alert, index) => /* @__PURE__ */ jsxRuntime.jsxs(
36
+ material.ListItem,
37
+ {
38
+ divider: index < displayAlerts.length - 1,
39
+ sx: { px: 0, display: "flex", flexDirection: "column", alignItems: "flex-start" },
40
+ children: [
41
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { width: "100%", display: "flex", alignItems: "center", gap: 1, mb: 0.5 }, children: [
42
+ /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { label: alert.type, size: "small", color: "primary" }),
43
+ alert.source_type && /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { label: alert.source_type, size: "small", variant: "outlined" }),
44
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { ml: "auto", display: "flex", gap: 0.5 }, children: [
45
+ alert.email_delivery && /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Email, { fontSize: "small", color: "action", titleAccess: "Email delivery" }),
46
+ alert.sms_delivery && /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Sms, { fontSize: "small", color: "action", titleAccess: "SMS delivery" })
47
+ ] })
48
+ ] }),
49
+ /* @__PURE__ */ jsxRuntime.jsx(
50
+ material.ListItemText,
51
+ {
52
+ primary: `Alert ID: ${alert.id}`,
53
+ secondary: alert.source_id ? `Source: ${alert.source_id}` : void 0,
54
+ primaryTypographyProps: { variant: "body2" },
55
+ secondaryTypographyProps: { variant: "caption" }
56
+ }
57
+ )
58
+ ]
59
+ },
60
+ alert.id
61
+ )) })
62
+ ] }) });
63
+ }
64
+ function AlertSummary({
65
+ userId,
66
+ title = "Alert Summary",
67
+ showTypes = true,
68
+ showDelivery = true,
69
+ showSources = true
70
+ }) {
71
+ const filters = alertsFeature.useAlertFilters(userId);
72
+ if (!filters) {
73
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
74
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
75
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading alerts..." })
76
+ ] }) });
77
+ }
78
+ const alertTypes = Object.keys(filters.byType);
79
+ const sourcTypes = Object.keys(filters.bySource);
80
+ const totalAlerts = filters.byDelivery.email.length + filters.byDelivery.sms.length + filters.byDelivery.both.length;
81
+ const hasData = totalAlerts > 0;
82
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
83
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
84
+ !hasData ? /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "No alerts configured" }) : /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 3, children: [
85
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
86
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Total Alerts" }),
87
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h4", fontWeight: "medium", children: totalAlerts })
88
+ ] }) }),
89
+ showTypes && alertTypes.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
90
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: [
91
+ "By Type (",
92
+ alertTypes.length,
93
+ " types)"
94
+ ] }),
95
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: alertTypes.map((type) => /* @__PURE__ */ jsxRuntime.jsx(
96
+ material.Chip,
97
+ {
98
+ label: `${type} (${filters.byType[type].length})`,
99
+ size: "small",
100
+ color: "primary",
101
+ variant: "outlined"
102
+ },
103
+ type
104
+ )) })
105
+ ] }) }),
106
+ showDelivery && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
107
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "By Delivery Method" }),
108
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", gap: 1 }, children: [
109
+ /* @__PURE__ */ jsxRuntime.jsx(
110
+ material.Chip,
111
+ {
112
+ label: `Email: ${filters.byDelivery.email.length}`,
113
+ size: "small",
114
+ color: "secondary"
115
+ }
116
+ ),
117
+ /* @__PURE__ */ jsxRuntime.jsx(
118
+ material.Chip,
119
+ {
120
+ label: `SMS: ${filters.byDelivery.sms.length}`,
121
+ size: "small",
122
+ color: "secondary"
123
+ }
124
+ ),
125
+ /* @__PURE__ */ jsxRuntime.jsx(
126
+ material.Chip,
127
+ {
128
+ label: `Both: ${filters.byDelivery.both.length}`,
129
+ size: "small",
130
+ color: "secondary"
131
+ }
132
+ )
133
+ ] })
134
+ ] }) }),
135
+ showSources && sourcTypes.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
136
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: [
137
+ "By Source (",
138
+ sourcTypes.length,
139
+ " sources)"
140
+ ] }),
141
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: sourcTypes.map((source) => /* @__PURE__ */ jsxRuntime.jsx(
142
+ material.Chip,
143
+ {
144
+ label: `${source} (${filters.bySource[source].length})`,
145
+ size: "small",
146
+ variant: "outlined"
147
+ },
148
+ source
149
+ )) })
150
+ ] }) })
151
+ ] })
152
+ ] }) });
153
+ }
154
+ var ALERT_TYPES = [
155
+ "AccountThresholdAlert",
156
+ "GoalAlert",
157
+ "MerchantNameAlert",
158
+ "SpendingTargetAlert",
159
+ "TransactionLimitAlert",
160
+ "UpcomingBillAlert"
161
+ ];
162
+ var SOURCE_TYPES = [
163
+ "none",
164
+ "Account",
165
+ "Budget",
166
+ "CashflowTransaction",
167
+ "PayoffGoal",
168
+ "SavingsGoal"
169
+ ];
170
+ function AlertCreateForm({ userId, onSuccess }) {
171
+ const [alertType, setAlertType] = react.useState("AccountThresholdAlert");
172
+ const [formData, setFormData] = react.useState({
173
+ options: {},
174
+ email_delivery: true,
175
+ sms_delivery: false,
176
+ source_type: null,
177
+ source_id: void 0
178
+ });
179
+ const [sourceTypeSelection, setSourceTypeSelection] = react.useState("none");
180
+ const [showSuccess, setShowSuccess] = react.useState(false);
181
+ const createMutation = alertsDataAccess.useCreateAlert({
182
+ onSuccess: () => {
183
+ setShowSuccess(true);
184
+ setFormData({
185
+ options: {},
186
+ email_delivery: true,
187
+ sms_delivery: false,
188
+ source_type: null,
189
+ source_id: void 0
190
+ });
191
+ setSourceTypeSelection("none");
192
+ onSuccess?.();
193
+ }
194
+ });
195
+ const handleSubmit = (e) => {
196
+ e.preventDefault();
197
+ const submitData = {
198
+ ...formData,
199
+ source_type: sourceTypeSelection === "none" ? null : sourceTypeSelection
200
+ };
201
+ createMutation.mutate({
202
+ userId,
203
+ type: alertType,
204
+ data: submitData
205
+ });
206
+ };
207
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Paper, { elevation: 2, sx: { p: 3 }, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { component: "form", onSubmit: handleSubmit, children: [
208
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: "Create New Alert" }),
209
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", required: true, children: [
210
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "Alert Type" }),
211
+ /* @__PURE__ */ jsxRuntime.jsx(
212
+ material.Select,
213
+ {
214
+ value: alertType,
215
+ onChange: (e) => setAlertType(e.target.value),
216
+ label: "Alert Type",
217
+ children: ALERT_TYPES.map((type) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: type, children: type.replace(/([A-Z])/g, " $1").trim() }, type))
218
+ }
219
+ )
220
+ ] }),
221
+ /* @__PURE__ */ jsxRuntime.jsx(
222
+ material.TextField,
223
+ {
224
+ label: "Alert Options (JSON)",
225
+ fullWidth: true,
226
+ margin: "normal",
227
+ value: JSON.stringify(formData.options, null, 2),
228
+ onChange: (e) => {
229
+ try {
230
+ const parsed = JSON.parse(e.target.value);
231
+ setFormData({ ...formData, options: parsed });
232
+ } catch {
233
+ }
234
+ },
235
+ multiline: true,
236
+ rows: 4,
237
+ helperText: 'Enter alert-specific configuration as JSON (e.g., {"threshold": 100})',
238
+ placeholder: "{}"
239
+ }
240
+ ),
241
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mt: 2, mb: 1 }, children: "Delivery Settings:" }),
242
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormGroup, { children: [
243
+ /* @__PURE__ */ jsxRuntime.jsx(
244
+ material.FormControlLabel,
245
+ {
246
+ control: /* @__PURE__ */ jsxRuntime.jsx(
247
+ material.Checkbox,
248
+ {
249
+ checked: formData.email_delivery ?? true,
250
+ onChange: (e) => setFormData({ ...formData, email_delivery: e.target.checked })
251
+ }
252
+ ),
253
+ label: "Email Delivery"
254
+ }
255
+ ),
256
+ /* @__PURE__ */ jsxRuntime.jsx(
257
+ material.FormControlLabel,
258
+ {
259
+ control: /* @__PURE__ */ jsxRuntime.jsx(
260
+ material.Checkbox,
261
+ {
262
+ checked: formData.sms_delivery ?? false,
263
+ onChange: (e) => setFormData({ ...formData, sms_delivery: e.target.checked })
264
+ }
265
+ ),
266
+ label: "SMS Delivery"
267
+ }
268
+ )
269
+ ] }),
270
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mt: 2, mb: 1 }, children: "Source Reference (Optional):" }),
271
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", children: [
272
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: "source-type-label", children: "Source Type" }),
273
+ /* @__PURE__ */ jsxRuntime.jsx(
274
+ material.Select,
275
+ {
276
+ labelId: "source-type-label",
277
+ id: "source-type",
278
+ value: sourceTypeSelection,
279
+ onChange: (e) => setSourceTypeSelection(e.target.value),
280
+ label: "Source Type",
281
+ children: SOURCE_TYPES.map((type) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: type, children: type === "none" ? "None" : type }, type))
282
+ }
283
+ )
284
+ ] }),
285
+ sourceTypeSelection !== "none" && /* @__PURE__ */ jsxRuntime.jsx(
286
+ material.TextField,
287
+ {
288
+ label: "Source ID",
289
+ fullWidth: true,
290
+ margin: "normal",
291
+ value: formData.source_id ?? "",
292
+ onChange: (e) => {
293
+ const value = e.target.value;
294
+ const parsed = /^\d+$/.test(value) ? parseInt(value) : value;
295
+ setFormData({ ...formData, source_id: parsed });
296
+ },
297
+ helperText: "Enter the ID of the source object (Account, Goal, etc.)"
298
+ }
299
+ ),
300
+ createMutation.isError && /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", sx: { mt: 2 }, children: createMutation.error instanceof Error ? createMutation.error.message : "Failed to create alert" }),
301
+ createMutation.isError && createMutation.error?.message.includes("issues") && /* @__PURE__ */ jsxRuntime.jsxs(material.Alert, { severity: "error", sx: { mt: 2 }, children: [
302
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", fontWeight: "bold", children: "Validation Errors:" }),
303
+ (() => {
304
+ try {
305
+ const parsed = JSON.parse(createMutation.error.message);
306
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: "8px 0", paddingLeft: "20px" }, children: parsed.map((issue, idx) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
307
+ issue.path?.join("."),
308
+ ": ",
309
+ issue.message
310
+ ] }, idx)) });
311
+ } catch {
312
+ return createMutation.error.message;
313
+ }
314
+ })()
315
+ ] }),
316
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { mt: 3 }, children: /* @__PURE__ */ jsxRuntime.jsx(material.Button, { type: "submit", variant: "contained", disabled: createMutation.isPending, children: createMutation.isPending ? "Creating..." : "Create Alert" }) }),
317
+ /* @__PURE__ */ jsxRuntime.jsx(
318
+ material.Snackbar,
319
+ {
320
+ open: showSuccess,
321
+ autoHideDuration: 3e3,
322
+ onClose: () => setShowSuccess(false),
323
+ message: "Alert created successfully"
324
+ }
325
+ )
326
+ ] }) });
327
+ }
328
+ var SOURCE_TYPES2 = [
329
+ "none",
330
+ "Account",
331
+ "Budget",
332
+ "CashflowTransaction",
333
+ "PayoffGoal",
334
+ "SavingsGoal"
335
+ ];
336
+ function AlertEditForm({ alert, open, onClose, userId }) {
337
+ const [formData, setFormData] = react.useState(alert);
338
+ const [sourceTypeSelection, setSourceTypeSelection] = react.useState(
339
+ alert.source_type ?? "none"
340
+ );
341
+ react.useEffect(() => {
342
+ setFormData(alert);
343
+ setSourceTypeSelection(alert.source_type ?? "none");
344
+ }, [alert]);
345
+ const updateMutation = alertsDataAccess.useUpdateAlert({
346
+ onSuccess: () => {
347
+ onClose();
348
+ }
349
+ });
350
+ const handleSubmit = (e) => {
351
+ e.preventDefault();
352
+ updateMutation.mutate({
353
+ userId,
354
+ alertId: alert.id,
355
+ type: alert.type,
356
+ data: {
357
+ options: formData.options,
358
+ email_delivery: formData.email_delivery,
359
+ sms_delivery: formData.sms_delivery,
360
+ source_type: sourceTypeSelection === "none" ? null : sourceTypeSelection,
361
+ source_id: formData.source_id
362
+ }
363
+ });
364
+ };
365
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Dialog, { open, onClose, maxWidth: "sm", fullWidth: true, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
366
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { children: "Edit Alert" }),
367
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogContent, { children: [
368
+ /* @__PURE__ */ jsxRuntime.jsx(
369
+ material.TextField,
370
+ {
371
+ label: "Alert Type",
372
+ fullWidth: true,
373
+ margin: "normal",
374
+ value: alert.type.replace(/([A-Z])/g, " $1").trim(),
375
+ disabled: true,
376
+ helperText: "Alert type cannot be changed after creation"
377
+ }
378
+ ),
379
+ /* @__PURE__ */ jsxRuntime.jsx(
380
+ material.TextField,
381
+ {
382
+ label: "Alert Options (JSON)",
383
+ fullWidth: true,
384
+ margin: "normal",
385
+ value: JSON.stringify(formData.options, null, 2),
386
+ onChange: (e) => {
387
+ try {
388
+ const parsed = JSON.parse(e.target.value);
389
+ setFormData({ ...formData, options: parsed });
390
+ } catch {
391
+ }
392
+ },
393
+ multiline: true,
394
+ rows: 4,
395
+ helperText: "Enter alert-specific configuration as JSON"
396
+ }
397
+ ),
398
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mt: 2, mb: 1 }, children: "Delivery Settings:" }),
399
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormGroup, { children: [
400
+ /* @__PURE__ */ jsxRuntime.jsx(
401
+ material.FormControlLabel,
402
+ {
403
+ control: /* @__PURE__ */ jsxRuntime.jsx(
404
+ material.Checkbox,
405
+ {
406
+ checked: formData.email_delivery,
407
+ onChange: (e) => setFormData({ ...formData, email_delivery: e.target.checked })
408
+ }
409
+ ),
410
+ label: "Email Delivery"
411
+ }
412
+ ),
413
+ /* @__PURE__ */ jsxRuntime.jsx(
414
+ material.FormControlLabel,
415
+ {
416
+ control: /* @__PURE__ */ jsxRuntime.jsx(
417
+ material.Checkbox,
418
+ {
419
+ checked: formData.sms_delivery,
420
+ onChange: (e) => setFormData({ ...formData, sms_delivery: e.target.checked })
421
+ }
422
+ ),
423
+ label: "SMS Delivery"
424
+ }
425
+ )
426
+ ] }),
427
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mt: 2, mb: 1 }, children: "Source Reference:" }),
428
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", children: [
429
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { id: "source-type-label", children: "Source Type" }),
430
+ /* @__PURE__ */ jsxRuntime.jsx(
431
+ material.Select,
432
+ {
433
+ labelId: "source-type-label",
434
+ id: "source-type",
435
+ value: sourceTypeSelection,
436
+ onChange: (e) => setSourceTypeSelection(e.target.value),
437
+ label: "Source Type",
438
+ children: SOURCE_TYPES2.map((type) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: type, children: type === "none" ? "None" : type }, type))
439
+ }
440
+ )
441
+ ] }),
442
+ sourceTypeSelection !== "none" && /* @__PURE__ */ jsxRuntime.jsx(
443
+ material.TextField,
444
+ {
445
+ label: "Source ID",
446
+ fullWidth: true,
447
+ margin: "normal",
448
+ value: formData.source_id ?? "",
449
+ onChange: (e) => {
450
+ const value = e.target.value;
451
+ const parsed = /^\d+$/.test(value) ? parseInt(value) : value;
452
+ setFormData({ ...formData, source_id: parsed });
453
+ },
454
+ helperText: "Enter the ID of the source object (Account, Goal, etc.)"
455
+ }
456
+ ),
457
+ updateMutation.isError && /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", sx: { mt: 2 }, children: updateMutation.error instanceof Error ? updateMutation.error.message : "Failed to update alert" })
458
+ ] }),
459
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
460
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: onClose, children: "Cancel" }),
461
+ /* @__PURE__ */ jsxRuntime.jsx(
462
+ material.Button,
463
+ {
464
+ type: "submit",
465
+ variant: "contained",
466
+ disabled: updateMutation.isPending,
467
+ children: updateMutation.isPending ? "Saving..." : "Save Changes"
468
+ }
469
+ )
470
+ ] })
471
+ ] }) });
472
+ }
473
+ function AlertDeleteButton({
474
+ alertId,
475
+ userId,
476
+ alertType
477
+ }) {
478
+ const [confirmOpen, setConfirmOpen] = react.useState(false);
479
+ const deleteMutation = alertsDataAccess.useDeleteAlert({
480
+ onSuccess: () => {
481
+ setConfirmOpen(false);
482
+ }
483
+ });
484
+ const handleDelete = () => {
485
+ deleteMutation.mutate({ userId, alertId });
486
+ };
487
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
488
+ /* @__PURE__ */ jsxRuntime.jsx(
489
+ material.IconButton,
490
+ {
491
+ color: "error",
492
+ onClick: () => setConfirmOpen(true),
493
+ size: "small",
494
+ "aria-label": "delete alert",
495
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Delete, {})
496
+ }
497
+ ),
498
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Dialog, { open: confirmOpen, onClose: () => setConfirmOpen(false), children: [
499
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { children: "Delete Alert?" }),
500
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { children: [
501
+ "Are you sure you want to delete this ",
502
+ alertType,
503
+ " alert? This action cannot be undone."
504
+ ] }) }),
505
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
506
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: () => setConfirmOpen(false), children: "Cancel" }),
507
+ /* @__PURE__ */ jsxRuntime.jsx(
508
+ material.Button,
509
+ {
510
+ onClick: handleDelete,
511
+ color: "error",
512
+ variant: "contained",
513
+ disabled: deleteMutation.isPending,
514
+ children: deleteMutation.isPending ? "Deleting..." : "Delete"
515
+ }
516
+ )
517
+ ] })
518
+ ] })
519
+ ] });
520
+ }
521
+
522
+ exports.AlertCreateForm = AlertCreateForm;
523
+ exports.AlertDeleteButton = AlertDeleteButton;
524
+ exports.AlertEditForm = AlertEditForm;
525
+ exports.AlertList = AlertList;
526
+ exports.AlertSummary = AlertSummary;
527
+ //# sourceMappingURL=index.cjs.map
528
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AlertList.tsx","../src/components/AlertSummary.tsx","../src/components/AlertCreateForm.tsx","../src/components/AlertEditForm.tsx","../src/components/AlertDeleteButton.tsx"],"names":["useAlerts","jsx","Card","jsxs","CardContent","Typography","List","ListItem","Box","Chip","EmailIcon","SmsIcon","ListItemText","useAlertFilters","Grid","useState","useCreateAlert","Paper","FormControl","InputLabel","Select","MenuItem","TextField","FormGroup","FormControlLabel","Checkbox","Alert","Button","Snackbar","SOURCE_TYPES","useEffect","useUpdateAlert","Dialog","DialogTitle","DialogContent","MuiAlert","DialogActions","useDeleteAlert","Fragment","IconButton","DeleteIcon"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Box, Card, CardContent, List, ListItem, ListItemText, Typography, Chip } from '@mui/material';\nimport { Email as EmailIcon, Sms as SmsIcon } from '@mui/icons-material';\nimport { useAlerts } from '@pfm-platform/alerts-data-access';\nimport type { Alert } from '@pfm-platform/shared';\n\nexport interface AlertListProps {\n userId: string;\n /** Filter by alert type */\n filterType?: string;\n /** Filter by source type */\n filterSource?: string;\n /** Custom title for the list */\n title?: string;\n /** Maximum number of alerts to display */\n maxItems?: number;\n}\n\n/**\n * AlertList component displays user alerts with type badges and delivery indicators.\n * Supports filtering by alert type or source type.\n */\nexport function AlertList({\n userId,\n filterType,\n filterSource,\n title = 'Alerts',\n maxItems,\n}: AlertListProps) {\n const { data: alerts } = useAlerts({ userId });\n\n if (!alerts) {\n return (\n <Card>\n <CardContent>\n <Typography variant=\"h6\" gutterBottom>\n {title}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Loading alerts...\n </Typography>\n </CardContent>\n </Card>\n );\n }\n\n // Apply filters\n let filteredAlerts = alerts;\n if (filterType) {\n filteredAlerts = filteredAlerts.filter((alert) => alert.type === filterType);\n }\n if (filterSource) {\n filteredAlerts = filteredAlerts.filter((alert) => alert.source_type === filterSource);\n }\n\n // Apply max items limit\n const displayAlerts = maxItems ? filteredAlerts.slice(0, maxItems) : filteredAlerts;\n\n return (\n <Card>\n <CardContent>\n <Typography variant=\"h6\" gutterBottom>\n {title}\n </Typography>\n {displayAlerts.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No alerts found\n </Typography>\n ) : (\n <List disablePadding>\n {displayAlerts.map((alert, index) => (\n <ListItem\n key={alert.id}\n divider={index < displayAlerts.length - 1}\n sx={{ px: 0, display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}\n >\n <Box sx={{ width: '100%', display: 'flex', alignItems: 'center', gap: 1, mb: 0.5 }}>\n <Chip label={alert.type} size=\"small\" color=\"primary\" />\n {alert.source_type && (\n <Chip label={alert.source_type} size=\"small\" variant=\"outlined\" />\n )}\n <Box sx={{ ml: 'auto', display: 'flex', gap: 0.5 }}>\n {alert.email_delivery && (\n <EmailIcon fontSize=\"small\" color=\"action\" titleAccess=\"Email delivery\" />\n )}\n {alert.sms_delivery && (\n <SmsIcon fontSize=\"small\" color=\"action\" titleAccess=\"SMS delivery\" />\n )}\n </Box>\n </Box>\n <ListItemText\n primary={`Alert ID: ${alert.id}`}\n secondary={alert.source_id ? `Source: ${alert.source_id}` : undefined}\n primaryTypographyProps={{ variant: 'body2' }}\n secondaryTypographyProps={{ variant: 'caption' }}\n />\n </ListItem>\n ))}\n </List>\n )}\n </CardContent>\n </Card>\n );\n}\n","import { Box, Card, CardContent, Typography, Grid, Chip } from '@mui/material';\nimport { useAlertFilters } from '@pfm-platform/alerts-feature';\n\nexport interface AlertSummaryProps {\n userId: string;\n /** Custom title for the summary */\n title?: string;\n /** Show type breakdown */\n showTypes?: boolean;\n /** Show delivery breakdown */\n showDelivery?: boolean;\n /** Show source breakdown */\n showSources?: boolean;\n}\n\n/**\n * AlertSummary component displays alert statistics grouped by type, delivery, and source.\n * Shows counts and categories for quick overview of alert configuration.\n */\nexport function AlertSummary({\n userId,\n title = 'Alert Summary',\n showTypes = true,\n showDelivery = true,\n showSources = true,\n}: AlertSummaryProps) {\n const filters = useAlertFilters(userId);\n\n if (!filters) {\n return (\n <Card>\n <CardContent>\n <Typography variant=\"h6\" gutterBottom>\n {title}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Loading alerts...\n </Typography>\n </CardContent>\n </Card>\n );\n }\n\n const alertTypes = Object.keys(filters.byType);\n const sourcTypes = Object.keys(filters.bySource);\n const totalAlerts =\n filters.byDelivery.email.length +\n filters.byDelivery.sms.length +\n filters.byDelivery.both.length;\n\n const hasData = totalAlerts > 0;\n\n return (\n <Card>\n <CardContent>\n <Typography variant=\"h6\" gutterBottom>\n {title}\n </Typography>\n {!hasData ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No alerts configured\n </Typography>\n ) : (\n <Grid container spacing={3}>\n {/* Total Count */}\n <Grid size={12}>\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Total Alerts\n </Typography>\n <Typography variant=\"h4\" fontWeight=\"medium\">\n {totalAlerts}\n </Typography>\n </Box>\n </Grid>\n\n {/* Alert Types */}\n {showTypes && alertTypes.length > 0 && (\n <Grid size={12}>\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n By Type ({alertTypes.length} types)\n </Typography>\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>\n {alertTypes.map((type) => (\n <Chip\n key={type}\n label={`${type} (${filters.byType[type].length})`}\n size=\"small\"\n color=\"primary\"\n variant=\"outlined\"\n />\n ))}\n </Box>\n </Box>\n </Grid>\n )}\n\n {/* Delivery Methods */}\n {showDelivery && (\n <Grid size={12}>\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n By Delivery Method\n </Typography>\n <Box sx={{ display: 'flex', gap: 1 }}>\n <Chip\n label={`Email: ${filters.byDelivery.email.length}`}\n size=\"small\"\n color=\"secondary\"\n />\n <Chip\n label={`SMS: ${filters.byDelivery.sms.length}`}\n size=\"small\"\n color=\"secondary\"\n />\n <Chip\n label={`Both: ${filters.byDelivery.both.length}`}\n size=\"small\"\n color=\"secondary\"\n />\n </Box>\n </Box>\n </Grid>\n )}\n\n {/* Source Types */}\n {showSources && sourcTypes.length > 0 && (\n <Grid size={12}>\n <Box>\n <Typography variant=\"body2\" color=\"text.secondary\" gutterBottom>\n By Source ({sourcTypes.length} sources)\n </Typography>\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>\n {sourcTypes.map((source) => (\n <Chip\n key={source}\n label={`${source} (${filters.bySource[source].length})`}\n size=\"small\"\n variant=\"outlined\"\n />\n ))}\n </Box>\n </Box>\n </Grid>\n )}\n </Grid>\n )}\n </CardContent>\n </Card>\n );\n}\n","import { useState } from 'react';\nimport {\n Box,\n Button,\n TextField,\n Select,\n MenuItem,\n FormControl,\n InputLabel,\n FormControlLabel,\n Checkbox,\n FormGroup,\n Alert,\n Snackbar,\n Typography,\n Paper,\n} from '@mui/material';\nimport { useCreateAlert } from '@pfm-platform/alerts-data-access';\nimport type { AlertCreate, AlertType, AlertSourceType } from '@pfm-platform/shared';\n\ninterface AlertCreateFormProps {\n userId: string;\n onSuccess?: () => void;\n}\n\nconst ALERT_TYPES: AlertType[] = [\n 'AccountThresholdAlert',\n 'GoalAlert',\n 'MerchantNameAlert',\n 'SpendingTargetAlert',\n 'TransactionLimitAlert',\n 'UpcomingBillAlert',\n];\n\nconst SOURCE_TYPES: (AlertSourceType | 'none')[] = [\n 'none',\n 'Account',\n 'Budget',\n 'CashflowTransaction',\n 'PayoffGoal',\n 'SavingsGoal',\n];\n\nexport function AlertCreateForm({ userId, onSuccess }: AlertCreateFormProps) {\n const [alertType, setAlertType] = useState<AlertType>('AccountThresholdAlert');\n const [formData, setFormData] = useState<Partial<AlertCreate>>({\n options: {},\n email_delivery: true,\n sms_delivery: false,\n source_type: null,\n source_id: undefined,\n });\n const [sourceTypeSelection, setSourceTypeSelection] = useState<AlertSourceType | 'none'>('none');\n const [showSuccess, setShowSuccess] = useState(false);\n\n const createMutation = useCreateAlert({\n onSuccess: () => {\n setShowSuccess(true);\n // Reset form\n setFormData({\n options: {},\n email_delivery: true,\n sms_delivery: false,\n source_type: null,\n source_id: undefined,\n });\n setSourceTypeSelection('none');\n onSuccess?.();\n },\n });\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n\n // Prepare data with source_type handling\n const submitData: AlertCreate = {\n ...formData,\n source_type: sourceTypeSelection === 'none' ? null : sourceTypeSelection,\n } as AlertCreate;\n\n createMutation.mutate({\n userId,\n type: alertType,\n data: submitData,\n });\n };\n\n return (\n <Paper elevation={2} sx={{ p: 3 }}>\n <Box component=\"form\" onSubmit={handleSubmit}>\n <Typography variant=\"h6\" gutterBottom>\n Create New Alert\n </Typography>\n\n {/* Alert Type Selection */}\n <FormControl fullWidth margin=\"normal\" required>\n <InputLabel>Alert Type</InputLabel>\n <Select\n value={alertType}\n onChange={(e) => setAlertType(e.target.value as AlertType)}\n label=\"Alert Type\"\n >\n {ALERT_TYPES.map((type) => (\n <MenuItem key={type} value={type}>\n {type.replace(/([A-Z])/g, ' $1').trim()}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n\n {/* Options (JSON input for flexibility) */}\n <TextField\n label=\"Alert Options (JSON)\"\n fullWidth\n margin=\"normal\"\n value={JSON.stringify(formData.options, null, 2)}\n onChange={(e) => {\n try {\n const parsed = JSON.parse(e.target.value);\n setFormData({ ...formData, options: parsed });\n } catch {\n // Invalid JSON, keep previous value\n }\n }}\n multiline\n rows={4}\n helperText=\"Enter alert-specific configuration as JSON (e.g., {&quot;threshold&quot;: 100})\"\n placeholder=\"{}\"\n />\n\n {/* Delivery Settings */}\n <Typography variant=\"subtitle2\" sx={{ mt: 2, mb: 1 }}>\n Delivery Settings:\n </Typography>\n <FormGroup>\n <FormControlLabel\n control={\n <Checkbox\n checked={formData.email_delivery ?? true}\n onChange={(e) =>\n setFormData({ ...formData, email_delivery: e.target.checked })\n }\n />\n }\n label=\"Email Delivery\"\n />\n <FormControlLabel\n control={\n <Checkbox\n checked={formData.sms_delivery ?? false}\n onChange={(e) =>\n setFormData({ ...formData, sms_delivery: e.target.checked })\n }\n />\n }\n label=\"SMS Delivery\"\n />\n </FormGroup>\n\n {/* Source Reference (Optional) */}\n <Typography variant=\"subtitle2\" sx={{ mt: 2, mb: 1 }}>\n Source Reference (Optional):\n </Typography>\n\n <FormControl fullWidth margin=\"normal\">\n <InputLabel id=\"source-type-label\">Source Type</InputLabel>\n <Select\n labelId=\"source-type-label\"\n id=\"source-type\"\n value={sourceTypeSelection}\n onChange={(e) => setSourceTypeSelection(e.target.value as AlertSourceType | 'none')}\n label=\"Source Type\"\n >\n {SOURCE_TYPES.map((type) => (\n <MenuItem key={type} value={type as string}>\n {type === 'none' ? 'None' : type}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n\n {sourceTypeSelection !== 'none' && (\n <TextField\n label=\"Source ID\"\n fullWidth\n margin=\"normal\"\n value={formData.source_id ?? ''}\n onChange={(e) => {\n const value = e.target.value;\n // Try to parse as number, fallback to string\n const parsed = /^\\d+$/.test(value) ? parseInt(value) : value;\n setFormData({ ...formData, source_id: parsed });\n }}\n helperText=\"Enter the ID of the source object (Account, Goal, etc.)\"\n />\n )}\n\n {/* Error display */}\n {createMutation.isError && (\n <Alert severity=\"error\" sx={{ mt: 2 }}>\n {createMutation.error instanceof Error\n ? createMutation.error.message\n : 'Failed to create alert'}\n </Alert>\n )}\n\n {/* Validation errors from Zod */}\n {createMutation.isError && createMutation.error?.message.includes('issues') && (\n <Alert severity=\"error\" sx={{ mt: 2 }}>\n <Typography variant=\"body2\" fontWeight=\"bold\">Validation Errors:</Typography>\n {(() => {\n try {\n const parsed = JSON.parse(createMutation.error.message);\n return (\n <ul style={{ margin: '8px 0', paddingLeft: '20px' }}>\n {parsed.map((issue: any, idx: number) => (\n <li key={idx}>\n {issue.path?.join('.')}: {issue.message}\n </li>\n ))}\n </ul>\n );\n } catch {\n return createMutation.error.message;\n }\n })()}\n </Alert>\n )}\n\n {/* Submit button */}\n <Box sx={{ mt: 3 }}>\n <Button type=\"submit\" variant=\"contained\" disabled={createMutation.isPending}>\n {createMutation.isPending ? 'Creating...' : 'Create Alert'}\n </Button>\n </Box>\n\n {/* Success notification */}\n <Snackbar\n open={showSuccess}\n autoHideDuration={3000}\n onClose={() => setShowSuccess(false)}\n message=\"Alert created successfully\"\n />\n </Box>\n </Paper>\n );\n}\n","import { useState, useEffect } from 'react';\nimport {\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n TextField,\n FormControl,\n InputLabel,\n Select,\n MenuItem,\n FormControlLabel,\n Checkbox,\n FormGroup,\n Alert as MuiAlert,\n Typography,\n} from '@mui/material';\nimport { useUpdateAlert } from '@pfm-platform/alerts-data-access';\nimport type { Alert, AlertSourceType } from '@pfm-platform/shared';\n\ninterface AlertEditFormProps {\n alert: Alert;\n open: boolean;\n onClose: () => void;\n userId: string;\n}\n\nconst SOURCE_TYPES: (AlertSourceType | 'none')[] = [\n 'none',\n 'Account',\n 'Budget',\n 'CashflowTransaction',\n 'PayoffGoal',\n 'SavingsGoal',\n];\n\nexport function AlertEditForm({ alert, open, onClose, userId }: AlertEditFormProps) {\n const [formData, setFormData] = useState(alert);\n const [sourceTypeSelection, setSourceTypeSelection] = useState<AlertSourceType | 'none'>(\n alert.source_type ?? 'none'\n );\n\n useEffect(() => {\n setFormData(alert);\n setSourceTypeSelection(alert.source_type ?? 'none');\n }, [alert]);\n\n const updateMutation = useUpdateAlert({\n onSuccess: () => {\n onClose();\n },\n });\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n\n updateMutation.mutate({\n userId,\n alertId: alert.id,\n type: alert.type,\n data: {\n options: formData.options,\n email_delivery: formData.email_delivery,\n sms_delivery: formData.sms_delivery,\n source_type: sourceTypeSelection === 'none' ? null : sourceTypeSelection,\n source_id: formData.source_id,\n },\n });\n };\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"sm\" fullWidth>\n <form onSubmit={handleSubmit}>\n <DialogTitle>Edit Alert</DialogTitle>\n <DialogContent>\n {/* Alert Type (Read-only) */}\n <TextField\n label=\"Alert Type\"\n fullWidth\n margin=\"normal\"\n value={alert.type.replace(/([A-Z])/g, ' $1').trim()}\n disabled\n helperText=\"Alert type cannot be changed after creation\"\n />\n\n {/* Options (JSON input for flexibility) */}\n <TextField\n label=\"Alert Options (JSON)\"\n fullWidth\n margin=\"normal\"\n value={JSON.stringify(formData.options, null, 2)}\n onChange={(e) => {\n try {\n const parsed = JSON.parse(e.target.value);\n setFormData({ ...formData, options: parsed });\n } catch {\n // Invalid JSON, keep previous value\n }\n }}\n multiline\n rows={4}\n helperText=\"Enter alert-specific configuration as JSON\"\n />\n\n {/* Delivery Settings */}\n <Typography variant=\"subtitle2\" sx={{ mt: 2, mb: 1 }}>\n Delivery Settings:\n </Typography>\n <FormGroup>\n <FormControlLabel\n control={\n <Checkbox\n checked={formData.email_delivery}\n onChange={(e) =>\n setFormData({ ...formData, email_delivery: e.target.checked })\n }\n />\n }\n label=\"Email Delivery\"\n />\n <FormControlLabel\n control={\n <Checkbox\n checked={formData.sms_delivery}\n onChange={(e) =>\n setFormData({ ...formData, sms_delivery: e.target.checked })\n }\n />\n }\n label=\"SMS Delivery\"\n />\n </FormGroup>\n\n {/* Source Reference (Optional) */}\n <Typography variant=\"subtitle2\" sx={{ mt: 2, mb: 1 }}>\n Source Reference:\n </Typography>\n\n <FormControl fullWidth margin=\"normal\">\n <InputLabel id=\"source-type-label\">Source Type</InputLabel>\n <Select\n labelId=\"source-type-label\"\n id=\"source-type\"\n value={sourceTypeSelection}\n onChange={(e) => setSourceTypeSelection(e.target.value as AlertSourceType | 'none')}\n label=\"Source Type\"\n >\n {SOURCE_TYPES.map((type) => (\n <MenuItem key={type} value={type as string}>\n {type === 'none' ? 'None' : type}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n\n {sourceTypeSelection !== 'none' && (\n <TextField\n label=\"Source ID\"\n fullWidth\n margin=\"normal\"\n value={formData.source_id ?? ''}\n onChange={(e) => {\n const value = e.target.value;\n // Try to parse as number, fallback to string\n const parsed = /^\\d+$/.test(value) ? parseInt(value) : value;\n setFormData({ ...formData, source_id: parsed });\n }}\n helperText=\"Enter the ID of the source object (Account, Goal, etc.)\"\n />\n )}\n\n {/* Error display */}\n {updateMutation.isError && (\n <MuiAlert severity=\"error\" sx={{ mt: 2 }}>\n {updateMutation.error instanceof Error\n ? updateMutation.error.message\n : 'Failed to update alert'}\n </MuiAlert>\n )}\n </DialogContent>\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n <Button\n type=\"submit\"\n variant=\"contained\"\n disabled={updateMutation.isPending}\n >\n {updateMutation.isPending ? 'Saving...' : 'Save Changes'}\n </Button>\n </DialogActions>\n </form>\n </Dialog>\n );\n}\n","import { useState } from 'react';\nimport {\n IconButton,\n Dialog,\n DialogTitle,\n DialogContent,\n DialogActions,\n Button,\n Typography,\n} from '@mui/material';\nimport { Delete as DeleteIcon } from '@mui/icons-material';\nimport { useDeleteAlert } from '@pfm-platform/alerts-data-access';\n\ninterface AlertDeleteButtonProps {\n alertId: number;\n userId: string;\n alertType: string;\n}\n\nexport function AlertDeleteButton({\n alertId,\n userId,\n alertType,\n}: AlertDeleteButtonProps) {\n const [confirmOpen, setConfirmOpen] = useState(false);\n\n const deleteMutation = useDeleteAlert({\n onSuccess: () => {\n setConfirmOpen(false);\n },\n });\n\n const handleDelete = () => {\n deleteMutation.mutate({ userId, alertId });\n };\n\n return (\n <>\n <IconButton\n color=\"error\"\n onClick={() => setConfirmOpen(true)}\n size=\"small\"\n aria-label=\"delete alert\"\n >\n <DeleteIcon />\n </IconButton>\n\n <Dialog open={confirmOpen} onClose={() => setConfirmOpen(false)}>\n <DialogTitle>Delete Alert?</DialogTitle>\n <DialogContent>\n <Typography>\n Are you sure you want to delete this {alertType} alert? This action cannot be undone.\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setConfirmOpen(false)}>Cancel</Button>\n <Button\n onClick={handleDelete}\n color=\"error\"\n variant=\"contained\"\n disabled={deleteMutation.isPending}\n >\n {deleteMutation.isPending ? 'Deleting...' : 'Delete'}\n </Button>\n </DialogActions>\n </Dialog>\n </>\n );\n}\n"]}