Initial commit: Meshkee dashboards monorepo.
Includes business, customer, and super-admin apps with shared packages and production deploy scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
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`
|
||||
}
|
||||
Reference in New Issue
Block a user