Treat invalid calendar URLs as missing availability

This commit is contained in:
Tero Halla-aho 2025-12-07 00:29:38 +02:00
parent 53bd324fa6
commit 1fa0b4d300
2 changed files with 40 additions and 10 deletions

View file

@ -138,6 +138,15 @@ export async function GET(req: Request) {
);
const translation = pickTranslation(listing.translations, locale);
const fallback = listing.translations[0];
const validCalendarUrls = (listing.calendarUrls ?? []).filter((url) => {
if (!url) return false;
try {
const parsed = new URL(url);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch {
return false;
}
});
return {
id: listing.id,
title: translation?.title ?? fallback?.title ?? 'Listing',
@ -173,7 +182,7 @@ export async function GET(req: Request) {
priceWeekendEuros: listing.priceWeekendEuros,
coverImage: resolveImageUrl(listing.images.find((img) => img.isCover) ?? listing.images[0] ?? { id: '', url: null, size: null }),
isSample,
hasCalendar: Boolean(listing.calendarUrls?.length),
hasCalendar: Boolean(validCalendarUrls.length),
availableForDates: availabilityFilterActive ? Boolean(availabilityMap.get(listing.id)) : undefined,
};
});

View file

@ -52,7 +52,15 @@ export default async function ListingPage({ params }: ListingPageProps) {
const { listing, title, description, teaser, locale: translationLocale } = translation;
const isSample = listing.isSample || listing.contactEmail === 'host@lomavuokraus.fi' || SAMPLE_LISTING_SLUGS.includes(params.slug);
const calendarUrls = listing.calendarUrls ?? [];
const calendarUrls = (listing.calendarUrls ?? []).filter((url) => {
if (!url) return false;
try {
const parsed = new URL(url);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch {
return false;
}
});
const hasCalendar = calendarUrls.length > 0;
const availabilityFrom = new Date();
availabilityFrom.setUTCHours(0, 0, 0, 0);
@ -143,14 +151,27 @@ export default async function ListingPage({ params }: ListingPageProps) {
)}
</div>
<div className="panel" style={{ padding: 12 }}>
{hasCalendar ? (
<AvailabilityCalendar blockedDates={blockedDates} months={1} disabled={!listing.calendarUrls?.length} />
) : (
<div style={{ display: 'grid', gap: 8 }}>
<div style={{ fontWeight: 700 }}>{t('availabilityTitle')}</div>
<p style={{ color: '#cbd5e1', margin: 0 }}>{t('availabilityMissing')}</p>
</div>
)}
<div style={{ position: 'relative' }}>
<AvailabilityCalendar blockedDates={blockedDates} months={1} disabled={!hasCalendar} />
{!hasCalendar ? (
<div
style={{
position: 'absolute',
inset: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#cbd5e1',
fontWeight: 600,
textAlign: 'center',
background: 'linear-gradient(135deg, rgba(15,23,42,0.55), rgba(15,23,42,0.65))',
borderRadius: 12,
}}
>
{t('availabilityMissing')}
</div>
) : null}
</div>
</div>
</div>
)}