Files
hoomat-store/lib/meshkee/format.ts
T

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;
}