@accounter/client 0.0.8-alpha-20251021150553-5fe662174014d6173ebcea8412cf0fa294abbed2 → 0.0.8-alpha-20251021163440-2ab1a9ffaec95fd99fac5495c3a392b97429ce77

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 (56) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/dist/assets/index-B2UYAO1O.css +1 -0
  3. package/dist/assets/index-BexxGuN6.js +1224 -0
  4. package/dist/assets/{index.es-BaJmdn-u.js → index.es-CWwhWGxX.js} +1 -1
  5. package/dist/index.html +2 -2
  6. package/package.json +2 -1
  7. package/src/app.tsx +35 -25
  8. package/src/components/business/business-header.tsx +68 -0
  9. package/src/components/business/charges-section.tsx +82 -0
  10. package/src/components/business/charts-section.tsx +115 -0
  11. package/src/components/business/configurations-section.tsx +885 -0
  12. package/src/components/business/contact-info-section.tsx +536 -0
  13. package/src/components/business/contracts-section.tsx +196 -0
  14. package/src/components/business/documents-section.tsx +26 -0
  15. package/src/components/business/index.tsx +171 -0
  16. package/src/components/business/integrations-section.tsx +477 -0
  17. package/src/components/business/transactions-section.tsx +26 -0
  18. package/src/components/business-transactions/business-extended-info.tsx +11 -15
  19. package/src/components/business-transactions/business-transactions-single.tsx +1 -1
  20. package/src/components/business-transactions/index.tsx +1 -1
  21. package/src/components/charges/charge-extended-info-menu.tsx +27 -21
  22. package/src/components/charges/charges-row.tsx +12 -10
  23. package/src/components/charges/charges-table.tsx +15 -9
  24. package/src/components/clients/contracts/modify-contract-dialog.tsx +464 -0
  25. package/src/components/clients/modify-client-dialog.tsx +276 -0
  26. package/src/components/common/documents/issue-document/index.tsx +3 -3
  27. package/src/components/common/documents/issue-document/{recent-client-docs.tsx → recent-business-docs.tsx} +19 -13
  28. package/src/components/common/forms/business-card.tsx +1 -0
  29. package/src/components/common/forms/modify-business-fields.tsx +2 -19
  30. package/src/components/common/inputs/combo-box.tsx +1 -1
  31. package/src/components/layout/sidelinks.tsx +3 -3
  32. package/src/components/reports/trial-balance-report/trial-balance-report-group.tsx +4 -6
  33. package/src/components/reports/trial-balance-report/trial-balance-report-sort-code.tsx +8 -11
  34. package/src/components/screens/businesses/business.tsx +44 -0
  35. package/src/components/screens/documents/issue-documents/edit-issue-document-modal.tsx +4 -4
  36. package/src/components/ui/progress.tsx +25 -0
  37. package/src/components/ui/skeleton.tsx +12 -0
  38. package/src/gql/gql.ts +93 -9
  39. package/src/gql/graphql.ts +300 -9
  40. package/src/helpers/contracts.ts +22 -0
  41. package/src/helpers/currency.ts +5 -0
  42. package/src/helpers/index.ts +2 -0
  43. package/src/helpers/pcn874.ts +17 -0
  44. package/src/hooks/use-add-sort-code.ts +1 -1
  45. package/src/hooks/use-add-tag.ts +1 -1
  46. package/src/hooks/use-create-contract.ts +62 -0
  47. package/src/hooks/use-delete-contract.ts +64 -0
  48. package/src/hooks/use-delete-tag.ts +1 -1
  49. package/src/hooks/use-get-all-contracts.ts +0 -1
  50. package/src/hooks/use-insert-client.ts +80 -0
  51. package/src/hooks/use-merge-businesses.ts +1 -1
  52. package/src/hooks/use-merge-charges.ts +1 -1
  53. package/src/hooks/use-update-client.ts +75 -0
  54. package/src/hooks/use-update-contract.ts +69 -0
  55. package/dist/assets/index-CqaS5jWM.css +0 -1
  56. package/dist/assets/index-IlfO2QvT.js +0 -1188
@@ -0,0 +1,22 @@
1
+ import { BillingCycle, SubscriptionPlan } from '@/gql/graphql.js';
2
+
3
+ export function standardBillingCycle(billingCycle: BillingCycle): string {
4
+ switch (billingCycle) {
5
+ case BillingCycle.Annual:
6
+ return 'Annual';
7
+ case BillingCycle.Monthly:
8
+ return 'Monthly';
9
+ default:
10
+ throw new Error(`Unsupported Billing Cycle: ${billingCycle}`);
11
+ }
12
+ }
13
+ export function standardPlan(plan: SubscriptionPlan): string {
14
+ switch (plan) {
15
+ case SubscriptionPlan.Enterprise:
16
+ return 'Enterprise';
17
+ case SubscriptionPlan.Pro:
18
+ return 'Pro';
19
+ default:
20
+ throw new Error(`Unsupported Subscription plan: ${plan}`);
21
+ }
22
+ }
@@ -1,4 +1,5 @@
1
1
  import { Currency } from '../gql/graphql.js';
2
+ import { formatStringifyAmount } from './index.js';
2
3
 
3
4
  export function getCurrencyFormatter(
4
5
  currency: Currency,
@@ -68,3 +69,7 @@ export const FIAT_CURRENCIES: Currency[] = [
68
69
  Currency.Aud,
69
70
  Currency.Sek,
70
71
  ] as const;
72
+
73
+ export function formatAmountWithCurrency(amount: number, currency: Currency, digits = 2): string {
74
+ return `${currencyCodeToSymbol(currency)} ${formatStringifyAmount(amount, digits)}`;
75
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './charges.js';
2
2
  export * from './clipboard.js';
3
3
  export * from './consts.js';
4
+ export * from './contracts.js';
4
5
  export * from './currency.js';
5
6
  export * from './dates.js';
6
7
  export * from './document-matches.js';
@@ -9,6 +10,7 @@ export * from './files.js';
9
10
  export * from './form.js';
10
11
  export * from './graphql-document-dedupe-fragments.js';
11
12
  export * from './numbers.js';
13
+ export * from './pcn874.js';
12
14
  export * from './strings-manipulations.js';
13
15
  export * from './vat.js';
14
16
  export * from './tags.js';
@@ -0,0 +1,17 @@
1
+ import type { Pcn874RecordType } from '@/gql/graphql.js';
2
+
3
+ export const pcn874RecordEnum: Record<Pcn874RecordType, string> = {
4
+ C: 'INPUT_SELF_INVOICE',
5
+ H: 'INPUT_SINGLE_DOC_BY_LAW',
6
+ I: 'SALE_PALESTINIAN_CUSTOMER',
7
+ K: 'INPUT_PETTY_CASH',
8
+ L1: 'SALE_UNIDENTIFIED_CUSTOMER',
9
+ L2: 'SALE_UNIDENTIFIED_ZERO_OR_EXEMPT',
10
+ M: 'SALE_SELF_INVOICE',
11
+ P: 'INPUT_PALESTINIAN_SUPPLIER',
12
+ R: 'INPUT_IMPORT',
13
+ S1: 'SALE_REGULAR',
14
+ S2: 'SALE_ZERO_OR_EXEMPT',
15
+ T: 'INPUT_REGULAR',
16
+ Y: 'SALE_EXPORT',
17
+ } as const;
@@ -20,7 +20,7 @@ const NOTIFICATION_ID = 'addSortCode';
20
20
 
21
21
  export const useAddSortCode = (): UseAddSortCode => {
22
22
  // TODO: add authentication
23
- // TODO: add local data update method after chang e
23
+ // TODO: add local data update method after change
24
24
 
25
25
  const [{ fetching }, mutate] = useMutation(AddSortCodeDocument);
26
26
  const addSortCode = useCallback(
@@ -20,7 +20,7 @@ const NOTIFICATION_ID = 'addTag';
20
20
 
21
21
  export const useAddTag = (): UseAddTag => {
22
22
  // TODO: add authentication
23
- // TODO: add local data update method after chang e
23
+ // TODO: add local data update method after change
24
24
 
25
25
  const [{ fetching }, mutate] = useMutation(AddTagDocument);
26
26
  const addTag = useCallback(
@@ -0,0 +1,62 @@
1
+ import { useCallback } from 'react';
2
+ import { toast } from 'sonner';
3
+ import { useMutation } from 'urql';
4
+ import { CreateContractDocument, type CreateContractMutationVariables } from '../gql/graphql.js';
5
+ import { handleCommonErrors } from '../helpers/error-handling.js';
6
+
7
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
8
+ /* GraphQL */ `
9
+ mutation CreateContract($input: CreateContractInput!) {
10
+ createContract(input: $input) {
11
+ id
12
+ }
13
+ }
14
+ `;
15
+
16
+ type UseCreateContract = {
17
+ creating: boolean;
18
+ createContract: (variables: CreateContractMutationVariables) => Promise<void>;
19
+ };
20
+
21
+ const NOTIFICATION_ID = 'createContract';
22
+
23
+ export const useCreateContract = (): UseCreateContract => {
24
+ // TODO: add authentication
25
+ // TODO: add local data update method after change
26
+
27
+ const [{ fetching }, mutate] = useMutation(CreateContractDocument);
28
+ const createContract = useCallback(
29
+ async (variables: CreateContractMutationVariables) => {
30
+ const message = `Error creating new contract for client[${variables.input.clientId}]`;
31
+ const notificationId = `${NOTIFICATION_ID}-${variables.input.clientId}`;
32
+ toast.loading('Creating contract', {
33
+ id: notificationId,
34
+ });
35
+ try {
36
+ const res = await mutate(variables);
37
+ const data = handleCommonErrors(res, message, notificationId);
38
+ if (data) {
39
+ toast.success('Success', {
40
+ id: notificationId,
41
+ description: `Contract for client ${variables.input.clientId} was successfully created`,
42
+ });
43
+ }
44
+ } catch (e) {
45
+ console.error(`${message}: ${e}`);
46
+ toast.error('Error', {
47
+ id: notificationId,
48
+ description: message,
49
+ duration: 100_000,
50
+ closeButton: true,
51
+ });
52
+ }
53
+ return void 0;
54
+ },
55
+ [mutate],
56
+ );
57
+
58
+ return {
59
+ creating: fetching,
60
+ createContract,
61
+ };
62
+ };
@@ -0,0 +1,64 @@
1
+ import { useCallback } from 'react';
2
+ import { toast } from 'sonner';
3
+ import { useMutation } from 'urql';
4
+ import { DeleteContractDocument, type DeleteContractMutationVariables } from '../gql/graphql.js';
5
+ import { handleCommonErrors } from '../helpers/error-handling.js';
6
+
7
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
8
+ /* GraphQL */ `
9
+ mutation DeleteContract($contractId: UUID!) {
10
+ deleteContract(id: $contractId)
11
+ }
12
+ `;
13
+
14
+ type UseDeleteContract = {
15
+ fetching: boolean;
16
+ deleteContract: (variables: DeleteContractMutationVariables) => Promise<boolean>;
17
+ };
18
+
19
+ const NOTIFICATION_ID = 'deleteContract';
20
+
21
+ export const useDeleteContract = (): UseDeleteContract => {
22
+ // TODO: add authentication
23
+ // TODO: add local data delete method after change
24
+
25
+ const [{ fetching }, mutate] = useMutation(DeleteContractDocument);
26
+ const deleteContract = useCallback(
27
+ async (variables: DeleteContractMutationVariables) => {
28
+ const message = `Error deleting contract ID [${variables.contractId}]`;
29
+ const notificationId = `${NOTIFICATION_ID}-${variables.contractId}`;
30
+ toast.loading('Deleting contract', {
31
+ id: notificationId,
32
+ });
33
+ try {
34
+ const res = await mutate(variables);
35
+ const data = handleCommonErrors(res, message, notificationId);
36
+ if (data) {
37
+ if (data.deleteContract === false) {
38
+ throw new Error('Unsuccessful deletion');
39
+ }
40
+ toast.success('Success', {
41
+ id: notificationId,
42
+ description: 'Contract was deleted',
43
+ });
44
+ return data.deleteContract;
45
+ }
46
+ } catch (e) {
47
+ console.error(`${message}: ${e}`);
48
+ toast.error('Error', {
49
+ id: notificationId,
50
+ description: message,
51
+ duration: 100_000,
52
+ closeButton: true,
53
+ });
54
+ }
55
+ return false;
56
+ },
57
+ [mutate],
58
+ );
59
+
60
+ return {
61
+ fetching,
62
+ deleteContract,
63
+ };
64
+ };
@@ -20,7 +20,7 @@ const NOTIFICATION_ID = 'deleteTag';
20
20
 
21
21
  export const useDeleteTag = (): UseDeleteTag => {
22
22
  // TODO: add authentication
23
- // TODO: add local data update method after chang e
23
+ // TODO: add local data update method after change
24
24
 
25
25
  const [{ fetching }, mutate] = useMutation(DeleteTagDocument);
26
26
  const deleteTag = useCallback(
@@ -31,7 +31,6 @@ import { AllOpenContractsDocument, type AllOpenContractsQuery } from '../gql/gra
31
31
  isActive
32
32
  product
33
33
  plan
34
- signedAgreement
35
34
  msCloud
36
35
  }
37
36
  }
@@ -0,0 +1,80 @@
1
+ import { useCallback } from 'react';
2
+ import { toast } from 'sonner';
3
+ import { useMutation } from 'urql';
4
+ import {
5
+ InsertClientDocument,
6
+ type InsertClientMutation,
7
+ type InsertClientMutationVariables,
8
+ } from '../gql/graphql.js';
9
+ import { handleCommonErrors } from '../helpers/error-handling.js';
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
12
+ /* GraphQL */ `
13
+ mutation InsertClient($fields: ClientInsertInput!) {
14
+ insertClient(fields: $fields) {
15
+ __typename
16
+ ... on Client {
17
+ id
18
+ }
19
+ ... on CommonError {
20
+ message
21
+ }
22
+ }
23
+ }
24
+ `;
25
+
26
+ type InsertClientSuccessfulResult = Extract<
27
+ InsertClientMutation['insertClient'],
28
+ { __typename: 'Client' }
29
+ >;
30
+
31
+ type UseInsertClient = {
32
+ fetching: boolean;
33
+ insertClient: (
34
+ variables: InsertClientMutationVariables,
35
+ ) => Promise<InsertClientSuccessfulResult | void>;
36
+ };
37
+
38
+ const NOTIFICATION_ID = 'insertClient';
39
+
40
+ export const useInsertClient = (): UseInsertClient => {
41
+ // TODO: add authentication
42
+ // TODO: add local data update method after insert
43
+
44
+ const [{ fetching }, mutate] = useMutation(InsertClientDocument);
45
+ const insertClient = useCallback(
46
+ async (variables: InsertClientMutationVariables) => {
47
+ const errorMessage = `Error creating client [${variables.fields.businessId}]`;
48
+ const notificationId = `${NOTIFICATION_ID}-${variables.fields.businessId}`;
49
+ toast.loading('Creating Client...', {
50
+ id: notificationId,
51
+ });
52
+ try {
53
+ const res = await mutate(variables);
54
+ const data = handleCommonErrors(res, errorMessage, notificationId, 'insertClient');
55
+ if (data) {
56
+ toast.success('Success', {
57
+ id: notificationId,
58
+ description: `Client [${variables.fields.businessId}] was created`,
59
+ });
60
+ return data.insertClient;
61
+ }
62
+ } catch (e) {
63
+ console.error(`${errorMessage}: ${e}`);
64
+ toast.error('Error', {
65
+ id: notificationId,
66
+ description: errorMessage,
67
+ duration: 100_000,
68
+ closeButton: true,
69
+ });
70
+ }
71
+ return void 0;
72
+ },
73
+ [mutate],
74
+ );
75
+
76
+ return {
77
+ fetching,
78
+ insertClient,
79
+ };
80
+ };
@@ -23,7 +23,7 @@ const NOTIFICATION_ID = 'mergeBusinesses';
23
23
 
24
24
  export const useMergeBusinesses = (): UseMergeBusinesses => {
25
25
  // TODO: add authentication
26
- // TODO: add local data update method after chang e
26
+ // TODO: add local data update method after change
27
27
 
28
28
  const [{ fetching }, mutate] = useMutation(MergeBusinessesDocument);
29
29
  const mergeBusinesses = useCallback(
@@ -47,7 +47,7 @@ const NOTIFICATION_ID = 'mergeCharges';
47
47
 
48
48
  export const useMergeCharges = (): UseMergeCharges => {
49
49
  // TODO: add authentication
50
- // TODO: add local data update method after chang e
50
+ // TODO: add local data update method after change
51
51
 
52
52
  const [{ fetching }, mutate] = useMutation(MergeChargesDocument);
53
53
  const mergeCharges = useCallback(
@@ -0,0 +1,75 @@
1
+ import { useCallback } from 'react';
2
+ import { toast } from 'sonner';
3
+ import { useMutation } from 'urql';
4
+ import {
5
+ UpdateClientDocument,
6
+ type UpdateClientMutation,
7
+ type UpdateClientMutationVariables,
8
+ } from '../gql/graphql.js';
9
+ import { handleCommonErrors } from '../helpers/error-handling.js';
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
12
+ /* GraphQL */ `
13
+ mutation UpdateClient($businessId: UUID!, $fields: ClientUpdateInput!) {
14
+ updateClient(businessId: $businessId, fields: $fields) {
15
+ __typename
16
+ ... on Client {
17
+ id
18
+ }
19
+ ... on CommonError {
20
+ message
21
+ }
22
+ }
23
+ }
24
+ `;
25
+
26
+ type Client = Extract<UpdateClientMutation['updateClient'], { __typename: 'Client' }>;
27
+
28
+ type UseUpdateClient = {
29
+ fetching: boolean;
30
+ updateClient: (variables: UpdateClientMutationVariables) => Promise<Client | void>;
31
+ };
32
+
33
+ const NOTIFICATION_ID = 'updateClient';
34
+
35
+ export const useUpdateClient = (): UseUpdateClient => {
36
+ // TODO: add authentication
37
+ // TODO: add local data update method after change
38
+
39
+ const [{ fetching }, mutate] = useMutation(UpdateClientDocument);
40
+ const updateClient = useCallback(
41
+ async (variables: UpdateClientMutationVariables) => {
42
+ const message = `Error updating client ID [${variables.businessId}]`;
43
+ const notificationId = `${NOTIFICATION_ID}-${variables.businessId}`;
44
+ toast.loading('Updating client', {
45
+ id: notificationId,
46
+ });
47
+ try {
48
+ const res = await mutate(variables);
49
+ const data = handleCommonErrors(res, message, notificationId, 'updateClient');
50
+ if (data) {
51
+ toast.success('Success', {
52
+ id: notificationId,
53
+ description: 'Client updated',
54
+ });
55
+ return data.updateClient;
56
+ }
57
+ } catch (e) {
58
+ console.error(`${message}: ${e}`);
59
+ toast.error('Error', {
60
+ id: notificationId,
61
+ description: message,
62
+ duration: 100_000,
63
+ closeButton: true,
64
+ });
65
+ }
66
+ return void 0;
67
+ },
68
+ [mutate],
69
+ );
70
+
71
+ return {
72
+ fetching,
73
+ updateClient,
74
+ };
75
+ };
@@ -0,0 +1,69 @@
1
+ import { useCallback } from 'react';
2
+ import { toast } from 'sonner';
3
+ import { useMutation } from 'urql';
4
+ import {
5
+ UpdateContractDocument,
6
+ type UpdateContractMutation,
7
+ type UpdateContractMutationVariables,
8
+ } from '../gql/graphql.js';
9
+ import { handleCommonErrors } from '../helpers/error-handling.js';
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
12
+ /* GraphQL */ `
13
+ mutation UpdateContract($contractId: UUID!, $input: UpdateContractInput!) {
14
+ updateContract(contractId: $contractId, input: $input) {
15
+ id
16
+ }
17
+ }
18
+ `;
19
+
20
+ type Contract = UpdateContractMutation['updateContract'];
21
+
22
+ type UseUpdateContract = {
23
+ updating: boolean;
24
+ updateContract: (variables: UpdateContractMutationVariables) => Promise<Contract | void>;
25
+ };
26
+
27
+ const NOTIFICATION_ID = 'updateContract';
28
+
29
+ export const useUpdateContract = (): UseUpdateContract => {
30
+ // TODO: add authentication
31
+ // TODO: add local data update method after change
32
+
33
+ const [{ fetching }, mutate] = useMutation(UpdateContractDocument);
34
+ const updateContract = useCallback(
35
+ async (variables: UpdateContractMutationVariables) => {
36
+ const message = `Error updating contract ID [${variables.contractId}]`;
37
+ const notificationId = `${NOTIFICATION_ID}-${variables.contractId}`;
38
+ toast.loading('Updating contract', {
39
+ id: notificationId,
40
+ });
41
+ try {
42
+ const res = await mutate(variables);
43
+ const data = handleCommonErrors(res, message, notificationId, 'updateContract');
44
+ if (data) {
45
+ toast.success('Success', {
46
+ id: notificationId,
47
+ description: 'Contract updated',
48
+ });
49
+ return data.updateContract;
50
+ }
51
+ } catch (e) {
52
+ console.error(`${message}: ${e}`);
53
+ toast.error('Error', {
54
+ id: notificationId,
55
+ description: message,
56
+ duration: 100_000,
57
+ closeButton: true,
58
+ });
59
+ }
60
+ return void 0;
61
+ },
62
+ [mutate],
63
+ );
64
+
65
+ return {
66
+ updating: fetching,
67
+ updateContract,
68
+ };
69
+ };