Add fixed categories dock and specials-driven home carousels.

Dock links use the six API category slugs so storefront navigation stays connected to catalog filters.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-23 15:44:53 +03:30
co-authored by Cursor
parent 35939e6ee4
commit 6c060e222c
24 changed files with 1131 additions and 92 deletions
+2
View File
@@ -9,6 +9,7 @@ export type ListProductsParams = {
q?: string
categoryId?: string
categorySlug?: string
tag?: string
minPrice?: number
maxPrice?: number
page?: number
@@ -112,6 +113,7 @@ function buildQuery(params: ListProductsParams) {
if (params.q?.trim()) search.set('q', params.q.trim())
if (params.categoryId) search.set('categoryId', params.categoryId)
if (params.categorySlug) search.set('categorySlug', params.categorySlug)
if (params.tag?.trim()) search.set('tag', params.tag.trim())
if (params.minPrice !== undefined) search.set('minPrice', String(params.minPrice))
if (params.maxPrice !== undefined) search.set('maxPrice', String(params.maxPrice))
if (params.page) search.set('page', String(params.page))
+64
View File
@@ -0,0 +1,64 @@
/**
* Home product carousels driven by admin special tags (ویژه).
* Sort by `order`. English placeholders are fixed for the website.
* Carousels with zero products are not rendered.
*/
export type HomeCarouselDef = {
id: string
/** Matches Product.tags values set in the dashboard specials UI */
tag: string
order: number
placeholder: string
secondary: string
primary: string
/** Full-bleed band with top/bottom borders */
framed?: boolean
}
export const HOME_PRODUCT_CAROUSELS: HomeCarouselDef[] = [
{
id: 'recommended',
tag: 'پیشنهادی',
order: 1,
placeholder: 'Recommended',
secondary: 'محصولات',
primary: 'پیشنهادی مــــا',
},
{
id: 'bestsellers',
tag: 'پرفروش',
order: 2,
placeholder: 'Best Sellers',
secondary: 'محصولات',
primary: 'پرفــــــــروش',
},
{
id: 'ready-to-ship',
tag: 'آماده',
order: 3,
placeholder: 'Ready to Ship',
secondary: 'محصولات',
primary: 'آماده ارســــال',
},
{
id: 'new-products',
tag: 'جدید',
order: 4,
placeholder: 'New Arrivals',
secondary: 'محصولات',
primary: 'جدیــــــــد',
framed: true,
},
{
id: 'gift',
tag: 'هدیه',
order: 5,
placeholder: 'Gift Ideas',
secondary: 'محصولات',
primary: 'مناسب هدیــــه',
},
]
export function sortedHomeCarousels(defs = HOME_PRODUCT_CAROUSELS) {
return [...defs].sort((a, b) => a.order - b.order)
}
+2
View File
@@ -39,6 +39,8 @@ export type Product = {
intro?: string | null
description?: string | null
tags?: string[]
preparationHours?: number | null
createdAt?: string
mainImageUrl: string | null
mainImageKey?: string | null
gallery?: ProductGalleryImage[]