mirror of
https://git.meshkee.com/Meshkee/dashboards.git
synced 2026-08-12 06:40:57 +04:30
Includes business, customer, and super-admin apps with shared packages and production deploy scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import type { StoreItem } from '../services/storeItemService'
|
|
import { hasStoreItemDiscount } from './irtPrice'
|
|
|
|
export interface StoreProductListing {
|
|
productId: string
|
|
productTitle: string
|
|
productNameFa: string
|
|
productImage: string | null
|
|
productTotalStock: number
|
|
variantCount: number
|
|
variants: StoreItem[]
|
|
representative: StoreItem
|
|
displayPrice: number | null
|
|
displayDiscountedPrice: number | null
|
|
showFestival: boolean
|
|
}
|
|
|
|
function effectivePrice(item: StoreItem): number | null {
|
|
if (hasStoreItemDiscount(item.price, item.discountedPrice)) {
|
|
return item.discountedPrice
|
|
}
|
|
return item.price
|
|
}
|
|
|
|
function pickDisplayPrice(variants: StoreItem[]) {
|
|
let displayPrice: number | null = null
|
|
let displayDiscountedPrice: number | null = null
|
|
let minEffective = Infinity
|
|
|
|
for (const variant of variants) {
|
|
const effective = effectivePrice(variant)
|
|
if (effective === null) continue
|
|
if (effective < minEffective) {
|
|
minEffective = effective
|
|
if (hasStoreItemDiscount(variant.price, variant.discountedPrice)) {
|
|
displayPrice = variant.price
|
|
displayDiscountedPrice = variant.discountedPrice
|
|
} else {
|
|
displayPrice = variant.price
|
|
displayDiscountedPrice = null
|
|
}
|
|
}
|
|
}
|
|
|
|
if (minEffective === Infinity) {
|
|
const first = variants[0]
|
|
return {
|
|
displayPrice: first?.price ?? null,
|
|
displayDiscountedPrice: first?.discountedPrice ?? null,
|
|
}
|
|
}
|
|
|
|
return { displayPrice, displayDiscountedPrice }
|
|
}
|
|
|
|
export function groupStoreItemsByProduct(items: StoreItem[]): StoreProductListing[] {
|
|
const byProduct = new Map<string, StoreItem[]>()
|
|
|
|
for (const item of items) {
|
|
const variants = byProduct.get(item.productId) ?? []
|
|
variants.push(item)
|
|
byProduct.set(item.productId, variants)
|
|
}
|
|
|
|
return [...byProduct.values()]
|
|
.map((variants) => {
|
|
const sorted = [...variants].sort(
|
|
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
|
)
|
|
const representative = sorted[0]
|
|
const { displayPrice, displayDiscountedPrice } = pickDisplayPrice(sorted)
|
|
|
|
return {
|
|
productId: representative.productId,
|
|
productTitle: representative.productTitle,
|
|
productNameFa: representative.productNameFa,
|
|
productImage: representative.productImage,
|
|
productTotalStock: representative.productTotalStock,
|
|
variantCount: sorted.length,
|
|
variants: sorted,
|
|
representative,
|
|
displayPrice,
|
|
displayDiscountedPrice,
|
|
showFestival: sorted.some(
|
|
(variant) => variant.isFestival || (variant.rewardPoints ?? 0) > 0,
|
|
),
|
|
}
|
|
})
|
|
.sort(
|
|
(a, b) =>
|
|
new Date(b.representative.createdAt).getTime() -
|
|
new Date(a.representative.createdAt).getTime(),
|
|
)
|
|
}
|
|
|
|
export function formatVariantCount(count: number): string {
|
|
return count === 1 ? '1 variant' : `${count} variants`
|
|
}
|