Add QueryClientProvider for react-query support
Integrate react-query by adding `QueryClientProvider` to the application. This involves updating dependencies, wrapping existing providers with `QueryProvider`, and refactoring the `account-info` module to utilize new hooks and APIs.
This commit is contained in:
parent
a75a87f683
commit
ea7ab60e5c
@ -41,6 +41,7 @@
|
||||
"@radix-ui/react-toggle": "^1.1.0",
|
||||
"@radix-ui/react-toggle-group": "^1.1.0",
|
||||
"@radix-ui/react-tooltip": "^1.1.4",
|
||||
"@tanstack/react-query": "^5.60.2",
|
||||
"@tanstack/react-table": "^8.20.5",
|
||||
"axios": "^1.7.7",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@ -95,6 +95,9 @@ importers:
|
||||
'@radix-ui/react-tooltip':
|
||||
specifier: ^1.1.4
|
||||
version: 1.1.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.60.2
|
||||
version: 5.60.2(react@18.3.1)
|
||||
'@tanstack/react-table':
|
||||
specifier: ^8.20.5
|
||||
version: 8.20.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@ -1246,6 +1249,14 @@ packages:
|
||||
'@swc/helpers@0.5.5':
|
||||
resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
|
||||
|
||||
'@tanstack/query-core@5.59.20':
|
||||
resolution: {integrity: sha512-e8vw0lf7KwfGe1if4uPFhvZRWULqHjFcz3K8AebtieXvnMOz5FSzlZe3mTLlPuUBcydCnBRqYs2YJ5ys68wwLg==}
|
||||
|
||||
'@tanstack/react-query@5.60.2':
|
||||
resolution: {integrity: sha512-JhpJNxIAPuE0YCpP1Py4zAsgx+zY0V531McRMtQbwVlJF8+mlZwcOPrzGmPV248K8IP+mPbsfxXToVNMNwjUcw==}
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-table@8.20.5':
|
||||
resolution: {integrity: sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==}
|
||||
engines: {node: '>=12'}
|
||||
@ -3850,6 +3861,13 @@ snapshots:
|
||||
'@swc/counter': 0.1.3
|
||||
tslib: 2.6.3
|
||||
|
||||
'@tanstack/query-core@5.59.20': {}
|
||||
|
||||
'@tanstack/react-query@5.60.2(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.59.20
|
||||
react: 18.3.1
|
||||
|
||||
'@tanstack/react-table@8.20.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/table-core': 8.20.5
|
||||
|
@ -1,4 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
@ -9,30 +10,55 @@ import {
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import type { IUserData, IUserWallet } from "@/interfaces/userdata.interface";
|
||||
|
||||
import { CopyButton } from "@/components/ui/copy-button";
|
||||
import {
|
||||
type ICryptoInUserWalletInfo,
|
||||
ICryptoInWalletInfo,
|
||||
import type {
|
||||
ICryptoInUserWalletInfo,
|
||||
} from "@/interfaces/crypto.interface";
|
||||
import { doDisconnect, getWallet } from "@/services/account.handler";
|
||||
import { Bitcoin, Fingerprint, Key, Landmark, Unplug, User, Wallet } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import type React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useState, useCallback, useMemo } from "react";
|
||||
import { EReturnState, type IStandardisedReturn } from "@/interfaces/general.interface";
|
||||
import type { IApiUserAssetsRes } from "@/interfaces/api.interface";
|
||||
import ApiRequest from "@/services/apiRequest";
|
||||
|
||||
export function AccountInfo({
|
||||
userData,
|
||||
setUserData,
|
||||
isDisconnected,
|
||||
}: {
|
||||
userData: IUserData;
|
||||
setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>;
|
||||
isDisconnected: boolean;
|
||||
}) {
|
||||
export function doDisconnect() {
|
||||
if (typeof window !== "undefined") {
|
||||
window.localStorage.removeItem("sub");
|
||||
//Redirect to homepage
|
||||
window.location.href = "/";
|
||||
return true;
|
||||
}
|
||||
console.log("Whut ? Why trying to remove an item from the localStorage when running in SSR ?");
|
||||
return false;
|
||||
}
|
||||
|
||||
async function getWallet(): Promise<IStandardisedReturn<IApiUserAssetsRes>> {
|
||||
try {
|
||||
const ReqRes =
|
||||
await ApiRequest.authenticated.get.json<IStandardisedReturn<IApiUserAssetsRes>>(
|
||||
"user/my-assets"
|
||||
);
|
||||
console.log(ReqRes.data);
|
||||
|
||||
if (ReqRes.status !== 200) {
|
||||
return {
|
||||
state: EReturnState.clientError,
|
||||
};
|
||||
}
|
||||
return {
|
||||
state: EReturnState.done,
|
||||
resolved: ReqRes.data,
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
state: EReturnState.serverError,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function useWallet(userData: IUserData, setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>) {
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@ -40,52 +66,80 @@ export function AccountInfo({
|
||||
getWallet().then((res) => {
|
||||
const wallet: IUserWallet = {
|
||||
uat: Date.now(),
|
||||
update_interval: 30_000,
|
||||
owned_cryptos:
|
||||
res.resolved?.UserHasCrypto?.map((el): ICryptoInUserWalletInfo => {
|
||||
return {
|
||||
id: el.Crypto.id,
|
||||
name: el.Crypto.name,
|
||||
value: el.Crypto.value,
|
||||
image: el.Crypto.image,
|
||||
quantity: el.Crypto.quantity,
|
||||
owned_amount: el.amount,
|
||||
created_at: el.Crypto.created_at,
|
||||
updated_at: el.Crypto.updated_at,
|
||||
};
|
||||
}) || [],
|
||||
update_interval: 30000,
|
||||
owned_cryptos: res.resolved?.UserHasCrypto?.map((el): ICryptoInUserWalletInfo => ({
|
||||
id: el.Crypto.id,
|
||||
name: el.Crypto.name,
|
||||
value: el.Crypto.value,
|
||||
image: el.Crypto.image,
|
||||
quantity: el.Crypto.quantity,
|
||||
owned_amount: el.amount,
|
||||
created_at: el.Crypto.created_at,
|
||||
updated_at: el.Crypto.updated_at,
|
||||
})) || [],
|
||||
};
|
||||
|
||||
delete res.resolved?.UserHasCrypto;
|
||||
//@ts-ignore
|
||||
setUserData({
|
||||
...userData,
|
||||
setUserData((prev) => ({
|
||||
...prev,
|
||||
...res.resolved,
|
||||
wallet: wallet,
|
||||
});
|
||||
wallet,
|
||||
}) as unknown as IUserData);
|
||||
console.log(userData);
|
||||
setIsLoaded(true);
|
||||
});
|
||||
}
|
||||
}, [isLoaded, userData, setUserData]);
|
||||
|
||||
return isLoaded;
|
||||
}
|
||||
|
||||
export function AccountInfo({
|
||||
userData,
|
||||
setUserData,
|
||||
isDisconnected,
|
||||
}: {
|
||||
userData: IUserData;
|
||||
setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>;
|
||||
isDisconnected: boolean;
|
||||
}) {
|
||||
const isLoaded = useWallet(userData, setUserData);
|
||||
|
||||
const walletInfo = useMemo(() => (
|
||||
<div className={"flex flex-col md:flex-row gap-2 justify-center md:justify-evenly items-start md:items-center w-full"}>
|
||||
<div className={"flex gap-1 justify-start md:justify-center items-center mx-auto w-full md:w-fit"}>
|
||||
<Landmark />
|
||||
<p className={"rounded bg-accent text-accent-foreground p-1"}>{userData.dollarAvailables} $</p>
|
||||
</div>
|
||||
<div className={"flex gap-1 justify-start md:justify-center items-center mx-auto w-full md:w-fit"}>
|
||||
<Bitcoin />
|
||||
<p className={"rounded bg-accent text-accent-foreground p-1"}>{`You currently have ${userData.wallet.owned_cryptos.length} crypto(s)`}</p>
|
||||
</div>
|
||||
</div>
|
||||
), [userData.dollarAvailables, userData.wallet.owned_cryptos.length]);
|
||||
|
||||
const userInfo = useMemo(() => (
|
||||
<div className={"flex flex-col gap-3 justify-center items-start mx-auto mt-4"}>
|
||||
<div className={"flex flex-row text-nowrap flex-nowrap gap-1 text-primary"}>
|
||||
<Fingerprint />
|
||||
<h2>Your identity</h2>
|
||||
</div>
|
||||
<div className={"font-light text-xs md:text-sm flex flex-row items-center justify-start gap-1 bg-accent p-2 rounded"}>
|
||||
<p>{userData.id}</p>
|
||||
<CopyButton value={userData.id} />
|
||||
</div>
|
||||
</div>
|
||||
), [userData.id]);
|
||||
|
||||
if (isDisconnected) {
|
||||
return (
|
||||
<div className={"flex flex-col justify-center items-center h-10 p-2 text-xs mt-2"}>
|
||||
<div
|
||||
className={
|
||||
"flex flex-row justify-center items-center gap-1 text-destructive to-red-900 animate-pulse"
|
||||
}
|
||||
>
|
||||
<div className={"flex flex-row justify-center items-center gap-1 text-destructive to-red-900 animate-pulse"}>
|
||||
<Unplug className={"w-4"} />
|
||||
<p>Disconnected</p>
|
||||
</div>
|
||||
<div>
|
||||
<Link
|
||||
href={"/auth"}
|
||||
className={
|
||||
"hover:text-primary flex justify-evenly items-center gap-1 p-1 text-nowrap"
|
||||
}
|
||||
>
|
||||
<Link href={"/auth"} className={"hover:text-primary flex justify-evenly items-center gap-1 p-1 text-nowrap"}>
|
||||
<Key className={"w-3"} /> Link account
|
||||
</Link>
|
||||
</div>
|
||||
@ -107,50 +161,8 @@ export function AccountInfo({
|
||||
<DialogDescription>{userData.pseudo}</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className={"flex flex-col items-center justify-center w-full"}>
|
||||
<div className={"flex flex-col justify-evenly items-center gap-2"}>
|
||||
<div
|
||||
className={
|
||||
"flex flex-col md:flex-row gap-2 justify-center md:justify-evenly items-start md:items-center w-full"
|
||||
}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
"flex gap-1 justify-start md:justify-center items-center mx-auto w-full md:w-fit"
|
||||
}
|
||||
>
|
||||
<Landmark />
|
||||
<p className={"rounded bg-accent text-accent-foreground p-1"}>
|
||||
{userData.dollarAvailables} $
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
"flex gap-1 justify-start md:justify-center items-center mx-auto w-full md:w-fit"
|
||||
}
|
||||
>
|
||||
<Bitcoin />
|
||||
<p className={"rounded bg-accent text-accent-foreground p-1"}>
|
||||
{`You currently have ${userData.wallet.owned_cryptos.length} crypto(s)`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={"flex flex-col gap-3 justify-center items-start mx-auto mt-4"}
|
||||
>
|
||||
<div className={"flex flex-row text-nowrap flex-nowrap gap-1 text-primary"}>
|
||||
<Fingerprint />
|
||||
<h2>Your identity</h2>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
"font-light text-xs md:text-sm flex flex-row items-center justify-start gap-1 bg-accent p-2 rounded"
|
||||
}
|
||||
>
|
||||
<p>{userData.id}</p>
|
||||
<CopyButton value={userData.id} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{walletInfo}
|
||||
{userInfo}
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant={"secondary"} className={"gap-2 px-2"} asChild>
|
||||
@ -159,11 +171,7 @@ export function AccountInfo({
|
||||
<p>My wallet</p>
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
variant={"destructive"}
|
||||
className={"gap-2 px-2 mb-2"}
|
||||
onClick={() => doDisconnect()}
|
||||
>
|
||||
<Button variant={"destructive"} className={"gap-2 px-2 mb-2"} onClick={() => doDisconnect()}>
|
||||
<Unplug />
|
||||
<p>Disconnect</p>
|
||||
</Button>
|
||||
|
@ -4,11 +4,16 @@ import { Header } from "@/components/header";
|
||||
import { ThemeProvider } from "@/components/providers/theme-provider";
|
||||
import { UserDataProvider } from "@/components/providers/userdata-provider";
|
||||
import type React from "react";
|
||||
import {QueryProvider} from "@/components/providers/query-provider";
|
||||
|
||||
export function Providers({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<UserDataProvider>{children}</UserDataProvider>
|
||||
<QueryProvider>
|
||||
<UserDataProvider>
|
||||
{children}
|
||||
</UserDataProvider>
|
||||
</QueryProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
13
src/components/providers/query-provider.tsx
Normal file
13
src/components/providers/query-provider.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
"use client"
|
||||
import type {ReactNode} from "react";
|
||||
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
|
||||
|
||||
|
||||
interface QueryProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
export function QueryProvider({ children }: QueryProviderProps) {
|
||||
return (<QueryClientProvider client={new QueryClient()}>
|
||||
{ children }
|
||||
</QueryClientProvider>)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user