@accounter/client 0.0.8-alpha-20251021150615-800574fc6d416cd319de216c97b431643d8958a2 → 0.0.8-alpha-20251021225827-178e480c997a9811913e16f85cb94329041b096e
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/CHANGELOG.md +67 -1
- package/dist/assets/Checkbox-CxedbJAl.js +6 -0
- package/dist/assets/Progress-D5SuJtCd.js +1 -0
- package/dist/assets/Typography-BQFz-z7L.js +1 -0
- package/dist/assets/accordion-COWOBKuq.js +1 -0
- package/dist/assets/accountant-approvals-Bd2y8us_.js +1 -0
- package/dist/assets/all-charges-SWBnaZu7.js +1 -0
- package/dist/assets/arrow-up-down-dZmrBLse.js +6 -0
- package/dist/assets/business--GVVfDEa.js +37 -0
- package/dist/assets/business-transactions-single-BsbkUf_H.js +1 -0
- package/dist/assets/business-trip-ByXPVXdG.js +1 -0
- package/dist/assets/charges-filters-D43UbXob.js +1 -0
- package/dist/assets/charges-ledger-validation-D0uMH_JE.js +1 -0
- package/dist/assets/chart-ClU1KbWe.js +74 -0
- package/dist/assets/data-table-pagination-D9Y0_Tn8.js +11 -0
- package/dist/assets/editable-business-trip-DhqOQBPa.js +16 -0
- package/dist/assets/graphql-document-dedupe-fragments-ByT8-wlV.js +1 -0
- package/dist/assets/index-1U6rQgQe.js +6 -0
- package/dist/assets/index-3-AKn8tg.js +1 -0
- package/dist/assets/index-91A2PLZ6.js +137 -0
- package/dist/assets/index-BBHuCWRn.js +1 -0
- package/dist/assets/index-BPNuFFtx.js +1 -0
- package/dist/assets/index-BXqHnRVY.js +1 -0
- package/dist/assets/index-BciOH8FS.js +1 -0
- package/dist/assets/index-BjHuUHDO.js +1 -0
- package/dist/assets/index-BxKmoNQd.js +1 -0
- package/dist/assets/index-C3bqiFIv.js +2 -0
- package/dist/assets/index-C5MeepK_.js +11 -0
- package/dist/assets/index-CAwm68Mg.js +1 -0
- package/dist/assets/index-CJ8OGXxv.js +1 -0
- package/dist/assets/index-CJyY-qF6.js +1 -0
- package/dist/assets/index-CMYnx46_.js +6 -0
- package/dist/assets/index-CNrwxUZ7.js +1 -0
- package/dist/assets/index-CvV5z5r9.js +876 -0
- package/dist/assets/index-D08H2GXq.js +17 -0
- package/dist/assets/index-GFsPY1p4.js +2 -0
- package/dist/assets/index-KwNwThNu.js +1 -0
- package/dist/assets/index-YA8IBFyB.js +1 -0
- package/dist/assets/index-ZpyI3qxW.js +24 -0
- package/dist/assets/index-gdTXrWXt.css +1 -0
- package/dist/assets/index-ytnIEraq.js +9 -0
- package/dist/assets/{index.es-DHwHzag1.js → index.es-CYeQ4a5s.js} +5 -5
- package/dist/assets/issue-document-CdikNnO2.js +1 -0
- package/dist/assets/login-page-effgZS3V.js +1 -0
- package/dist/assets/missing-info-charges-CnPFTzoZ.js +1 -0
- package/dist/assets/page-not-found-D8YlgDOm.js +1 -0
- package/dist/assets/pencil-mxW0-tGM.js +6 -0
- package/dist/assets/report-commentary-row-DCozKgVE.js +1 -0
- package/dist/assets/save-CHlytUqu.js +11 -0
- package/dist/assets/sequential-CAnleQny.js +1 -0
- package/dist/assets/similar-charges-by-business-modal-Dzbspk_r.js +1 -0
- package/dist/assets/sub-Cp_PhKiD.js +1 -0
- package/dist/assets/subMonths-DCj_iXAn.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +6 -5
- package/src/app.tsx +35 -25
- package/src/components/business/business-header.tsx +68 -0
- package/src/components/business/charges-section.tsx +82 -0
- package/src/components/business/charts-section.tsx +115 -0
- package/src/components/business/configurations-section.tsx +885 -0
- package/src/components/business/contact-info-section.tsx +536 -0
- package/src/components/business/contracts-section.tsx +196 -0
- package/src/components/business/documents-section.tsx +26 -0
- package/src/components/business/index.tsx +171 -0
- package/src/components/business/integrations-section.tsx +477 -0
- package/src/components/business/transactions-section.tsx +26 -0
- package/src/components/business-transactions/business-extended-info.tsx +22 -28
- package/src/components/business-transactions/business-transactions-single.tsx +3 -3
- package/src/components/business-transactions/index.tsx +13 -2
- package/src/components/business-trips/business-trip.tsx +3 -3
- package/src/components/charges/cells/business-trip.tsx +6 -8
- package/src/components/charges/cells/counterparty.tsx +7 -5
- package/src/components/charges/charge-extended-info-menu.tsx +27 -21
- package/src/components/charges/charges-row.tsx +12 -10
- package/src/components/charges/charges-table.tsx +15 -9
- package/src/components/clients/contracts/modify-contract-dialog.tsx +464 -0
- package/src/components/clients/modify-client-dialog.tsx +276 -0
- package/src/components/common/accounter-table.tsx +6 -5
- package/src/components/common/business-trip-report/parts/core-expense-row.tsx +11 -9
- package/src/components/common/business-trip-report/parts/uncategorized-transactions.tsx +11 -13
- package/src/components/common/buttons/index.ts +0 -2
- package/src/components/common/buttons/logout-button.tsx +7 -6
- package/src/components/common/documents/issue-document/index.tsx +3 -3
- package/src/components/common/documents/issue-document/{recent-client-docs.tsx → recent-business-docs.tsx} +19 -13
- package/src/components/common/documents-to-charge-matcher/selection-handler/index.tsx +4 -2
- package/src/components/common/documents-to-charge-matcher/selection-handler/wide-filtered-selection.tsx +5 -7
- package/src/components/common/forms/business-card.tsx +1 -0
- package/src/components/common/forms/edit-document.tsx +23 -10
- package/src/components/common/forms/modify-business-fields.tsx +2 -19
- package/src/components/common/inputs/combo-box.tsx +1 -1
- package/src/components/common/new-documents-list.tsx +10 -8
- package/src/components/documents-table/cells/creditor.tsx +11 -4
- package/src/components/documents-table/cells/debtor.tsx +11 -4
- package/src/components/error-boundary.tsx +189 -0
- package/src/components/layout/breadcrumbs.tsx +77 -0
- package/src/components/layout/dashboard-layout.tsx +4 -0
- package/src/components/layout/document-title.tsx +31 -0
- package/src/components/layout/navigation-progress.tsx +52 -0
- package/src/components/layout/page-skeleton.tsx +49 -0
- package/src/components/layout/sidelinks.tsx +28 -27
- package/src/components/ledger-table/counterparty-cell.tsx +19 -13
- package/src/components/login-page.tsx +2 -1
- package/src/components/reports/corporate-tax-ruling-compliance-report/index.tsx +3 -3
- package/src/components/reports/profit-and-loss-report/index.tsx +3 -3
- package/src/components/reports/tax-report/index.tsx +3 -3
- package/src/components/reports/trial-balance-report/trial-balance-report-group.tsx +4 -6
- package/src/components/reports/trial-balance-report/trial-balance-report-sort-code.tsx +8 -11
- package/src/components/screens/businesses/business.tsx +56 -0
- package/src/components/screens/charges/charge.tsx +22 -9
- package/src/components/screens/documents/issue-documents/edit-issue-document-modal.tsx +4 -4
- package/src/components/transactions-table/cells/counterparty.tsx +9 -2
- package/src/components/transactions-table/cells-legacy/counterparty.tsx +9 -2
- package/src/components/ui/progress.tsx +25 -0
- package/src/components/ui/skeleton.tsx +12 -0
- package/src/gql/gql.ts +93 -9
- package/src/gql/graphql.ts +289 -9
- package/src/helpers/contracts.ts +22 -0
- package/src/helpers/currency.ts +5 -0
- package/src/helpers/index.ts +2 -0
- package/src/helpers/pcn874.ts +17 -0
- package/src/hooks/use-add-sort-code.ts +1 -1
- package/src/hooks/use-add-tag.ts +1 -1
- package/src/hooks/use-create-contract.ts +62 -0
- package/src/hooks/use-delete-contract.ts +64 -0
- package/src/hooks/use-delete-tag.ts +1 -1
- package/src/hooks/use-get-all-contracts.ts +0 -1
- package/src/hooks/use-insert-client.ts +80 -0
- package/src/hooks/use-merge-businesses.ts +1 -1
- package/src/hooks/use-merge-charges.ts +1 -1
- package/src/hooks/use-update-client.ts +75 -0
- package/src/hooks/use-update-contract.ts +69 -0
- package/src/index.tsx +4 -22
- package/src/providers/auth-guard.tsx +14 -23
- package/src/providers/index.tsx +7 -2
- package/src/providers/urql-client.ts +86 -0
- package/src/providers/urql.tsx +7 -12
- package/src/providers/user-provider.tsx +3 -2
- package/src/router/config.tsx +534 -0
- package/src/router/layouts/dashboard-layout.tsx +20 -0
- package/src/router/layouts/root-layout.tsx +69 -0
- package/src/router/loaders/auth-loader.ts +32 -0
- package/src/router/loaders/business-loader.ts +25 -0
- package/src/router/loaders/charge-loader.ts +25 -0
- package/src/router/loaders/index.ts +17 -0
- package/src/router/routes.ts +88 -0
- package/src/router/types.ts +62 -0
- package/dist/assets/index-0eCf1BcD.css +0 -1
- package/dist/assets/index-DHTbHvtz.js +0 -1188
- package/src/components/common/buttons/button-with-label.tsx +0 -41
- package/src/components/common/buttons/button.tsx +0 -44
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
Scale,
|
|
27
27
|
Tags,
|
|
28
28
|
} from 'lucide-react';
|
|
29
|
+
import { ROUTES } from '../../router/routes.js';
|
|
29
30
|
|
|
30
31
|
export interface NavLink {
|
|
31
32
|
title: string;
|
|
@@ -49,19 +50,19 @@ export const sidelinks: SideLink[] = [
|
|
|
49
50
|
{
|
|
50
51
|
title: 'All Charges',
|
|
51
52
|
label: '',
|
|
52
|
-
href:
|
|
53
|
+
href: ROUTES.CHARGES.ALL,
|
|
53
54
|
icon: <Receipt size={18} />,
|
|
54
55
|
},
|
|
55
56
|
{
|
|
56
57
|
title: 'Missing Info Charges',
|
|
57
58
|
label: '',
|
|
58
|
-
href:
|
|
59
|
+
href: ROUTES.CHARGES.MISSING_INFO,
|
|
59
60
|
icon: <RectangleEllipsis size={18} />,
|
|
60
61
|
},
|
|
61
62
|
{
|
|
62
63
|
title: 'Ledger Validation',
|
|
63
64
|
label: '',
|
|
64
|
-
href:
|
|
65
|
+
href: ROUTES.CHARGES.LEDGER_VALIDATION,
|
|
65
66
|
icon: <BookOpenCheck size={18} />,
|
|
66
67
|
},
|
|
67
68
|
],
|
|
@@ -75,73 +76,73 @@ export const sidelinks: SideLink[] = [
|
|
|
75
76
|
{
|
|
76
77
|
title: 'VAT Monthly Report',
|
|
77
78
|
label: '',
|
|
78
|
-
href:
|
|
79
|
+
href: ROUTES.REPORTS.VAT_MONTHLY,
|
|
79
80
|
icon: <Receipt size={18} />,
|
|
80
81
|
},
|
|
81
82
|
{
|
|
82
83
|
title: 'Trial Balance Report',
|
|
83
84
|
label: '',
|
|
84
|
-
href:
|
|
85
|
+
href: ROUTES.REPORTS.TRIAL_BALANCE,
|
|
85
86
|
icon: <Scale size={18} />,
|
|
86
87
|
},
|
|
87
88
|
{
|
|
88
89
|
title: 'Conto Report',
|
|
89
90
|
label: '',
|
|
90
|
-
href:
|
|
91
|
+
href: ROUTES.REPORTS.CONTO,
|
|
91
92
|
icon: <Puzzle size={18} />,
|
|
92
93
|
},
|
|
93
94
|
{
|
|
94
95
|
title: 'Profit and Loss Report',
|
|
95
96
|
label: '',
|
|
96
|
-
href:
|
|
97
|
+
href: ROUTES.REPORTS.PROFIT_AND_LOSS(),
|
|
97
98
|
icon: <HandCoins size={18} />,
|
|
98
99
|
},
|
|
99
100
|
{
|
|
100
101
|
title: 'Tax Report',
|
|
101
102
|
label: '',
|
|
102
|
-
href:
|
|
103
|
+
href: ROUTES.REPORTS.TAX(),
|
|
103
104
|
icon: <ParkingMeter size={18} />,
|
|
104
105
|
},
|
|
105
106
|
{
|
|
106
107
|
title: 'Corporate Tax Ruling Compliance Report',
|
|
107
108
|
label: '',
|
|
108
|
-
href:
|
|
109
|
+
href: ROUTES.REPORTS.CORPORATE_TAX_RULING_COMPLIANCE(),
|
|
109
110
|
icon: <ParkingMeter size={18} />,
|
|
110
111
|
},
|
|
111
112
|
{
|
|
112
113
|
title: 'Depreciation Report',
|
|
113
114
|
label: '',
|
|
114
|
-
href:
|
|
115
|
+
href: ROUTES.REPORTS.DEPRECIATION,
|
|
115
116
|
icon: <ChartColumnDecreasing size={18} />,
|
|
116
117
|
},
|
|
117
118
|
{
|
|
118
119
|
title: 'Shaam 6111 Report',
|
|
119
120
|
label: '',
|
|
120
|
-
href:
|
|
121
|
+
href: ROUTES.REPORTS.SHAAM_6111,
|
|
121
122
|
icon: <HandCoins size={18} />,
|
|
122
123
|
},
|
|
123
124
|
{
|
|
124
125
|
title: 'Accountant Approvals',
|
|
125
126
|
label: '',
|
|
126
|
-
href:
|
|
127
|
+
href: ROUTES.ACCOUNTANT_APPROVALS,
|
|
127
128
|
icon: <Calculator size={18} />,
|
|
128
129
|
},
|
|
129
130
|
{
|
|
130
131
|
title: 'Yearly Ledger Report',
|
|
131
132
|
label: '',
|
|
132
|
-
href:
|
|
133
|
+
href: ROUTES.REPORTS.YEARLY_LEDGER,
|
|
133
134
|
icon: <Rows4 size={18} />,
|
|
134
135
|
},
|
|
135
136
|
{
|
|
136
137
|
title: 'Transactions Balance',
|
|
137
138
|
label: '',
|
|
138
|
-
href:
|
|
139
|
+
href: ROUTES.REPORTS.BALANCE,
|
|
139
140
|
icon: <ChartNoAxesCombined size={18} />,
|
|
140
141
|
},
|
|
141
142
|
{
|
|
142
143
|
title: 'Validate Reports',
|
|
143
144
|
label: '',
|
|
144
|
-
href:
|
|
145
|
+
href: ROUTES.REPORTS.VALIDATE_REPORTS,
|
|
145
146
|
icon: <CheckCheck size={18} />,
|
|
146
147
|
},
|
|
147
148
|
{
|
|
@@ -160,25 +161,25 @@ export const sidelinks: SideLink[] = [
|
|
|
160
161
|
{
|
|
161
162
|
title: 'Businesses',
|
|
162
163
|
label: '',
|
|
163
|
-
href:
|
|
164
|
+
href: ROUTES.BUSINESSES.ALL,
|
|
164
165
|
icon: <Factory size={18} />,
|
|
165
166
|
},
|
|
166
167
|
{
|
|
167
168
|
title: 'Business Transactions',
|
|
168
169
|
label: '',
|
|
169
|
-
href:
|
|
170
|
+
href: ROUTES.BUSINESSES.TRANSACTIONS,
|
|
170
171
|
icon: <ArrowLeftRight size={18} />,
|
|
171
172
|
},
|
|
172
173
|
{
|
|
173
174
|
title: 'Tax Categories',
|
|
174
175
|
label: '',
|
|
175
|
-
href:
|
|
176
|
+
href: ROUTES.TAX_CATEGORIES,
|
|
176
177
|
icon: <ArrowDown01 size={18} />,
|
|
177
178
|
},
|
|
178
179
|
{
|
|
179
180
|
title: 'Sort Codes',
|
|
180
181
|
label: '',
|
|
181
|
-
href:
|
|
182
|
+
href: ROUTES.SORT_CODES,
|
|
182
183
|
icon: <Book size={18} />,
|
|
183
184
|
},
|
|
184
185
|
],
|
|
@@ -190,7 +191,7 @@ export const sidelinks: SideLink[] = [
|
|
|
190
191
|
icon: <Files size={18} />,
|
|
191
192
|
sub: [
|
|
192
193
|
{
|
|
193
|
-
href:
|
|
194
|
+
href: ROUTES.DOCUMENTS.ALL,
|
|
194
195
|
title: 'All Documents',
|
|
195
196
|
label: '',
|
|
196
197
|
icon: <Files size={18} />,
|
|
@@ -198,19 +199,19 @@ export const sidelinks: SideLink[] = [
|
|
|
198
199
|
{
|
|
199
200
|
title: 'Issue Documents',
|
|
200
201
|
label: '',
|
|
201
|
-
href:
|
|
202
|
+
href: ROUTES.DOCUMENTS.ISSUE_DOCUMENTS,
|
|
202
203
|
icon: <FilePen size={18} />,
|
|
203
204
|
},
|
|
204
205
|
{
|
|
205
206
|
title: 'Issue Document',
|
|
206
207
|
label: '',
|
|
207
|
-
href:
|
|
208
|
+
href: ROUTES.DOCUMENTS.ISSUE_DOCUMENT,
|
|
208
209
|
icon: <FilePen size={18} />,
|
|
209
210
|
},
|
|
210
211
|
],
|
|
211
212
|
},
|
|
212
213
|
{
|
|
213
|
-
href:
|
|
214
|
+
href: ROUTES.BUSINESS_TRIPS.ALL,
|
|
214
215
|
title: 'Business Trips',
|
|
215
216
|
label: '',
|
|
216
217
|
icon: <PlaneTakeoff size={18} />,
|
|
@@ -224,25 +225,25 @@ export const sidelinks: SideLink[] = [
|
|
|
224
225
|
{
|
|
225
226
|
title: 'Main',
|
|
226
227
|
label: '',
|
|
227
|
-
href:
|
|
228
|
+
href: ROUTES.CHARTS.MAIN,
|
|
228
229
|
icon: <BarChartBig size={18} />,
|
|
229
230
|
},
|
|
230
231
|
{
|
|
231
232
|
title: 'Monthly Income/Expense',
|
|
232
233
|
label: '',
|
|
233
|
-
href:
|
|
234
|
+
href: ROUTES.CHARTS.MONTHLY_INCOME_EXPENSE,
|
|
234
235
|
icon: <BarChartBig size={18} />,
|
|
235
236
|
},
|
|
236
237
|
],
|
|
237
238
|
},
|
|
238
239
|
{
|
|
239
|
-
href:
|
|
240
|
+
href: ROUTES.SALARIES,
|
|
240
241
|
title: 'Salaries',
|
|
241
242
|
label: '',
|
|
242
243
|
icon: <BadgeDollarSign size={18} />,
|
|
243
244
|
},
|
|
244
245
|
{
|
|
245
|
-
href:
|
|
246
|
+
href: ROUTES.TAGS,
|
|
246
247
|
title: 'Tags',
|
|
247
248
|
label: '',
|
|
248
249
|
icon: <Tags size={18} />,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, type ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
3
|
import type { ChargeFilter } from '../../gql/graphql.js';
|
|
4
4
|
import { useUrlQuery } from '../../hooks/use-url-query.js';
|
|
5
5
|
import { getBusinessTransactionsHref } from '../business-transactions/index.js';
|
|
@@ -50,21 +50,27 @@ export const CounterpartyCell = ({ account, diffAccount }: Props): ReactElement
|
|
|
50
50
|
{(account || isAccountDiff) && (
|
|
51
51
|
<>
|
|
52
52
|
{account && (
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
<Link
|
|
54
|
+
to={getHref(account.id)}
|
|
55
|
+
target="_blank"
|
|
56
|
+
rel="noreferrer"
|
|
57
|
+
onClick={event => event.stopPropagation()}
|
|
58
|
+
className="inline-flex items-center font-semibold"
|
|
59
|
+
>
|
|
60
|
+
{account.name}
|
|
61
|
+
</Link>
|
|
59
62
|
)}
|
|
60
63
|
{isAccountDiff && diffAccount && (
|
|
61
64
|
<div className="border-2 border-yellow-500 rounded-md">
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
<Link
|
|
66
|
+
to={getHref(diffAccount.id)}
|
|
67
|
+
target="_blank"
|
|
68
|
+
rel="noreferrer"
|
|
69
|
+
onClick={event => event.stopPropagation()}
|
|
70
|
+
className="inline-flex items-center font-semibold"
|
|
71
|
+
>
|
|
72
|
+
{diffAccount.name}
|
|
73
|
+
</Link>
|
|
68
74
|
</div>
|
|
69
75
|
)}
|
|
70
76
|
</>
|
|
@@ -5,6 +5,7 @@ import { toast } from 'sonner';
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
7
7
|
import { AuthContext } from '../providers/auth-guard.js';
|
|
8
|
+
import { ROUTES } from '../router/routes.js';
|
|
8
9
|
import { Button } from './ui/button.js';
|
|
9
10
|
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from './ui/form.js';
|
|
10
11
|
import { Input } from './ui/input.js';
|
|
@@ -32,7 +33,7 @@ export function LoginPage(): ReactElement {
|
|
|
32
33
|
function onSubmit(values: z.infer<typeof formSchema>) {
|
|
33
34
|
try {
|
|
34
35
|
authService.login(values.username, values.password).then(_user => {
|
|
35
|
-
navigate(
|
|
36
|
+
navigate(ROUTES.HOME);
|
|
36
37
|
});
|
|
37
38
|
toast.success('Success', {
|
|
38
39
|
description: 'You have successfully logged in.',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext, useEffect, useState, type ReactElement } from 'react';
|
|
2
2
|
import { Loader2 } from 'lucide-react';
|
|
3
|
-
import {
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useQuery } from 'urql';
|
|
5
5
|
import { Indicator, Table, Tooltip } from '@mantine/core';
|
|
6
6
|
import { CorporateTaxRulingComplianceReportDocument, Currency } from '../../../gql/graphql.js';
|
|
@@ -109,10 +109,10 @@ function multipleOptionalFormatter(amounts: number[], currency: Currency) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
export const CorporateTaxRulingComplianceReport = (): ReactElement => {
|
|
112
|
-
const
|
|
112
|
+
const { year: yearFromUrl } = useParams<{ year: string }>();
|
|
113
113
|
const { setFiltersContext } = useContext(FiltersContext);
|
|
114
114
|
const [years, setYears] = useState<number[]>(
|
|
115
|
-
|
|
115
|
+
yearFromUrl ? [Number(yearFromUrl)] : [new Date().getFullYear()],
|
|
116
116
|
);
|
|
117
117
|
|
|
118
118
|
// fetch data
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext, useEffect, useState, type ReactElement } from 'react';
|
|
2
2
|
import { Loader2 } from 'lucide-react';
|
|
3
|
-
import {
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useQuery } from 'urql';
|
|
5
5
|
import { Table } from '@mantine/core';
|
|
6
6
|
import { ProfitAndLossReportDocument } from '../../../gql/graphql.js';
|
|
@@ -135,10 +135,10 @@ import { ProfitAndLossReportFilter } from './profit-and-loss-report-filters.js';
|
|
|
135
135
|
`;
|
|
136
136
|
|
|
137
137
|
export const ProfitAndLossReport = (): ReactElement => {
|
|
138
|
-
const
|
|
138
|
+
const { year: yearFromUrl } = useParams<{ year: string }>();
|
|
139
139
|
const { setFiltersContext } = useContext(FiltersContext);
|
|
140
140
|
const [year, setYear] = useState<number>(
|
|
141
|
-
|
|
141
|
+
yearFromUrl ? Number(yearFromUrl) : new Date().getFullYear(),
|
|
142
142
|
);
|
|
143
143
|
const [referenceYears, setReferenceYears] = useState<number[]>([]);
|
|
144
144
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext, useEffect, useState, type ReactElement } from 'react';
|
|
2
2
|
import { Loader2 } from 'lucide-react';
|
|
3
|
-
import {
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useQuery } from 'urql';
|
|
5
5
|
import { Table } from '@mantine/core';
|
|
6
6
|
import { TaxReportDocument } from '../../../gql/graphql.js';
|
|
@@ -140,10 +140,10 @@ import { TaxReportFilter } from './tax-report-filters.js';
|
|
|
140
140
|
`;
|
|
141
141
|
|
|
142
142
|
export const TaxReport = (): ReactElement => {
|
|
143
|
-
const
|
|
143
|
+
const { year: yearFromUrl } = useParams<{ year: string }>();
|
|
144
144
|
const { setFiltersContext } = useContext(FiltersContext);
|
|
145
145
|
const [year, setYear] = useState<number>(
|
|
146
|
-
|
|
146
|
+
yearFromUrl ? Number(yearFromUrl) : new Date().getFullYear(),
|
|
147
147
|
);
|
|
148
148
|
const [referenceYears, setReferenceYears] = useState<number[]>([]);
|
|
149
149
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { Text } from '@mantine/core';
|
|
3
3
|
import { Currency } from '../../../gql/graphql.js';
|
|
4
|
-
import {
|
|
4
|
+
import { formatAmountWithCurrency } from '../../../helpers/index.js';
|
|
5
5
|
import { TrialBalanceReportFilters } from './trial-balance-report-filters.js';
|
|
6
6
|
import {
|
|
7
7
|
TrialBalanceReportSortCode,
|
|
@@ -44,16 +44,14 @@ export const TrialBalanceReportGroup = ({
|
|
|
44
44
|
<td colSpan={2}>Group total:</td>
|
|
45
45
|
<td colSpan={1}>{group.replaceAll('0', '*')}</td>
|
|
46
46
|
<td colSpan={1}>
|
|
47
|
-
{!!data.totalDebit &&
|
|
48
|
-
`${currencyCodeToSymbol(Currency.Ils)} ${formatStringifyAmount(data.totalDebit)}`}
|
|
47
|
+
{!!data.totalDebit && formatAmountWithCurrency(data.totalDebit, Currency.Ils)}
|
|
49
48
|
</td>
|
|
50
49
|
<td colSpan={1}>
|
|
51
|
-
{!!data.totalCredit &&
|
|
52
|
-
`${currencyCodeToSymbol(Currency.Ils)} ${formatStringifyAmount(data.totalCredit)}`}
|
|
50
|
+
{!!data.totalCredit && formatAmountWithCurrency(data.totalCredit, Currency.Ils)}
|
|
53
51
|
</td>
|
|
54
52
|
<td colSpan={1}>
|
|
55
53
|
<Text fw={700} c={data.sum > 0 ? 'green' : data.sum < 0 ? 'red' : undefined}>
|
|
56
|
-
{
|
|
54
|
+
{formatAmountWithCurrency(data.sum, Currency.Ils)}
|
|
57
55
|
</Text>
|
|
58
56
|
</td>
|
|
59
57
|
</tr>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { Text } from '@mantine/core';
|
|
3
3
|
import { Currency } from '../../../gql/graphql.js';
|
|
4
|
-
import {
|
|
4
|
+
import { formatAmountWithCurrency } from '../../../helpers/index.js';
|
|
5
5
|
import {
|
|
6
6
|
TrialBalanceReportBusiness,
|
|
7
7
|
type ExtendedBusiness,
|
|
@@ -55,29 +55,26 @@ export const TrialBalanceReportSortCode = ({
|
|
|
55
55
|
<td colSpan={2}>Group total:</td>
|
|
56
56
|
<td colSpan={1}>{sortCode.key}</td>
|
|
57
57
|
<td colSpan={1}>
|
|
58
|
-
{!!sortCode.totalDebit &&
|
|
59
|
-
`${currencyCodeToSymbol(Currency.Ils)} ${formatStringifyAmount(sortCode.totalDebit)}`}
|
|
58
|
+
{!!sortCode.totalDebit && formatAmountWithCurrency(sortCode.totalDebit, Currency.Ils)}
|
|
60
59
|
</td>
|
|
61
60
|
<td colSpan={1}>
|
|
62
61
|
{!!sortCode.totalCredit &&
|
|
63
|
-
|
|
62
|
+
formatAmountWithCurrency(sortCode.totalCredit, Currency.Ils)}
|
|
64
63
|
</td>
|
|
65
64
|
<td colSpan={1}>
|
|
66
|
-
<Text
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
<Text c={sortCode.sum > 0 ? 'green' : sortCode.sum < 0 ? 'red' : undefined}>
|
|
66
|
+
{formatAmountWithCurrency(sortCode.sum, Currency.Ils)}
|
|
67
|
+
</Text>
|
|
69
68
|
{!!sortCode.debit && (
|
|
70
69
|
<>
|
|
71
70
|
<br />
|
|
72
|
-
Total Debit Balances:{
|
|
73
|
-
{`${currencyCodeToSymbol(Currency.Ils)} ${formatStringifyAmount(sortCode.debit)}`}
|
|
71
|
+
Total Debit Balances: {formatAmountWithCurrency(sortCode.debit, Currency.Ils)}
|
|
74
72
|
</>
|
|
75
73
|
)}
|
|
76
74
|
{!!sortCode.credit && (
|
|
77
75
|
<>
|
|
78
76
|
<br />
|
|
79
|
-
Total Credit Balances:{
|
|
80
|
-
{`${currencyCodeToSymbol(Currency.Ils)} ${formatStringifyAmount(sortCode.credit)}`}
|
|
77
|
+
Total Credit Balances: {formatAmountWithCurrency(sortCode.credit, Currency.Ils)}
|
|
81
78
|
</>
|
|
82
79
|
)}
|
|
83
80
|
</td>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import { useLoaderData, useParams } from 'react-router-dom';
|
|
3
|
+
import { useQuery } from 'urql';
|
|
4
|
+
import Business from '@/components/business/index.js';
|
|
5
|
+
import { BusinessScreenDocument, type BusinessScreenQuery } from '../../../gql/graphql.js';
|
|
6
|
+
import { AccounterLoader } from '../../common/index.js';
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
9
|
+
/* GraphQL */ `
|
|
10
|
+
query BusinessScreen($businessId: UUID!) {
|
|
11
|
+
business(id: $businessId) {
|
|
12
|
+
id
|
|
13
|
+
...BusinessPage
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export function getBusinessHref(businessId: string): string {
|
|
19
|
+
return `/businesses/${businessId}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const BusinessScreen = (): ReactElement => {
|
|
23
|
+
const { businessId } = useParams<{ businessId: string }>();
|
|
24
|
+
|
|
25
|
+
// Try to get loader data (will be available when navigating via router)
|
|
26
|
+
let loaderData: BusinessScreenQuery | undefined;
|
|
27
|
+
try {
|
|
28
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
29
|
+
loaderData = useLoaderData() as BusinessScreenQuery;
|
|
30
|
+
} catch {
|
|
31
|
+
// No loader data - fallback to query
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Only fetch if we don't have loader data
|
|
35
|
+
const [{ data, fetching }, fetchBusiness] = useQuery({
|
|
36
|
+
query: BusinessScreenDocument,
|
|
37
|
+
pause: !businessId || !!loaderData,
|
|
38
|
+
variables: {
|
|
39
|
+
businessId: businessId ?? '',
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Use loader data if available, otherwise use query data
|
|
44
|
+
const businessData = loaderData || data;
|
|
45
|
+
const isLoading = !loaderData && fetching;
|
|
46
|
+
|
|
47
|
+
if (isLoading && !businessData?.business) {
|
|
48
|
+
return <AccounterLoader />;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!businessId || !businessData?.business) {
|
|
52
|
+
return <div>Business not found</div>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return <Business data={businessData.business} refetchBusiness={async () => fetchBusiness()} />;
|
|
56
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState, type ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useLoaderData, useParams } from 'react-router-dom';
|
|
3
3
|
import { useQuery } from 'urql';
|
|
4
|
-
import { ChargeScreenDocument } from '../../../gql/graphql.js';
|
|
4
|
+
import { ChargeScreenDocument, type ChargeScreenQuery } from '../../../gql/graphql.js';
|
|
5
5
|
import { ChargesTable } from '../../charges/charges-table.js';
|
|
6
6
|
import {
|
|
7
7
|
AccounterLoader,
|
|
@@ -29,9 +29,17 @@ type Props = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export const Charge = ({ chargeId }: Props): ReactElement => {
|
|
32
|
-
const
|
|
32
|
+
const { chargeId: chargeIdFromUrl } = useParams<{ chargeId: string }>();
|
|
33
|
+
const id = chargeId || chargeIdFromUrl;
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
// Try to get loader data (will be available when navigating via router)
|
|
36
|
+
let loaderData: ChargeScreenQuery | undefined;
|
|
37
|
+
try {
|
|
38
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
39
|
+
loaderData = useLoaderData() as ChargeScreenQuery;
|
|
40
|
+
} catch {
|
|
41
|
+
// No loader data - component used outside router context (e.g., as child component)
|
|
42
|
+
}
|
|
35
43
|
|
|
36
44
|
const [editChargeId, setEditChargeId] = useState<
|
|
37
45
|
{ id: string; onChange: () => void } | undefined
|
|
@@ -43,19 +51,24 @@ export const Charge = ({ chargeId }: Props): ReactElement => {
|
|
|
43
51
|
undefined,
|
|
44
52
|
);
|
|
45
53
|
|
|
54
|
+
// Only fetch if we don't have loader data and need to fetch (prop-based usage)
|
|
46
55
|
const [{ data, fetching }, fetchCharge] = useQuery({
|
|
47
56
|
query: ChargeScreenDocument,
|
|
48
|
-
pause: !id,
|
|
57
|
+
pause: !id || !!loaderData,
|
|
49
58
|
variables: {
|
|
50
59
|
chargeId: id ?? '',
|
|
51
60
|
},
|
|
52
61
|
});
|
|
53
62
|
|
|
54
63
|
useEffect(() => {
|
|
55
|
-
if (id) {
|
|
64
|
+
if (id && !loaderData) {
|
|
56
65
|
fetchCharge();
|
|
57
66
|
}
|
|
58
|
-
}, [id, fetchCharge]);
|
|
67
|
+
}, [id, loaderData, fetchCharge]);
|
|
68
|
+
|
|
69
|
+
// Use loader data if available, otherwise use query data
|
|
70
|
+
const chargeData = loaderData || data;
|
|
71
|
+
const isLoading = !loaderData && fetching;
|
|
59
72
|
|
|
60
73
|
if (!id) {
|
|
61
74
|
return <div>Charge not found</div>;
|
|
@@ -63,14 +76,14 @@ export const Charge = ({ chargeId }: Props): ReactElement => {
|
|
|
63
76
|
|
|
64
77
|
return (
|
|
65
78
|
<>
|
|
66
|
-
{
|
|
79
|
+
{isLoading ? (
|
|
67
80
|
<AccounterLoader />
|
|
68
81
|
) : (
|
|
69
82
|
<ChargesTable
|
|
70
83
|
setEditChargeId={setEditChargeId}
|
|
71
84
|
setInsertDocument={setInsertDocument}
|
|
72
85
|
setMatchDocuments={setMatchDocuments}
|
|
73
|
-
data={
|
|
86
|
+
data={chargeData?.charge ? [chargeData.charge] : []}
|
|
74
87
|
isAllOpened
|
|
75
88
|
/>
|
|
76
89
|
)}
|
|
@@ -3,7 +3,7 @@ import { Check, Edit, Eye, FileText, Loader2 } from 'lucide-react';
|
|
|
3
3
|
import type { NewDocumentInfoFragment } from '../../../../gql/graphql.js';
|
|
4
4
|
import { usePreviewDocument } from '../../../../hooks/use-preview-document.js';
|
|
5
5
|
import { PdfViewer } from '../../../common/documents/issue-document/pdf-viewer.js';
|
|
6
|
-
import {
|
|
6
|
+
import { RecentBusinessDocs } from '../../../common/documents/issue-document/recent-business-docs.js';
|
|
7
7
|
import { RecentDocsOfSameType } from '../../../common/documents/issue-document/recent-docs-of-same-type.js';
|
|
8
8
|
import {
|
|
9
9
|
convertNewDocumentInfoFragmentIntoPreviewDocumentInput,
|
|
@@ -201,10 +201,10 @@ export function EditIssueDocumentModal({ onApprove, draft }: Props): ReactElemen
|
|
|
201
201
|
</CardContent>
|
|
202
202
|
</Card>
|
|
203
203
|
|
|
204
|
-
{/* Previous
|
|
204
|
+
{/* Previous business documents */}
|
|
205
205
|
{document.client?.id && (
|
|
206
|
-
<
|
|
207
|
-
|
|
206
|
+
<RecentBusinessDocs
|
|
207
|
+
businessId={document.client?.id}
|
|
208
208
|
linkedDocumentIds={document.linkedDocumentIds ?? []}
|
|
209
209
|
/>
|
|
210
210
|
)}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useState, type ReactElement } from 'react';
|
|
2
2
|
import { CheckIcon } from 'lucide-react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
3
4
|
import type { ChargeFilter } from '../../../gql/graphql.js';
|
|
4
5
|
import { useGetBusinesses } from '../../../hooks/use-get-businesses.js';
|
|
5
6
|
import { useUpdateTransaction } from '../../../hooks/use-update-transaction.js';
|
|
@@ -85,9 +86,15 @@ export function Counterparty({ transaction, onChange }: Props): ReactElement {
|
|
|
85
86
|
<>
|
|
86
87
|
<div className="flex flex-wrap flex-col justify-center">
|
|
87
88
|
{counterparty?.id ? (
|
|
88
|
-
<
|
|
89
|
+
<Link
|
|
90
|
+
to={getHref(counterparty.id)}
|
|
91
|
+
target="_blank"
|
|
92
|
+
rel="noreferrer"
|
|
93
|
+
onClick={event => event.stopPropagation()}
|
|
94
|
+
className="inline-flex items-center font-semibold"
|
|
95
|
+
>
|
|
89
96
|
{name}
|
|
90
|
-
</
|
|
97
|
+
</Link>
|
|
91
98
|
) : (
|
|
92
99
|
<>
|
|
93
100
|
<SelectWithSearch
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useState, type ReactElement } from 'react';
|
|
2
2
|
import { CheckIcon } from 'lucide-react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
3
4
|
import {
|
|
4
5
|
TransactionsTableEntityFieldsFragmentDoc,
|
|
5
6
|
type ChargeFilter,
|
|
@@ -106,9 +107,15 @@ export function Counterparty({ data, onChange, enableEdit }: Props): ReactElemen
|
|
|
106
107
|
<td>
|
|
107
108
|
<div className="flex flex-wrap gap-1 items-center justify-center">
|
|
108
109
|
{counterparty?.id ? (
|
|
109
|
-
<
|
|
110
|
+
<Link
|
|
111
|
+
to={getHref(counterparty.id)}
|
|
112
|
+
target="_blank"
|
|
113
|
+
rel="noreferrer"
|
|
114
|
+
onClick={event => event.stopPropagation()}
|
|
115
|
+
className="inline-flex items-center font-semibold"
|
|
116
|
+
>
|
|
110
117
|
{name}
|
|
111
|
-
</
|
|
118
|
+
</Link>
|
|
112
119
|
) : (
|
|
113
120
|
<>
|
|
114
121
|
<SelectWithSearch
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { forwardRef, type ComponentPropsWithoutRef, type ComponentRef } from 'react';
|
|
2
|
+
import { cn } from '@/lib/utils.js';
|
|
3
|
+
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
4
|
+
|
|
5
|
+
const Progress = forwardRef<
|
|
6
|
+
ComponentRef<typeof ProgressPrimitive.Root>,
|
|
7
|
+
ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
|
|
8
|
+
>(({ className, value, ...props }, ref) => (
|
|
9
|
+
<ProgressPrimitive.Root
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
'relative h-2 w-full overflow-hidden rounded-full bg-gray-900/20 dark:bg-gray-50/20',
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<ProgressPrimitive.Indicator
|
|
18
|
+
className="h-full w-full flex-1 bg-gray-900 transition-all dark:bg-gray-50"
|
|
19
|
+
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
20
|
+
/>
|
|
21
|
+
</ProgressPrimitive.Root>
|
|
22
|
+
));
|
|
23
|
+
Progress.displayName = ProgressPrimitive.Root.displayName;
|
|
24
|
+
|
|
25
|
+
export { Progress };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { cn } from '@/lib/utils.js';
|
|
2
|
+
|
|
3
|
+
function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
4
|
+
return (
|
|
5
|
+
<div
|
|
6
|
+
className={cn('animate-pulse rounded-md bg-gray-900/10 dark:bg-gray-50/10', className)}
|
|
7
|
+
{...props}
|
|
8
|
+
/>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { Skeleton };
|