fix: widget — show category photos, load rental objects in settings preview

- Category cards now show photos[0] as <img> when available, fallback to 🛏️ emoji
- Settings page preview loads rentalObjects from API and passes to WidgetPreview
- MockCategory type and MOCK_CATEGORIES get photos: [] to match updated type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 10:50:56 +03:00
parent 36015e9cee
commit f5878c0447

View File

@@ -140,20 +140,21 @@ interface MockCategory {
maxGuests: number maxGuests: number
amenities: string[] amenities: string[]
description: string description: string
photos: string[]
availableCount: number availableCount: number
} }
const MOCK_CATEGORIES: MockCategory[] = [ const MOCK_CATEGORIES: MockCategory[] = [
{ id: 'c1', name: 'Стандарт', minPrice: 4500, maxGuests: 2, availableCount: 3, { id: 'c1', name: 'Стандарт', minPrice: 4500, maxGuests: 2, availableCount: 3, photos: [],
amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Фен'], amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Фен'],
description: 'Уютные номера с современным ремонтом и всем необходимым для комфортного проживания.' }, description: 'Уютные номера с современным ремонтом и всем необходимым для комфортного проживания.' },
{ id: 'c2', name: 'Комфорт', minPrice: 6500, maxGuests: 2, availableCount: 2, { id: 'c2', name: 'Комфорт', minPrice: 6500, maxGuests: 2, availableCount: 2, photos: [],
amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Мини-бар', 'Кофемашина'], amenities: ['Wi-Fi', 'TV', 'Кондиционер', 'Мини-бар', 'Кофемашина'],
description: 'Просторные номера с расширенными удобствами и зоной отдыха.' }, description: 'Просторные номера с расширенными удобствами и зоной отдыха.' },
{ id: 'c3', name: 'Делюкс', minPrice: 8900, maxGuests: 3, availableCount: 1, { id: 'c3', name: 'Делюкс', minPrice: 8900, maxGuests: 3, availableCount: 1, photos: [],
amenities: ['Wi-Fi', 'Smart TV', 'Кондиционер', 'Джакузи', 'Балкон'], amenities: ['Wi-Fi', 'Smart TV', 'Кондиционер', 'Джакузи', 'Балкон'],
description: 'Роскошные номера с панорамными окнами и собственным джакузи.' }, description: 'Роскошные номера с панорамными окнами и собственным джакузи.' },
{ id: 'c4', name: 'Пентхаус', minPrice: 15000, maxGuests: 4, availableCount: 1, { id: 'c4', name: 'Пентхаус', minPrice: 15000, maxGuests: 4, availableCount: 1, photos: [],
amenities: ['Wi-Fi 1Гбит', 'Smart TV 75"', 'Сауна', 'Терраса', 'Дворецкий'], amenities: ['Wi-Fi 1Гбит', 'Smart TV 75"', 'Сауна', 'Терраса', 'Дворецкий'],
description: 'Эксклюзивный пентхаус на верхнем этаже с террасой и видом 360°.' }, description: 'Эксклюзивный пентхаус на верхнем этаже с террасой и видом 360°.' },
] ]
@@ -245,7 +246,7 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, realR
: MOCK_ROOMS : MOCK_ROOMS
// Categories mode // Categories mode
const displayCategories: Array<{ id: string; name: string; minPrice: number; maxGuests: number; amenities: string[]; description: string; availableCount: number }> = const displayCategories: Array<{ id: string; name: string; minPrice: number; maxGuests: number; amenities: string[]; description: string; photos: string[]; availableCount: number }> =
realCategories && realCategories.length > 0 realCategories && realCategories.length > 0
? realCategories.map(c => ({ ? realCategories.map(c => ({
...c, ...c,
@@ -833,10 +834,18 @@ export function WidgetPreview({ settings, slug, realRooms, realCategories, realR
style={isSelected ? { background: settings.primaryColor + '08' } : {}} style={isSelected ? { background: settings.primaryColor + '08' } : {}}
> >
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">
{/* Icon */} {/* Photo or icon */}
{cat.photos?.[0] ? (
<img
src={cat.photos[0]}
alt={cat.name}
className="w-14 h-14 rounded-xl object-cover shrink-0"
/>
) : (
<div className="w-14 h-14 rounded-xl bg-gradient-to-br from-slate-100 to-slate-200 flex items-center justify-center text-2xl shrink-0"> <div className="w-14 h-14 rounded-xl bg-gradient-to-br from-slate-100 to-slate-200 flex items-center justify-center text-2xl shrink-0">
🛏 🛏
</div> </div>
)}
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<p className="font-semibold text-slate-900 text-sm">{cat.name}</p> <p className="font-semibold text-slate-900 text-sm">{cat.name}</p>
<div className="flex items-center gap-2 mt-0.5 flex-wrap"> <div className="flex items-center gap-2 mt-0.5 flex-wrap">
@@ -1205,6 +1214,7 @@ export function BookingWidgetPage() {
// Real data for preview // Real data for preview
const [realRooms, setRealRooms] = useState<WidgetRoom[]>([]) const [realRooms, setRealRooms] = useState<WidgetRoom[]>([])
const [realCategories, setRealCategories] = useState<WidgetCategory[]>([]) const [realCategories, setRealCategories] = useState<WidgetCategory[]>([])
const [realRentalObjects, setRealRentalObjects] = useState<WidgetRentalObject[]>([])
const [gateway, setGateway] = useState<PaymentGateway | null>(null) const [gateway, setGateway] = useState<PaymentGateway | null>(null)
const [gatewayLoading, setGatewayLoading] = useState(false) const [gatewayLoading, setGatewayLoading] = useState(false)
@@ -1219,6 +1229,7 @@ export function BookingWidgetPage() {
const hs = hsRaw as Record<string, unknown> const hs = hsRaw as Record<string, unknown>
if (config?.rooms) setRealRooms(config.rooms) if (config?.rooms) setRealRooms(config.rooms)
if (config?.categories) setRealCategories(config.categories) if (config?.categories) setRealCategories(config.categories)
if (config?.rentalObjects) setRealRentalObjects(config.rentalObjects)
const widgetGw = gws.find(g => g.isActive && g.modules?.includes('booking-widget')) const widgetGw = gws.find(g => g.isActive && g.modules?.includes('booking-widget'))
setGateway(widgetGw ?? null) setGateway(widgetGw ?? null)
// Restore saved widget settings // Restore saved widget settings
@@ -1682,6 +1693,7 @@ export function BookingWidgetPage() {
slug={slug || undefined} slug={slug || undefined}
realRooms={realRooms.length > 0 ? realRooms : undefined} realRooms={realRooms.length > 0 ? realRooms : undefined}
realCategories={realCategories.length > 0 ? realCategories : undefined} realCategories={realCategories.length > 0 ? realCategories : undefined}
realRentalObjects={realRentalObjects.length > 0 ? realRentalObjects : undefined}
paymentEnabled={gateway ? gateway.isActive : undefined} paymentEnabled={gateway ? gateway.isActive : undefined}
/> />
</div> </div>