fix: rate overrides save + add Без категории group

- Fix applyPrices: build overrides array before setPrices (updater is async, side-effects inside it are unreliable)
- Add "Без категории" group for rooms not assigned to any category

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-23 16:23:10 +03:00
parent e5daf91ed4
commit 2a741d89d0

View File

@@ -693,6 +693,7 @@ export function AvailabilityPage() {
api.rateOverrides.list(slug).catch(() => []), api.rateOverrides.list(slug).catch(() => []),
]).then(([cats, rooms, apiPeriods, apiOverrides]) => { ]).then(([cats, rooms, apiPeriods, apiOverrides]) => {
// Build AvailabilityCat[] from real categories, derive basePrice from rooms // Build AvailabilityCat[] from real categories, derive basePrice from rooms
const colors = ['#6366f1','#10b981','#f59e0b','#ef4444','#8b5cf6','#06b6d4']
const availCats: AvailabilityCat[] = cats.map(cat => { const availCats: AvailabilityCat[] = cats.map(cat => {
const catRooms = rooms.filter(r => r.categoryId === cat.id) const catRooms = rooms.filter(r => r.categoryId === cat.id)
const basePrice = catRooms.length > 0 const basePrice = catRooms.length > 0
@@ -702,8 +703,7 @@ export function AvailabilityPage() {
}) })
// If no categories, fall back to room types as groups // If no categories, fall back to room types as groups
const colors = ['#6366f1','#10b981','#f59e0b','#ef4444','#8b5cf6','#06b6d4'] let finalCats: AvailabilityCat[] = availCats.length > 0 ? availCats : (() => {
const finalCats = availCats.length > 0 ? availCats : (() => {
const typeMap = new Map<string, number>() const typeMap = new Map<string, number>()
for (const r of rooms) { for (const r of rooms) {
if (!r.type) continue if (!r.type) continue
@@ -716,6 +716,19 @@ export function AvailabilityPage() {
})) }))
})() })()
// Add "Без категории" group for rooms not assigned to any category
const assignedCatIds = new Set(cats.map(c => c.id))
const uncategorized = rooms.filter(r => !r.categoryId || !assignedCatIds.has(r.categoryId))
if (uncategorized.length > 0) {
const basePrice = Math.min(...uncategorized.map(r => r.baseRate))
finalCats = [...finalCats, {
id: '__no_category__',
name: 'Без категории',
color: '#94a3b8',
basePrice,
}]
}
setRoomCategories(finalCats) setRoomCategories(finalCats)
// Build initial grid then apply saved overrides on top // Build initial grid then apply saved overrides on top
@@ -798,34 +811,36 @@ export function AvailabilityPage() {
? roomCategories.filter(c => c.id === onlyCategoryId) ? roomCategories.filter(c => c.id === onlyCategoryId)
: roomCategories : roomCategories
// Build overrides BEFORE setPrices (updater runs async, can't rely on side-effects inside it)
const overrides: Array<{ const overrides: Array<{
category_id: string; date: string; price: number category_id: string; date: string; price: number
extra_person: number; min_nights: number extra_person: number; min_nights: number
channel_prices: Record<string, number>; closed: boolean channel_prices: Record<string, number>; closed: boolean
}> = [] }> = []
for (const cat of catsToUpdate) {
const basePrice = categoryPrices[cat.id] ?? cat.basePrice
for (const d of days) {
const channelPrices: Record<string, number> = {}
for (const ch of RATE_CHANNELS) {
channelPrices[ch.id] = Math.round(basePrice * (channelMarkup[ch.id] ?? 1))
}
overrides.push({
category_id: cat.id, date: d, price: basePrice,
extra_person: extraPerson, min_nights: minNights,
channel_prices: channelPrices, closed,
})
}
}
setPrices(prev => { setPrices(prev => {
const next = { ...prev } const next = { ...prev }
for (const cat of catsToUpdate) { for (const o of overrides) {
next[cat.id] = { ...prev[cat.id] } if (!next[o.category_id]) next[o.category_id] = {}
const basePrice = categoryPrices[cat.id] ?? cat.basePrice next[o.category_id] = { ...next[o.category_id] }
for (const d of days) { next[o.category_id][o.date] = {
const channelPrices: Record<string, number> = {} price: o.price, extraPerson: o.extra_person, minNights: o.min_nights,
for (const ch of RATE_CHANNELS) { channelPrices: o.channel_prices, closed: o.closed,
channelPrices[ch.id] = Math.round(basePrice * (channelMarkup[ch.id] ?? 1))
}
next[cat.id][d] = {
price: basePrice, extraPerson, minNights, channelPrices, closed,
}
overrides.push({
category_id: cat.id,
date: d,
price: basePrice,
extra_person: extraPerson,
min_nights: minNights,
channel_prices: channelPrices,
closed,
})
} }
} }
return next return next