Compare commits

...

1 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
3bf2803360 feat(trpc): implement tRPC integration for accounts module
- Add tRPC server setup with NestJS (nestjs-trpc)
- Create AccountsTrpcRouter with CRUD operations
- Add tRPC client configuration in webapp
- Create tRPC React hooks for accounts module
- Replace existing REST hooks with tRPC hooks across 35+ files
- Maintain backward compatibility with existing REST API
- Add proper cache invalidation for mutations

New files:
- packages/server/src/modules/Trpc/*
- packages/webapp/src/trpc.ts
- packages/webapp/src/hooks/trpc/*
- shared/bigcapital-utils/src/trpc.ts

Dependencies added:
- @trpc/server, @trpc/client, @trpc/react-query
- nestjs-trpc, superjson
- @tanstack/react-query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 04:34:04 +02:00
48 changed files with 622 additions and 85 deletions

View File

@@ -127,7 +127,10 @@
"uuid": "^10.0.0", "uuid": "^10.0.0",
"xlsx": "^0.18.5", "xlsx": "^0.18.5",
"yup": "^0.28.1", "yup": "^0.28.1",
"zod": "^3.23.8" "zod": "^3.23.8",
"@trpc/server": "^11.0.0-rc.648",
"nestjs-trpc": "^1.6.1",
"superjson": "^2.2.2"
}, },
"devDependencies": { "devDependencies": {
"@nestjs/cli": "^10.0.0", "@nestjs/cli": "^10.0.0",

View File

@@ -104,6 +104,7 @@ import { BillLandedCostsModule } from '../BillLandedCosts/BillLandedCosts.module
import { SocketModule } from '../Socket/Socket.module'; import { SocketModule } from '../Socket/Socket.module';
import { ThrottlerGuard } from '@nestjs/throttler'; import { ThrottlerGuard } from '@nestjs/throttler';
import { AppThrottleModule } from './AppThrottle.module'; import { AppThrottleModule } from './AppThrottle.module';
import { AppTrpcModule } from '../Trpc/Trpc.module';
@Module({ @Module({
imports: [ imports: [
@@ -256,6 +257,7 @@ import { AppThrottleModule } from './AppThrottle.module';
UsersModule, UsersModule,
ContactsModule, ContactsModule,
SocketModule, SocketModule,
AppTrpcModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [ providers: [

View File

@@ -0,0 +1,19 @@
import { Injectable } from '@nestjs/common';
import { TRPCContext, ContextOptions } from 'nestjs-trpc';
@Injectable()
export class TrpcContext implements TRPCContext {
async create(opts: ContextOptions): Promise<Record<string, unknown>> {
const { req } = opts;
// Extract auth token and organization from headers
const token = req.headers['x-access-token'];
const organizationId = req.headers['organization-id'];
return {
token,
organizationId: organizationId ? parseInt(organizationId as string, 10) : null,
req,
};
}
}

View File

@@ -0,0 +1,19 @@
import { Module } from '@nestjs/common';
import { TRPCModule } from 'nestjs-trpc';
import { TrpcService } from './Trpc.service';
import { TrpcContext } from './Trpc.context';
import { AccountsTrpcRouter } from './routers/Accounts.router';
import { AccountsModule } from '@/modules/Accounts/Accounts.module';
@Module({
imports: [
TRPCModule.forRoot({
basePath: '/api/trpc',
context: TrpcContext,
}),
AccountsModule,
],
providers: [TrpcService, TrpcContext, AccountsTrpcRouter],
exports: [TrpcService],
})
export class AppTrpcModule {}

View File

@@ -0,0 +1,13 @@
import { Injectable } from '@nestjs/common';
import { Request, Response } from 'express';
export interface TrpcContext {
req: Request;
res: Response;
user: any;
organizationId: number | null;
}
@Injectable()
export class TrpcService {
}

View File

@@ -0,0 +1,192 @@
import { Injectable } from '@nestjs/common';
import { Router, Query, Mutation } from 'nestjs-trpc';
import { z } from 'zod';
import { AccountsApplication } from '@/modules/Accounts/AccountsApplication.service';
import { CreateAccountDTO } from '@/modules/Accounts/CreateAccount.dto';
import { EditAccountDTO } from '@/modules/Accounts/EditAccount.dto';
import { IAccountsStructureType } from '@/modules/Accounts/Accounts.types';
const accountResponseSchema = z.object({
id: z.number(),
name: z.string(),
slug: z.string(),
code: z.string(),
index: z.number(),
accountType: z.string(),
accountTypeLabel: z.string(),
parentAccountId: z.number().nullable(),
predefined: z.boolean(),
currencyCode: z.string(),
active: z.boolean(),
bankBalance: z.number(),
bankBalanceFormatted: z.string(),
lastFeedsUpdatedAt: z.union([z.string(), z.date(), z.null()]),
lastFeedsUpdatedAtFormatted: z.string(),
amount: z.number(),
formattedAmount: z.string(),
plaidItemId: z.string(),
plaidAccountId: z.string().nullable(),
isFeedsActive: z.boolean(),
isSyncingOwner: z.boolean(),
isFeedsPaused: z.boolean(),
accountNormal: z.string(),
accountNormalFormatted: z.string(),
flattenName: z.string(),
accountLevel: z.number().optional(),
createdAt: z.date(),
updatedAt: z.date(),
});
const accountTypeSchema = z.object({
label: z.string(),
key: z.string(),
normal: z.string(),
parentType: z.string(),
rootType: z.string(),
multiCurrency: z.boolean(),
balanceSheet: z.boolean(),
incomeSheet: z.boolean(),
});
const getAccountsQuerySchema = z.object({
onlyInactive: z.boolean().optional(),
structure: z.nativeEnum(IAccountsStructureType).optional(),
page: z.number().optional(),
pageSize: z.number().optional(),
searchKeyword: z.string().optional(),
});
const getAccountsResponseSchema = z.object({
accounts: z.array(z.any()),
filterMeta: z.object({
count: z.number(),
total: z.number(),
page: z.number(),
pageSize: z.number(),
}),
});
const getAccountTransactionsQuerySchema = z.object({
accountId: z.number(),
});
const createAccountInputSchema = z.object({
name: z.string().min(3).max(255),
code: z.string().min(3).max(6).optional(),
currencyCode: z.string().optional(),
accountType: z.string().min(3).max(255),
description: z.string().max(65535).optional(),
parentAccountId: z.number().optional(),
active: z.boolean().optional(),
plaidAccountId: z.string().optional(),
plaidItemId: z.string().optional(),
});
const editAccountInputSchema = createAccountInputSchema.partial();
const bulkDeleteInputSchema = z.object({
ids: z.array(z.number()),
skipUndeletable: z.boolean().optional(),
});
const validateBulkDeleteResponseSchema = z.object({
deletableIds: z.array(z.number()),
nonDeletableIds: z.array(z.number()),
deletableCount: z.number(),
nonDeletableCount: z.number(),
});
@Injectable()
@Router({ alias: 'accounts' })
export class AccountsTrpcRouter {
constructor(private readonly accountsApplication: AccountsApplication) {}
@Query({
input: getAccountsQuerySchema,
output: getAccountsResponseSchema,
})
async getAccounts(input: z.infer<typeof getAccountsQuerySchema>) {
return this.accountsApplication.getAccounts(input);
}
@Query({
input: z.object({ id: z.number() }),
output: accountResponseSchema,
})
async getAccount(input: { id: number }) {
return this.accountsApplication.getAccount(input.id);
}
@Query({
output: z.array(accountTypeSchema),
})
async getAccountTypes() {
return this.accountsApplication.getAccountTypes();
}
@Query({
input: getAccountTransactionsQuerySchema,
output: z.array(z.any()),
})
async getAccountTransactions(input: z.infer<typeof getAccountTransactionsQuerySchema>) {
return this.accountsApplication.getAccountsTransactions({
accountId: input.accountId,
limit: undefined,
});
}
@Mutation({
input: createAccountInputSchema,
})
async createAccount(input: z.infer<typeof createAccountInputSchema>) {
return this.accountsApplication.createAccount(input as CreateAccountDTO);
}
@Mutation({
input: z.object({
id: z.number(),
data: editAccountInputSchema,
}),
})
async editAccount(input: { id: number; data: any }) {
return this.accountsApplication.editAccount(input.id, input.data as EditAccountDTO);
}
@Mutation({
input: z.object({ id: z.number() }),
})
async deleteAccount(input: { id: number }) {
return this.accountsApplication.deleteAccount(input.id);
}
@Mutation({
input: z.object({ id: z.number() }),
})
async activateAccount(input: { id: number }) {
return this.accountsApplication.activateAccount(input.id);
}
@Mutation({
input: z.object({ id: z.number() }),
})
async inactivateAccount(input: { id: number }) {
return this.accountsApplication.inactivateAccount(input.id);
}
@Mutation({
input: bulkDeleteInputSchema,
})
async bulkDeleteAccounts(input: z.infer<typeof bulkDeleteInputSchema>) {
return this.accountsApplication.bulkDeleteAccounts(input.ids, {
skipUndeletable: input.skipUndeletable ?? false,
});
}
@Mutation({
input: z.object({ ids: z.array(z.number()) }),
output: validateBulkDeleteResponseSchema,
})
async validateBulkDeleteAccounts(input: { ids: number[] }) {
return this.accountsApplication.validateBulkDeleteAccounts(input.ids);
}
}

View File

@@ -95,6 +95,10 @@
"react-plaid-link": "^3.2.1", "react-plaid-link": "^3.2.1",
"react-query": "^3.6.0", "react-query": "^3.6.0",
"react-query-devtools": "^2.1.1", "react-query-devtools": "^2.1.1",
"@trpc/client": "^11.0.0-rc.648",
"@trpc/react-query": "^11.0.0-rc.648",
"@tanstack/react-query": "^5.62.0",
"superjson": "^2.2.2",
"react-redux": "^7.2.9", "react-redux": "^7.2.9",
"react-router": "5.3.4", "react-router": "5.3.4",
"react-router-breadcrumbs-hoc": "^3.2.10", "react-router-breadcrumbs-hoc": "^3.2.10",

View File

@@ -4,6 +4,7 @@ import { Router, Switch, Route } from 'react-router';
import { createBrowserHistory } from 'history'; import { createBrowserHistory } from 'history';
import { QueryClientProvider, QueryClient } from 'react-query'; import { QueryClientProvider, QueryClient } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools'; import { ReactQueryDevtools } from 'react-query/devtools';
import { trpc, trpcClient, queryClient } from '@/trpc';
import '@/style/App.scss'; import '@/style/App.scss';
import 'moment/locale/ar-ly'; import 'moment/locale/ar-ly';
@@ -86,14 +87,16 @@ export default function App() {
const queryClient = new QueryClient(queryConfig); const queryClient = new QueryClient(queryConfig);
return ( return (
<QueryClientProvider client={queryClient}> <trpc.Provider client={trpcClient} queryClient={queryClient}>
<SplashScreen /> <QueryClientProvider client={queryClient}>
<SplashScreen />
<AppIntlLoader> <AppIntlLoader>
<AppInsider history={history} /> <AppInsider history={history} />
</AppIntlLoader> </AppIntlLoader>
<ReactQueryDevtools initialIsOpen /> <ReactQueryDevtools initialIsOpen />
</QueryClientProvider> </QueryClientProvider>
</trpc.Provider>
); );
} }

View File

@@ -4,7 +4,6 @@ import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { DashboardInsider } from '@/components'; import { DashboardInsider } from '@/components';
import { import {
useAccounts,
useAutoCompleteContacts, useAutoCompleteContacts,
useCurrencies, useCurrencies,
useJournal, useJournal,
@@ -13,6 +12,7 @@ import {
useBranches, useBranches,
useSettingsManualJournals, useSettingsManualJournals,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useProjects } from '@/containers/Projects/hooks'; import { useProjects } from '@/containers/Projects/hooks';
const MakeJournalFormContext = createContext(); const MakeJournalFormContext = createContext();
@@ -27,7 +27,7 @@ function MakeJournalProvider({ journalId, query, ...props }) {
const isProjectFeatureCan = featureCan(Features.Projects); const isProjectFeatureCan = featureCan(Features.Projects);
// Load the accounts list. // Load the accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Load the customers list. // Load the customers list.
const { data: contacts, isLoading: isContactsLoading } = const { data: contacts, isLoading: isContactsLoading } =

View File

@@ -1,7 +1,8 @@
// @ts-nocheck // @ts-nocheck
import React, { createContext } from 'react'; import React, { createContext } from 'react';
import { DashboardInsider } from '@/components'; import { DashboardInsider } from '@/components';
import { useResourceViews, useResourceMeta, useAccounts } from '@/hooks/query'; import { useResourceViews, useResourceMeta } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { getFieldsFromResourceMeta } from '@/utils'; import { getFieldsFromResourceMeta } from '@/utils';
const AccountsChartContext = createContext(); const AccountsChartContext = createContext();
@@ -26,7 +27,7 @@ function AccountsChartProvider({ query, tableStateChanged, ...props }) {
data: accounts, data: accounts,
isFetching: isAccountsFetching, isFetching: isAccountsFetching,
isLoading: isAccountsLoading, isLoading: isAccountsLoading,
} = useAccounts(query, { keepPreviousData: true }); } = useAccountsTrpc(query, { placeholderData: (previousData) => previousData });
// Provider payload. // Provider payload.
const provider = { const provider = {

View File

@@ -1,10 +1,10 @@
// @ts-nocheck // @ts-nocheck
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
import { useValidateBulkDeleteAccounts } from '@/hooks/query/accounts'; import { useValidateBulkDeleteAccountsTrpc } from '@/hooks/trpc';
import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog';
export const useBulkDeleteAccountsDialog = () => { export const useBulkDeleteAccountsDialog = () => {
const validateBulkDeleteMutation = useValidateBulkDeleteAccounts(); const validateBulkDeleteMutation = useValidateBulkDeleteAccountsTrpc();
const { const {
openBulkDeleteDialog, openBulkDeleteDialog,
closeBulkDeleteDialog, closeBulkDeleteDialog,

View File

@@ -7,7 +7,7 @@ import { AppToaster, FormattedMessage as T } from '@/components';
import { withAlertStoreConnect } from '@/containers/Alert/withAlertStoreConnect'; import { withAlertStoreConnect } from '@/containers/Alert/withAlertStoreConnect';
import { withAlertActions } from '@/containers/Alert/withAlertActions'; import { withAlertActions } from '@/containers/Alert/withAlertActions';
import { useActivateAccount } from '@/hooks/query'; import { useActivateAccountTrpc } from '@/hooks/trpc';
import { compose } from '@/utils'; import { compose } from '@/utils';
/** /**
@@ -24,8 +24,8 @@ function AccountActivateAlert({
const { const {
mutateAsync: activateAccount, mutateAsync: activateAccount,
isLoading isLoading
} = useActivateAccount(); } = useActivateAccountTrpc();
// Handle alert cancel. // Handle alert cancel.
const handleCancel = () => { const handleCancel = () => {

View File

@@ -14,7 +14,7 @@ import { withAlertStoreConnect } from '@/containers/Alert/withAlertStoreConnect'
import { withAlertActions } from '@/containers/Alert/withAlertActions'; import { withAlertActions } from '@/containers/Alert/withAlertActions';
import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions';
import { useDeleteAccount } from '@/hooks/query'; import { useDeleteAccountTrpc } from '@/hooks/trpc';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { DRAWERS } from '@/constants/drawers'; import { DRAWERS } from '@/constants/drawers';
@@ -34,7 +34,7 @@ function AccountDeleteAlert({
// #withDrawerActions // #withDrawerActions
closeDrawer, closeDrawer,
}) { }) {
const { isLoading, mutateAsync: deleteAccount } = useDeleteAccount(); const { isLoading, mutateAsync: deleteAccount } = useDeleteAccountTrpc();
// handle cancel delete account alert. // handle cancel delete account alert.
const handleCancelAccountDelete = () => { const handleCancelAccountDelete = () => {

View File

@@ -8,7 +8,7 @@ import { withAlertStoreConnect } from '@/containers/Alert/withAlertStoreConnect'
import { withAlertActions } from '@/containers/Alert/withAlertActions'; import { withAlertActions } from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { useInactivateAccount } from '@/hooks/query'; import { useInactivateAccountTrpc } from '@/hooks/trpc';
/** /**
* Account inactivate alert. * Account inactivate alert.
@@ -23,7 +23,7 @@ function AccountInactivateAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { mutateAsync: inactivateAccount, isLoading } = useInactivateAccount(); const { mutateAsync: inactivateAccount, isLoading } = useInactivateAccountTrpc();
const handleCancelInactiveAccount = () => { const handleCancelInactiveAccount = () => {
closeAlert('account-inactivate'); closeAlert('account-inactivate');

View File

@@ -1,7 +1,7 @@
import React, { createContext } from 'react'; import React, { createContext } from 'react';
import { DialogContent } from '@/components'; import { DialogContent } from '@/components';
import { useBankRule } from '@/hooks/query/bank-rules'; import { useBankRule } from '@/hooks/query/bank-rules';
import { useAccounts } from '@/hooks/query'; import { useAccountsTrpc } from '@/hooks/trpc';
interface RuleFormBootValues { interface RuleFormBootValues {
bankRule?: null; bankRule?: null;
@@ -27,7 +27,7 @@ function RuleFormBoot({ bankRuleId, ...props }: RuleFormBootProps) {
enabled: !!bankRuleId, enabled: !!bankRuleId,
}, },
); );
const { data: accounts, isLoading: isAccountsLoading } = useAccounts({}, {}); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
const isNewMode = !bankRuleId; const isNewMode = !bankRuleId;
const isEditMode = !isNewMode; const isEditMode = !isNewMode;

View File

@@ -2,7 +2,8 @@
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { DashboardInsider } from '@/components'; import { DashboardInsider } from '@/components';
import { useCashflowAccounts, useAccount } from '@/hooks/query'; import { useCashflowAccounts } from '@/hooks/query';
import { useAccountTrpc } from '@/hooks/trpc';
import { useAppQueryString } from '@/hooks'; import { useAppQueryString } from '@/hooks';
import { useGetBankAccountSummaryMeta } from '@/hooks/query/bank-rules'; import { useGetBankAccountSummaryMeta } from '@/hooks/query/bank-rules';
@@ -33,7 +34,7 @@ function AccountTransactionsProvider({ query, ...props }) {
data: currentAccount, data: currentAccount,
isFetching: isCurrentAccountFetching, isFetching: isCurrentAccountFetching,
isLoading: isCurrentAccountLoading, isLoading: isCurrentAccountLoading,
} = useAccount(accountId, { keepPreviousData: true }); } = useAccountTrpc(accountId, { placeholderData: (previousData) => previousData });
// Retrieves the bank account meta summary. // Retrieves the bank account meta summary.
const { const {

View File

@@ -2,7 +2,8 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { first } from 'lodash'; import { first } from 'lodash';
import { DrawerLoading } from '@/components'; import { DrawerLoading } from '@/components';
import { useAccounts, useBranches } from '@/hooks/query'; import { useBranches } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { Spinner } from '@blueprintjs/core'; import { Spinner } from '@blueprintjs/core';
@@ -43,7 +44,7 @@ function CategorizeTransactionBoot({
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Fetches accounts list. // Fetches accounts list.
const { isLoading: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
// Fetches the branches list. // Fetches the branches list.
const { data: branches, isLoading: isBranchesLoading } = useBranches( const { data: branches, isLoading: isBranchesLoading } = useBranches(

View File

@@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { Spinner } from '@blueprintjs/core'; import { Spinner } from '@blueprintjs/core';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useAccounts, useBranches } from '@/hooks/query'; import { useBranches } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
interface MatchingReconcileTransactionBootProps { interface MatchingReconcileTransactionBootProps {
@@ -21,7 +22,7 @@ export function MatchingReconcileTransactionBoot({
const { featureCan } = useFeatureCan(); const { featureCan } = useFeatureCan();
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
const { data: accounts, isLoading: isAccountsLoading } = useAccounts({}, {}); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
const { data: branches, isLoading: isBranchesLoading } = useBranches( const { data: branches, isLoading: isBranchesLoading } = useBranches(
{}, {},
{ {

View File

@@ -5,11 +5,11 @@ import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useCreateCashflowTransaction, useCreateCashflowTransaction,
useAccounts,
useBranches, useBranches,
useCashflowAccounts, useCashflowAccounts,
useSettingCashFlow, useSettingCashFlow,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const MoneyInDialogContent = React.createContext(); const MoneyInDialogContent = React.createContext();
@@ -30,7 +30,7 @@ function MoneyInDialogProvider({
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Fetches accounts list. // Fetches accounts list.
const { isLoading: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
// Fetches the branches list. // Fetches the branches list.
const { const {

View File

@@ -1,7 +1,7 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { DialogContent } from '@/components'; import { DialogContent } from '@/components';
import { useAccount } from '@/hooks/query'; import { useAccountTrpc } from '@/hooks/trpc';
import { useMoneyInDailogContext } from './MoneyInDialogProvider'; import { useMoneyInDailogContext } from './MoneyInDialogProvider';
const MoneyInFieldsContext = React.createContext(); const MoneyInFieldsContext = React.createContext();
@@ -13,7 +13,7 @@ function MoneyInFieldsProvider({ ...props }) {
const { accountId } = useMoneyInDailogContext(); const { accountId } = useMoneyInDailogContext();
// Fetches the specific account details. // Fetches the specific account details.
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, { const { data: account, isLoading: isAccountLoading } = useAccountTrpc(accountId, {
enabled: !!accountId, enabled: !!accountId,
}); });
// Provider data. // Provider data.

View File

@@ -4,12 +4,12 @@ import { DialogContent } from '@/components';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useAccounts,
useBranches, useBranches,
useCreateCashflowTransaction, useCreateCashflowTransaction,
useCashflowAccounts, useCashflowAccounts,
useSettingCashFlow, useSettingCashFlow,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const MoneyInDialogContent = React.createContext(); const MoneyInDialogContent = React.createContext();
@@ -30,7 +30,7 @@ function MoneyOutProvider({
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Fetches accounts list. // Fetches accounts list.
const { isLoading: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
// Fetches the branches list. // Fetches the branches list.
const { const {

View File

@@ -1,7 +1,7 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { DialogContent } from '@/components'; import { DialogContent } from '@/components';
import { useAccount } from '@/hooks/query'; import { useAccountTrpc } from '@/hooks/trpc';
import { useMoneyOutDialogContext } from './MoneyOutDialogProvider'; import { useMoneyOutDialogContext } from './MoneyOutDialogProvider';
const MoneyOutFieldsContext = React.createContext(); const MoneyOutFieldsContext = React.createContext();
@@ -13,7 +13,7 @@ function MoneyOutFieldsProvider({ ...props }) {
const { accountId } = useMoneyOutDialogContext(); const { accountId } = useMoneyOutDialogContext();
// Fetches the specific account details. // Fetches the specific account details.
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, { const { data: account, isLoading: isAccountLoading } = useAccountTrpc(accountId, {
enabled: !!accountId, enabled: !!accountId,
}); });
// Provider data. // Provider data.

View File

@@ -2,13 +2,15 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import { DialogContent } from '@/components'; import { DialogContent } from '@/components';
import { import {
useCreateAccount,
useAccountsTypes,
useCurrencies, useCurrencies,
useAccount,
useAccounts,
useEditAccount,
} from '@/hooks/query'; } from '@/hooks/query';
import {
useCreateAccountTrpc,
useAccountsTypesTrpc,
useAccountTrpc,
useAccountsTrpc,
useEditAccountTrpc,
} from '@/hooks/trpc';
import { AccountDialogAction, getDisabledFormFields } from './utils'; import { AccountDialogAction, getDisabledFormFields } from './utils';
const AccountDialogContext = createContext(); const AccountDialogContext = createContext();
@@ -18,18 +20,18 @@ const AccountDialogContext = createContext();
*/ */
function AccountDialogProvider({ dialogName, payload, ...props }) { function AccountDialogProvider({ dialogName, payload, ...props }) {
// Create and edit account mutations. // Create and edit account mutations.
const { mutateAsync: createAccountMutate } = useCreateAccount(); const { mutateAsync: createAccountMutate } = useCreateAccountTrpc();
const { mutateAsync: editAccountMutate } = useEditAccount(); const { mutateAsync: editAccountMutate } = useEditAccountTrpc();
// Fetches accounts list. // Fetches accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Fetches accounts types. // Fetches accounts types.
const { data: accountsTypes, isLoading: isAccountsTypesLoading } = const { data: accountsTypes, isLoading: isAccountsTypesLoading } =
useAccountsTypes(); useAccountsTypesTrpc();
// Fetches the specific account details. // Fetches the specific account details.
const { data: account, isLoading: isAccountLoading } = useAccount( const { data: account, isLoading: isAccountLoading } = useAccountTrpc(
payload.accountId, payload.accountId,
{ {
enabled: enabled:

View File

@@ -5,7 +5,7 @@ import { FormattedMessage as T, AppToaster } from '@/components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent';
import { useBulkDeleteAccounts } from '@/hooks/query/accounts'; import { useBulkDeleteAccountsTrpc } from '@/hooks/trpc';
import withDialogRedux from '@/components/DialogReduxConnect'; import withDialogRedux from '@/components/DialogReduxConnect';
import { withDialogActions } from '@/containers/Dialog/withDialogActions'; import { withDialogActions } from '@/containers/Dialog/withDialogActions';
import { withAccountsTableActions } from '@/containers/Accounts/withAccountsTableActions'; import { withAccountsTableActions } from '@/containers/Accounts/withAccountsTableActions';
@@ -28,7 +28,7 @@ function AccountBulkDeleteDialog({
// #withDialogActions // #withDialogActions
closeDialog, closeDialog,
}) { }) {
const { mutateAsync: bulkDeleteAccounts, isLoading } = useBulkDeleteAccounts(); const { mutateAsync: bulkDeleteAccounts, isLoading } = useBulkDeleteAccountsTrpc();
const handleCancel = () => { const handleCancel = () => {
closeDialog(dialogName); closeDialog(dialogName);

View File

@@ -2,7 +2,8 @@
import React from 'react'; import React from 'react';
import { DialogContent } from '@/components'; import { DialogContent } from '@/components';
import { useAccounts, useInvoice, useCreateBadDebt } from '@/hooks/query'; import { useInvoice, useCreateBadDebt } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const BadDebtContext = React.createContext(); const BadDebtContext = React.createContext();
@@ -11,7 +12,7 @@ const BadDebtContext = React.createContext();
*/ */
function BadDebtFormProvider({ invoiceId, dialogName, ...props }) { function BadDebtFormProvider({ invoiceId, dialogName, ...props }) {
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Handle fetch invoice data. // Handle fetch invoice data.
const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, { const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, {

View File

@@ -5,11 +5,11 @@ import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useItem, useItem,
useAccounts,
useBranches, useBranches,
useWarehouses, useWarehouses,
useCreateInventoryAdjustment, useCreateInventoryAdjustment,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const InventoryAdjustmentContext = createContext(); const InventoryAdjustmentContext = createContext();
@@ -23,7 +23,7 @@ function InventoryAdjustmentFormProvider({ itemId, dialogName, ...props }) {
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Fetches accounts list. // Fetches accounts list.
const { isFetching: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
// Fetches the item details. // Fetches the item details.
const { isFetching: isItemLoading, data: item } = useItem(itemId); const { isFetching: isItemLoading, data: item } = useItem(itemId);

View File

@@ -3,10 +3,10 @@ import React, { useMemo } from 'react';
import { DialogContent } from '@/components'; import { DialogContent } from '@/components';
import { import {
useBill, useBill,
useAccounts,
useBranches, useBranches,
useCreatePaymentMade, useCreatePaymentMade,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { pick } from 'lodash'; import { pick } from 'lodash';
@@ -27,7 +27,7 @@ function QuickPaymentMadeFormProvider({ query, billId, dialogName, ...props }) {
}); });
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Create payment made mutations. // Create payment made mutations.
const { mutateAsync: createPaymentMadeMutate } = useCreatePaymentMade(); const { mutateAsync: createPaymentMadeMutate } = useCreatePaymentMade();

View File

@@ -5,12 +5,12 @@ import { DialogContent } from '@/components';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useAccounts,
useInvoice, useInvoice,
useBranches, useBranches,
useSettingsPaymentReceives, useSettingsPaymentReceives,
useCreatePaymentReceive, useCreatePaymentReceive,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const QuickPaymentReceiveContext = createContext(); const QuickPaymentReceiveContext = createContext();
@@ -28,7 +28,7 @@ function QuickPaymentReceiveFormProvider({
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Handle fetch invoice data. // Handle fetch invoice data.
const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, { const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, {

View File

@@ -5,11 +5,11 @@ import { pick } from 'lodash';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useAccounts,
useCreditNote, useCreditNote,
useBranches, useBranches,
useCreateRefundCreditNote, useCreateRefundCreditNote,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const RefundCreditNoteContext = React.createContext(); const RefundCreditNoteContext = React.createContext();
@@ -27,7 +27,7 @@ function RefundCreditNoteFormProvider({
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Handle fetch credit note data. // Handle fetch credit note data.
const { data: creditNote, isLoading: isCreditNoteLoading } = useCreditNote( const { data: creditNote, isLoading: isCreditNoteLoading } = useCreditNote(

View File

@@ -5,11 +5,11 @@ import { pick } from 'lodash';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useAccounts,
useVendorCredit, useVendorCredit,
useBranches, useBranches,
useCreateRefundVendorCredit, useCreateRefundVendorCredit,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
const RefundVendorCreditContext = React.createContext(); const RefundVendorCreditContext = React.createContext();
@@ -24,7 +24,7 @@ function RefundVendorCreditFormProvider({
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Fetches the branches list. // Fetches the branches list.
const { const {

View File

@@ -1,6 +1,6 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { useAccount, useAccountTransactions } from '@/hooks/query'; import { useAccountTrpc, useAccountTransactionsTrpc } from '@/hooks/trpc';
import { DrawerHeaderContent, DrawerLoading } from '@/components'; import { DrawerHeaderContent, DrawerLoading } from '@/components';
import { DRAWERS } from '@/constants/drawers'; import { DRAWERS } from '@/constants/drawers';
@@ -11,13 +11,13 @@ const AccountDrawerContext = React.createContext();
*/ */
function AccountDrawerProvider({ accountId, name, ...props }) { function AccountDrawerProvider({ accountId, name, ...props }) {
// Fetches the specific account details. // Fetches the specific account details.
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, { const { data: account, isLoading: isAccountLoading } = useAccountTrpc(accountId, {
enabled: !!accountId, enabled: !!accountId,
}); });
// Load the specific account transactions. // Load the specific account transactions.
const { data: accounts, isLoading: isAccountsLoading } = const { data: accounts, isLoading: isAccountsLoading } =
useAccountTransactions(accountId, { useAccountTransactionsTrpc(accountId, {}, {
enabled: !!accountId, enabled: !!accountId,
}); });

View File

@@ -8,11 +8,11 @@ import {
useCurrencies, useCurrencies,
useCustomers, useCustomers,
useExpense, useExpense,
useAccounts,
useBranches, useBranches,
useCreateExpense, useCreateExpense,
useEditExpense, useEditExpense,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useProjects } from '@/containers/Projects/hooks'; import { useProjects } from '@/containers/Projects/hooks';
const ExpenseFormPageContext = createContext(); const ExpenseFormPageContext = createContext();
@@ -47,7 +47,7 @@ function ExpenseFormPageProvider({ query, expenseId, ...props }) {
} = useBranches(query, { enabled: isBranchFeatureCan }); } = useBranches(query, { enabled: isBranchFeatureCan });
// Fetch accounts list. // Fetch accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Fetch the projects list. // Fetch the projects list.
const { const {

View File

@@ -1,7 +1,7 @@
// @ts-nocheck // @ts-nocheck
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import { useAccounts } from '@/hooks/query'; import { useAccountsTrpc } from '@/hooks/trpc';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton'; import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const GLHeaderGeneralPanelContext = createContext(); const GLHeaderGeneralPanelContext = createContext();
@@ -11,7 +11,7 @@ const GLHeaderGeneralPanelContext = createContext();
*/ */
function GLHeaderGeneralPanelProvider({ ...props }) { function GLHeaderGeneralPanelProvider({ ...props }) {
// Accounts list. // Accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Provider // Provider
const provider = { const provider = {

View File

@@ -7,8 +7,8 @@ import {
useItemsCategories, useItemsCategories,
useCreateItem, useCreateItem,
useEditItem, useEditItem,
useAccounts,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useWatchItemError } from './utils'; import { useWatchItemError } from './utils';
import { useTaxRates } from '@/hooks/query/taxRates'; import { useTaxRates } from '@/hooks/query/taxRates';
@@ -23,7 +23,7 @@ function ItemFormProvider({ itemId, ...props }) {
const duplicateId = state?.action; const duplicateId = state?.action;
// Fetches the accounts list. // Fetches the accounts list.
const { isLoading: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
// Fetches the items categories list. // Fetches the items categories list.
const { const {

View File

@@ -5,7 +5,8 @@ import styled from 'styled-components';
import { Card } from '@/components'; import { Card } from '@/components';
import { CLASSES } from '@/constants/classes'; import { CLASSES } from '@/constants/classes';
import { useAccounts, useSaveSettings, useSettings } from '@/hooks/query'; import { useSaveSettings, useSettings } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import PreferencesPageLoader from '../PreferencesPageLoader'; import PreferencesPageLoader from '../PreferencesPageLoader';
const AccountantFormContext = React.createContext(); const AccountantFormContext = React.createContext();
@@ -15,7 +16,7 @@ const AccountantFormContext = React.createContext();
*/ */
function AccountantFormProvider({ ...props }) { function AccountantFormProvider({ ...props }) {
// Fetches the accounts list. // Fetches the accounts list.
const { isLoading: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
// Fetches Organization Settings. // Fetches Organization Settings.
const { isLoading: isSettingsLoading } = useSettings(); const { isLoading: isSettingsLoading } = useSettings();

View File

@@ -5,7 +5,8 @@ import styled from 'styled-components';
import { CLASSES } from '@/constants/classes'; import { CLASSES } from '@/constants/classes';
import { Card } from '@/components'; import { Card } from '@/components';
import { useSettingsItems, useAccounts, useSaveSettings } from '@/hooks/query'; import { useSettingsItems, useSaveSettings } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import PreferencesPageLoader from '../PreferencesPageLoader'; import PreferencesPageLoader from '../PreferencesPageLoader';
const ItemFormContext = createContext(); const ItemFormContext = createContext();
@@ -16,7 +17,7 @@ const ItemFormContext = createContext();
function ItemPreferencesFormProvider({ ...props }) { function ItemPreferencesFormProvider({ ...props }) {
// Fetches the accounts list. // Fetches the accounts list.
const { isLoading: isAccountsLoading, data: accounts } = useAccounts(); const { isLoading: isAccountsLoading, data: accounts } = useAccountsTrpc();
const { const {
isLoading: isItemsSettingsLoading, isLoading: isItemsSettingsLoading,

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import { Spinner } from '@blueprintjs/core'; import { Spinner } from '@blueprintjs/core';
import { useAccounts } from '@/hooks/query'; import { useAccountsTrpc } from '@/hooks/trpc';
import { useGetPaymentMethod } from '@/hooks/query/payment-services'; import { useGetPaymentMethod } from '@/hooks/query/payment-services';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider'; import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
@@ -40,7 +40,7 @@ export const StripeIntegrationEditBoot: React.FC<
payload: { stripePaymentMethodId }, payload: { stripePaymentMethodId },
} = useDrawerContext(); } = useDrawerContext();
const { data: accounts, isLoading: isAccountsLoading } = useAccounts({}, {}); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
const { data: paymentMethod, isLoading: isPaymentMethodLoading } = const { data: paymentMethod, isLoading: isPaymentMethodLoading } =
useGetPaymentMethod(stripePaymentMethodId, { useGetPaymentMethod(stripePaymentMethodId, {
enabled: !!stripePaymentMethodId, enabled: !!stripePaymentMethodId,

View File

@@ -5,7 +5,6 @@ import { useFeatureCan } from '@/hooks/state';
import { DashboardInsider } from '@/components/Dashboard'; import { DashboardInsider } from '@/components/Dashboard';
import { useProjects } from '@/containers/Projects/hooks'; import { useProjects } from '@/containers/Projects/hooks';
import { import {
useAccounts,
useVendors, useVendors,
useItems, useItems,
useBill, useBill,
@@ -15,6 +14,7 @@ import {
useCreateBill, useCreateBill,
useEditBill, useEditBill,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useTaxRates } from '@/hooks/query/taxRates'; import { useTaxRates } from '@/hooks/query/taxRates';
const BillFormContext = createContext(); const BillFormContext = createContext();
@@ -48,7 +48,7 @@ function BillFormProvider({ billId, ...props }) {
const isProjectsFeatureCan = featureCan(Features.Projects); const isProjectsFeatureCan = featureCan(Features.Projects);
// Handle fetch accounts. // Handle fetch accounts.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Handle fetch vendors data table // Handle fetch vendors data table
const { const {

View File

@@ -3,7 +3,6 @@ import React, { createContext, useContext, useState } from 'react';
import { Features } from '@/constants'; import { Features } from '@/constants';
import { useFeatureCan } from '@/hooks/state'; import { useFeatureCan } from '@/hooks/state';
import { import {
useAccounts,
useVendors, useVendors,
useItems, useItems,
useBranches, useBranches,
@@ -12,6 +11,7 @@ import {
useCreatePaymentMade, useCreatePaymentMade,
useEditPaymentMade, useEditPaymentMade,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { DashboardInsider } from '@/components'; import { DashboardInsider } from '@/components';
// Payment made form context. // Payment made form context.
@@ -29,7 +29,7 @@ function PaymentMadeFormProvider({ query, paymentMadeId, ...props }) {
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Handle fetch Items data table or list. // Handle fetch Items data table or list.
const { const {

View File

@@ -7,7 +7,6 @@ import { useProjects } from '@/containers/Projects/hooks';
import { import {
useSettingsPaymentReceives, useSettingsPaymentReceives,
usePaymentReceiveEditPage, usePaymentReceiveEditPage,
useAccounts,
useCustomers, useCustomers,
useBranches, useBranches,
useCreatePaymentReceive, useCreatePaymentReceive,
@@ -15,6 +14,7 @@ import {
usePaymentReceivedState, usePaymentReceivedState,
PaymentReceivedStateResponse, PaymentReceivedStateResponse,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useGetPdfTemplates } from '@/hooks/query/pdf-templates'; import { useGetPdfTemplates } from '@/hooks/query/pdf-templates';
interface PaymentReceivedFormContextValue { interface PaymentReceivedFormContextValue {
@@ -52,7 +52,7 @@ function PaymentReceiveFormProvider({ query, paymentReceiveId, ...props }) {
const paymentEntriesEditPage = paymentReceivedEditData?.entries const paymentEntriesEditPage = paymentReceivedEditData?.entries
// Handle fetch accounts data. // Handle fetch accounts data.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Fetch payment made settings. // Fetch payment made settings.
const fetchSettings = useSettingsPaymentReceives(); const fetchSettings = useSettingsPaymentReceives();

View File

@@ -5,7 +5,6 @@ import { useFeatureCan } from '@/hooks/state';
import { DashboardInsider } from '@/components/Dashboard'; import { DashboardInsider } from '@/components/Dashboard';
import { import {
useReceipt, useReceipt,
useAccounts,
useSettingsReceipts, useSettingsReceipts,
useCustomers, useCustomers,
useWarehouses, useWarehouses,
@@ -16,6 +15,7 @@ import {
useGetReceiptState, useGetReceiptState,
IGetReceiptStateResponse, IGetReceiptStateResponse,
} from '@/hooks/query'; } from '@/hooks/query';
import { useAccountsTrpc } from '@/hooks/trpc';
import { useProjects } from '@/containers/Projects/hooks'; import { useProjects } from '@/containers/Projects/hooks';
import { useGetPdfTemplates } from '@/hooks/query/pdf-templates'; import { useGetPdfTemplates } from '@/hooks/query/pdf-templates';
@@ -43,7 +43,7 @@ function ReceiptFormProvider({ receiptId, ...props }) {
enabled: !!receiptId, enabled: !!receiptId,
}); });
// Fetch accounts list. // Fetch accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts(); const { data: accounts, isLoading: isAccountsLoading } = useAccountsTrpc();
// Fetch customers list. // Fetch customers list.
const { const {

View File

@@ -1,4 +1,6 @@
// @ts-nocheck // @ts-nocheck
import { QueryClient } from '@tanstack/react-query';
// Query client config. // Query client config.
export const queryConfig = { export const queryConfig = {
defaultOptions: { defaultOptions: {
@@ -8,3 +10,6 @@ export const queryConfig = {
}, },
}, },
}; };
// Create a new QueryClient instance for tRPC
export const tanstackQueryClient = new QueryClient(queryConfig);

View File

@@ -0,0 +1,2 @@
// tRPC hooks for accounts module
export * from './useAccounts';

View File

@@ -0,0 +1,188 @@
import { trpc } from '@/trpc';
import { useQueryClient } from '@tanstack/react-query';
// Query keys for cache invalidation
const accountQueryKeys = {
accounts: ['accounts'],
account: (id: number) => ['account', id],
accountTypes: ['accountTypes'],
accountTransactions: (id: number) => ['accountTransactions', id],
cashFlowAccounts: ['cashFlowAccounts'],
financialReport: ['financialReport'],
};
/**
* Retrieve accounts list using tRPC.
*/
export function useAccountsTrpc(query?: Record<string, any>, options = {}) {
return trpc.accounts.getAccounts.useQuery(query || {}, {
select: (res) => res.accounts,
...options,
});
}
/**
* Retrieve the given account details using tRPC.
*/
export function useAccountTrpc(id: number, options = {}) {
return trpc.accounts.getAccount.useQuery(
{ id },
{
enabled: !!id,
...options,
}
);
}
/**
* Retrieve accounts types list using tRPC.
*/
export function useAccountsTypesTrpc(options = {}) {
return trpc.accounts.getAccountTypes.useQuery(undefined, options);
}
/**
* Retrieve account transactions using tRPC.
*/
export function useAccountTransactionsTrpc(
accountId: number,
filters?: { fromDate?: string; toDate?: string },
options = {}
) {
return trpc.accounts.getAccountTransactions.useQuery(
{
accountId,
fromDate: filters?.fromDate,
toDate: filters?.toDate,
},
{
enabled: !!accountId,
...options,
}
);
}
/**
* Creates account using tRPC.
*/
export function useCreateAccountTrpc(options = {}) {
const queryClient = useQueryClient();
return trpc.accounts.createAccount.useMutation({
onSuccess: () => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.cashFlowAccounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.financialReport });
},
...options,
});
}
/**
* Edits the given account using tRPC.
*/
export function useEditAccountTrpc(options = {}) {
const queryClient = useQueryClient();
return trpc.accounts.editAccount.useMutation({
onSuccess: (_, variables) => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
queryClient.invalidateQueries({
queryKey: accountQueryKeys.account(variables.id),
});
queryClient.invalidateQueries({ queryKey: accountQueryKeys.cashFlowAccounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.financialReport });
},
...options,
});
}
/**
* Deletes the given account using tRPC.
*/
export function useDeleteAccountTrpc(options = {}) {
const queryClient = useQueryClient();
return trpc.accounts.deleteAccount.useMutation({
onSuccess: () => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.cashFlowAccounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.financialReport });
},
...options,
});
}
/**
* Activates the given account using tRPC.
*/
export function useActivateAccountTrpc(options = {}) {
const queryClient = useQueryClient();
return trpc.accounts.activateAccount.useMutation({
onSuccess: () => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.cashFlowAccounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.financialReport });
},
...options,
});
}
/**
* Inactivates the given account using tRPC.
*/
export function useInactivateAccountTrpc(options = {}) {
const queryClient = useQueryClient();
return trpc.accounts.inactivateAccount.useMutation({
onSuccess: () => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.cashFlowAccounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.financialReport });
},
...options,
});
}
/**
* Validates which accounts can be deleted in bulk using tRPC.
*/
export function useValidateBulkDeleteAccountsTrpc(options = {}) {
return trpc.accounts.validateBulkDeleteAccounts.useMutation(options);
}
/**
* Deletes multiple accounts in bulk using tRPC.
*/
export function useBulkDeleteAccountsTrpc(options = {}) {
const queryClient = useQueryClient();
return trpc.accounts.bulkDeleteAccounts.useMutation({
onSuccess: () => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.cashFlowAccounts });
queryClient.invalidateQueries({ queryKey: accountQueryKeys.financialReport });
},
...options,
});
}
/**
* Hook to refresh accounts list.
*/
export function useRefreshAccountsTrpc() {
const queryClient = useQueryClient();
return {
refresh: () => {
queryClient.invalidateQueries({ queryKey: accountQueryKeys.accounts });
},
};
}

View File

@@ -0,0 +1,42 @@
import { createTRPCReact } from '@trpc/react-query';
import { httpBatchLink } from '@trpc/client';
import superjson from 'superjson';
import { store } from '@/store/createStore';
import { tanstackQueryClient } from '@/hooks/query/base';
// Define the AppRouter type - this will be imported from the server package
// For now, we use any until the server exports the proper types
export type AppRouter = any;
export const trpc = createTRPCReact<AppRouter>();
export function getAuthHeaders() {
const state = store.getState();
const { token, organizationId } = state.authentication;
const headers: Record<string, string> = {};
if (token) {
headers['x-access-token'] = token;
}
if (organizationId) {
headers['organization-id'] = organizationId.toString();
}
headers['Accept-Language'] = 'en';
return headers;
}
export const trpcClient = trpc.createClient({
transformer: superjson,
links: [
httpBatchLink({
url: '/api/trpc',
headers() {
return getAuthHeaders();
},
}),
],
});
// Export the QueryClient for use in the TRPCProvider
export const queryClient = tanstackQueryClient;

View File

@@ -19,5 +19,8 @@
"dev": "npm run build -- --watch" "dev": "npm run build -- --watch"
}, },
"author": "", "author": "",
"license": "ISC" "license": "ISC",
"dependencies": {
"@trpc/server": "^11.10.0"
}
} }

View File

@@ -1,3 +1,4 @@
export * from './countries'; export * from './countries';
export * from './trpc';
export const test = () => {}; export const test = () => {};

View File

@@ -0,0 +1,32 @@
/**
* tRPC Router Types
* This file exports the types for the tRPC router that are shared between
* the server and the webapp (frontend).
*
* Note: This file only contains TYPE definitions. It does not import any
* runtime code from the server to avoid bundle bloat in the webapp.
*/
// We define the router type structure here to avoid importing the actual router
// from the server package, which would cause issues with bundling.
import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
// This is a placeholder type that will be replaced by the actual router type
// when the server builds and exports it.
// The webapp will import the actual type from the server package during development
// but will use the built type declaration during production.
export type AppRouter = any;
/**
* Inference helpers for input types
* @example type MyInput = RouterInputs['accounts']['getAccount']
*/
export type RouterInputs = inferRouterInputs<AppRouter>;
/**
* Inference helpers for output types
* @example type MyOutput = RouterOutputs['accounts']['getAccount']
*/
export type RouterOutputs = inferRouterOutputs<AppRouter>;