diff --git a/package.json b/package.json index 4fdd116..aff2bef 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5bbb956..50cfe71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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 diff --git a/src/components/account-info.tsx b/src/components/account-info.tsx index e84301a..c871952 100644 --- a/src/components/account-info.tsx +++ b/src/components/account-info.tsx @@ -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>; - 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> { + try { + const ReqRes = + await ApiRequest.authenticated.get.json>( + "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>) { 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>; + isDisconnected: boolean; +}) { + const isLoaded = useWallet(userData, setUserData); + + const walletInfo = useMemo(() => ( +
+
+ +

{userData.dollarAvailables} $

+
+
+ +

{`You currently have ${userData.wallet.owned_cryptos.length} crypto(s)`}

+
+
+ ), [userData.dollarAvailables, userData.wallet.owned_cryptos.length]); + + const userInfo = useMemo(() => ( +
+
+ +

Your identity

+
+
+

{userData.id}

+ +
+
+ ), [userData.id]); + if (isDisconnected) { return (
-
+

Disconnected

- + Link account
@@ -107,50 +161,8 @@ export function AccountInfo({ {userData.pseudo}
-
-
-
- -

- {userData.dollarAvailables} $ -

-
-
- -

- {`You currently have ${userData.wallet.owned_cryptos.length} crypto(s)`} -

-
-
-
-
- -

Your identity

-
-
-

{userData.id}

- -
-
-
+ {walletInfo} + {userInfo}
- @@ -171,4 +179,4 @@ export function AccountInfo({ ); -} +} \ No newline at end of file diff --git a/src/components/providers/providers.tsx b/src/components/providers/providers.tsx index 593b054..3b0e501 100644 --- a/src/components/providers/providers.tsx +++ b/src/components/providers/providers.tsx @@ -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 ( - {children} + + + {children} + + ); } diff --git a/src/components/providers/query-provider.tsx b/src/components/providers/query-provider.tsx new file mode 100644 index 0000000..15665ca --- /dev/null +++ b/src/components/providers/query-provider.tsx @@ -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 ( + { children } + ) +} \ No newline at end of file