Skip to content

Commit 57cb0ad

Browse files
committed
chore: mock info request
1 parent ff5e85b commit 57cb0ad

File tree

9 files changed

+107
-21
lines changed

9 files changed

+107
-21
lines changed

src/constants/endpoints.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
const INFO = "/info"
12
const BALANCES = "/balances"
23

34
export {
5+
INFO,
46
BALANCES,
57
}

src/lib/api.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { INFO } from "@/constants/endpoints";
2+
import { apiFetch } from "@/utils/api";
3+
4+
export interface InfoResponse {
5+
version: string
6+
}
7+
8+
export async function fetchInfo(): Promise<InfoResponse> {
9+
return apiFetch<InfoResponse>(INFO, {
10+
headers: {
11+
"Content-Type": "application/json",
12+
},
13+
})
14+
}

src/main.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import BalancesPage from './pages/balances/BalancesPage'
88
import QuotesPage from './pages/quotes/QuotesPage';
99
import SettingsPage from './pages/settings/SettingsPage';
1010
import meta from './constants/meta';
11+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
1112

13+
const queryClient = new QueryClient();
1214

1315
const prepare = async () => {
1416
if (meta.apiMocksEnabled) {
@@ -20,16 +22,18 @@ const prepare = async () => {
2022
void prepare().then(() => {
2123
createRoot(document.getElementById('root')!).render(
2224
<StrictMode>
23-
<BrowserRouter>
24-
<Routes>
25-
<Route element={<Layout />}>
26-
<Route index element={<HomePage />} />
27-
<Route path="balances" element={<BalancesPage />} />
28-
<Route path="quotes" element={<QuotesPage />} />
29-
<Route path="settings" element={<SettingsPage />} />
30-
</Route>
31-
</Routes>
32-
</BrowserRouter>
25+
<QueryClientProvider client={queryClient}>
26+
<BrowserRouter>
27+
<Routes>
28+
<Route element={<Layout />}>
29+
<Route index element={<HomePage />} />
30+
<Route path="balances" element={<BalancesPage />} />
31+
<Route path="quotes" element={<QuotesPage />} />
32+
<Route path="settings" element={<SettingsPage />} />
33+
</Route>
34+
</Routes>
35+
</BrowserRouter>
36+
</QueryClientProvider>
3337
</StrictMode>,
3438
)
3539
})

src/mocks/browser.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const scenarioName = new URLSearchParams(window.location.search).get(
66
"scenario"
77
) as unknown as keyof typeof scenarios;
88

9-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
109
const runtimeScenarios = scenarios[scenarioName] || [];
1110

1211
export const worker = setupWorker(...runtimeScenarios, ...handlers);

src/mocks/handlers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1+
import { fetchInfo } from "./handlers/info"
12

23
export const handlers = [
3-
4+
fetchInfo
45
]

src/mocks/handlers/home.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/mocks/handlers/info.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { http, delay, HttpResponse } from "msw"
2+
import { INFO } from "@/constants/endpoints"
3+
import type { InfoResponse } from "@/lib/api"
4+
5+
export const fetchInfo = http.get<never, never, InfoResponse>(INFO, async () => {
6+
await delay(1000)
7+
8+
return HttpResponse.json({
9+
version: '0.1.0-dev'
10+
})
11+
})

src/pages/home/HomePage.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
11
import { PageTitle } from "@/components/PageTitle";
2+
import { Skeleton } from "@/components/ui/skeleton";
3+
import { fetchInfo } from "@/lib/api";
4+
import { useSuspenseQuery } from "@tanstack/react-query";
5+
import { Suspense } from "react";
6+
7+
8+
function Loader() {
9+
return (
10+
<div className="flex flex-col gap-1.5 py-2">
11+
<Skeleton className="h-12 rounded-lg" />
12+
<Skeleton className="h-12 rounded-lg" />
13+
</div>
14+
)
15+
}
16+
17+
function HomePageBody() {
18+
const { data } = useSuspenseQuery({
19+
queryKey: ["info"],
20+
queryFn: fetchInfo,
21+
});
22+
23+
return (
24+
<>
25+
<pre>
26+
{JSON.stringify(data)}
27+
</pre>
28+
</>
29+
)
30+
}
231

332
export default function HomePage() {
433
return (
534
<>
635
<PageTitle>Home</PageTitle>
36+
<Suspense fallback={<Loader />}>
37+
<HomePageBody />
38+
</Suspense>
739
</>
840
)
941
}

src/utils/api.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { API_URL } from "@/constants/api";
2+
3+
export const apiFetch = async <T = unknown>(
4+
endpoint: string,
5+
options: RequestInit = {}
6+
): Promise<T> => {
7+
const url = `${API_URL}${endpoint}`;
8+
9+
const response = await fetch(url, {
10+
...options,
11+
/* headers: {
12+
"Content-Type": "application/json",
13+
...(options.headers || {}),
14+
}, */
15+
headers: options.headers ?? [],
16+
});
17+
18+
if (!response.ok) {
19+
throw new Error(`HTTP error! status: ${response.statusText}`);
20+
}
21+
22+
const contentLength = response.headers.get("Content-Length");
23+
24+
if (
25+
contentLength === "0" ||
26+
response.headers.get("Content-Type")?.includes("application/json") === false
27+
) {
28+
return {} as T;
29+
}
30+
31+
return response.json() as Promise<T>;
32+
};

0 commit comments

Comments
 (0)