@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 +528 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +59 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +522 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
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., {"threshold": 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"]}
|