Files
web/apps/scandic-web/utils/jsonSchemas.ts
Anton Gunnarsson 002d093af4 Merged in feat/sw-2863-move-contentstack-router-to-trpc-package (pull request #2389)
feat(SW-2863): Move contentstack router to trpc package

* Add exports to packages and lint rule to prevent relative imports

* Add env to trpc package

* Add eslint to trpc package

* Apply lint rules

* Use direct imports from trpc package

* Add lint-staged config to trpc

* Move lang enum to common

* Restructure trpc package folder structure

* WIP first step

* update internal imports in trpc

* Fix most errors in scandic-web

Just 100 left...

* Move Props type out of trpc

* Fix CategorizedFilters types

* Move more schemas in hotel router

* Fix deps

* fix getNonContentstackUrls

* Fix import error

* Fix entry error handling

* Fix generateMetadata metrics

* Fix alertType enum

* Fix duplicated types

* lint:fix

* Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package

* Fix broken imports

* Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package


Approved-by: Linus Flood
2025-06-26 07:53:01 +00:00

83 lines
2.2 KiB
TypeScript

import { env } from "@/env/server"
import type {
BreadcrumbList,
Hotel as HotelSchema,
ListItem,
WithContext,
} from "schema-dts"
import type { HotelData } from "@scandic-hotels/trpc/types/hotel"
import type { Breadcrumbs } from "@scandic-hotels/trpc/types/breadcrumbs"
export function generateBreadcrumbsSchema(breadcrumbs: Breadcrumbs) {
const itemListElement: ListItem[] = breadcrumbs.map((item, index) => ({
"@type": "ListItem",
position: index + 1,
name: item.title,
// Only include "item" if "href" exists; otherwise, omit it
...(item.href ? { item: `${env.PUBLIC_URL}${item.href}` } : {}),
}))
const jsonLd: WithContext<BreadcrumbList> = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement,
}
return {
key: "breadcrumbs",
type: "application/ld+json",
jsonLd,
}
}
export function generateHotelSchema(hotelData: HotelData) {
const { hotel, additionalData } = hotelData
const ratings = hotel.ratings?.tripAdvisor
const checkinData = hotel.hotelFacts.checkin
const image =
additionalData.gallery?.heroImages[0] ||
additionalData.gallery?.smallerImages[0]
const facilities = hotel.detailedFacilities
const jsonLd: WithContext<HotelSchema> = {
"@context": "https://schema.org",
"@type": "Hotel",
name: hotel.name,
address: {
"@type": "PostalAddress",
streetAddress: hotel.address.streetAddress,
addressLocality: hotel.address.city,
postalCode: hotel.address.zipCode,
addressCountry: hotel.address.country,
},
checkinTime: checkinData.checkInTime,
checkoutTime: checkinData.checkOutTime,
amenityFeature: facilities.map((facility) => ({
"@type": "LocationFeatureSpecification",
name: facility.name,
})),
}
if (image) {
jsonLd.image = {
"@type": "ImageObject",
url: image.imageSizes.small,
caption: image.metaData.title,
}
}
if (ratings && ratings.rating && ratings.numberOfReviews) {
jsonLd.aggregateRating = {
"@type": "AggregateRating",
ratingValue: ratings.rating,
reviewCount: ratings.numberOfReviews,
}
}
return {
type: "application/ld+json",
jsonLd,
}
}