91 lines
2.2 KiB
TypeScript
91 lines
2.2 KiB
TypeScript
const DEFAULT_BASE_URL = "/api/proxy";
|
|
|
|
export const API_BASE_URL =
|
|
process.env.NEXT_PUBLIC_API_BASE_URL || DEFAULT_BASE_URL;
|
|
|
|
function normalizePath(path: string) {
|
|
return path.startsWith("/") ? path : `/${path}`;
|
|
}
|
|
|
|
async function requestJson<T>(path: string, init: RequestInit = {}): Promise<T> {
|
|
const token = typeof window !== "undefined" ? localStorage.getItem("auth_token") : null;
|
|
const headers = new Headers(init.headers || {});
|
|
|
|
if (!headers.has("Content-Type") && !(init.body instanceof FormData)) {
|
|
headers.set("Content-Type", "application/json");
|
|
}
|
|
|
|
if (token) {
|
|
headers.set("Authorization", `Bearer ${token}`);
|
|
}
|
|
|
|
const endpoint = `${API_BASE_URL}${normalizePath(path)}`;
|
|
|
|
let attempt = 0;
|
|
const maxAttempts = 3;
|
|
|
|
while (attempt < maxAttempts) {
|
|
try {
|
|
const response = await fetch(endpoint, {
|
|
...init,
|
|
headers,
|
|
cache: "no-store",
|
|
method: init.method || "GET",
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const text = await response.text();
|
|
throw new Error(text || `Request failed with status ${response.status}`);
|
|
}
|
|
|
|
return (await response.json()) as T;
|
|
} catch (error) {
|
|
attempt += 1;
|
|
if (attempt >= maxAttempts) {
|
|
throw error;
|
|
}
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 2 ** attempt * 300));
|
|
}
|
|
}
|
|
|
|
throw new Error("Request failed after retries.");
|
|
}
|
|
|
|
export type DashboardSummaryResponse = {
|
|
success: boolean;
|
|
message: string;
|
|
data: {
|
|
stats: {
|
|
clients: number;
|
|
orders: number;
|
|
trips: number;
|
|
cars: number;
|
|
drivers: number;
|
|
};
|
|
alerts: {
|
|
expiringCars: Array<Record<string, unknown>>;
|
|
expiringDrivers: Array<Record<string, unknown>>;
|
|
upcomingMaint: Array<Record<string, unknown>>;
|
|
};
|
|
activeTrips: Array<{
|
|
id: string;
|
|
tripNumber: string;
|
|
title: string;
|
|
progress: number;
|
|
}>;
|
|
accountSecurity: {
|
|
lastLogin: string | null;
|
|
requestMeta: Record<string, unknown> | null;
|
|
};
|
|
};
|
|
};
|
|
|
|
export async function getDashboardSummary() {
|
|
return requestJson<DashboardSummaryResponse>("/v1/dashboard/summary");
|
|
}
|
|
|
|
export async function getHealth() {
|
|
return requestJson<{ status: string; message: string }>("/health");
|
|
}
|