Merge branch 'develop'

This commit is contained in:
Linus Flood
2024-11-07 10:20:12 +01:00
261 changed files with 5132 additions and 2106 deletions
+3
View File
@@ -85,4 +85,7 @@ fragment AlertRef on Alert {
json
}
}
system {
...System
}
}
@@ -5,6 +5,7 @@
#import "./Refs/Card.graphql"
#import "./Refs/LoyaltyCard.graphql"
#import "./Refs/TeaserCard.graphql"
fragment CardsGrid_ContentPage on ContentPageBlocksCardsGrid {
cards_grid {
layout
@@ -39,6 +40,38 @@ fragment CardsGrid_ContentPageRefs on ContentPageBlocksCardsGrid {
}
}
fragment CardsGrid_CollectionPage on CollectionPageBlocksCardsGrid {
cards_grid {
layout
preamble
theme
title
cardConnection(limit: 10) {
edges {
node {
__typename
...CardBlock
...TeaserCardBlock
}
}
}
}
}
fragment CardsGrid_CollectionPageRefs on CollectionPageBlocksCardsGrid {
cards_grid {
cardConnection(limit: 10) {
edges {
node {
__typename
...CardBlockRef
...TeaserCardBlockRef
}
}
}
}
}
fragment CardsGrid_LoyaltyPage on LoyaltyPageBlocksCardsGrid {
cards_grid {
layout
@@ -1,8 +1,10 @@
#import "../AccountPage/Ref.graphql"
#import "../CollectionPage/Ref.graphql"
#import "../ContentPage/Ref.graphql"
#import "../LoyaltyPage/Ref.graphql"
#import "../PageLink/AccountPageLink.graphql"
#import "../PageLink/CollectionPageLink.graphql"
#import "../PageLink/ContentPageLink.graphql"
#import "../PageLink/LoyaltyPageLink.graphql"
@@ -32,6 +34,12 @@ fragment Shortcuts_AccountPage on AccountPageContentShortcuts {
}
}
fragment Shortcuts_CollectionPage on CollectionPageBlocksShortcuts {
shortcuts {
...Shortcuts
}
}
fragment Shortcuts_ContentPage on ContentPageBlocksShortcuts {
shortcuts {
...Shortcuts
@@ -65,6 +73,12 @@ fragment Shortcuts_AccountPageRefs on AccountPageContentShortcuts {
}
}
fragment Shortcuts_CollectionPageRefs on CollectionPageBlocksShortcuts {
shortcuts {
...ShortcutsRefs
}
}
fragment Shortcuts_ContentPageRefs on ContentPageBlocksShortcuts {
shortcuts {
...ShortcutsRefs
@@ -68,3 +68,64 @@ fragment UspGrid_ContentPageRefs on ContentPageBlocksUspGrid {
}
}
}
fragment UspGrid_CollectionPage on CollectionPageBlocksUspGrid {
__typename
usp_grid {
cardsConnection {
edges {
node {
... on UspGrid {
usp_card {
__typename
icon
text {
embedded_itemsConnection {
totalCount
edges {
node {
__typename
...AccountPageLink
...ContentPageLink
...HotelPageLink
...LoyaltyPageLink
}
}
}
json
}
}
}
}
}
}
}
}
fragment UspGrid_CollectionPageRefs on CollectionPageBlocksUspGrid {
usp_grid {
cardsConnection {
edges {
node {
... on UspGrid {
usp_card {
text {
embedded_itemsConnection {
edges {
node {
__typename
...AccountPageRef
...ContentPageRef
...HotelPageRef
...LoyaltyPageRef
}
}
}
}
}
}
}
}
}
}
}
@@ -0,0 +1,21 @@
#import "../PageLink/CollectionPageLink.graphql"
#import "../PageLink/ContentPageLink.graphql"
#import "../PageLink/HotelPageLink.graphql"
#import "../PageLink/LoyaltyPageLink.graphql"
fragment NavigationLinks on CollectionPageHeader {
navigation_links {
title
linkConnection {
edges {
node {
__typename
...HotelPageLink
...CollectionPageLink
...ContentPageLink
...LoyaltyPageLink
}
}
}
}
}
@@ -0,0 +1,7 @@
#import "../System.graphql"
fragment CollectionPageRef on CollectionPage {
system {
...System
}
}
@@ -0,0 +1,12 @@
#import "../System.graphql"
fragment CollectionPageLink on CollectionPage {
title
url
system {
...System
}
web {
original_url
}
}
@@ -14,6 +14,14 @@ query GetLoyaltyPageSettings($uid: String!, $locale: String!) {
}
}
query GetCollectionPageSettings($uid: String!, $locale: String!) {
collection_page(uid: $uid, locale: $locale) {
page_settings {
hide_booking_widget
}
}
}
query GetContentPageSettings($uid: String!, $locale: String!) {
content_page(uid: $uid, locale: $locale) {
page_settings {
@@ -0,0 +1,28 @@
#import "../../Fragments/Breadcrumbs/Breadcrumbs.graphql"
#import "../../Fragments/System.graphql"
query GetCollectionPageBreadcrumbs($locale: String!, $uid: String!) {
collection_page(locale: $locale, uid: $uid) {
web {
breadcrumbs {
...Breadcrumbs
}
}
system {
...System
}
}
}
query GetCollectionPageBreadcrumbsRefs($locale: String!, $uid: String!) {
collection_page(locale: $locale, uid: $uid) {
web {
breadcrumbs {
...BreadcrumbsRefs
}
}
system {
...System
}
}
}
@@ -0,0 +1,83 @@
#import "../../Fragments/System.graphql"
#import "../../Fragments/Blocks/CardsGrid.graphql"
#import "../../Fragments/Blocks/Shortcuts.graphql"
#import "../../Fragments/Blocks/UspGrid.graphql"
#import "../../Fragments/CollectionPage/NavigationLinks.graphql"
query GetCollectionPage($locale: String!, $uid: String!) {
collection_page(uid: $uid, locale: $locale) {
hero_image
title
header {
heading
preamble
...NavigationLinks
}
blocks {
__typename
...CardsGrid_CollectionPage
...Shortcuts_CollectionPage
...UspGrid_CollectionPage
}
system {
...System
created_at
updated_at
}
}
}
query GetCollectionPageRefs($locale: String!, $uid: String!) {
collection_page(locale: $locale, uid: $uid) {
header {
navigation_links {
linkConnection {
edges {
node {
__typename
...CollectionPageRef
...ContentPageRef
...HotelPageRef
...LoyaltyPageRef
}
}
}
}
}
blocks {
__typename
...CardsGrid_CollectionPageRefs
...Shortcuts_CollectionPageRefs
...UspGrid_CollectionPageRefs
}
system {
...System
}
}
}
query GetDaDeEnUrlsCollectionPage($uid: String!) {
de: collection_page(locale: "de", uid: $uid) {
url
}
en: collection_page(locale: "en", uid: $uid) {
url
}
da: collection_page(locale: "da", uid: $uid) {
url
}
}
query GetFiNoSvUrlsCollectionPage($uid: String!) {
fi: collection_page(locale: "fi", uid: $uid) {
url
}
no: collection_page(locale: "no", uid: $uid) {
url
}
sv: collection_page(locale: "sv", uid: $uid) {
url
}
}
+8
View File
@@ -9,6 +9,14 @@ query ResolveEntryByUrl($locale: String!, $url: String!) {
}
total
}
all_collection_page(where: { url: $url }, locale: $locale) {
items {
system {
...System
}
}
total
}
all_content_page(where: { url: $url }, locale: $locale) {
items {
system {
+47 -36
View File
@@ -1,5 +1,6 @@
import "server-only"
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
import { ClientError, GraphQLClient } from "graphql-request"
import { Lang } from "@/constants/languages"
@@ -16,40 +17,54 @@ export async function request<T>(
params?: RequestInit
): Promise<Data<T>> {
try {
if (params?.cache) {
client.requestConfig.cache = params.cache
}
if (params?.headers) {
client.requestConfig.headers = params.headers
}
if (params?.next) {
client.requestConfig.next = params.next
}
client.setHeaders({
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
})
if (env.PRINT_QUERY) {
const print = (await import("graphql/language/printer")).print
const rawResponse = await client.rawRequest<T>(
print(query as DocumentNode),
variables,
{
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
const previewHash = ContentstackLivePreview.hash
if (previewHash) {
client.setEndpoint(env.CMS_PREVIEW_URL)
client.setHeader("preview_token", env.CMS_PREVIEW_TOKEN)
client.setHeader("live_preview", previewHash)
} else {
if (params?.cache) {
client.requestConfig.cache = params.cache
}
if (params?.headers) {
client.requestConfig.headers = params.headers
}
if (params?.next) {
client.requestConfig.next = params.next
}
if (env.PRINT_QUERY) {
const print = (await import("graphql/language/printer")).print
const rawResponse = await client.rawRequest<T>(
print(query as DocumentNode),
variables,
{
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
}
)
/**
* TODO: Send to Monitoring (Logging and Metrics)
*/
console.log({
complexityLimit: rawResponse.headers.get("x-query-complexity"),
})
console.log({
referenceDepth: rawResponse.headers.get("x-reference-depth"),
})
console.log({
resolverCost: rawResponse.headers.get("x-resolver-cost"),
})
return {
data: rawResponse.data,
}
)
/**
* TODO: Send to Monitoring (Logging and Metrics)
*/
console.log({
complexityLimit: rawResponse.headers.get("x-query-complexity"),
})
console.log({
referenceDepth: rawResponse.headers.get("x-reference-depth"),
})
console.log({ resolverCost: rawResponse.headers.get("x-resolver-cost") })
return {
data: rawResponse.data,
}
}
@@ -78,10 +93,6 @@ export async function request<T>(
const response = await client.request<T>({
document: query,
requestHeaders: {
access_token: env.CMS_ACCESS_TOKEN,
"Content-Type": "application/json",
},
variables,
})
+28 -2
View File
@@ -1,11 +1,31 @@
import "server-only"
import deepmerge from "deepmerge"
import { request } from "./request"
import type { BatchRequestDocument } from "graphql-request"
import type { Data } from "@/types/request"
function arrayMerge(
target: any[],
source: any[],
options: deepmerge.ArrayMergeOptions | undefined
) {
const destination = target.slice()
source.forEach((item, index) => {
if (typeof destination[index] === "undefined") {
destination[index] = options?.cloneUnlessOtherwiseSpecified(item, options)
} else if (options?.isMergeableObject(item)) {
destination[index] = deepmerge(target[index], item, options)
} else if (target.indexOf(item) === -1) {
destination.push(item)
}
})
return destination
}
export async function batchRequest<T>(
queries: (BatchRequestDocument & { options?: RequestInit })[]
): Promise<Data<T>> {
@@ -17,15 +37,21 @@ export async function batchRequest<T>(
)
let data = {} as T
const reasons = []
const reasons: PromiseRejectedResult["reason"][] = []
response.forEach((res) => {
if (res.status === "fulfilled") {
data = Object.assign({}, data, res.value.data)
data = deepmerge(data, res.value.data, { arrayMerge })
} else {
reasons.push(res.reason)
}
})
if (reasons.length) {
reasons.forEach((reason) => {
console.error(`Batch request failed`, reason)
})
}
return { data }
} catch (error) {
console.error("Error in batched graphql request")
+1 -1
View File
@@ -1,6 +1,6 @@
import "server-only"
import ContentstackLivePreview from "@contentstack/live-preview-utils"
import { ContentstackLivePreview } from "@contentstack/live-preview-utils"
import { request as graphqlRequest } from "graphql-request"
import { env } from "@/env/server"
+32 -16
View File
@@ -1,9 +1,15 @@
import { cache } from "react"
import { Lang } from "@/constants/languages"
import {
GetRoomsAvailabilityInput,
GetSelectedRoomAvailabilityInput,
} from "@/server/routers/hotels/input"
import { serverClient } from "../server"
import type { BreackfastPackagesInput } from "@/types/requests/packages"
export const getLocations = cache(async function getMemoizedLocations() {
return serverClient().hotel.locations.get()
})
@@ -50,11 +56,15 @@ export const getUserTracking = cache(async function getMemoizedUserTracking() {
return serverClient().user.tracking()
})
export const getHotelData = cache(async function getMemoizedHotelData(
hotelId: string,
language: string,
export const getHotelData = cache(async function getMemoizedHotelData({
hotelId,
language,
isCardOnlyPayment,
}: {
hotelId: string
language: string
isCardOnlyPayment?: boolean
) {
}) {
return serverClient().hotel.hotelData.get({
hotelId,
language,
@@ -71,17 +81,9 @@ export const getRoomAvailability = cache(
children,
promotionCode,
rateCode,
}: {
hotelId: string
adults: number
roomStayStartDate: string
roomStayEndDate: string
children?: string
promotionCode?: string
rateCode?: string
}) {
}: GetRoomsAvailabilityInput) {
return serverClient().hotel.availability.rooms({
hotelId: parseInt(hotelId),
hotelId,
adults,
roomStayStartDate,
roomStayEndDate,
@@ -92,6 +94,14 @@ export const getRoomAvailability = cache(
}
)
export const getSelectedRoomAvailability = cache(
async function getMemoizedRoomAvailability(
args: GetSelectedRoomAvailabilityInput
) {
return serverClient().hotel.availability.room(args)
}
)
export const getFooter = cache(async function getMemoizedFooter() {
return serverClient().contentstack.base.footer()
})
@@ -106,6 +116,12 @@ export const getCurrentHeader = cache(async function getMemoizedCurrentHeader(
return serverClient().contentstack.base.currentHeader({ lang })
})
export const getCurrentFooter = cache(async function getMemoizedCurrentFooter(
lang: Lang
) {
return serverClient().contentstack.base.currentFooter({ lang })
})
export const getMyPagesNavigation = cache(
async function getMemoizedMyPagesNavigation() {
return serverClient().contentstack.myPages.navigation.get()
@@ -123,7 +139,7 @@ export const getSiteConfig = cache(async function getMemoizedSiteConfig() {
})
export const getBreakfastPackages = cache(async function getMemoizedPackages(
hotelId: string
input: BreackfastPackagesInput
) {
return serverClient().hotel.packages.breakfast({ hotelId })
return serverClient().hotel.packages.breakfast(input)
})