fix(kvytky): combo cards driven by ezy API — no test tariffs, correct prices
buildComboCards now uses ezy tariffs as primary source when available. Static cards are only used for descriptions and as fallback when ezy is down. This removes test/placeholder cards and fixes mismatched prices from CMS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
12cd941da5
commit
8ffd6ebaa6
1 changed files with 36 additions and 29 deletions
|
|
@ -210,42 +210,49 @@ const COMBO_CARDS_STATIC: ComboCardData[] = [
|
|||
const parsePrice = (s: string): number => Number(String(s).replace(/[^\d]/g, '')) || 0
|
||||
|
||||
function buildComboCards(pageData: TicketsPage | null, tariffs: Tariff[]): ComboCardData[] {
|
||||
const cms = pageData?.comboCards
|
||||
const cards: ComboCardData[] =
|
||||
!cms || cms.length === 0
|
||||
? COMBO_CARDS_STATIC
|
||||
: cms.map((c, i) => ({
|
||||
id: c.id ?? `combo-${i}`,
|
||||
tariffId: `combo-${i}`,
|
||||
priceValue: parsePrice(c.price),
|
||||
name: c.name,
|
||||
subtitle: c.subtitle ?? null,
|
||||
price: c.price,
|
||||
description: c.description ?? '',
|
||||
featured: !!c.featured,
|
||||
badge: c.badge ?? null,
|
||||
locations: (c.locations ?? []).map((l) => l.text).filter(Boolean) as string[],
|
||||
}))
|
||||
|
||||
// Match combo cards to live combo tariffs (by ascending price) to get a real
|
||||
// cart tariffId + current price for the cart/checkout flow.
|
||||
const apiCombos = tariffs
|
||||
.filter((t) => t.categoryTag === 'combo')
|
||||
.sort((a, b) => a.price - b.price)
|
||||
if (apiCombos.length === 0) return cards
|
||||
|
||||
const sorted = [...cards].sort((a, b) => a.priceValue - b.priceValue)
|
||||
const overrides = new Map<string, { tariffId: string; priceValue: number; price: string }>()
|
||||
sorted.forEach((card, i) => {
|
||||
const api = apiCombos[i]
|
||||
if (api)
|
||||
overrides.set(card.id, {
|
||||
// When ezy has live combo tariffs, use them as the authoritative source for
|
||||
// names and prices. Match descriptions/badges from static cards by name prefix.
|
||||
if (apiCombos.length > 0) {
|
||||
return apiCombos.map((api, i) => {
|
||||
const nameKey = api.name.slice(0, 7).toLowerCase()
|
||||
const staticMatch =
|
||||
COMBO_CARDS_STATIC.find((c) =>
|
||||
`${c.name} ${c.subtitle ?? ''}`.toLowerCase().includes(nameKey)
|
||||
) ?? COMBO_CARDS_STATIC[Math.min(i, COMBO_CARDS_STATIC.length - 1)]!
|
||||
return {
|
||||
id: `combo-${api.id}`,
|
||||
tariffId: String(api.id),
|
||||
priceValue: api.price,
|
||||
name: api.name,
|
||||
subtitle: null,
|
||||
price: `${api.price} ₴`,
|
||||
})
|
||||
})
|
||||
return cards.map((c) => ({ ...c, ...(overrides.get(c.id) ?? {}) }))
|
||||
description: staticMatch.description,
|
||||
featured: i === 1,
|
||||
badge: i === 1 ? 'Найпопулярніший' : null,
|
||||
locations: COMBO_LOCATIONS,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// No ezy data — fall back to CMS (excluding test/placeholder cards) or static.
|
||||
const cms = pageData?.comboCards?.filter((c) => parsePrice(c.price) > 0 && c.name.length > 2)
|
||||
if (!cms || cms.length === 0) return COMBO_CARDS_STATIC
|
||||
return cms.map((c, i) => ({
|
||||
id: c.id ?? `combo-${i}`,
|
||||
tariffId: `combo-${i}`,
|
||||
priceValue: parsePrice(c.price),
|
||||
name: c.name,
|
||||
subtitle: c.subtitle ?? null,
|
||||
price: c.price,
|
||||
description: c.description ?? '',
|
||||
featured: !!c.featured,
|
||||
badge: c.badge ?? null,
|
||||
locations: (c.locations ?? []).map((l) => l.text).filter(Boolean) as string[],
|
||||
}))
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue