Merge master
This commit is contained in:
22
utils/cache.ts
Normal file
22
utils/cache.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import stringify from "json-stable-stringify-without-jsonify"
|
||||
import { cache as reactCache } from "react"
|
||||
|
||||
/**
|
||||
* Wrapper function to handle caching of memoized requests that recieve objects as args.
|
||||
* React Cache will use shallow equality of the arguments to determine if there is a cache hit,
|
||||
* therefore we need to stringify the arguments to ensure that the cache works as expected.
|
||||
* This function will handle the stingification of the arguments, the caching of the function,
|
||||
* and the parsing of the arguments back to their original form.
|
||||
*
|
||||
* @param fn - The function to memoize
|
||||
*/
|
||||
export function cache<T extends (...args: any[]) => any>(fn: T) {
|
||||
const cachedFunction = reactCache((stringifiedParams: string) => {
|
||||
return fn(...JSON.parse(stringifiedParams))
|
||||
})
|
||||
|
||||
return (...args: Parameters<T>): ReturnType<T> => {
|
||||
const stringifiedParams = stringify(args)
|
||||
return cachedFunction(stringifiedParams)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import type { BreadcrumbList, ListItem, WithContext } from "schema-dts"
|
||||
import type {
|
||||
BreadcrumbList,
|
||||
Hotel as HotelSchema,
|
||||
ListItem,
|
||||
WithContext,
|
||||
} from "schema-dts"
|
||||
|
||||
import type { Hotel } from "@/types/hotel"
|
||||
import type { Breadcrumbs } from "@/types/trpc/routers/contentstack/breadcrumbs"
|
||||
|
||||
export function generateBreadcrumbsSchema(breadcrumbs: Breadcrumbs) {
|
||||
@@ -25,3 +31,49 @@ export function generateBreadcrumbsSchema(breadcrumbs: Breadcrumbs) {
|
||||
jsonLd,
|
||||
}
|
||||
}
|
||||
|
||||
export function generateHotelSchema(hotel: Hotel) {
|
||||
const ratings = hotel.ratings?.tripAdvisor
|
||||
const checkinData = hotel.hotelFacts.checkin
|
||||
const image = hotel.gallery?.heroImages[0] || hotel.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,
|
||||
}
|
||||
}
|
||||
|
||||
8
utils/numberFormatting.ts
Normal file
8
utils/numberFormatting.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Function to parse number with single decimal if any
|
||||
* @param n
|
||||
* @returns number in float type with single digit decimal if any
|
||||
*/
|
||||
export default function getSingleDecimal(n: Number | string) {
|
||||
return parseFloat(Number(n).toFixed(1))
|
||||
}
|
||||
Reference in New Issue
Block a user