replace zustand with @tanstack/react-query
This commit is contained in:
parent
59e9d61e37
commit
4af2ae4d4e
@ -1,4 +1,4 @@
|
||||
import { TelegramProvider } from '@/providers';
|
||||
import { TelegramProvider } from '@/providers/telegram';
|
||||
import { type PropsWithChildren } from 'react';
|
||||
|
||||
export default async function Layout({ children }: Readonly<PropsWithChildren>) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { AuthProvider } from '@/providers';
|
||||
import { AuthProvider } from '@/providers/auth';
|
||||
import { QueryProvider } from '@/providers/query';
|
||||
import { ThemeProvider } from '@/providers/theme-provider';
|
||||
import { I18nProvider } from '@/utils/i18n/provider';
|
||||
import '@repo/ui/globals.css';
|
||||
@ -18,7 +19,9 @@ export default async function RootLayout({ children }: Readonly<PropsWithChildre
|
||||
<body className="bg-secondary">
|
||||
<I18nProvider>
|
||||
<ThemeProvider>
|
||||
<AuthProvider>{children}</AuthProvider>
|
||||
<AuthProvider>
|
||||
<QueryProvider>{children}</QueryProvider>
|
||||
</AuthProvider>
|
||||
</ThemeProvider>
|
||||
</I18nProvider>
|
||||
</body>
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
'use client';
|
||||
import { getClients, getMasters } from '@/actions/contacts';
|
||||
import { ContactsFilterContext } from '@/context/contacts-filter';
|
||||
import { useBoundStore } from '@/store';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { sift } from 'radash';
|
||||
import { use, useEffect, useMemo } from 'react';
|
||||
import { use, useMemo } from 'react';
|
||||
|
||||
export function useCustomerContacts() {
|
||||
const { filter } = use(ContactsFilterContext);
|
||||
const { clients, masters, setClients, setMasters } = useBoundStore();
|
||||
|
||||
useEffect(() => {
|
||||
if ((filter === 'masters' || filter === 'all') && !masters)
|
||||
getMasters().then((response) => {
|
||||
if (response?.masters) setMasters(response.masters);
|
||||
});
|
||||
const { data: clientsData } = useQuery({
|
||||
queryFn: getClients,
|
||||
queryKey: ['contacts', 'clients'],
|
||||
});
|
||||
|
||||
if ((filter === 'clients' || filter === 'all') && !clients)
|
||||
getClients().then((response) => {
|
||||
if (response?.clients) setClients(response.clients);
|
||||
});
|
||||
}, [filter]);
|
||||
const clients = clientsData?.clients;
|
||||
|
||||
const { data: mastersData } = useQuery({
|
||||
queryFn: getMasters,
|
||||
queryKey: ['contacts', 'masters'],
|
||||
});
|
||||
|
||||
const masters = mastersData?.masters;
|
||||
|
||||
const contacts = useMemo(() => {
|
||||
switch (filter) {
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@repo/ui": "workspace:*",
|
||||
"@tanstack/react-query": "^5.64.1",
|
||||
"@telegram-apps/sdk-react": "^2.0.19",
|
||||
"graphql": "catalog:",
|
||||
"lucide-react": "catalog:",
|
||||
@ -26,8 +27,7 @@
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"use-debounce": "^10.0.4",
|
||||
"zod": "catalog:",
|
||||
"zustand": "^5.0.3"
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.1",
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
export * from './auth';
|
||||
export * from './telegram';
|
||||
42
apps/web/providers/query.tsx
Normal file
42
apps/web/providers/query.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
'use client';
|
||||
|
||||
// Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top
|
||||
import { isServer, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
|
||||
function makeQueryClient() {
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
// With SSR, we usually want to set some default staleTime
|
||||
// above 0 to avoid refetching immediately on the client
|
||||
staleTime: 60 * 1_000,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let browserQueryClient: QueryClient | undefined;
|
||||
|
||||
export function QueryProvider({ children }: { readonly children: React.ReactNode }) {
|
||||
// NOTE: Avoid useState when initializing the query client if you don't
|
||||
// have a suspense boundary between this and the code that may
|
||||
// suspend because React will throw away the client on the initial
|
||||
// render if it suspends and there is no boundary
|
||||
const queryClient = getQueryClient();
|
||||
|
||||
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
|
||||
}
|
||||
|
||||
function getQueryClient() {
|
||||
if (isServer) {
|
||||
// Server: always make a new query client
|
||||
return makeQueryClient();
|
||||
} else {
|
||||
// Browser: make a new query client if we don't already have one
|
||||
// This is very important, so we don't re-make a new client if React
|
||||
// suspends during the initial render. This may not be needed if we
|
||||
// have a suspense boundary BELOW the creation of the query client
|
||||
if (!browserQueryClient) browserQueryClient = makeQueryClient();
|
||||
return browserQueryClient;
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
import type * as GQL from '@repo/graphql/types';
|
||||
import { type StateCreator } from 'zustand';
|
||||
|
||||
export type ContactsStore = {
|
||||
clients: Clients | null;
|
||||
masters: Masters | null;
|
||||
setClients: (clients: Clients) => void;
|
||||
setMasters: (masters: Masters) => void;
|
||||
};
|
||||
|
||||
type Clients = NonNullable<GQL.GetCustomerClientsQuery['customers'][0]>['clients'];
|
||||
type Masters = NonNullable<GQL.GetCustomerMastersQuery['customers'][0]>['masters'];
|
||||
|
||||
export const createContactsSlice: StateCreator<ContactsStore> = (set) => {
|
||||
return {
|
||||
clients: null,
|
||||
masters: null,
|
||||
setClients: (clients) => set({ clients }),
|
||||
setMasters: (masters) => set({ masters }),
|
||||
};
|
||||
};
|
||||
@ -1,6 +0,0 @@
|
||||
import { type ContactsStore, createContactsSlice } from './contacts';
|
||||
import { create } from 'zustand';
|
||||
|
||||
type Store = ContactsStore;
|
||||
|
||||
export const useBoundStore = create<Store>()((...a) => ({ ...createContactsSlice(...a) }));
|
||||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
@ -141,6 +141,9 @@ importers:
|
||||
'@repo/ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/ui
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.64.1
|
||||
version: 5.64.1(react@19.0.0)
|
||||
'@telegram-apps/sdk-react':
|
||||
specifier: ^2.0.19
|
||||
version: 2.0.19(@types/react@19.0.1)(react@19.0.0)
|
||||
@ -177,9 +180,6 @@ importers:
|
||||
zod:
|
||||
specifier: 'catalog:'
|
||||
version: 3.24.1
|
||||
zustand:
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.3(@types/react@19.0.1)(react@19.0.0)
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.49.1
|
||||
@ -2440,6 +2440,14 @@ packages:
|
||||
'@swc/helpers@0.5.15':
|
||||
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
|
||||
|
||||
'@tanstack/query-core@5.64.1':
|
||||
resolution: {integrity: sha512-978Wx4Wl4UJZbmvU/rkaM9cQtXXrbhK0lsz/UZhYIbyKYA8E4LdomTwyh2GHZ4oU0BKKoDH4YlKk2VscCUgNmg==}
|
||||
|
||||
'@tanstack/react-query@5.64.1':
|
||||
resolution: {integrity: sha512-vW5ggHpIO2Yjj44b4sB+Fd3cdnlMJppXRBJkEHvld6FXh3j5dwWJoQo7mGtKI2RbSFyiyu/PhGAy0+Vv5ev9Eg==}
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
'@telegraf/types@7.1.0':
|
||||
resolution: {integrity: sha512-kGevOIbpMcIlCDeorKGpwZmdH7kHbqlk/Yj6dEpJMKEQw5lk0KVQY0OLXaCswy8GqlIVLd5625OB+rAntP9xVw==}
|
||||
|
||||
@ -6308,24 +6316,6 @@ packages:
|
||||
zod@3.24.1:
|
||||
resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
|
||||
|
||||
zustand@5.0.3:
|
||||
resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
peerDependencies:
|
||||
'@types/react': '>=18.0.0'
|
||||
immer: '>=9.0.6'
|
||||
react: '>=18.0.0'
|
||||
use-sync-external-store: '>=1.2.0'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
immer:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
use-sync-external-store:
|
||||
optional: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
@ -8709,6 +8699,13 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@tanstack/query-core@5.64.1': {}
|
||||
|
||||
'@tanstack/react-query@5.64.1(react@19.0.0)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.64.1
|
||||
react: 19.0.0
|
||||
|
||||
'@telegraf/types@7.1.0': {}
|
||||
|
||||
'@telegram-apps/bridge@1.7.1':
|
||||
@ -13080,8 +13077,3 @@ snapshots:
|
||||
zen-observable@0.8.15: {}
|
||||
|
||||
zod@3.24.1: {}
|
||||
|
||||
zustand@5.0.3(@types/react@19.0.1)(react@19.0.0):
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.1
|
||||
react: 19.0.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user