Files
website/lib/meshkee-categories.ts
T

77 lines
2.1 KiB
TypeScript

import { getAccessToken } from "@/lib/session";
export interface MeshkeeCategory {
id: string;
parentId: string | null;
name: string;
nameFa: string | null;
slug: string;
description: string | null;
icon: string | null;
sortOrder: number;
tags: string[];
}
export function categoryLabel(category: {
name: string;
nameFa?: string | null;
slug: string;
}) {
if (category.nameFa && category.nameFa !== category.name) {
return `${category.name} / ${category.nameFa}`;
}
return category.name || category.slug;
}
function mapCategory(row: Record<string, unknown>): MeshkeeCategory {
return {
id: String(row.id),
parentId:
row.parentId == null && row.parent_id == null
? null
: String(row.parentId ?? row.parent_id),
name: String(row.name ?? ""),
nameFa:
row.nameFa == null && row.name_fa == null
? null
: String(row.nameFa ?? row.name_fa),
slug: String(row.slug ?? ""),
description: row.description == null ? null : String(row.description),
icon: row.icon == null ? null : String(row.icon),
sortOrder: Number(row.sortOrder ?? row.sort_order ?? 0),
tags: Array.isArray(row.tags) ? (row.tags as string[]) : [],
};
}
export async function searchMeshkeeCategories(
q = "",
signal?: AbortSignal,
): Promise<MeshkeeCategory[]> {
const params = new URLSearchParams();
if (q.trim()) params.set("q", q.trim());
const headers = new Headers();
const token = getAccessToken();
if (token) headers.set("Authorization", `Bearer ${token}`);
const response = await fetch(`/api/meshkee/categories?${params}`, {
headers,
signal,
cache: "no-store",
});
const payload = await response.json().catch(() => null);
if (!response.ok) {
const message =
typeof payload?.message === "string"
? payload.message
: Array.isArray(payload?.message)
? payload.message.join(", ")
: `Failed to load categories (${response.status})`;
throw new Error(message);
}
const items = Array.isArray(payload?.items) ? payload.items : [];
return items.map((row: Record<string, unknown>) => mapCategory(row));
}