Add Oudelaa dashboard API integration
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled

هذا الالتزام موجود في:
boutmoun123
2026-05-25 20:36:52 +03:00
الأصل 367fce6557
التزام 8863f61d00
90 ملفات معدلة مع 16694 إضافات و1 حذوفات

عرض الملف

@@ -0,0 +1,108 @@
import { apiEndpoints } from "@/lib/api/endpoints";
import type { LoginResponse } from "@/types/api";
const API_PREFIX = "/api/proxy";
function isHardAuthFailure(error: unknown) {
const message = String(error);
return message.includes("400") || message.includes("401");
}
function extractErrorMessage(payload: unknown): string | null {
if (!payload || typeof payload !== "object") {
return null;
}
const candidate = payload as { message?: unknown; error?: unknown };
if (Array.isArray(candidate.message)) {
return candidate.message.map((item) => String(item)).join(", ");
}
if (typeof candidate.message === "string" && candidate.message.trim()) {
return candidate.message.trim();
}
if (typeof candidate.error === "string" && candidate.error.trim()) {
return candidate.error.trim();
}
return null;
}
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const isFormDataRequest =
typeof FormData !== "undefined" && init?.body instanceof FormData;
const res = await fetch(`${API_PREFIX}${path}`, {
...init,
credentials: "include",
headers: {
...(isFormDataRequest ? {} : { "Content-Type": "application/json" }),
...(init?.headers ?? {}),
},
});
if (!res.ok) {
const contentType = res.headers.get("content-type") ?? "";
let detail = "";
if (contentType.includes("application/json")) {
const payload = (await res.json()) as unknown;
const message = extractErrorMessage(payload);
detail = message ? ` - ${message}` : ` - ${JSON.stringify(payload)}`;
} else {
const text = await res.text();
detail = text ? ` - ${text}` : "";
}
throw new Error(`Request failed: ${res.status}${detail}`);
}
if (res.status === 204) {
return undefined as T;
}
return res.json() as Promise<T>;
}
export async function loginSuperAdmin(email: string, password: string): Promise<void> {
await request<LoginResponse>(apiEndpoints.auth.superAdminLogin, {
method: "POST",
body: JSON.stringify({ email, password }),
});
}
export async function refreshSuperAdmin(): Promise<boolean> {
try {
await request<LoginResponse>(apiEndpoints.auth.superAdminRefresh, {
method: "POST",
body: JSON.stringify({}),
});
return true;
} catch (error) {
if (isHardAuthFailure(error)) {
return false;
}
throw error;
}
}
export async function logoutSuperAdmin(): Promise<void> {
await request<void>(apiEndpoints.auth.superAdminLogout, {
method: "POST",
body: JSON.stringify({}),
});
}
export async function fetchWithAuth<T>(path: string, init?: RequestInit): Promise<T> {
const makeRequest = async () => request<T>(path, init);
try {
return await makeRequest();
} catch (error) {
if (String(error).includes("401")) {
const refreshed = await refreshSuperAdmin();
if (refreshed) {
return makeRequest();
}
}
throw error;
}
}

عرض الملف

@@ -0,0 +1,23 @@
export function parseJwtPayload(token: string): Record<string, unknown> | null {
const parts = token.split(".");
if (parts.length < 2) return null;
try {
const normalized = parts[1].replace(/-/g, "+").replace(/_/g, "/");
const decoded =
typeof window !== "undefined"
? window.atob(normalized)
: Buffer.from(normalized, "base64").toString("utf8");
return JSON.parse(decoded) as Record<string, unknown>;
} catch {
return null;
}
}
export function isJwtExpired(token: string, skewSeconds = 15): boolean {
const payload = parseJwtPayload(token);
const exp = typeof payload?.exp === "number" ? payload.exp : null;
if (!exp) return false;
const now = Math.floor(Date.now() / 1000);
return exp <= now + skewSeconds;
}

عرض الملف

@@ -0,0 +1,14 @@
import type { AuthTokens } from "@/types/api";
export function loadTokens(): AuthTokens | null {
return null;
}
export function saveTokens(tokens: AuthTokens) {
void tokens;
return;
}
export function clearTokens() {
return;
}