fuck if i know
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"use client";
|
||||
|
||||
import { useAuth } from "@/context/AuthContext";
|
||||
import { useCallback, useMemo } from "react";
|
||||
|
||||
const DEFAULT_API_BASE =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080";
|
||||
|
||||
export function useApi(baseUrl: string = DEFAULT_API_BASE) {
|
||||
const { token } = useAuth();
|
||||
|
||||
const apiFetch = useCallback(
|
||||
async <T = any>(path: string, options: RequestInit = {}): Promise<T> => {
|
||||
// Allow either full URLs or just `/api/...`
|
||||
const url = path.startsWith("http")
|
||||
? path
|
||||
: `${baseUrl.replace(/\/$/, "")}${path}`;
|
||||
|
||||
const headers: HeadersInit = {
|
||||
"Content-Type": "application/json",
|
||||
...(options.headers || {}),
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
};
|
||||
|
||||
const res = await fetch(url, {
|
||||
...options,
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
let bodyText = "";
|
||||
try {
|
||||
bodyText = await res.text();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
throw new Error(
|
||||
`API error ${res.status}: ${
|
||||
bodyText || res.statusText || "Unknown error"
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
// handle 204 / empty body safely
|
||||
try {
|
||||
return (await res.json()) as T;
|
||||
} catch {
|
||||
return {} as T;
|
||||
}
|
||||
},
|
||||
[baseUrl, token] // 👈 only changes when baseUrl or token change
|
||||
);
|
||||
|
||||
const get = useCallback(
|
||||
<T = any>(path: string) => apiFetch<T>(path, { method: "GET" }),
|
||||
[apiFetch]
|
||||
);
|
||||
|
||||
const post = useCallback(
|
||||
<T = any>(path: string, body?: unknown) =>
|
||||
apiFetch<T>(path, {
|
||||
method: "POST",
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||
}),
|
||||
[apiFetch]
|
||||
);
|
||||
|
||||
const put = useCallback(
|
||||
<T = any>(path: string, body?: unknown) =>
|
||||
apiFetch<T>(path, {
|
||||
method: "PUT",
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||
}),
|
||||
[apiFetch]
|
||||
);
|
||||
|
||||
const del = useCallback(
|
||||
<T = any>(path: string) => apiFetch<T>(path, { method: "DELETE" }),
|
||||
[apiFetch]
|
||||
);
|
||||
|
||||
// Optional: memoize the returned object so destructuring doesn't change refs
|
||||
return useMemo(
|
||||
() => ({ apiFetch, get, post, put, del }),
|
||||
[apiFetch, get, post, put, del]
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user