@accounter/client 0.0.8-alpha-20251022132023-9f41aae2ce16f8761101edc548f486cc6ce80333 → 0.0.8-alpha-20251022144027-c9c7a4b309de8a72dfd0ec4f11e63713ad12878f

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +1 -25
  2. package/dist/assets/index-B2UYAO1O.css +1 -0
  3. package/dist/assets/index-CZb2m31K.js +1229 -0
  4. package/dist/assets/{index.es-CL8po8bM.js → index.es-9gVMpHTc.js} +5 -5
  5. package/dist/index.html +2 -2
  6. package/package.json +1 -1
  7. package/src/components/business/admin-business-section.tsx +284 -0
  8. package/src/components/business/index.tsx +22 -0
  9. package/src/components/business-transactions/business-extended-info.tsx +15 -13
  10. package/src/components/business-transactions/business-transactions-single.tsx +3 -3
  11. package/src/components/business-transactions/index.tsx +1 -12
  12. package/src/components/business-trips/business-trip.tsx +3 -3
  13. package/src/components/charges/cells/business-trip.tsx +8 -6
  14. package/src/components/charges/cells/counterparty.tsx +5 -7
  15. package/src/components/common/accounter-table.tsx +5 -6
  16. package/src/components/common/business-trip-report/parts/core-expense-row.tsx +9 -11
  17. package/src/components/common/business-trip-report/parts/uncategorized-transactions.tsx +13 -11
  18. package/src/components/common/buttons/button-with-label.tsx +41 -0
  19. package/src/components/common/buttons/button.tsx +44 -0
  20. package/src/components/common/buttons/index.ts +2 -0
  21. package/src/components/common/buttons/logout-button.tsx +6 -7
  22. package/src/components/common/documents-to-charge-matcher/selection-handler/index.tsx +2 -4
  23. package/src/components/common/documents-to-charge-matcher/selection-handler/wide-filtered-selection.tsx +7 -5
  24. package/src/components/common/forms/edit-document.tsx +10 -21
  25. package/src/components/common/new-documents-list.tsx +8 -10
  26. package/src/components/documents-table/cells/creditor.tsx +4 -11
  27. package/src/components/documents-table/cells/debtor.tsx +4 -11
  28. package/src/components/layout/dashboard-layout.tsx +0 -4
  29. package/src/components/layout/sidelinks.tsx +27 -28
  30. package/src/components/ledger-table/counterparty-cell.tsx +13 -19
  31. package/src/components/login-page.tsx +1 -2
  32. package/src/components/reports/corporate-tax-ruling-compliance-report/index.tsx +3 -3
  33. package/src/components/reports/profit-and-loss-report/index.tsx +3 -3
  34. package/src/components/reports/tax-report/index.tsx +3 -3
  35. package/src/components/screens/businesses/business.tsx +9 -21
  36. package/src/components/screens/charges/charge.tsx +9 -22
  37. package/src/components/transactions-table/cells/counterparty.tsx +2 -9
  38. package/src/components/transactions-table/cells-legacy/counterparty.tsx +2 -9
  39. package/src/gql/gql.ts +15 -3
  40. package/src/gql/graphql.ts +4913 -1559
  41. package/src/hooks/use-update-admin-business.ts +71 -0
  42. package/src/index.tsx +22 -4
  43. package/src/providers/auth-guard.tsx +23 -14
  44. package/src/providers/index.tsx +2 -7
  45. package/src/providers/urql.tsx +12 -7
  46. package/src/providers/user-provider.tsx +2 -3
  47. package/dist/assets/Checkbox-DBF5r7jA.js +0 -6
  48. package/dist/assets/Progress-Cjv9yrat.js +0 -1
  49. package/dist/assets/Typography-DdVppmQe.js +0 -1
  50. package/dist/assets/accordion-DcMd-Til.js +0 -1
  51. package/dist/assets/accountant-approvals-CU_EA64d.js +0 -1
  52. package/dist/assets/all-charges-DKGmrDeD.js +0 -1
  53. package/dist/assets/arrow-up-down-BeIaAKWn.js +0 -6
  54. package/dist/assets/business-EtSaFzKh.js +0 -37
  55. package/dist/assets/business-transactions-single-B0Up2Bs4.js +0 -1
  56. package/dist/assets/business-trip-CmMmdjCh.js +0 -1
  57. package/dist/assets/charges-filters-CqWjSIKI.js +0 -1
  58. package/dist/assets/charges-ledger-validation-DHfLjNlq.js +0 -1
  59. package/dist/assets/chart-D1Y6fN3z.js +0 -74
  60. package/dist/assets/data-table-pagination-BCciANKD.js +0 -11
  61. package/dist/assets/editable-business-trip-VNJjiYOp.js +0 -16
  62. package/dist/assets/graphql-document-dedupe-fragments-ByT8-wlV.js +0 -1
  63. package/dist/assets/index-1L3dEkVN.js +0 -1
  64. package/dist/assets/index-4ZIYAzBJ.js +0 -1
  65. package/dist/assets/index-4r9JDo8p.js +0 -1
  66. package/dist/assets/index-BFHiMLVc.js +0 -1
  67. package/dist/assets/index-BGmhxff9.js +0 -1
  68. package/dist/assets/index-BMcyYDGt.js +0 -11
  69. package/dist/assets/index-BVQkLk5i.js +0 -1
  70. package/dist/assets/index-Bj3HckU6.js +0 -876
  71. package/dist/assets/index-BnQW4CTb.js +0 -1
  72. package/dist/assets/index-C0FVazZA.js +0 -24
  73. package/dist/assets/index-CUDeasQ_.js +0 -1
  74. package/dist/assets/index-Cfm6e2hX.js +0 -1
  75. package/dist/assets/index-Cqz-mRoO.js +0 -17
  76. package/dist/assets/index-Cs7MeC4J.js +0 -137
  77. package/dist/assets/index-CzzfC-dD.css +0 -1
  78. package/dist/assets/index-DABsOOfA.js +0 -1
  79. package/dist/assets/index-DB4BgQdp.js +0 -2
  80. package/dist/assets/index-DV-Q6DUw.js +0 -1
  81. package/dist/assets/index-Dd5ylSyH.js +0 -9
  82. package/dist/assets/index-Dn7p3J8Q.js +0 -1
  83. package/dist/assets/index-Dpk6i3ex.js +0 -6
  84. package/dist/assets/index-EiT4SOpW.js +0 -2
  85. package/dist/assets/index-rcKvu7eR.js +0 -6
  86. package/dist/assets/index-sDbz8nnb.js +0 -1
  87. package/dist/assets/issue-document-CYdlZijI.js +0 -1
  88. package/dist/assets/login-page-CnMdssTN.js +0 -1
  89. package/dist/assets/missing-info-charges-CzeKbCyG.js +0 -1
  90. package/dist/assets/page-not-found-Bsa0DCM4.js +0 -1
  91. package/dist/assets/pencil-BMWYIsZB.js +0 -6
  92. package/dist/assets/report-commentary-row-D9AtKtZx.js +0 -1
  93. package/dist/assets/save-DC_eQcBj.js +0 -11
  94. package/dist/assets/sequential-CAnleQny.js +0 -1
  95. package/dist/assets/similar-charges-by-business-modal-Dmb2ZymF.js +0 -1
  96. package/dist/assets/sub-BIMwxqar.js +0 -1
  97. package/dist/assets/subMonths-B7SR4Lli.js +0 -1
  98. package/src/components/error-boundary.tsx +0 -189
  99. package/src/components/layout/breadcrumbs.tsx +0 -72
  100. package/src/components/layout/document-title.tsx +0 -26
  101. package/src/components/layout/navigation-progress.tsx +0 -52
  102. package/src/components/layout/page-skeleton.tsx +0 -49
  103. package/src/providers/urql-client.ts +0 -86
  104. package/src/router/config.tsx +0 -534
  105. package/src/router/layouts/dashboard-layout.tsx +0 -20
  106. package/src/router/layouts/root-layout.tsx +0 -69
  107. package/src/router/loaders/auth-loader.ts +0 -32
  108. package/src/router/loaders/business-loader.ts +0 -25
  109. package/src/router/loaders/charge-loader.ts +0 -25
  110. package/src/router/loaders/index.ts +0 -17
  111. package/src/router/routes.ts +0 -88
  112. package/src/router/types.ts +0 -68
@@ -1,534 +0,0 @@
1
- import { lazy, Suspense, type ReactElement } from 'react';
2
- import type { RouteObject } from 'react-router-dom';
3
- import { ErrorBoundary } from '../components/error-boundary.js';
4
- import { PageSkeleton, ReportSkeleton, TableSkeleton } from '../components/layout/page-skeleton.js';
5
- import { DashboardLayoutRoute } from './layouts/dashboard-layout.js';
6
- import { RootLayout } from './layouts/root-layout.js';
7
- import { businessLoader, chargeLoader, publicOnly, requireAuth } from './loaders/index.js';
8
- import { ROUTES } from './routes.js';
9
-
10
- /**
11
- * Lazy load page components for code splitting
12
- * Components use named exports, so we need to extract them
13
- */
14
-
15
- // Charges
16
- const AllCharges = lazy(() =>
17
- import('../components/screens/charges/all-charges.js').then(m => ({ default: m.AllCharges })),
18
- );
19
- const MissingInfoCharges = lazy(() =>
20
- import('../components/screens/charges/missing-info-charges.js').then(m => ({
21
- default: m.MissingInfoCharges,
22
- })),
23
- );
24
- const Charge = lazy(() =>
25
- import('../components/screens/charges/charge.js').then(m => ({ default: m.Charge })),
26
- );
27
- const ChargesLedgerValidation = lazy(() =>
28
- import('../components/charges-ledger-validation.js').then(m => ({
29
- default: m.ChargesLedgerValidation,
30
- })),
31
- );
32
-
33
- // Businesses
34
- const Businesses = lazy(() =>
35
- import('../components/businesses/index.js').then(m => ({ default: m.Businesses })),
36
- );
37
- const BusinessScreen = lazy(() =>
38
- import('../components/screens/businesses/business.js').then(m => ({ default: m.BusinessScreen })),
39
- );
40
- const BusinessTransactionsSummery = lazy(() =>
41
- import('../components/business-transactions/index.js').then(m => ({
42
- default: m.BusinessTransactionsSummery,
43
- })),
44
- );
45
- const BusinessTransactionsSingle = lazy(() =>
46
- import('../components/business-transactions/business-transactions-single.js').then(m => ({
47
- default: m.BusinessTransactionsSingle,
48
- })),
49
- );
50
-
51
- // Business Trips
52
- const BusinessTrips = lazy(() =>
53
- import('../components/business-trips/index.js').then(m => ({ default: m.BusinessTrips })),
54
- );
55
- const BusinessTrip = lazy(() =>
56
- import('../components/business-trips/business-trip.js').then(m => ({ default: m.BusinessTrip })),
57
- );
58
-
59
- // Charts
60
- const ChartPage = lazy(() =>
61
- import('../components/charts/index.js').then(m => ({ default: m.ChartPage })),
62
- );
63
- const MonthlyIncomeExpenseChart = lazy(() =>
64
- import('../components/charts/monthly-income-expense/index.js').then(m => ({
65
- default: m.MonthlyIncomeExpenseChart,
66
- })),
67
- );
68
-
69
- // Documents
70
- const DocumentsReport = lazy(() =>
71
- import('../components/screens/documents/all-documents/index.jsx').then(m => ({
72
- default: m.DocumentsReport,
73
- })),
74
- );
75
- const IssueDocumentScreen = lazy(() =>
76
- import('../components/screens/documents/issue-document.js').then(m => ({
77
- default: m.IssueDocumentScreen,
78
- })),
79
- );
80
- const IssueDocuments = lazy(() =>
81
- import('../components/screens/documents/issue-documents/index.js').then(m => ({
82
- default: m.IssueDocuments,
83
- })),
84
- );
85
-
86
- // Reports
87
- const TrialBalanceReport = lazy(() =>
88
- import('../components/reports/trial-balance-report/index.js').then(m => ({
89
- default: m.TrialBalanceReport,
90
- })),
91
- );
92
- const ContoReport = lazy(() =>
93
- import('../components/reports/conto/index.js').then(m => ({ default: m.ContoReport })),
94
- );
95
- const VatMonthlyReport = lazy(() =>
96
- import('../components/reports/vat-monthly-report/index.js').then(m => ({
97
- default: m.VatMonthlyReport,
98
- })),
99
- );
100
- const ProfitAndLossReport = lazy(() =>
101
- import('../components/reports/profit-and-loss-report/index.js').then(m => ({
102
- default: m.ProfitAndLossReport,
103
- })),
104
- );
105
- const TaxReport = lazy(() =>
106
- import('../components/reports/tax-report/index.js').then(m => ({ default: m.TaxReport })),
107
- );
108
- const DepreciationReport = lazy(() =>
109
- import('../components/screens/reports/depreciation-report/index.js').then(m => ({
110
- default: m.DepreciationReport,
111
- })),
112
- );
113
- const Shaam6111Report = lazy(() =>
114
- import('../components/screens/reports/shaam6111-report/index.js').then(m => ({
115
- default: m.Shaam6111Report,
116
- })),
117
- );
118
- const YearlyLedgerReport = lazy(() =>
119
- import('../components/reports/yearly-ledger/index.js').then(m => ({
120
- default: m.YearlyLedgerReport,
121
- })),
122
- );
123
- const CorporateTaxRulingComplianceReport = lazy(() =>
124
- import('../components/reports/corporate-tax-ruling-compliance-report/index.js').then(m => ({
125
- default: m.CorporateTaxRulingComplianceReport,
126
- })),
127
- );
128
- const BalanceReport = lazy(() =>
129
- import('../components/screens/reports/balance-report/index.js').then(m => ({
130
- default: m.BalanceReport,
131
- })),
132
- );
133
- const ValidateReportsScreen = lazy(() =>
134
- import('../components/reports/validations/index.js').then(m => ({
135
- default: m.ValidateReportsScreen,
136
- })),
137
- );
138
- const AccountantApprovals = lazy(() =>
139
- import('../components/reports/accountant-approvals.js').then(m => ({
140
- default: m.AccountantApprovals,
141
- })),
142
- );
143
-
144
- // Other
145
- const Salaries = lazy(() =>
146
- import('../components/salaries/index.js').then(m => ({ default: m.Salaries })),
147
- );
148
- const TagsManager = lazy(() =>
149
- import('../components/tags/index.js').then(m => ({ default: m.TagsManager })),
150
- );
151
- const TaxCategories = lazy(() =>
152
- import('../components/tax-categories/index.js').then(m => ({ default: m.TaxCategories })),
153
- );
154
- const SortCodes = lazy(() =>
155
- import('../components/screens/sort-codes/index.js').then(m => ({ default: m.SortCodes })),
156
- );
157
- const PageNotFound = lazy(() =>
158
- import('../components/screens/page-not-found.js').then(m => ({ default: m.PageNotFound })),
159
- );
160
-
161
- // Auth
162
- const LoginPage = lazy(() =>
163
- import('../components/login-page.js').then(m => ({ default: m.LoginPage })),
164
- );
165
-
166
- /**
167
- * Helper to wrap components with Suspense
168
- */
169
- function withSuspense(
170
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
171
- Component: React.LazyExoticComponent<React.ComponentType<any>>,
172
- fallback?: ReactElement,
173
- ) {
174
- return (
175
- <Suspense fallback={fallback || <PageSkeleton />}>
176
- <Component />
177
- </Suspense>
178
- );
179
- }
180
-
181
- /**
182
- * Application route configuration
183
- * Using object-based routes for better type safety and features
184
- */
185
- export const routes: RouteObject[] = [
186
- {
187
- path: '/',
188
- element: <RootLayout />,
189
- errorElement: <ErrorBoundary />,
190
- children: [
191
- // Public routes (login, error pages)
192
- {
193
- path: ROUTES.LOGIN,
194
- loader: publicOnly,
195
- element: withSuspense(LoginPage),
196
- handle: {
197
- title: 'Login',
198
- },
199
- },
200
-
201
- // Protected routes (require authentication)
202
- {
203
- path: '/',
204
- loader: requireAuth,
205
- element: <DashboardLayoutRoute />,
206
- errorElement: <ErrorBoundary />,
207
- children: [
208
- // Home / Charges (default)
209
- {
210
- index: true,
211
- element: withSuspense(AllCharges, <TableSkeleton />),
212
- handle: {
213
- title: 'All Charges',
214
- breadcrumb: 'Charges',
215
- },
216
- },
217
-
218
- // Charges section
219
- {
220
- path: 'charges',
221
- handle: { breadcrumb: 'Charges' },
222
- children: [
223
- {
224
- index: true,
225
- element: withSuspense(AllCharges, <TableSkeleton />),
226
- handle: { title: 'All Charges' },
227
- },
228
- {
229
- path: 'missing-info',
230
- element: withSuspense(MissingInfoCharges, <TableSkeleton />),
231
- handle: {
232
- title: 'Missing Info Charges',
233
- breadcrumb: 'Missing Info',
234
- },
235
- },
236
- {
237
- path: 'ledger-validation',
238
- element: withSuspense(ChargesLedgerValidation, <TableSkeleton />),
239
- handle: {
240
- title: 'Ledger Validation',
241
- breadcrumb: 'Ledger Validation',
242
- },
243
- },
244
- {
245
- path: ':chargeId',
246
- loader: chargeLoader,
247
- element: withSuspense(Charge),
248
- handle: {
249
- title: 'Charge Details',
250
- breadcrumb: 'Details',
251
- },
252
- },
253
- ],
254
- },
255
-
256
- // Businesses section
257
- {
258
- path: 'businesses',
259
- handle: { breadcrumb: 'Businesses' },
260
- children: [
261
- {
262
- index: true,
263
- element: withSuspense(Businesses, <TableSkeleton />),
264
- handle: { title: 'All Businesses' },
265
- },
266
- {
267
- path: 'transactions',
268
- element: withSuspense(BusinessTransactionsSummery, <TableSkeleton />),
269
- handle: {
270
- title: 'Business Transactions Summary',
271
- breadcrumb: 'Transactions',
272
- },
273
- },
274
- {
275
- path: ':businessId',
276
- loader: businessLoader,
277
- element: withSuspense(BusinessScreen),
278
- handle: {
279
- title: 'Business Details',
280
- breadcrumb: 'Details',
281
- },
282
- },
283
- {
284
- path: ':businessId/transactions',
285
- element: withSuspense(BusinessTransactionsSingle, <TableSkeleton />),
286
- handle: {
287
- title: 'Business Transactions',
288
- breadcrumb: 'Transactions',
289
- },
290
- },
291
- ],
292
- },
293
-
294
- // Business Trips section
295
- {
296
- path: 'business-trips',
297
- handle: { breadcrumb: 'Business Trips' },
298
- children: [
299
- {
300
- index: true,
301
- element: withSuspense(BusinessTrips, <TableSkeleton />),
302
- handle: { title: 'Business Trips' },
303
- },
304
- {
305
- path: ':businessTripId',
306
- element: withSuspense(BusinessTrip),
307
- handle: {
308
- title: 'Business Trip Details',
309
- breadcrumb: 'Details',
310
- },
311
- },
312
- ],
313
- },
314
-
315
- // Charts section
316
- {
317
- path: 'charts',
318
- handle: { breadcrumb: 'Charts' },
319
- children: [
320
- {
321
- index: true,
322
- element: withSuspense(ChartPage),
323
- handle: { title: 'Charts' },
324
- },
325
- {
326
- path: 'monthly-income-expense',
327
- element: withSuspense(MonthlyIncomeExpenseChart),
328
- handle: {
329
- title: 'Monthly Income/Expense',
330
- breadcrumb: 'Income/Expense',
331
- },
332
- },
333
- ],
334
- },
335
-
336
- // Documents section
337
- {
338
- path: 'documents',
339
- handle: { breadcrumb: 'Documents' },
340
- children: [
341
- {
342
- index: true,
343
- element: withSuspense(DocumentsReport, <TableSkeleton />),
344
- handle: { title: 'All Documents' },
345
- },
346
- {
347
- path: 'issue-document',
348
- element: withSuspense(IssueDocumentScreen),
349
- handle: {
350
- title: 'Issue Document',
351
- breadcrumb: 'Issue Document',
352
- },
353
- },
354
- {
355
- path: 'issue-documents',
356
- element: withSuspense(IssueDocuments),
357
- handle: {
358
- title: 'Issue Documents',
359
- breadcrumb: 'Issue Documents',
360
- },
361
- },
362
- ],
363
- },
364
-
365
- // Reports section
366
- {
367
- path: 'reports',
368
- handle: { breadcrumb: 'Reports' },
369
- children: [
370
- {
371
- path: 'trial-balance',
372
- element: withSuspense(TrialBalanceReport, <ReportSkeleton />),
373
- handle: {
374
- title: 'Trial Balance Report',
375
- breadcrumb: 'Trial Balance',
376
- },
377
- },
378
- {
379
- path: 'conto',
380
- element: withSuspense(ContoReport, <ReportSkeleton />),
381
- handle: {
382
- title: 'Conto Report',
383
- breadcrumb: 'Conto',
384
- },
385
- },
386
- {
387
- path: 'vat-monthly',
388
- element: withSuspense(VatMonthlyReport, <ReportSkeleton />),
389
- handle: {
390
- title: 'VAT Monthly Report',
391
- breadcrumb: 'VAT Monthly',
392
- },
393
- },
394
- {
395
- path: 'profit-and-loss',
396
- handle: { breadcrumb: 'Profit & Loss' },
397
- children: [
398
- {
399
- index: true,
400
- element: withSuspense(ProfitAndLossReport, <ReportSkeleton />),
401
- handle: { title: 'Profit & Loss Report' },
402
- },
403
- {
404
- path: ':year',
405
- element: withSuspense(ProfitAndLossReport, <ReportSkeleton />),
406
- handle: {
407
- title: 'Profit & Loss Report',
408
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- loader data type varies by route
409
- breadcrumb: (data: any) => data?.year || 'Year',
410
- },
411
- },
412
- ],
413
- },
414
- {
415
- path: 'tax',
416
- handle: { breadcrumb: 'Tax' },
417
- children: [
418
- {
419
- index: true,
420
- element: withSuspense(TaxReport, <ReportSkeleton />),
421
- handle: { title: 'Tax Report' },
422
- },
423
- {
424
- path: ':year',
425
- element: withSuspense(TaxReport, <ReportSkeleton />),
426
- handle: {
427
- title: 'Tax Report',
428
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- loader data type varies by route
429
- breadcrumb: (data: any) => data?.year || 'Year',
430
- },
431
- },
432
- ],
433
- },
434
- {
435
- path: 'depreciation',
436
- element: withSuspense(DepreciationReport, <ReportSkeleton />),
437
- handle: {
438
- title: 'Depreciation Report',
439
- breadcrumb: 'Depreciation',
440
- },
441
- },
442
- {
443
- path: 'shaam-6111',
444
- element: withSuspense(Shaam6111Report, <ReportSkeleton />),
445
- handle: {
446
- title: 'Shaam 6111 Report',
447
- breadcrumb: 'Shaam 6111',
448
- },
449
- },
450
- {
451
- path: 'yearly-ledger',
452
- element: withSuspense(YearlyLedgerReport, <ReportSkeleton />),
453
- handle: {
454
- title: 'Yearly Ledger Report',
455
- breadcrumb: 'Yearly Ledger',
456
- },
457
- },
458
- {
459
- path: 'corporate-tax-ruling-compliance',
460
- handle: { breadcrumb: 'Tax Ruling' },
461
- children: [
462
- {
463
- index: true,
464
- element: withSuspense(CorporateTaxRulingComplianceReport, <ReportSkeleton />),
465
- handle: { title: 'Corporate Tax Ruling Compliance Report' },
466
- },
467
- {
468
- path: ':year',
469
- element: withSuspense(CorporateTaxRulingComplianceReport, <ReportSkeleton />),
470
- handle: {
471
- title: 'Corporate Tax Ruling Compliance Report',
472
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- loader data type varies by route
473
- breadcrumb: (data: any) => data?.year || 'Year',
474
- },
475
- },
476
- ],
477
- },
478
- {
479
- path: 'balance',
480
- element: withSuspense(BalanceReport, <ReportSkeleton />),
481
- handle: {
482
- title: 'Balance Report',
483
- breadcrumb: 'Balance',
484
- },
485
- },
486
- {
487
- path: 'validate-reports',
488
- element: withSuspense(ValidateReportsScreen),
489
- handle: {
490
- title: 'Validate Reports',
491
- breadcrumb: 'Validate',
492
- },
493
- },
494
- ],
495
- },
496
-
497
- // Standalone routes
498
- {
499
- path: 'accountant-approvals',
500
- element: withSuspense(AccountantApprovals, <TableSkeleton />),
501
- handle: { title: 'Accountant Approvals', breadcrumb: 'Accountant Approvals' },
502
- },
503
- {
504
- path: 'salaries',
505
- element: withSuspense(Salaries, <TableSkeleton />),
506
- handle: { title: 'Salaries', breadcrumb: 'Salaries' },
507
- },
508
- {
509
- path: 'tags',
510
- element: withSuspense(TagsManager),
511
- handle: { title: 'Tags', breadcrumb: 'Tags' },
512
- },
513
- {
514
- path: 'tax-categories',
515
- element: withSuspense(TaxCategories),
516
- handle: { title: 'Tax Categories', breadcrumb: 'Tax Categories' },
517
- },
518
- {
519
- path: 'sort-codes',
520
- element: withSuspense(SortCodes),
521
- handle: { title: 'Sort Codes', breadcrumb: 'Sort Codes' },
522
- },
523
-
524
- // 404 catch-all
525
- {
526
- path: '*',
527
- element: withSuspense(PageNotFound),
528
- handle: { title: 'Page Not Found' },
529
- },
530
- ],
531
- },
532
- ],
533
- },
534
- ];
@@ -1,20 +0,0 @@
1
- import { useState, type ReactElement } from 'react';
2
- import { Outlet } from 'react-router-dom';
3
- import { DashboardLayout as DashboardUI } from '../../components/layout/dashboard-layout.js';
4
- import { FiltersContext } from '../../providers/filters-context.js';
5
-
6
- /**
7
- * Dashboard layout route wrapper
8
- * Provides the dashboard UI with sidebar, header, footer
9
- */
10
- export function DashboardLayoutRoute(): ReactElement {
11
- const [filtersContext, setFiltersContext] = useState<ReactElement | null>(null);
12
-
13
- return (
14
- <FiltersContext.Provider value={{ filtersContext, setFiltersContext }}>
15
- <DashboardUI filtersContext={filtersContext}>
16
- <Outlet />
17
- </DashboardUI>
18
- </FiltersContext.Provider>
19
- );
20
- }
@@ -1,69 +0,0 @@
1
- import type { ReactElement } from 'react';
2
- import { Outlet } from 'react-router-dom';
3
- import { MantineProvider } from '@mantine/core';
4
- import { CssBaseline, ThemeProvider } from '@mui/material';
5
- import { red } from '@mui/material/colors';
6
- import { createTheme } from '@mui/material/styles';
7
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
8
- import { DocumentTitle } from '../../components/layout/document-title.js';
9
- import { NavigationProgress } from '../../components/layout/navigation-progress.js';
10
- import { Toaster } from '../../components/ui/sonner.js';
11
- import { AuthProvider } from '../../providers/auth-guard.js';
12
- import { UrqlProvider } from '../../providers/urql.js';
13
- import { UserProvider } from '../../providers/user-provider.js';
14
-
15
- // Create these outside the component to prevent recreation on every render
16
- const queryClient = new QueryClient({
17
- defaultOptions: {
18
- queries: {
19
- refetchOnWindowFocus: false,
20
- retry: 1,
21
- },
22
- },
23
- });
24
-
25
- const theme = createTheme({
26
- palette: {
27
- primary: {
28
- main: '#556cd6',
29
- },
30
- secondary: {
31
- main: '#19857b',
32
- },
33
- error: {
34
- main: red.A400,
35
- },
36
- },
37
- });
38
-
39
- /**
40
- * Root layout - wraps all routes
41
- * Provides all app-level providers and navigation progress indicator
42
- */
43
- export function RootLayout(): ReactElement {
44
- return (
45
- <MantineProvider
46
- withGlobalStyles
47
- theme={{
48
- fontFamily: 'Roboto, sans-serif',
49
- fontSizes: { md: '14' },
50
- }}
51
- >
52
- <ThemeProvider theme={theme}>
53
- <CssBaseline />
54
- <AuthProvider>
55
- <Toaster />
56
- <UrqlProvider>
57
- <QueryClientProvider client={queryClient}>
58
- <UserProvider>
59
- <DocumentTitle />
60
- <NavigationProgress />
61
- <Outlet />
62
- </UserProvider>
63
- </QueryClientProvider>
64
- </UrqlProvider>
65
- </AuthProvider>
66
- </ThemeProvider>
67
- </MantineProvider>
68
- );
69
- }
@@ -1,32 +0,0 @@
1
- import { redirect } from 'react-router-dom';
2
- import { UserService } from '../../services/user-service.js';
3
- import { ROUTES } from '../routes.js';
4
-
5
- /**
6
- * Auth loader - protects routes that require authentication
7
- * Redirects to login if user is not authenticated
8
- */
9
- export function requireAuth() {
10
- const authService = new UserService();
11
-
12
- if (!authService.isLoggedIn()) {
13
- // Redirect to login page
14
- throw redirect(ROUTES.LOGIN);
15
- }
16
-
17
- return null;
18
- }
19
-
20
- /**
21
- * Public only loader - redirects authenticated users away from login page
22
- */
23
- export function publicOnly() {
24
- const authService = new UserService();
25
-
26
- if (authService.isLoggedIn()) {
27
- // Redirect to home page if already logged in
28
- throw redirect(ROUTES.HOME);
29
- }
30
-
31
- return null;
32
- }
@@ -1,25 +0,0 @@
1
- import type { LoaderFunctionArgs } from 'react-router-dom';
2
- import { BusinessScreenDocument } from '../../gql/graphql.js';
3
- import { getUrqlClient } from '../../providers/urql-client.js';
4
- import { validateBusinessParams } from '../types.js';
5
-
6
- /**
7
- * Business loader - prefetches business data before component renders
8
- * Used by: /businesses/:businessId route
9
- */
10
- export async function businessLoader({ params }: LoaderFunctionArgs) {
11
- const { businessId } = validateBusinessParams(params);
12
-
13
- const client = getUrqlClient();
14
- const result = await client.query(BusinessScreenDocument, { businessId }).toPromise();
15
-
16
- if (result.error) {
17
- throw new Response('Failed to load business', { status: 500 });
18
- }
19
-
20
- if (!result.data?.business) {
21
- throw new Response('Business not found', { status: 404 });
22
- }
23
-
24
- return result.data;
25
- }