diff --git a/.gitignore b/.gitignore
index 184d14b..ac4b41d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,3 +50,4 @@ coverage/
# Misc
.vercel
+.dual-graph/
diff --git a/next-env.d.ts b/next-env.d.ts
index c4b7818..9edff1c 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
///
///
-import "./.next/dev/types/routes.d.ts";
+import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/package-lock.json b/package-lock.json
index 345996c..55e13d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,8 @@
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.8",
+ "@tanstack/react-query": "^5.101.0",
+ "@tanstack/react-query-devtools": "^5.101.0",
"@tanstack/react-table": "^8.21.3",
"axios": "^1.13.6",
"class-variance-authority": "^0.7.1",
@@ -3416,6 +3418,59 @@
"tailwindcss": "4.2.1"
}
},
+ "node_modules/@tanstack/query-core": {
+ "version": "5.101.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.0.tgz",
+ "integrity": "sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/query-devtools": {
+ "version": "5.101.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.101.0.tgz",
+ "integrity": "sha512-MVqw17k08RQtGGLEL654+dX/btbX9p/8WjkznO//zusLTMaObxi3Q+MoFwGVkC9K3tqjn8qrrNhJevXx4fJTeQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.101.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.0.tgz",
+ "integrity": "sha512-rLlJXSpkqfizLWgkR5+eLeIk0MvTx/meEIR7LRjxic+qxiQP8zVjq7BqQkiCMNLQBlLfuOLqqr6KO5GtrDlmSg==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.101.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@tanstack/react-query-devtools": {
+ "version": "5.101.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.101.0.tgz",
+ "integrity": "sha512-cpZA0+WqKXwrwMfiWZEGGF6QrIWVQFbhBtxqDF5sQsAfrFf47HIE6fiPbQU3wyAUEN2+7UNqLCQe7oG6m3f93w==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-devtools": "5.101.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "@tanstack/react-query": "^5.101.0",
+ "react": "^18 || ^19"
+ }
+ },
"node_modules/@tanstack/react-table": {
"version": "8.21.3",
"resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.3.tgz",
diff --git a/package.json b/package.json
index ae27e9c..30f7a84 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,8 @@
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.8",
+ "@tanstack/react-query": "^5.101.0",
+ "@tanstack/react-query-devtools": "^5.101.0",
"@tanstack/react-table": "^8.21.3",
"axios": "^1.13.6",
"class-variance-authority": "^0.7.1",
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 5c535a5..6ff243b 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,7 @@
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import './globals.css';
-import { ThemeProvider } from '@/components/theme-provider';
+import { ThemeProvider } from '@/providers/ThemeProvider';
import { Toaster } from '@/components/ui/sonner';
import { BackgroundGradient } from '@/components/background-gradient';
diff --git a/src/providers/QueryProvider.tsx b/src/providers/QueryProvider.tsx
new file mode 100644
index 0000000..4bd9311
--- /dev/null
+++ b/src/providers/QueryProvider.tsx
@@ -0,0 +1,26 @@
+'use client';
+
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
+import { useState } from 'react';
+
+export default function QueryProvider({ children }: { children: React.ReactNode }) {
+ const [queryClient] = useState(
+ () =>
+ new QueryClient({
+ defaultOptions: {
+ queries: {
+ staleTime: 60 * 1000,
+ refetchOnWindowFocus: false,
+ },
+ },
+ })
+ );
+
+ return (
+
+ {children}
+
+
+ );
+}
diff --git a/src/components/theme-provider.tsx b/src/providers/ThemeProvider.tsx
similarity index 100%
rename from src/components/theme-provider.tsx
rename to src/providers/ThemeProvider.tsx