feat: polish admin UI, phone login, and product details
Switch admin auth to mobile, restyle shell/login with Vuesax icons, and add product detail fields plus public product pages. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { PublicCategory, SiteSettings } from "@imen/shared";
|
||||
import type { PublicCategory, PublicProductDetail, SiteSettings } from "@imen/shared";
|
||||
import { siteConfig } from "../config/site";
|
||||
|
||||
type Json = Record<string, unknown>;
|
||||
@@ -97,12 +97,46 @@ export const categoryPageSchema = (ctx: SeoContext, category: PublicCategory) =>
|
||||
name: p.name,
|
||||
description: p.desc,
|
||||
sku: p.code,
|
||||
url: abs(ctx, `/products/${p.slug}`),
|
||||
...(p.image && { image: abs(ctx, p.image) }),
|
||||
},
|
||||
})),
|
||||
},
|
||||
});
|
||||
|
||||
export const productSchema = (ctx: SeoContext, p: PublicProductDetail) =>
|
||||
clean({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Product",
|
||||
"@id": `${ctx.siteUrl}/products/${p.slug}#product`,
|
||||
name: p.name,
|
||||
alternateName: p.nameEn,
|
||||
sku: p.code,
|
||||
mpn: p.code,
|
||||
description: p.seoDescription || p.desc || p.details.slice(0, 300),
|
||||
url: abs(ctx, `/products/${p.slug}`),
|
||||
image: p.images.map((i) => abs(ctx, i.url)),
|
||||
category: p.category.name,
|
||||
...(p.brand && { brand: { "@type": "Brand", name: p.brand } }),
|
||||
countryOfOrigin: p.origin,
|
||||
additionalProperty: [
|
||||
...p.attributes.map((a) => ({ "@type": "PropertyValue", name: a.name, value: a.value })),
|
||||
...p.standards.map((s) => ({ "@type": "PropertyValue", name: "استاندارد", value: s })),
|
||||
],
|
||||
seller: { "@id": `${ctx.siteUrl}/#organization` },
|
||||
});
|
||||
|
||||
export const breadcrumbSchema = (ctx: SeoContext, items: { name: string; path: string }[]) => ({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
itemListElement: items.map((it, i) => ({
|
||||
"@type": "ListItem",
|
||||
position: i + 1,
|
||||
name: it.name,
|
||||
item: abs(ctx, it.path),
|
||||
})),
|
||||
});
|
||||
|
||||
/** Serialize JSON-LD safely for an inline <script> (escape "<"). */
|
||||
export const toJsonLd = (data: Json) =>
|
||||
JSON.stringify(data).replace(/</g, "\\u003c");
|
||||
|
||||
Reference in New Issue
Block a user