103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
import type { Category, CategoryTreeNode, GuestCartLine } from "@/lib/meshkee/types";
|
|
|
|
export function slugifyFa(value: string | null | undefined): string {
|
|
const raw = (value ?? "").trim().toLowerCase();
|
|
if (!raw) return "item";
|
|
return raw
|
|
.replace(/\s+/g, "-")
|
|
.replace(/[^\u0600-\u06FFa-z0-9-]+/g, "")
|
|
.replace(/-+/g, "-")
|
|
.replace(/^-|-$/g, "") || "item";
|
|
}
|
|
|
|
export function formatPrice(value: number | null | undefined): string {
|
|
const amount = Number(value ?? 0);
|
|
return `${new Intl.NumberFormat("fa-IR").format(amount)} تومان`;
|
|
}
|
|
|
|
export function formatDate(value: string | null | undefined): string {
|
|
if (!value) return "";
|
|
try {
|
|
return new Intl.DateTimeFormat("fa-IR", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
}).format(new Date(value));
|
|
} catch {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
export function displayName(user: {
|
|
firstName?: string | null;
|
|
lastName?: string | null;
|
|
}): string {
|
|
const first = user.firstName?.trim();
|
|
if (first) return first;
|
|
const last = user.lastName?.trim();
|
|
if (last) return last;
|
|
return "کاربر";
|
|
}
|
|
|
|
export function buildCategoryTree(categories: Category[]): CategoryTreeNode[] {
|
|
const map = new Map<string, CategoryTreeNode>();
|
|
for (const category of categories) {
|
|
if (category.isActive === false) continue;
|
|
map.set(category.id, { ...category, children: [] });
|
|
}
|
|
|
|
const roots: CategoryTreeNode[] = [];
|
|
for (const node of map.values()) {
|
|
if (node.parentId && map.has(node.parentId)) {
|
|
map.get(node.parentId)!.children.push(node);
|
|
} else {
|
|
roots.push(node);
|
|
}
|
|
}
|
|
|
|
const sortNodes = (nodes: CategoryTreeNode[]) => {
|
|
nodes.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
|
|
nodes.forEach((node) => sortNodes(node.children));
|
|
};
|
|
sortNodes(roots);
|
|
return roots;
|
|
}
|
|
|
|
export function categoryLabel(category: Category): string {
|
|
return category.nameFa?.trim() || category.name;
|
|
}
|
|
|
|
export function storeItemName(item: {
|
|
productNameFa?: string | null;
|
|
productTitle?: string | null;
|
|
label?: string | null;
|
|
}): string {
|
|
return item.productNameFa?.trim() || item.productTitle?.trim() || "محصول";
|
|
}
|
|
|
|
export function storeItemPrice(item: {
|
|
price: number;
|
|
discountedPrice?: number | null;
|
|
}): number {
|
|
return item.discountedPrice != null && item.discountedPrice > 0
|
|
? item.discountedPrice
|
|
: item.price;
|
|
}
|
|
|
|
export function normalizeGuestLines(items: GuestCartLine[]): GuestCartLine[] {
|
|
const result: GuestCartLine[] = [];
|
|
for (const item of items) {
|
|
const id = (item.id || "").trim();
|
|
if (!id) continue;
|
|
result.push({
|
|
id,
|
|
name: item.name || "محصول",
|
|
slug: item.slug,
|
|
price: Number(item.price) || 0,
|
|
image: item.image ?? null,
|
|
quantity: Math.max(1, Math.floor(item.quantity) || 1),
|
|
});
|
|
}
|
|
return result;
|
|
}
|