Add Torob tags, Meshkee SEO routes, and updated static-image slots.
Product pages emit crawler-readable meta, public URLs use id plus Farsi slugs, and the homepage catalog matches the dashboard slot keys. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
f42c30a4b7
commit
c84147e765
+47
-9
@@ -87,13 +87,18 @@ export type ApiCategory = {
|
||||
name: string;
|
||||
nameFa: string | null;
|
||||
slug: string;
|
||||
description?: string | null;
|
||||
isActive?: boolean;
|
||||
};
|
||||
|
||||
export type ApiVariant = {
|
||||
id: string;
|
||||
productId?: string;
|
||||
productTitle?: string | null;
|
||||
productNameFa?: string | null;
|
||||
productImage?: string | null;
|
||||
label?: string | null;
|
||||
price: number;
|
||||
price: number | null;
|
||||
discountedPrice?: number | null;
|
||||
stockQuantity?: number | null;
|
||||
sortOrder?: number;
|
||||
@@ -152,6 +157,18 @@ export async function getProduct(slug: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getProductById(productId: string) {
|
||||
try {
|
||||
const data = await apiGet<{ product: ApiProduct }>(
|
||||
`${tenant()}/products/by-id/${encodeURIComponent(productId)}`,
|
||||
);
|
||||
return data.product ?? null;
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 404) return null;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getBlogs(query: { page?: number; pageSize?: number; title?: string } = {}) {
|
||||
return apiGet<Paginated<ApiBlog>>(`${tenant()}/blogs`, query);
|
||||
}
|
||||
@@ -166,6 +183,16 @@ export async function getBlog(slug: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getBlogById(blogId: string) {
|
||||
try {
|
||||
const data = await apiGet<{ blog: ApiBlog }>(`${tenant()}/blogs/by-id/${encodeURIComponent(blogId)}`);
|
||||
return data.blog ?? null;
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 404) return null;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStoreSpecials() {
|
||||
const data = await apiGet<{ items: ApiStoreSpecial[] }>(`${tenant()}/store-specials`);
|
||||
return data.items ?? [];
|
||||
@@ -173,8 +200,10 @@ export async function getStoreSpecials() {
|
||||
|
||||
export async function getStoreItemByProduct(productId: string) {
|
||||
try {
|
||||
const data = await apiGet<{ storeItem: ApiStoreItem }>(`${tenant()}/store-items/by-product/${productId}`);
|
||||
return data.storeItem;
|
||||
const data = await apiGet<{ storeItem: ApiStoreItem | null }>(
|
||||
`${tenant()}/store-items/by-product/${productId}`,
|
||||
);
|
||||
return data.storeItem ?? null;
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 404) return null;
|
||||
throw error;
|
||||
@@ -195,6 +224,21 @@ export async function getCategoryBySlug(slug: string) {
|
||||
return categories.find((category) => category.slug === slug) ?? null;
|
||||
}
|
||||
|
||||
export async function getCategoryById(categoryId: string) {
|
||||
try {
|
||||
const data = await apiGet<{ category: ApiCategory }>(
|
||||
`${tenant()}/categories/by-id/${encodeURIComponent(categoryId)}`,
|
||||
);
|
||||
return data.category ?? null;
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 404) {
|
||||
const categories = await getCategories();
|
||||
return categories.find((category) => category.id === categoryId) ?? null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export type ApiTenant = {
|
||||
id: string | number;
|
||||
name: string;
|
||||
@@ -219,9 +263,3 @@ export async function getComments(entityType: "product" | "blog", entityId: stri
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export async function resolveProductSlug(productId: string, name: string) {
|
||||
if (!name) return "";
|
||||
const { items } = await getProducts({ name, pageSize: 20 });
|
||||
return items.find((item) => item.id === productId)?.slug ?? "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user