Dock links use the six API category slugs so storefront navigation stays connected to catalog filters. Co-authored-by: Cursor <cursoragent@cursor.com>
88 lines
1.7 KiB
TypeScript
88 lines
1.7 KiB
TypeScript
export type SellUnit = 'unit' | 'kilo'
|
|
|
|
export type UserRole = 'customer' | 'admin' | 'superAdmin'
|
|
|
|
export type ProductCategoryRef = {
|
|
id: string
|
|
nameFa: string
|
|
nameEn: string
|
|
parentId?: string | null
|
|
}
|
|
|
|
export type ProductOptionValue = {
|
|
id: string
|
|
flavorId: string
|
|
amount: string
|
|
price: number
|
|
flavor?: {
|
|
id: string
|
|
nameFa: string
|
|
nameEn: string
|
|
}
|
|
}
|
|
|
|
export type ProductGalleryImage = {
|
|
id?: string
|
|
url: string
|
|
storageKey?: string
|
|
sortOrder?: number
|
|
}
|
|
|
|
export type Product = {
|
|
id: string
|
|
nameFa: string
|
|
nameEn: string
|
|
price: number
|
|
sellUnit: SellUnit
|
|
categoryId: string
|
|
category: ProductCategoryRef
|
|
intro?: string | null
|
|
description?: string | null
|
|
tags?: string[]
|
|
preparationHours?: number | null
|
|
createdAt?: string
|
|
mainImageUrl: string | null
|
|
mainImageKey?: string | null
|
|
gallery?: ProductGalleryImage[]
|
|
options?: ProductOptionValue[]
|
|
}
|
|
|
|
export type CategoryNode = {
|
|
id: string
|
|
nameFa: string
|
|
nameEn: string
|
|
slug: string
|
|
parentId: string | null
|
|
sortOrder: number
|
|
children?: CategoryNode[]
|
|
}
|
|
|
|
export type ProductListResponse = {
|
|
items: Product[]
|
|
total: number
|
|
page: number
|
|
pageSize: number
|
|
}
|
|
|
|
const sellUnitLabel: Record<SellUnit, string> = {
|
|
unit: 'واحد',
|
|
kilo: 'کیلو',
|
|
}
|
|
|
|
export function formatPriceFa(price: number) {
|
|
return price.toLocaleString('fa-IR')
|
|
}
|
|
|
|
export function formatProductPrice(product: Product) {
|
|
const unit = sellUnitLabel[product.sellUnit] ?? ''
|
|
return {
|
|
amount: formatPriceFa(product.price),
|
|
unitLabel: unit,
|
|
full: `${formatPriceFa(product.price)} تومان /${unit}`,
|
|
}
|
|
}
|
|
|
|
export function productImageSrc(product: Product, fallback: string) {
|
|
return product.mainImageUrl || fallback
|
|
}
|