@pfm-platform/accounts-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,2089 @@
1
+ 'use strict';
2
+
3
+ var material = require('@mui/material');
4
+ var accountsDataAccess = require('@pfm-platform/accounts-data-access');
5
+ var accountsFeature = require('@pfm-platform/accounts-feature');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var react = require('react');
8
+ var iconsMaterial = require('@mui/icons-material');
9
+ var LineChart = require('@mui/x-charts/LineChart');
10
+
11
+ // src/components/AccountList.tsx
12
+ function AccountList({
13
+ userId,
14
+ filter = "all",
15
+ groupByType = false,
16
+ title = "Accounts",
17
+ maxItems
18
+ }) {
19
+ const { data } = accountsDataAccess.useAccounts({ userId });
20
+ const filters = accountsFeature.useAccountFilters(userId);
21
+ const accountTypes = accountsFeature.useAccountTypes(userId);
22
+ if (!data?.accounts) {
23
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
24
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
25
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading accounts..." })
26
+ ] }) });
27
+ }
28
+ let filteredAccounts = data.accounts;
29
+ if (filter === "opened") {
30
+ filteredAccounts = filters.opened;
31
+ } else if (filter === "closed") {
32
+ filteredAccounts = filters.closed;
33
+ }
34
+ const displayAccounts = maxItems ? filteredAccounts.slice(0, maxItems) : filteredAccounts;
35
+ if (groupByType) {
36
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
37
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
38
+ accountTypes.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "No accounts found" }) : accountTypes.map((group) => /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
39
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1 }, children: [
40
+ /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { label: group.name, size: "small", color: "primary" }),
41
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "caption", color: "text.secondary", children: [
42
+ group.accounts.length,
43
+ " account",
44
+ group.accounts.length !== 1 ? "s" : "",
45
+ " | $",
46
+ parseFloat(group.sum.toString()).toFixed(2)
47
+ ] })
48
+ ] }),
49
+ /* @__PURE__ */ jsxRuntime.jsx(material.List, { disablePadding: true, children: group.accounts.slice(0, maxItems).map((account, index) => /* @__PURE__ */ jsxRuntime.jsxs(
50
+ material.ListItem,
51
+ {
52
+ divider: index < group.accounts.length - 1,
53
+ sx: { px: 0 },
54
+ children: [
55
+ /* @__PURE__ */ jsxRuntime.jsx(
56
+ material.ListItemText,
57
+ {
58
+ primary: account.name,
59
+ secondary: account.fi?.name || account.account_type,
60
+ primaryTypographyProps: { variant: "body2" },
61
+ secondaryTypographyProps: { variant: "caption" }
62
+ }
63
+ ),
64
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "body2", fontWeight: "medium", children: [
65
+ "$",
66
+ parseFloat(account.balance).toFixed(2)
67
+ ] })
68
+ ]
69
+ },
70
+ account.id
71
+ )) })
72
+ ] }, group.name))
73
+ ] }) });
74
+ }
75
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
76
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
77
+ displayAccounts.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "No accounts found" }) : /* @__PURE__ */ jsxRuntime.jsx(material.List, { disablePadding: true, children: displayAccounts.map((account, index) => /* @__PURE__ */ jsxRuntime.jsxs(
78
+ material.ListItem,
79
+ {
80
+ divider: index < displayAccounts.length - 1,
81
+ sx: { px: 0, display: "flex", flexDirection: "column", alignItems: "flex-start" },
82
+ children: [
83
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between", mb: 0.5 }, children: [
84
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", fontWeight: "medium", children: account.name }),
85
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "body2", fontWeight: "medium", children: [
86
+ "$",
87
+ parseFloat(account.balance).toFixed(2)
88
+ ] })
89
+ ] }),
90
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "caption", color: "text.secondary", children: account.fi?.name || account.account_type })
91
+ ]
92
+ },
93
+ account.id
94
+ )) })
95
+ ] }) });
96
+ }
97
+ function AccountSummary({
98
+ userId,
99
+ title = "Account Summary",
100
+ currencySymbol = "$"
101
+ }) {
102
+ const summary = accountsFeature.useAccountSummary(userId);
103
+ if (!summary) {
104
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
105
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
106
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading accounts..." })
107
+ ] }) });
108
+ }
109
+ if (!summary.hasAccounts) {
110
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
111
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
112
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "No accounts found" })
113
+ ] }) });
114
+ }
115
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
116
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
117
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 2, children: [
118
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
119
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Total Accounts" }),
120
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h5", children: summary.totalAccounts })
121
+ ] }) }),
122
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
123
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Opened" }),
124
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h5", children: summary.openedCount })
125
+ ] }) }),
126
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
127
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Closed" }),
128
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h5", children: summary.closedCount })
129
+ ] }) }),
130
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 1 }, children: [
131
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Total Balance" }),
132
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "h4", color: "primary", children: [
133
+ currencySymbol,
134
+ summary.totalBalance.toFixed(2)
135
+ ] })
136
+ ] }) })
137
+ ] })
138
+ ] }) });
139
+ }
140
+ var ACCOUNT_TYPES = [
141
+ "checking",
142
+ "savings",
143
+ "cards",
144
+ "student_loans",
145
+ "bill",
146
+ "autos",
147
+ "home",
148
+ "investment",
149
+ "loan",
150
+ "asset",
151
+ "cd",
152
+ "money_market",
153
+ "certificates",
154
+ "commercial",
155
+ "creditline"
156
+ ];
157
+ var ACCOUNT_STATES = [
158
+ "active",
159
+ "closed",
160
+ "archived",
161
+ "pending_deletion"
162
+ ];
163
+ function AccountCreateForm({ userId, onSuccess }) {
164
+ const [formData, setFormData] = react.useState({
165
+ name: "",
166
+ balance: "0.00",
167
+ account_type: "checking",
168
+ state: "active",
169
+ aggregation_type: "partner",
170
+ include_in_expenses: true,
171
+ include_in_budget: true,
172
+ include_in_cashflow: true,
173
+ include_in_dashboard: true,
174
+ include_in_goals: false,
175
+ include_in_networth: true,
176
+ // Required nullable fields for schema validation
177
+ harvest_updated_at: null,
178
+ fi: null,
179
+ cashedge_account_type: null
180
+ });
181
+ const [showSuccess, setShowSuccess] = react.useState(false);
182
+ const createMutation = accountsDataAccess.useCreateAccount();
183
+ const handleSubmit = (e) => {
184
+ e.preventDefault();
185
+ createMutation.mutate(
186
+ { userId, data: formData },
187
+ {
188
+ onSuccess: () => {
189
+ setShowSuccess(true);
190
+ setFormData({
191
+ name: "",
192
+ balance: "0.00",
193
+ account_type: "checking",
194
+ state: "active",
195
+ aggregation_type: "partner",
196
+ include_in_expenses: true,
197
+ include_in_budget: true,
198
+ include_in_cashflow: true,
199
+ include_in_dashboard: true,
200
+ include_in_goals: false,
201
+ include_in_networth: true,
202
+ harvest_updated_at: null,
203
+ fi: null,
204
+ cashedge_account_type: null
205
+ });
206
+ onSuccess?.();
207
+ }
208
+ }
209
+ );
210
+ };
211
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Paper, { elevation: 2, sx: { p: 3 }, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { component: "form", onSubmit: handleSubmit, children: [
212
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: "Create New Account" }),
213
+ /* @__PURE__ */ jsxRuntime.jsx(
214
+ material.TextField,
215
+ {
216
+ label: "Account Name",
217
+ fullWidth: true,
218
+ margin: "normal",
219
+ value: formData.name,
220
+ onChange: (e) => setFormData({ ...formData, name: e.target.value }),
221
+ required: true
222
+ }
223
+ ),
224
+ /* @__PURE__ */ jsxRuntime.jsx(
225
+ material.TextField,
226
+ {
227
+ label: "Balance",
228
+ fullWidth: true,
229
+ margin: "normal",
230
+ value: formData.balance,
231
+ onChange: (e) => setFormData({ ...formData, balance: e.target.value }),
232
+ placeholder: "0.00",
233
+ required: true,
234
+ helperText: "Format: 1234.56"
235
+ }
236
+ ),
237
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", children: [
238
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "Account Type" }),
239
+ /* @__PURE__ */ jsxRuntime.jsx(
240
+ material.Select,
241
+ {
242
+ value: formData.account_type || "checking",
243
+ onChange: (e) => setFormData({ ...formData, account_type: e.target.value }),
244
+ label: "Account Type",
245
+ children: ACCOUNT_TYPES.map((type) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: type, children: type.replace("_", " ").toUpperCase() }, type))
246
+ }
247
+ )
248
+ ] }),
249
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", children: [
250
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "State" }),
251
+ /* @__PURE__ */ jsxRuntime.jsx(
252
+ material.Select,
253
+ {
254
+ value: formData.state || "active",
255
+ onChange: (e) => setFormData({ ...formData, state: e.target.value }),
256
+ label: "State",
257
+ children: ACCOUNT_STATES.map((state) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: state, children: state.replace("_", " ").toUpperCase() }, state))
258
+ }
259
+ )
260
+ ] }),
261
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mt: 2, mb: 1 }, children: "Include in:" }),
262
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormGroup, { children: [
263
+ /* @__PURE__ */ jsxRuntime.jsx(
264
+ material.FormControlLabel,
265
+ {
266
+ control: /* @__PURE__ */ jsxRuntime.jsx(
267
+ material.Checkbox,
268
+ {
269
+ checked: formData.include_in_expenses ?? true,
270
+ onChange: (e) => setFormData({ ...formData, include_in_expenses: e.target.checked })
271
+ }
272
+ ),
273
+ label: "Expenses"
274
+ }
275
+ ),
276
+ /* @__PURE__ */ jsxRuntime.jsx(
277
+ material.FormControlLabel,
278
+ {
279
+ control: /* @__PURE__ */ jsxRuntime.jsx(
280
+ material.Checkbox,
281
+ {
282
+ checked: formData.include_in_budget ?? true,
283
+ onChange: (e) => setFormData({ ...formData, include_in_budget: e.target.checked })
284
+ }
285
+ ),
286
+ label: "Budget"
287
+ }
288
+ ),
289
+ /* @__PURE__ */ jsxRuntime.jsx(
290
+ material.FormControlLabel,
291
+ {
292
+ control: /* @__PURE__ */ jsxRuntime.jsx(
293
+ material.Checkbox,
294
+ {
295
+ checked: formData.include_in_cashflow ?? true,
296
+ onChange: (e) => setFormData({ ...formData, include_in_cashflow: e.target.checked })
297
+ }
298
+ ),
299
+ label: "Cashflow"
300
+ }
301
+ ),
302
+ /* @__PURE__ */ jsxRuntime.jsx(
303
+ material.FormControlLabel,
304
+ {
305
+ control: /* @__PURE__ */ jsxRuntime.jsx(
306
+ material.Checkbox,
307
+ {
308
+ checked: formData.include_in_dashboard ?? true,
309
+ onChange: (e) => setFormData({ ...formData, include_in_dashboard: e.target.checked })
310
+ }
311
+ ),
312
+ label: "Dashboard"
313
+ }
314
+ ),
315
+ /* @__PURE__ */ jsxRuntime.jsx(
316
+ material.FormControlLabel,
317
+ {
318
+ control: /* @__PURE__ */ jsxRuntime.jsx(
319
+ material.Checkbox,
320
+ {
321
+ checked: formData.include_in_goals ?? false,
322
+ onChange: (e) => setFormData({ ...formData, include_in_goals: e.target.checked })
323
+ }
324
+ ),
325
+ label: "Goals"
326
+ }
327
+ ),
328
+ /* @__PURE__ */ jsxRuntime.jsx(
329
+ material.FormControlLabel,
330
+ {
331
+ control: /* @__PURE__ */ jsxRuntime.jsx(
332
+ material.Checkbox,
333
+ {
334
+ checked: formData.include_in_networth ?? true,
335
+ onChange: (e) => setFormData({ ...formData, include_in_networth: e.target.checked })
336
+ }
337
+ ),
338
+ label: "Net Worth"
339
+ }
340
+ )
341
+ ] }),
342
+ createMutation.isError && /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", sx: { mt: 2 }, children: createMutation.error instanceof Error ? createMutation.error.message : "Failed to create account" }),
343
+ createMutation.isError && createMutation.error?.message.includes("issues") && /* @__PURE__ */ jsxRuntime.jsxs(material.Alert, { severity: "error", sx: { mt: 2 }, children: [
344
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", fontWeight: "bold", children: "Validation Errors:" }),
345
+ (() => {
346
+ try {
347
+ const parsed = JSON.parse(createMutation.error.message);
348
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: "8px 0", paddingLeft: "20px" }, children: parsed.map((issue, idx) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
349
+ issue.path?.join("."),
350
+ ": ",
351
+ issue.message
352
+ ] }, idx)) });
353
+ } catch {
354
+ return createMutation.error.message;
355
+ }
356
+ })()
357
+ ] }),
358
+ /* @__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 Account" }) }),
359
+ /* @__PURE__ */ jsxRuntime.jsx(
360
+ material.Snackbar,
361
+ {
362
+ open: showSuccess,
363
+ autoHideDuration: 3e3,
364
+ onClose: () => setShowSuccess(false),
365
+ message: "Account created successfully"
366
+ }
367
+ )
368
+ ] }) });
369
+ }
370
+ var ACCOUNT_TYPES2 = [
371
+ "checking",
372
+ "savings",
373
+ "cards",
374
+ "student_loans",
375
+ "bill",
376
+ "autos",
377
+ "home",
378
+ "investment",
379
+ "loan",
380
+ "asset",
381
+ "cd",
382
+ "money_market",
383
+ "certificates",
384
+ "commercial",
385
+ "creditline"
386
+ ];
387
+ var ACCOUNT_STATES2 = [
388
+ "active",
389
+ "closed",
390
+ "archived",
391
+ "pending_deletion"
392
+ ];
393
+ function AccountEditForm({ account, open, onClose, userId }) {
394
+ const [formData, setFormData] = react.useState(account);
395
+ react.useEffect(() => {
396
+ setFormData(account);
397
+ }, [account]);
398
+ const updateMutation = accountsDataAccess.useUpdateAccount({
399
+ onSuccess: () => {
400
+ onClose();
401
+ }
402
+ });
403
+ const handleSubmit = (e) => {
404
+ e.preventDefault();
405
+ updateMutation.mutate({
406
+ userId,
407
+ accountId: account.id,
408
+ data: formData
409
+ });
410
+ };
411
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Dialog, { open, onClose, maxWidth: "sm", fullWidth: true, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
412
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { children: "Edit Account" }),
413
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogContent, { children: [
414
+ /* @__PURE__ */ jsxRuntime.jsx(
415
+ material.TextField,
416
+ {
417
+ label: "Account Name",
418
+ fullWidth: true,
419
+ margin: "normal",
420
+ value: formData.name,
421
+ onChange: (e) => setFormData({ ...formData, name: e.target.value }),
422
+ required: true
423
+ }
424
+ ),
425
+ /* @__PURE__ */ jsxRuntime.jsx(
426
+ material.TextField,
427
+ {
428
+ label: "Balance",
429
+ fullWidth: true,
430
+ margin: "normal",
431
+ value: formData.balance,
432
+ onChange: (e) => setFormData({ ...formData, balance: e.target.value }),
433
+ required: true,
434
+ helperText: "Format: 1234.56"
435
+ }
436
+ ),
437
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", children: [
438
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "Account Type" }),
439
+ /* @__PURE__ */ jsxRuntime.jsx(
440
+ material.Select,
441
+ {
442
+ value: formData.account_type,
443
+ onChange: (e) => setFormData({ ...formData, account_type: e.target.value }),
444
+ label: "Account Type",
445
+ children: ACCOUNT_TYPES2.map((type) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: type, children: type.replace("_", " ").toUpperCase() }, type))
446
+ }
447
+ )
448
+ ] }),
449
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", children: [
450
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "State" }),
451
+ /* @__PURE__ */ jsxRuntime.jsx(
452
+ material.Select,
453
+ {
454
+ value: formData.state,
455
+ onChange: (e) => setFormData({ ...formData, state: e.target.value }),
456
+ label: "State",
457
+ children: ACCOUNT_STATES2.map((state) => /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: state, children: state.replace("_", " ").toUpperCase() }, state))
458
+ }
459
+ )
460
+ ] }),
461
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", sx: { mt: 2, mb: 1 }, children: "Include in:" }),
462
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormGroup, { children: [
463
+ /* @__PURE__ */ jsxRuntime.jsx(
464
+ material.FormControlLabel,
465
+ {
466
+ control: /* @__PURE__ */ jsxRuntime.jsx(
467
+ material.Checkbox,
468
+ {
469
+ checked: formData.include_in_expenses,
470
+ onChange: (e) => setFormData({ ...formData, include_in_expenses: e.target.checked })
471
+ }
472
+ ),
473
+ label: "Expenses"
474
+ }
475
+ ),
476
+ /* @__PURE__ */ jsxRuntime.jsx(
477
+ material.FormControlLabel,
478
+ {
479
+ control: /* @__PURE__ */ jsxRuntime.jsx(
480
+ material.Checkbox,
481
+ {
482
+ checked: formData.include_in_budget,
483
+ onChange: (e) => setFormData({ ...formData, include_in_budget: e.target.checked })
484
+ }
485
+ ),
486
+ label: "Budget"
487
+ }
488
+ ),
489
+ /* @__PURE__ */ jsxRuntime.jsx(
490
+ material.FormControlLabel,
491
+ {
492
+ control: /* @__PURE__ */ jsxRuntime.jsx(
493
+ material.Checkbox,
494
+ {
495
+ checked: formData.include_in_cashflow,
496
+ onChange: (e) => setFormData({ ...formData, include_in_cashflow: e.target.checked })
497
+ }
498
+ ),
499
+ label: "Cashflow"
500
+ }
501
+ ),
502
+ /* @__PURE__ */ jsxRuntime.jsx(
503
+ material.FormControlLabel,
504
+ {
505
+ control: /* @__PURE__ */ jsxRuntime.jsx(
506
+ material.Checkbox,
507
+ {
508
+ checked: formData.include_in_dashboard,
509
+ onChange: (e) => setFormData({ ...formData, include_in_dashboard: e.target.checked })
510
+ }
511
+ ),
512
+ label: "Dashboard"
513
+ }
514
+ ),
515
+ /* @__PURE__ */ jsxRuntime.jsx(
516
+ material.FormControlLabel,
517
+ {
518
+ control: /* @__PURE__ */ jsxRuntime.jsx(
519
+ material.Checkbox,
520
+ {
521
+ checked: formData.include_in_goals,
522
+ onChange: (e) => setFormData({ ...formData, include_in_goals: e.target.checked })
523
+ }
524
+ ),
525
+ label: "Goals"
526
+ }
527
+ ),
528
+ /* @__PURE__ */ jsxRuntime.jsx(
529
+ material.FormControlLabel,
530
+ {
531
+ control: /* @__PURE__ */ jsxRuntime.jsx(
532
+ material.Checkbox,
533
+ {
534
+ checked: formData.include_in_networth,
535
+ onChange: (e) => setFormData({ ...formData, include_in_networth: e.target.checked })
536
+ }
537
+ ),
538
+ label: "Net Worth"
539
+ }
540
+ )
541
+ ] }),
542
+ updateMutation.isError && /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", sx: { mt: 2 }, children: updateMutation.error instanceof Error ? updateMutation.error.message : "Failed to update account" })
543
+ ] }),
544
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
545
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: onClose, children: "Cancel" }),
546
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { type: "submit", variant: "contained", disabled: updateMutation.isPending, children: updateMutation.isPending ? "Saving..." : "Save" })
547
+ ] })
548
+ ] }) });
549
+ }
550
+ function AccountDeleteButton({
551
+ accountId,
552
+ userId,
553
+ accountName
554
+ }) {
555
+ const [confirmOpen, setConfirmOpen] = react.useState(false);
556
+ const deleteMutation = accountsDataAccess.useDeleteAccount({
557
+ onSuccess: () => {
558
+ setConfirmOpen(false);
559
+ }
560
+ });
561
+ const handleDelete = () => {
562
+ deleteMutation.mutate({ userId, accountId });
563
+ };
564
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
565
+ /* @__PURE__ */ jsxRuntime.jsx(
566
+ material.IconButton,
567
+ {
568
+ color: "error",
569
+ onClick: () => setConfirmOpen(true),
570
+ size: "small",
571
+ "aria-label": "delete account",
572
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Delete, {})
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Dialog, { open: confirmOpen, onClose: () => setConfirmOpen(false), children: [
576
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { children: "Delete Account?" }),
577
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { children: [
578
+ 'Are you sure you want to delete "',
579
+ accountName,
580
+ '"? This action cannot be undone.'
581
+ ] }) }),
582
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
583
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: () => setConfirmOpen(false), children: "Cancel" }),
584
+ /* @__PURE__ */ jsxRuntime.jsx(
585
+ material.Button,
586
+ {
587
+ onClick: handleDelete,
588
+ color: "error",
589
+ variant: "contained",
590
+ disabled: deleteMutation.isPending,
591
+ children: deleteMutation.isPending ? "Deleting..." : "Delete"
592
+ }
593
+ )
594
+ ] })
595
+ ] })
596
+ ] });
597
+ }
598
+ var defaultCurrencyFormatter = (value) => {
599
+ if (Math.abs(value) >= 1e3) {
600
+ return new Intl.NumberFormat("en-US", {
601
+ style: "currency",
602
+ currency: "USD",
603
+ notation: "compact",
604
+ minimumFractionDigits: 0,
605
+ maximumFractionDigits: 1
606
+ }).format(value);
607
+ }
608
+ return new Intl.NumberFormat("en-US", {
609
+ style: "currency",
610
+ currency: "USD",
611
+ minimumFractionDigits: 0,
612
+ maximumFractionDigits: 0
613
+ }).format(value);
614
+ };
615
+ function AccountBalanceChart({
616
+ series,
617
+ width = "100%",
618
+ height = 150,
619
+ showLegend,
620
+ currencyFormatter = defaultCurrencyFormatter,
621
+ onPointClick
622
+ }) {
623
+ const theme = material.useTheme();
624
+ const displayLegend = showLegend !== void 0 ? showLegend : series.length > 1;
625
+ const chartData = react.useMemo(() => {
626
+ const allDates = /* @__PURE__ */ new Set();
627
+ series.forEach((s) => {
628
+ s.data.forEach((d) => allDates.add(d.date.getTime()));
629
+ });
630
+ const sortedDates = Array.from(allDates).sort((a, b) => a - b);
631
+ const xAxisData = sortedDates.map((timestamp) => new Date(timestamp));
632
+ const seriesData = series.map((s, index) => {
633
+ const dataMap = /* @__PURE__ */ new Map();
634
+ s.data.forEach((d) => {
635
+ dataMap.set(d.date.getTime(), d.balance);
636
+ });
637
+ const yData = sortedDates.map((timestamp) => dataMap.get(timestamp) ?? null);
638
+ return {
639
+ id: s.accountId,
640
+ label: s.accountName,
641
+ data: yData,
642
+ color: s.color || theme.palette.primary.main,
643
+ showMark: false,
644
+ curve: "linear"
645
+ };
646
+ });
647
+ return { xAxisData, seriesData };
648
+ }, [series, theme.palette.primary.main]);
649
+ return /* @__PURE__ */ jsxRuntime.jsx(
650
+ material.Box,
651
+ {
652
+ "data-testid": "account-balance-chart",
653
+ sx: {
654
+ width: "100%",
655
+ height
656
+ },
657
+ children: /* @__PURE__ */ jsxRuntime.jsx(
658
+ LineChart.LineChart,
659
+ {
660
+ xAxis: [
661
+ {
662
+ data: chartData.xAxisData,
663
+ scaleType: "time",
664
+ valueFormatter: (value) => {
665
+ return new Intl.DateTimeFormat("en-US", { month: "short" }).format(value);
666
+ }
667
+ }
668
+ ],
669
+ yAxis: [
670
+ {
671
+ valueFormatter: currencyFormatter
672
+ }
673
+ ],
674
+ series: chartData.seriesData,
675
+ width: typeof width === "number" ? width : void 0,
676
+ height,
677
+ margin: { top: 10, right: 20, bottom: 20, left: 50 },
678
+ grid: { vertical: false, horizontal: true },
679
+ slotProps: displayLegend ? {
680
+ legend: {
681
+ position: { vertical: "top", horizontal: "center" }
682
+ }
683
+ } : void 0,
684
+ sx: {
685
+ "& .MuiLineElement-root": {
686
+ strokeWidth: 3
687
+ },
688
+ "& .MuiChartsAxis-tickLabel": {
689
+ fontSize: "10px"
690
+ },
691
+ "& .MuiChartsGrid-line": {
692
+ stroke: theme.palette.grey[600],
693
+ strokeOpacity: 0.3,
694
+ strokeWidth: 0.5
695
+ }
696
+ }
697
+ }
698
+ )
699
+ }
700
+ );
701
+ }
702
+ function NetWorthSummary({
703
+ userId,
704
+ title = "Net Worth Summary",
705
+ currencySymbol = "$"
706
+ }) {
707
+ const summary = accountsFeature.useNetWorthSummary(userId);
708
+ if (!summary) {
709
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
711
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading net worth..." })
712
+ ] }) });
713
+ }
714
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
715
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
716
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 3 }, children: [
717
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1 }, children: [
718
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Net Worth" }),
719
+ summary.isIncreasing ? /* @__PURE__ */ jsxRuntime.jsx(
720
+ material.Chip,
721
+ {
722
+ icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingUp, {}),
723
+ label: `+${currencySymbol}${Math.abs(summary.netWorthChange).toFixed(2)}`,
724
+ color: "success",
725
+ size: "small"
726
+ }
727
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
728
+ material.Chip,
729
+ {
730
+ icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingDown, {}),
731
+ label: `-${currencySymbol}${Math.abs(summary.netWorthChange).toFixed(2)}`,
732
+ color: "error",
733
+ size: "small"
734
+ }
735
+ )
736
+ ] }),
737
+ /* @__PURE__ */ jsxRuntime.jsxs(
738
+ material.Typography,
739
+ {
740
+ variant: "h4",
741
+ color: summary.isPositiveNetWorth ? "primary" : "error",
742
+ children: [
743
+ currencySymbol,
744
+ summary.netWorth.toFixed(2)
745
+ ]
746
+ }
747
+ )
748
+ ] }),
749
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 2, children: [
750
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
751
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Total Assets" }),
752
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "h6", color: "success.main", children: [
753
+ currencySymbol,
754
+ summary.totalAssets.toFixed(2)
755
+ ] }),
756
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "caption", color: "text.secondary", children: [
757
+ summary.assetCount,
758
+ " accounts (",
759
+ summary.manualAssetCount,
760
+ " manual, ",
761
+ summary.aggregatedAssetCount,
762
+ " aggregated)"
763
+ ] })
764
+ ] }) }),
765
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
766
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Total Debts" }),
767
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "h6", color: "error.main", children: [
768
+ currencySymbol,
769
+ summary.totalDebts.toFixed(2)
770
+ ] }),
771
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "caption", color: "text.secondary", children: [
772
+ summary.debtCount,
773
+ " accounts (",
774
+ summary.manualDebtCount,
775
+ " manual, ",
776
+ summary.aggregatedDebtCount,
777
+ " aggregated)"
778
+ ] })
779
+ ] }) })
780
+ ] }),
781
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 2, display: "flex", gap: 1, flexWrap: "wrap" }, children: [
782
+ summary.hasAssets && /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { label: "Has Assets", size: "small", color: "success", variant: "outlined" }),
783
+ summary.hasDebts && /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { label: "Has Debts", size: "small", color: "error", variant: "outlined" }),
784
+ summary.hasManualAccounts && /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { label: "Manual Accounts", size: "small", variant: "outlined" })
785
+ ] })
786
+ ] }) });
787
+ }
788
+ function NetWorthHistoryChart({
789
+ userId,
790
+ title = "Net Worth History",
791
+ height = 400,
792
+ currencySymbol = "$"
793
+ }) {
794
+ const history = accountsFeature.useNetWorthHistory(userId);
795
+ const theme = material.useTheme();
796
+ if (!history) {
797
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
798
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
799
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading history..." })
800
+ ] }) });
801
+ }
802
+ if (history.length === 0) {
803
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
804
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
805
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "No history data available" })
806
+ ] }) });
807
+ }
808
+ const dates = history.map((point) => point.formattedDate);
809
+ const netWorthData = history.map((point) => point.totalAsNumber);
810
+ const assetsData = history.map((point) => point.totalAssetAsNumber);
811
+ const debtsData = history.map((point) => point.totalDebtAsNumber);
812
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
813
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: title }),
814
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { width: "100%", height }, children: /* @__PURE__ */ jsxRuntime.jsx(
815
+ LineChart.LineChart,
816
+ {
817
+ xAxis: [
818
+ {
819
+ data: dates,
820
+ scaleType: "point",
821
+ label: "Date"
822
+ }
823
+ ],
824
+ series: [
825
+ {
826
+ data: netWorthData,
827
+ label: "Net Worth",
828
+ color: theme.palette.primary.main,
829
+ curve: "linear"
830
+ },
831
+ {
832
+ data: assetsData,
833
+ label: "Assets",
834
+ color: theme.palette.success.main,
835
+ curve: "linear"
836
+ },
837
+ {
838
+ data: debtsData,
839
+ label: "Debts",
840
+ color: theme.palette.error.main,
841
+ curve: "linear"
842
+ }
843
+ ],
844
+ height,
845
+ margin: { left: 80, right: 20, top: 20, bottom: 50 },
846
+ grid: { vertical: true, horizontal: true },
847
+ slotProps: {
848
+ legend: {
849
+ position: { vertical: "top", horizontal: "center" }
850
+ }
851
+ }
852
+ }
853
+ ) }),
854
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 2, display: "flex", gap: 3, justifyContent: "center" }, children: [
855
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { textAlign: "center" }, children: [
856
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "caption", color: "text.secondary", children: "Latest" }),
857
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "body2", fontWeight: "bold", children: [
858
+ currencySymbol,
859
+ history[history.length - 1].totalAsNumber.toFixed(2)
860
+ ] })
861
+ ] }),
862
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { textAlign: "center" }, children: [
863
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "caption", color: "text.secondary", children: "Change" }),
864
+ /* @__PURE__ */ jsxRuntime.jsxs(
865
+ material.Typography,
866
+ {
867
+ variant: "body2",
868
+ fontWeight: "bold",
869
+ color: history[history.length - 1].isGrowing ? "success.main" : "error.main",
870
+ children: [
871
+ history[history.length - 1].isGrowing ? "+" : "",
872
+ currencySymbol,
873
+ history[history.length - 1].sinceLastMonthAsNumber.toFixed(2)
874
+ ]
875
+ }
876
+ )
877
+ ] }),
878
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { textAlign: "center" }, children: [
879
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "caption", color: "text.secondary", children: "Data Points" }),
880
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", fontWeight: "bold", children: history.length })
881
+ ] })
882
+ ] })
883
+ ] }) });
884
+ }
885
+ function NetWorthAccountForm({
886
+ userId,
887
+ accountId,
888
+ initialValues,
889
+ onSuccess,
890
+ onCancel
891
+ }) {
892
+ const isEditMode = !!accountId;
893
+ const [formData, setFormData] = react.useState(
894
+ initialValues || {
895
+ networth_account: {
896
+ account_type: "asset",
897
+ name: "",
898
+ balance: "0.00"
899
+ }
900
+ }
901
+ );
902
+ const [showSuccess, setShowSuccess] = react.useState(false);
903
+ const [showError, setShowError] = react.useState(false);
904
+ const [errorMessage, setErrorMessage] = react.useState("");
905
+ const createMutation = accountsDataAccess.useCreateNetWorthAccount({
906
+ onSuccess: () => {
907
+ setShowSuccess(true);
908
+ setFormData({
909
+ networth_account: {
910
+ account_type: "asset",
911
+ name: "",
912
+ balance: "0.00"
913
+ }
914
+ });
915
+ onSuccess?.();
916
+ },
917
+ onError: (error) => {
918
+ setErrorMessage(error.message);
919
+ setShowError(true);
920
+ }
921
+ });
922
+ const updateMutation = accountsDataAccess.useUpdateNetWorthAccount({
923
+ onSuccess: () => {
924
+ setShowSuccess(true);
925
+ onSuccess?.();
926
+ },
927
+ onError: (error) => {
928
+ setErrorMessage(error.message);
929
+ setShowError(true);
930
+ }
931
+ });
932
+ const handleSubmit = (e) => {
933
+ e.preventDefault();
934
+ if (isEditMode && accountId) {
935
+ updateMutation.mutate({
936
+ userId,
937
+ accountId,
938
+ data: {
939
+ networth_account: {
940
+ name: formData.networth_account?.name,
941
+ balance: formData.networth_account?.balance,
942
+ account_type: formData.networth_account?.account_type
943
+ }
944
+ }
945
+ });
946
+ } else {
947
+ createMutation.mutate({
948
+ userId,
949
+ data: formData
950
+ });
951
+ }
952
+ };
953
+ const handleChange = (field, value) => {
954
+ setFormData((prev) => ({
955
+ ...prev,
956
+ networth_account: {
957
+ ...prev.networth_account,
958
+ [field]: value
959
+ }
960
+ }));
961
+ };
962
+ const isLoading = createMutation.isPending || updateMutation.isPending;
963
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Paper, { sx: { p: 3 }, children: [
964
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: isEditMode ? "Edit Manual Account" : "Add Manual Account" }),
965
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { component: "form", onSubmit: handleSubmit, sx: { mt: 2 }, children: [
966
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", required: true, children: [
967
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "Type" }),
968
+ /* @__PURE__ */ jsxRuntime.jsxs(
969
+ material.Select,
970
+ {
971
+ value: formData.networth_account?.account_type || "asset",
972
+ label: "Type",
973
+ onChange: (e) => handleChange("account_type", e.target.value),
974
+ disabled: isLoading,
975
+ children: [
976
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "asset", children: "Asset" }),
977
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "debt", children: "Debt" })
978
+ ]
979
+ }
980
+ )
981
+ ] }),
982
+ /* @__PURE__ */ jsxRuntime.jsx(
983
+ material.TextField,
984
+ {
985
+ fullWidth: true,
986
+ margin: "normal",
987
+ label: "Account Name",
988
+ value: formData.networth_account?.name || "",
989
+ onChange: (e) => handleChange("name", e.target.value),
990
+ required: true,
991
+ disabled: isLoading,
992
+ helperText: "e.g., 'Car', 'Investment Property', 'Student Loan'"
993
+ }
994
+ ),
995
+ /* @__PURE__ */ jsxRuntime.jsx(
996
+ material.TextField,
997
+ {
998
+ fullWidth: true,
999
+ margin: "normal",
1000
+ label: "Balance",
1001
+ type: "number",
1002
+ inputProps: {
1003
+ step: "0.01",
1004
+ min: "0"
1005
+ },
1006
+ value: formData.networth_account?.balance || "0.00",
1007
+ onChange: (e) => handleChange("balance", e.target.value),
1008
+ required: true,
1009
+ disabled: isLoading,
1010
+ helperText: "Current value (for assets) or amount owed (for debts)"
1011
+ }
1012
+ ),
1013
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 3, display: "flex", gap: 2 }, children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx(
1015
+ material.Button,
1016
+ {
1017
+ type: "submit",
1018
+ variant: "contained",
1019
+ disabled: isLoading,
1020
+ fullWidth: !onCancel,
1021
+ children: isEditMode ? "Update Account" : "Add Account"
1022
+ }
1023
+ ),
1024
+ onCancel && /* @__PURE__ */ jsxRuntime.jsx(
1025
+ material.Button,
1026
+ {
1027
+ variant: "outlined",
1028
+ onClick: onCancel,
1029
+ disabled: isLoading,
1030
+ children: "Cancel"
1031
+ }
1032
+ )
1033
+ ] })
1034
+ ] }),
1035
+ /* @__PURE__ */ jsxRuntime.jsx(
1036
+ material.Snackbar,
1037
+ {
1038
+ open: showSuccess,
1039
+ autoHideDuration: 3e3,
1040
+ onClose: () => setShowSuccess(false),
1041
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1042
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "success", onClose: () => setShowSuccess(false), children: isEditMode ? "Account updated successfully!" : "Account added successfully!" })
1043
+ }
1044
+ ),
1045
+ /* @__PURE__ */ jsxRuntime.jsx(
1046
+ material.Snackbar,
1047
+ {
1048
+ open: showError,
1049
+ autoHideDuration: 5e3,
1050
+ onClose: () => setShowError(false),
1051
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1052
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", onClose: () => setShowError(false), children: errorMessage || "An error occurred" })
1053
+ }
1054
+ )
1055
+ ] });
1056
+ }
1057
+ function NetWorthAccountEnhancedForm({
1058
+ userId,
1059
+ accountId,
1060
+ initialValues,
1061
+ onSuccess,
1062
+ onCancel,
1063
+ wizardMode = false,
1064
+ currencySymbol = "$"
1065
+ }) {
1066
+ const isEditMode = !!accountId;
1067
+ const [activeStep, setActiveStep] = react.useState(0);
1068
+ const [formData, setFormData] = react.useState(
1069
+ initialValues || {
1070
+ networth_account: {
1071
+ account_type: "asset",
1072
+ name: "",
1073
+ balance: "0.00"
1074
+ },
1075
+ category: "",
1076
+ notes: "",
1077
+ institution: ""
1078
+ }
1079
+ );
1080
+ const [validation, setValidation] = react.useState({
1081
+ name: true,
1082
+ balance: true,
1083
+ category: true
1084
+ });
1085
+ const [showSuccess, setShowSuccess] = react.useState(false);
1086
+ const [showError, setShowError] = react.useState(false);
1087
+ const [errorMessage, setErrorMessage] = react.useState("");
1088
+ const createMutation = accountsDataAccess.useCreateNetWorthAccount({
1089
+ onSuccess: () => {
1090
+ setShowSuccess(true);
1091
+ setFormData({
1092
+ networth_account: {
1093
+ account_type: "asset",
1094
+ name: "",
1095
+ balance: "0.00"
1096
+ },
1097
+ category: "",
1098
+ notes: "",
1099
+ institution: ""
1100
+ });
1101
+ setActiveStep(0);
1102
+ onSuccess?.();
1103
+ },
1104
+ onError: (error) => {
1105
+ setErrorMessage(error.message);
1106
+ setShowError(true);
1107
+ }
1108
+ });
1109
+ const updateMutation = accountsDataAccess.useUpdateNetWorthAccount({
1110
+ onSuccess: () => {
1111
+ setShowSuccess(true);
1112
+ onSuccess?.();
1113
+ },
1114
+ onError: (error) => {
1115
+ setErrorMessage(error.message);
1116
+ setShowError(true);
1117
+ }
1118
+ });
1119
+ const assetCategories = [
1120
+ "Cash & Checking",
1121
+ "Savings",
1122
+ "Investment Account",
1123
+ "Retirement (401k/IRA)",
1124
+ "Real Estate",
1125
+ "Vehicle",
1126
+ "Personal Property",
1127
+ "Business Assets",
1128
+ "Other Assets"
1129
+ ];
1130
+ const debtCategories = [
1131
+ "Credit Card",
1132
+ "Mortgage",
1133
+ "Auto Loan",
1134
+ "Student Loan",
1135
+ "Personal Loan",
1136
+ "Medical Debt",
1137
+ "Business Loan",
1138
+ "Other Debt"
1139
+ ];
1140
+ const categories = formData.networth_account?.account_type === "asset" ? assetCategories : debtCategories;
1141
+ const validateForm = () => {
1142
+ const newValidation = {
1143
+ name: !!formData.networth_account?.name?.trim(),
1144
+ balance: !!formData.networth_account?.balance,
1145
+ category: !!formData.category
1146
+ };
1147
+ setValidation(newValidation);
1148
+ return Object.values(newValidation).every((v) => v);
1149
+ };
1150
+ const handleSubmit = (e) => {
1151
+ e.preventDefault();
1152
+ if (!validateForm()) {
1153
+ setErrorMessage("Please fill in all required fields");
1154
+ setShowError(true);
1155
+ return;
1156
+ }
1157
+ const accountData = {
1158
+ networth_account: {
1159
+ account_type: formData.networth_account.account_type,
1160
+ name: formData.networth_account.name,
1161
+ balance: formData.networth_account.balance
1162
+ }
1163
+ };
1164
+ if (isEditMode && accountId) {
1165
+ updateMutation.mutate({
1166
+ userId,
1167
+ accountId,
1168
+ data: {
1169
+ networth_account: {
1170
+ name: accountData.networth_account.name,
1171
+ balance: accountData.networth_account.balance,
1172
+ account_type: accountData.networth_account.account_type
1173
+ }
1174
+ }
1175
+ });
1176
+ } else {
1177
+ createMutation.mutate({
1178
+ userId,
1179
+ data: accountData
1180
+ });
1181
+ }
1182
+ };
1183
+ const handleChange = (field, value) => {
1184
+ if (field === "category" || field === "notes" || field === "institution" || field === "lastUpdated") {
1185
+ setFormData((prev) => ({
1186
+ ...prev,
1187
+ [field]: value
1188
+ }));
1189
+ } else {
1190
+ setFormData((prev) => ({
1191
+ ...prev,
1192
+ networth_account: {
1193
+ ...prev.networth_account,
1194
+ [field]: value
1195
+ }
1196
+ }));
1197
+ }
1198
+ };
1199
+ const handleNext = () => {
1200
+ if (activeStep === 0 && !formData.networth_account?.name?.trim()) {
1201
+ setValidation((prev) => ({ ...prev, name: false }));
1202
+ return;
1203
+ }
1204
+ setActiveStep((prev) => prev + 1);
1205
+ };
1206
+ const handleBack = () => {
1207
+ setActiveStep((prev) => prev - 1);
1208
+ };
1209
+ const isLoading = createMutation.isPending || updateMutation.isPending;
1210
+ const balance = parseFloat(formData.networth_account?.balance || "0");
1211
+ const isAsset = formData.networth_account?.account_type === "asset";
1212
+ const steps = ["Basic Info", "Details", "Review"];
1213
+ const renderStepContent = (step) => {
1214
+ switch (step) {
1215
+ case 0:
1216
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1217
+ /* @__PURE__ */ jsxRuntime.jsxs(material.FormControl, { fullWidth: true, margin: "normal", required: true, children: [
1218
+ /* @__PURE__ */ jsxRuntime.jsx(material.InputLabel, { children: "Account Type" }),
1219
+ /* @__PURE__ */ jsxRuntime.jsxs(
1220
+ material.Select,
1221
+ {
1222
+ value: formData.networth_account?.account_type || "asset",
1223
+ label: "Account Type",
1224
+ onChange: (e) => handleChange("account_type", e.target.value),
1225
+ disabled: isLoading,
1226
+ startAdornment: /* @__PURE__ */ jsxRuntime.jsx(material.InputAdornment, { position: "start", children: isAsset ? /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingUp, { color: "success" }) : /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingDown, { color: "error" }) }),
1227
+ children: [
1228
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "asset", children: "Asset (Increases Net Worth)" }),
1229
+ /* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { value: "debt", children: "Debt (Decreases Net Worth)" })
1230
+ ]
1231
+ }
1232
+ )
1233
+ ] }),
1234
+ /* @__PURE__ */ jsxRuntime.jsx(
1235
+ material.TextField,
1236
+ {
1237
+ fullWidth: true,
1238
+ margin: "normal",
1239
+ label: "Account Name",
1240
+ value: formData.networth_account?.name || "",
1241
+ onChange: (e) => handleChange("name", e.target.value),
1242
+ required: true,
1243
+ error: !validation.name,
1244
+ disabled: isLoading,
1245
+ helperText: !validation.name ? "Account name is required" : isAsset ? 'e.g., "Emergency Fund", "401k", "Home Equity"' : 'e.g., "Credit Card", "Car Loan", "Mortgage"',
1246
+ InputProps: {
1247
+ startAdornment: /* @__PURE__ */ jsxRuntime.jsx(material.InputAdornment, { position: "start", children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.AccountBalance, {}) })
1248
+ }
1249
+ }
1250
+ ),
1251
+ /* @__PURE__ */ jsxRuntime.jsx(
1252
+ material.TextField,
1253
+ {
1254
+ fullWidth: true,
1255
+ margin: "normal",
1256
+ label: isAsset ? "Current Value" : "Amount Owed",
1257
+ type: "number",
1258
+ inputProps: {
1259
+ step: "0.01",
1260
+ min: "0"
1261
+ },
1262
+ value: formData.networth_account?.balance || "0.00",
1263
+ onChange: (e) => handleChange("balance", e.target.value),
1264
+ required: true,
1265
+ error: !validation.balance,
1266
+ disabled: isLoading,
1267
+ helperText: !validation.balance ? "Balance is required" : isAsset ? "Enter the current market value" : "Enter the total amount you owe",
1268
+ InputProps: {
1269
+ startAdornment: /* @__PURE__ */ jsxRuntime.jsx(material.InputAdornment, { position: "start", children: currencySymbol })
1270
+ }
1271
+ }
1272
+ )
1273
+ ] });
1274
+ case 1:
1275
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1276
+ /* @__PURE__ */ jsxRuntime.jsx(
1277
+ material.Autocomplete,
1278
+ {
1279
+ freeSolo: true,
1280
+ options: categories,
1281
+ value: formData.category || "",
1282
+ onChange: (_e, value) => handleChange("category", value || ""),
1283
+ renderInput: (params) => /* @__PURE__ */ jsxRuntime.jsx(
1284
+ material.TextField,
1285
+ {
1286
+ ...params,
1287
+ label: "Category",
1288
+ margin: "normal",
1289
+ required: true,
1290
+ error: !validation.category,
1291
+ helperText: !validation.category ? "Category is required" : "Select or create a custom category"
1292
+ }
1293
+ ),
1294
+ disabled: isLoading
1295
+ }
1296
+ ),
1297
+ /* @__PURE__ */ jsxRuntime.jsx(
1298
+ material.TextField,
1299
+ {
1300
+ fullWidth: true,
1301
+ margin: "normal",
1302
+ label: "Institution (Optional)",
1303
+ value: formData.institution || "",
1304
+ onChange: (e) => handleChange("institution", e.target.value),
1305
+ disabled: isLoading,
1306
+ helperText: "e.g., Bank name, Credit card issuer"
1307
+ }
1308
+ ),
1309
+ /* @__PURE__ */ jsxRuntime.jsx(
1310
+ material.TextField,
1311
+ {
1312
+ fullWidth: true,
1313
+ margin: "normal",
1314
+ label: "Notes (Optional)",
1315
+ multiline: true,
1316
+ rows: 3,
1317
+ value: formData.notes || "",
1318
+ onChange: (e) => handleChange("notes", e.target.value),
1319
+ disabled: isLoading,
1320
+ helperText: "Add any additional details or context"
1321
+ }
1322
+ )
1323
+ ] });
1324
+ case 2:
1325
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
1326
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Alert, { severity: isAsset ? "success" : "warning", sx: { mb: 2 }, children: [
1327
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "subtitle2", gutterBottom: true, children: [
1328
+ "Review Your ",
1329
+ isAsset ? "Asset" : "Debt"
1330
+ ] }),
1331
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "caption", children: isAsset ? "This account will increase your net worth" : "This account will decrease your net worth" })
1332
+ ] }),
1333
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
1334
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Account Type" }),
1335
+ /* @__PURE__ */ jsxRuntime.jsx(
1336
+ material.Chip,
1337
+ {
1338
+ label: isAsset ? "Asset" : "Debt",
1339
+ color: isAsset ? "success" : "error",
1340
+ icon: isAsset ? /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingUp, {}) : /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.TrendingDown, {}),
1341
+ size: "small"
1342
+ }
1343
+ )
1344
+ ] }),
1345
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
1346
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Account Name" }),
1347
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", children: formData.networth_account?.name })
1348
+ ] }),
1349
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
1350
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: isAsset ? "Current Value" : "Amount Owed" }),
1351
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "h4", color: isAsset ? "success.main" : "error.main", children: [
1352
+ currencySymbol,
1353
+ balance.toFixed(2)
1354
+ ] })
1355
+ ] }),
1356
+ formData.category && /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
1357
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Category" }),
1358
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { children: formData.category })
1359
+ ] }),
1360
+ formData.institution && /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
1361
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Institution" }),
1362
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { children: formData.institution })
1363
+ ] }),
1364
+ formData.notes && /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 2 }, children: [
1365
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Notes" }),
1366
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", children: formData.notes })
1367
+ ] }),
1368
+ /* @__PURE__ */ jsxRuntime.jsx(material.Divider, { sx: { my: 2 } }),
1369
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Alert, { severity: "info", children: [
1370
+ "Net Worth Impact: ",
1371
+ isAsset ? "+" : "-",
1372
+ currencySymbol,
1373
+ balance.toFixed(2)
1374
+ ] })
1375
+ ] });
1376
+ default:
1377
+ return null;
1378
+ }
1379
+ };
1380
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Paper, { sx: { p: 3 }, children: [
1381
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: isEditMode ? "Edit Manual Account" : "Add Manual Account" }),
1382
+ wizardMode && !isEditMode && /* @__PURE__ */ jsxRuntime.jsx(material.Stepper, { activeStep, sx: { mt: 2, mb: 3 }, children: steps.map((label) => /* @__PURE__ */ jsxRuntime.jsx(material.Step, { children: /* @__PURE__ */ jsxRuntime.jsx(material.StepLabel, { children: label }) }, label)) }),
1383
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { component: "form", onSubmit: handleSubmit, sx: { mt: 2 }, children: wizardMode && !isEditMode ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1384
+ renderStepContent(activeStep),
1385
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 3, display: "flex", gap: 2, justifyContent: "space-between" }, children: [
1386
+ /* @__PURE__ */ jsxRuntime.jsx(
1387
+ material.Button,
1388
+ {
1389
+ disabled: activeStep === 0 || isLoading,
1390
+ onClick: handleBack,
1391
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.NavigateBefore, {}),
1392
+ children: "Back"
1393
+ }
1394
+ ),
1395
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { flex: "1 1 auto" } }),
1396
+ activeStep === steps.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
1397
+ material.Button,
1398
+ {
1399
+ type: "submit",
1400
+ variant: "contained",
1401
+ disabled: isLoading,
1402
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Save, {}),
1403
+ children: isLoading ? "Saving..." : "Save Account"
1404
+ }
1405
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1406
+ material.Button,
1407
+ {
1408
+ variant: "contained",
1409
+ onClick: handleNext,
1410
+ endIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.NavigateNext, {}),
1411
+ disabled: isLoading,
1412
+ children: "Next"
1413
+ }
1414
+ )
1415
+ ] })
1416
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1417
+ renderStepContent(0),
1418
+ renderStepContent(1),
1419
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mt: 3, display: "flex", gap: 2 }, children: [
1420
+ /* @__PURE__ */ jsxRuntime.jsx(
1421
+ material.Button,
1422
+ {
1423
+ type: "submit",
1424
+ variant: "contained",
1425
+ disabled: isLoading,
1426
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Save, {}),
1427
+ fullWidth: !onCancel,
1428
+ children: isLoading ? "Saving..." : isEditMode ? "Update Account" : "Add Account"
1429
+ }
1430
+ ),
1431
+ onCancel && /* @__PURE__ */ jsxRuntime.jsx(
1432
+ material.Button,
1433
+ {
1434
+ variant: "outlined",
1435
+ onClick: onCancel,
1436
+ disabled: isLoading,
1437
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Cancel, {}),
1438
+ children: "Cancel"
1439
+ }
1440
+ )
1441
+ ] })
1442
+ ] }) }),
1443
+ /* @__PURE__ */ jsxRuntime.jsx(
1444
+ material.Snackbar,
1445
+ {
1446
+ open: showSuccess,
1447
+ autoHideDuration: 3e3,
1448
+ onClose: () => setShowSuccess(false),
1449
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1450
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "success", onClose: () => setShowSuccess(false), children: isEditMode ? "Account updated successfully!" : "Account added successfully!" })
1451
+ }
1452
+ ),
1453
+ /* @__PURE__ */ jsxRuntime.jsx(
1454
+ material.Snackbar,
1455
+ {
1456
+ open: showError,
1457
+ autoHideDuration: 5e3,
1458
+ onClose: () => setShowError(false),
1459
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1460
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", onClose: () => setShowError(false), children: errorMessage || "An error occurred" })
1461
+ }
1462
+ )
1463
+ ] });
1464
+ }
1465
+ function NetWorthAccountDeleteButton({
1466
+ userId,
1467
+ accountId,
1468
+ accountName,
1469
+ iconButton = false,
1470
+ onSuccess
1471
+ }) {
1472
+ const [open, setOpen] = react.useState(false);
1473
+ const [showSuccess, setShowSuccess] = react.useState(false);
1474
+ const [showError, setShowError] = react.useState(false);
1475
+ const [errorMessage, setErrorMessage] = react.useState("");
1476
+ const deleteMutation = accountsDataAccess.useDeleteNetWorthAccount({
1477
+ onSuccess: () => {
1478
+ setOpen(false);
1479
+ setShowSuccess(true);
1480
+ onSuccess?.();
1481
+ },
1482
+ onError: (error) => {
1483
+ setOpen(false);
1484
+ setErrorMessage(error.message);
1485
+ setShowError(true);
1486
+ }
1487
+ });
1488
+ const handleClickOpen = () => {
1489
+ setOpen(true);
1490
+ };
1491
+ const handleClose = () => {
1492
+ setOpen(false);
1493
+ };
1494
+ const handleDelete = () => {
1495
+ deleteMutation.mutate({ userId, accountId });
1496
+ };
1497
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1498
+ iconButton ? /* @__PURE__ */ jsxRuntime.jsx(
1499
+ material.IconButton,
1500
+ {
1501
+ color: "error",
1502
+ onClick: handleClickOpen,
1503
+ disabled: deleteMutation.isPending,
1504
+ "aria-label": "delete account",
1505
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Delete, {})
1506
+ }
1507
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1508
+ material.Button,
1509
+ {
1510
+ variant: "outlined",
1511
+ color: "error",
1512
+ onClick: handleClickOpen,
1513
+ disabled: deleteMutation.isPending,
1514
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Delete, {}),
1515
+ children: "Delete"
1516
+ }
1517
+ ),
1518
+ /* @__PURE__ */ jsxRuntime.jsxs(
1519
+ material.Dialog,
1520
+ {
1521
+ open,
1522
+ onClose: handleClose,
1523
+ "aria-labelledby": "delete-dialog-title",
1524
+ "aria-describedby": "delete-dialog-description",
1525
+ children: [
1526
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { id: "delete-dialog-title", children: "Delete Account?" }),
1527
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.DialogContentText, { id: "delete-dialog-description", children: [
1528
+ "Are you sure you want to delete",
1529
+ " ",
1530
+ accountName ? `"${accountName}"` : "this account",
1531
+ "? This action cannot be undone."
1532
+ ] }) }),
1533
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
1534
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: handleClose, disabled: deleteMutation.isPending, children: "Cancel" }),
1535
+ /* @__PURE__ */ jsxRuntime.jsx(
1536
+ material.Button,
1537
+ {
1538
+ onClick: handleDelete,
1539
+ color: "error",
1540
+ variant: "contained",
1541
+ disabled: deleteMutation.isPending,
1542
+ autoFocus: true,
1543
+ children: deleteMutation.isPending ? "Deleting..." : "Delete"
1544
+ }
1545
+ )
1546
+ ] })
1547
+ ]
1548
+ }
1549
+ ),
1550
+ /* @__PURE__ */ jsxRuntime.jsx(
1551
+ material.Snackbar,
1552
+ {
1553
+ open: showSuccess,
1554
+ autoHideDuration: 3e3,
1555
+ onClose: () => setShowSuccess(false),
1556
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1557
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "success", onClose: () => setShowSuccess(false), children: "Account deleted successfully!" })
1558
+ }
1559
+ ),
1560
+ /* @__PURE__ */ jsxRuntime.jsx(
1561
+ material.Snackbar,
1562
+ {
1563
+ open: showError,
1564
+ autoHideDuration: 5e3,
1565
+ onClose: () => setShowError(false),
1566
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
1567
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", onClose: () => setShowError(false), children: errorMessage || "Failed to delete account" })
1568
+ }
1569
+ )
1570
+ ] });
1571
+ }
1572
+ function NetWorthAccountList({
1573
+ userId,
1574
+ currencySymbol = "$",
1575
+ enableBulkOperations = false
1576
+ }) {
1577
+ const { data, isLoading } = accountsDataAccess.useNetWorth({ userId });
1578
+ const [selectedTab, setSelectedTab] = react.useState("all");
1579
+ const [selectedAccounts, setSelectedAccounts] = react.useState(/* @__PURE__ */ new Set());
1580
+ const [editingAccount, setEditingAccount] = react.useState(null);
1581
+ const [showCreateForm, setShowCreateForm] = react.useState(false);
1582
+ const [showBulkDeleteDialog, setShowBulkDeleteDialog] = react.useState(false);
1583
+ const manualAssets = data?.assets.filter((a) => a.additional_networth_account) || [];
1584
+ const manualDebts = data?.debts.filter((d) => d.additional_networth_account) || [];
1585
+ const displayedAccounts = selectedTab === "assets" ? manualAssets : selectedTab === "debts" ? manualDebts : [...manualAssets, ...manualDebts];
1586
+ const handleTabChange = (_event, newValue) => {
1587
+ setSelectedTab(newValue);
1588
+ setSelectedAccounts(/* @__PURE__ */ new Set());
1589
+ };
1590
+ const handleToggleSelect = (id) => {
1591
+ const newSelection = new Set(selectedAccounts);
1592
+ if (newSelection.has(id)) {
1593
+ newSelection.delete(id);
1594
+ } else {
1595
+ newSelection.add(id);
1596
+ }
1597
+ setSelectedAccounts(newSelection);
1598
+ };
1599
+ const handleSelectAll = () => {
1600
+ if (selectedAccounts.size === displayedAccounts.length) {
1601
+ setSelectedAccounts(/* @__PURE__ */ new Set());
1602
+ } else {
1603
+ setSelectedAccounts(new Set(displayedAccounts.map((a) => a.id)));
1604
+ }
1605
+ };
1606
+ const handleEdit = (account) => {
1607
+ setEditingAccount({
1608
+ id: account.id,
1609
+ data: account
1610
+ });
1611
+ };
1612
+ const handleCloseEdit = () => {
1613
+ setEditingAccount(null);
1614
+ };
1615
+ const handleCreateSuccess = () => {
1616
+ setShowCreateForm(false);
1617
+ };
1618
+ const handleEditSuccess = () => {
1619
+ setEditingAccount(null);
1620
+ };
1621
+ const formatBalance = (balance) => {
1622
+ const num = parseFloat(balance);
1623
+ return `${currencySymbol}${num.toFixed(2)}`;
1624
+ };
1625
+ if (isLoading) {
1626
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
1627
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", gutterBottom: true, children: "Manual Accounts" }),
1628
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: "Loading accounts..." })
1629
+ ] }) });
1630
+ }
1631
+ const hasManualAccounts = manualAssets.length > 0 || manualDebts.length > 0;
1632
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Card, { children: [
1633
+ /* @__PURE__ */ jsxRuntime.jsxs(material.CardContent, { children: [
1634
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2 }, children: [
1635
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", children: "Manual Accounts" }),
1636
+ /* @__PURE__ */ jsxRuntime.jsx(
1637
+ material.Button,
1638
+ {
1639
+ variant: "contained",
1640
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Add, {}),
1641
+ onClick: () => setShowCreateForm(true),
1642
+ size: "small",
1643
+ children: "Add Account"
1644
+ }
1645
+ )
1646
+ ] }),
1647
+ !hasManualAccounts ? /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "info", children: 'No manual accounts found. Click "Add Account" to create one.' }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1648
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Tabs, { value: selectedTab, onChange: handleTabChange, sx: { mb: 2 }, children: [
1649
+ /* @__PURE__ */ jsxRuntime.jsx(material.Tab, { label: `All (${manualAssets.length + manualDebts.length})`, value: "all" }),
1650
+ /* @__PURE__ */ jsxRuntime.jsx(material.Tab, { label: `Assets (${manualAssets.length})`, value: "assets" }),
1651
+ /* @__PURE__ */ jsxRuntime.jsx(material.Tab, { label: `Debts (${manualDebts.length})`, value: "debts" })
1652
+ ] }),
1653
+ enableBulkOperations && displayedAccounts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", gap: 2, mb: 2, alignItems: "center" }, children: [
1654
+ /* @__PURE__ */ jsxRuntime.jsx(
1655
+ material.Checkbox,
1656
+ {
1657
+ checked: selectedAccounts.size === displayedAccounts.length && displayedAccounts.length > 0,
1658
+ indeterminate: selectedAccounts.size > 0 && selectedAccounts.size < displayedAccounts.length,
1659
+ onChange: handleSelectAll
1660
+ }
1661
+ ),
1662
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", children: selectedAccounts.size > 0 ? `${selectedAccounts.size} selected` : "Select all" }),
1663
+ selectedAccounts.size > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1664
+ material.Button,
1665
+ {
1666
+ variant: "outlined",
1667
+ color: "error",
1668
+ size: "small",
1669
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Delete, {}),
1670
+ onClick: () => setShowBulkDeleteDialog(true),
1671
+ children: [
1672
+ "Delete Selected (",
1673
+ selectedAccounts.size,
1674
+ ")"
1675
+ ]
1676
+ }
1677
+ )
1678
+ ] }),
1679
+ /* @__PURE__ */ jsxRuntime.jsx(material.List, { children: displayedAccounts.map((account, index) => {
1680
+ const isAsset = "additional_networth_account" in account && account.additional_networth_account;
1681
+ const accountType = isAsset ? "Asset" : "Debt";
1682
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { children: [
1683
+ index > 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Divider, {}),
1684
+ /* @__PURE__ */ jsxRuntime.jsxs(
1685
+ material.ListItem,
1686
+ {
1687
+ sx: {
1688
+ "&:hover": {
1689
+ backgroundColor: "action.hover"
1690
+ }
1691
+ },
1692
+ children: [
1693
+ enableBulkOperations && /* @__PURE__ */ jsxRuntime.jsx(
1694
+ material.Checkbox,
1695
+ {
1696
+ checked: selectedAccounts.has(account.id),
1697
+ onChange: () => handleToggleSelect(account.id),
1698
+ sx: { mr: 1 }
1699
+ }
1700
+ ),
1701
+ /* @__PURE__ */ jsxRuntime.jsx(
1702
+ material.ListItemText,
1703
+ {
1704
+ primary: account.name,
1705
+ secondary: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { component: "span", variant: "body2", color: "text.secondary", children: [
1706
+ accountType,
1707
+ " \u2022 ",
1708
+ formatBalance(account.balance)
1709
+ ] }) })
1710
+ }
1711
+ ),
1712
+ /* @__PURE__ */ jsxRuntime.jsxs(material.ListItemSecondaryAction, { children: [
1713
+ /* @__PURE__ */ jsxRuntime.jsx(
1714
+ material.IconButton,
1715
+ {
1716
+ edge: "end",
1717
+ "aria-label": "edit",
1718
+ onClick: () => handleEdit(account),
1719
+ sx: { mr: 1 },
1720
+ children: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Edit, {})
1721
+ }
1722
+ ),
1723
+ /* @__PURE__ */ jsxRuntime.jsx(
1724
+ NetWorthAccountDeleteButton,
1725
+ {
1726
+ userId,
1727
+ accountId: account.id,
1728
+ accountName: account.name,
1729
+ iconButton: true
1730
+ }
1731
+ )
1732
+ ] })
1733
+ ]
1734
+ }
1735
+ )
1736
+ ] }, account.id);
1737
+ }) })
1738
+ ] })
1739
+ ] }),
1740
+ /* @__PURE__ */ jsxRuntime.jsxs(
1741
+ material.Dialog,
1742
+ {
1743
+ open: showCreateForm,
1744
+ onClose: () => setShowCreateForm(false),
1745
+ maxWidth: "sm",
1746
+ fullWidth: true,
1747
+ children: [
1748
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { children: "Add Manual Account" }),
1749
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsx(
1750
+ NetWorthAccountForm,
1751
+ {
1752
+ userId,
1753
+ onSuccess: handleCreateSuccess,
1754
+ onCancel: () => setShowCreateForm(false)
1755
+ }
1756
+ ) })
1757
+ ]
1758
+ }
1759
+ ),
1760
+ /* @__PURE__ */ jsxRuntime.jsxs(
1761
+ material.Dialog,
1762
+ {
1763
+ open: !!editingAccount,
1764
+ onClose: handleCloseEdit,
1765
+ maxWidth: "sm",
1766
+ fullWidth: true,
1767
+ children: [
1768
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { children: "Edit Account" }),
1769
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: editingAccount && /* @__PURE__ */ jsxRuntime.jsx(
1770
+ NetWorthAccountForm,
1771
+ {
1772
+ userId,
1773
+ accountId: editingAccount.id,
1774
+ initialValues: {
1775
+ networth_account: {
1776
+ account_type: "additional_networth_account" in editingAccount.data ? "asset" : "debt",
1777
+ name: editingAccount.data.name,
1778
+ balance: editingAccount.data.balance
1779
+ }
1780
+ },
1781
+ onSuccess: handleEditSuccess,
1782
+ onCancel: handleCloseEdit
1783
+ }
1784
+ ) })
1785
+ ]
1786
+ }
1787
+ ),
1788
+ /* @__PURE__ */ jsxRuntime.jsxs(
1789
+ material.Dialog,
1790
+ {
1791
+ open: showBulkDeleteDialog,
1792
+ onClose: () => setShowBulkDeleteDialog(false),
1793
+ children: [
1794
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogTitle, { children: [
1795
+ "Delete ",
1796
+ selectedAccounts.size,
1797
+ " Accounts?"
1798
+ ] }),
1799
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { children: [
1800
+ "Are you sure you want to delete ",
1801
+ selectedAccounts.size,
1802
+ " selected account(s)? This action cannot be undone."
1803
+ ] }) }),
1804
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
1805
+ /* @__PURE__ */ jsxRuntime.jsx(material.Button, { onClick: () => setShowBulkDeleteDialog(false), children: "Cancel" }),
1806
+ /* @__PURE__ */ jsxRuntime.jsx(
1807
+ material.Button,
1808
+ {
1809
+ color: "error",
1810
+ variant: "contained",
1811
+ onClick: () => {
1812
+ setShowBulkDeleteDialog(false);
1813
+ setSelectedAccounts(/* @__PURE__ */ new Set());
1814
+ },
1815
+ children: "Delete"
1816
+ }
1817
+ )
1818
+ ] })
1819
+ ]
1820
+ }
1821
+ )
1822
+ ] });
1823
+ }
1824
+ function NetWorthDashboard({
1825
+ userId,
1826
+ title = "Net Worth",
1827
+ currencySymbol = "$",
1828
+ showChart = true,
1829
+ showAccountList = true
1830
+ }) {
1831
+ if (!userId) {
1832
+ return /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", children: "User ID is required to display net worth dashboard" });
1833
+ }
1834
+ return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { width: "100%" }, children: [
1835
+ title && /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h4", gutterBottom: true, sx: { mb: 3 }, children: title }),
1836
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Grid, { container: true, spacing: 3, children: [
1837
+ /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: { xs: 12, md: showChart ? 6 : 12 }, children: /* @__PURE__ */ jsxRuntime.jsx(
1838
+ NetWorthSummary,
1839
+ {
1840
+ userId,
1841
+ currencySymbol
1842
+ }
1843
+ ) }),
1844
+ showChart && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: { xs: 12, md: 6 }, children: /* @__PURE__ */ jsxRuntime.jsx(
1845
+ NetWorthHistoryChart,
1846
+ {
1847
+ userId,
1848
+ currencySymbol,
1849
+ height: 400
1850
+ }
1851
+ ) }),
1852
+ showAccountList && /* @__PURE__ */ jsxRuntime.jsx(material.Grid, { size: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
1853
+ NetWorthAccountList,
1854
+ {
1855
+ userId,
1856
+ currencySymbol
1857
+ }
1858
+ ) })
1859
+ ] })
1860
+ ] });
1861
+ }
1862
+ function NetWorthAccountReconciliationDialog({
1863
+ account,
1864
+ open,
1865
+ onClose,
1866
+ onSuccess,
1867
+ currencySymbol = "$"
1868
+ }) {
1869
+ const [actualBalance, setActualBalance] = react.useState("");
1870
+ const [notes, setNotes] = react.useState("");
1871
+ const [showSuccess, setShowSuccess] = react.useState(false);
1872
+ const [showError, setShowError] = react.useState(false);
1873
+ const [errorMessage, setErrorMessage] = react.useState("");
1874
+ const updateMutation = accountsDataAccess.useUpdateNetWorthAccount({
1875
+ onSuccess: () => {
1876
+ setShowSuccess(true);
1877
+ setActualBalance("");
1878
+ setNotes("");
1879
+ onSuccess?.();
1880
+ onClose();
1881
+ },
1882
+ onError: (error) => {
1883
+ setErrorMessage(error.message);
1884
+ setShowError(true);
1885
+ }
1886
+ });
1887
+ if (!account) {
1888
+ return null;
1889
+ }
1890
+ const recordedBalance = parseFloat(account.balance);
1891
+ const actual = actualBalance ? parseFloat(actualBalance) : 0;
1892
+ const difference = actual - recordedBalance;
1893
+ const hasDiscrepancy = difference !== 0;
1894
+ const handleSubmit = (e) => {
1895
+ e.preventDefault();
1896
+ if (!actualBalance || parseFloat(actualBalance) < 0) {
1897
+ setErrorMessage("Please enter a valid balance");
1898
+ setShowError(true);
1899
+ return;
1900
+ }
1901
+ updateMutation.mutate({
1902
+ userId: account.user_id,
1903
+ accountId: account.id,
1904
+ data: {
1905
+ networth_account: {
1906
+ name: account.name,
1907
+ balance: parseFloat(actualBalance).toFixed(2),
1908
+ account_type: account.account_type
1909
+ }
1910
+ }
1911
+ });
1912
+ };
1913
+ const handleClose = () => {
1914
+ if (!updateMutation.isPending) {
1915
+ setActualBalance("");
1916
+ setNotes("");
1917
+ onClose();
1918
+ }
1919
+ };
1920
+ const isLoading = updateMutation.isPending;
1921
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1922
+ /* @__PURE__ */ jsxRuntime.jsxs(
1923
+ material.Dialog,
1924
+ {
1925
+ open,
1926
+ onClose: handleClose,
1927
+ maxWidth: "sm",
1928
+ fullWidth: true,
1929
+ "aria-labelledby": "reconciliation-dialog-title",
1930
+ children: [
1931
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogTitle, { id: "reconciliation-dialog-title", children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { display: "flex", alignItems: "center", gap: 1, children: [
1932
+ /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.AccountBalance, { color: "primary" }),
1933
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "h6", component: "span", children: "Reconcile Account" })
1934
+ ] }) }),
1935
+ /* @__PURE__ */ jsxRuntime.jsx(material.DialogContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { component: "form", onSubmit: handleSubmit, sx: { mt: 1 }, children: [
1936
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Alert, { severity: "info", sx: { mb: 3 }, children: [
1937
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "subtitle2", gutterBottom: true, children: account.name }),
1938
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "caption", children: account.account_type === "asset" ? "Asset Account" : "Debt Account" })
1939
+ ] }),
1940
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { mb: 3 }, children: [
1941
+ /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { variant: "body2", color: "text.secondary", gutterBottom: true, children: "Recorded Balance" }),
1942
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "h5", color: "text.primary", children: [
1943
+ currencySymbol,
1944
+ recordedBalance.toFixed(2)
1945
+ ] })
1946
+ ] }),
1947
+ /* @__PURE__ */ jsxRuntime.jsx(material.Divider, { sx: { my: 2 } }),
1948
+ /* @__PURE__ */ jsxRuntime.jsx(
1949
+ material.TextField,
1950
+ {
1951
+ fullWidth: true,
1952
+ margin: "normal",
1953
+ label: "Actual Balance (from statement)",
1954
+ type: "number",
1955
+ inputProps: {
1956
+ step: "0.01",
1957
+ min: "0"
1958
+ },
1959
+ value: actualBalance,
1960
+ onChange: (e) => setActualBalance(e.target.value),
1961
+ required: true,
1962
+ disabled: isLoading,
1963
+ helperText: "Enter the current balance from your bank or account statement",
1964
+ InputProps: {
1965
+ startAdornment: /* @__PURE__ */ jsxRuntime.jsx(material.InputAdornment, { position: "start", children: currencySymbol })
1966
+ }
1967
+ }
1968
+ ),
1969
+ actualBalance && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { mt: 2, mb: 2 }, children: /* @__PURE__ */ jsxRuntime.jsx(
1970
+ material.Alert,
1971
+ {
1972
+ severity: hasDiscrepancy ? "warning" : "success",
1973
+ sx: { display: "flex", alignItems: "center" },
1974
+ children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { width: "100%" }, children: [
1975
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "subtitle2", gutterBottom: true, children: [
1976
+ "Difference: ",
1977
+ currencySymbol,
1978
+ Math.abs(difference).toFixed(2)
1979
+ ] }),
1980
+ /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", gap: 1, mt: 1 }, children: [
1981
+ /* @__PURE__ */ jsxRuntime.jsx(
1982
+ material.Chip,
1983
+ {
1984
+ label: difference > 0 ? "Over" : difference < 0 ? "Under" : "Balanced",
1985
+ color: hasDiscrepancy ? "warning" : "success",
1986
+ size: "small"
1987
+ }
1988
+ ),
1989
+ !hasDiscrepancy && /* @__PURE__ */ jsxRuntime.jsx(
1990
+ material.Chip,
1991
+ {
1992
+ label: "Reconciled",
1993
+ color: "success",
1994
+ size: "small",
1995
+ icon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Check, {})
1996
+ }
1997
+ )
1998
+ ] })
1999
+ ] })
2000
+ }
2001
+ ) }),
2002
+ /* @__PURE__ */ jsxRuntime.jsx(
2003
+ material.TextField,
2004
+ {
2005
+ fullWidth: true,
2006
+ margin: "normal",
2007
+ label: "Notes (Optional)",
2008
+ multiline: true,
2009
+ rows: 3,
2010
+ value: notes,
2011
+ onChange: (e) => setNotes(e.target.value),
2012
+ disabled: isLoading,
2013
+ helperText: "Add any notes about this reconciliation",
2014
+ sx: { mt: 2 }
2015
+ }
2016
+ ),
2017
+ !actualBalance && /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "info", sx: { mt: 2 }, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Typography, { variant: "caption", children: [
2018
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "How to reconcile:" }),
2019
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
2020
+ "1. Check your latest bank or account statement",
2021
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
2022
+ "2. Enter the actual current balance",
2023
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
2024
+ "3. Review the difference and click Reconcile"
2025
+ ] }) })
2026
+ ] }) }),
2027
+ /* @__PURE__ */ jsxRuntime.jsxs(material.DialogActions, { children: [
2028
+ /* @__PURE__ */ jsxRuntime.jsx(
2029
+ material.Button,
2030
+ {
2031
+ onClick: handleClose,
2032
+ disabled: isLoading,
2033
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Close, {}),
2034
+ children: "Cancel"
2035
+ }
2036
+ ),
2037
+ /* @__PURE__ */ jsxRuntime.jsx(
2038
+ material.Button,
2039
+ {
2040
+ onClick: handleSubmit,
2041
+ variant: "contained",
2042
+ disabled: isLoading || !actualBalance,
2043
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(iconsMaterial.Check, {}),
2044
+ children: isLoading ? "Reconciling..." : "Reconcile"
2045
+ }
2046
+ )
2047
+ ] })
2048
+ ]
2049
+ }
2050
+ ),
2051
+ /* @__PURE__ */ jsxRuntime.jsx(
2052
+ material.Snackbar,
2053
+ {
2054
+ open: showSuccess,
2055
+ autoHideDuration: 3e3,
2056
+ onClose: () => setShowSuccess(false),
2057
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
2058
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "success", onClose: () => setShowSuccess(false), children: "Account reconciled successfully!" })
2059
+ }
2060
+ ),
2061
+ /* @__PURE__ */ jsxRuntime.jsx(
2062
+ material.Snackbar,
2063
+ {
2064
+ open: showError,
2065
+ autoHideDuration: 5e3,
2066
+ onClose: () => setShowError(false),
2067
+ anchorOrigin: { vertical: "bottom", horizontal: "center" },
2068
+ children: /* @__PURE__ */ jsxRuntime.jsx(material.Alert, { severity: "error", onClose: () => setShowError(false), children: errorMessage || "Reconciliation failed" })
2069
+ }
2070
+ )
2071
+ ] });
2072
+ }
2073
+
2074
+ exports.AccountBalanceChart = AccountBalanceChart;
2075
+ exports.AccountCreateForm = AccountCreateForm;
2076
+ exports.AccountDeleteButton = AccountDeleteButton;
2077
+ exports.AccountEditForm = AccountEditForm;
2078
+ exports.AccountList = AccountList;
2079
+ exports.AccountSummary = AccountSummary;
2080
+ exports.NetWorthAccountDeleteButton = NetWorthAccountDeleteButton;
2081
+ exports.NetWorthAccountEnhancedForm = NetWorthAccountEnhancedForm;
2082
+ exports.NetWorthAccountForm = NetWorthAccountForm;
2083
+ exports.NetWorthAccountList = NetWorthAccountList;
2084
+ exports.NetWorthAccountReconciliationDialog = NetWorthAccountReconciliationDialog;
2085
+ exports.NetWorthDashboard = NetWorthDashboard;
2086
+ exports.NetWorthHistoryChart = NetWorthHistoryChart;
2087
+ exports.NetWorthSummary = NetWorthSummary;
2088
+ //# sourceMappingURL=index.cjs.map
2089
+ //# sourceMappingURL=index.cjs.map