refactor(SW-302): update typings

This commit is contained in:
Matilda Landström
2024-10-07 13:47:23 +02:00
parent 0fa8251cd3
commit cdb51bae73
9 changed files with 186 additions and 125 deletions

View File

@@ -0,0 +1,49 @@
import { activities } from "@/constants/routes/hotelPageParams"
import Card from "@/components/TempDesignSystem/Card"
import CardImage from "@/components/TempDesignSystem/Card/CardImage"
import Grids from "@/components/TempDesignSystem/Grids"
import { getLang } from "@/i18n/serverContext"
import styles from "./cardGrid.module.css"
import type { ActivityCard } from "@/types/trpc/routers/contentstack/hotelPage"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export default function ActivitiesCardGrid(activitiesCard: ActivityCard) {
const lang = getLang()
const hasImage = activitiesCard.background_image
const updatedCard: CardProps = {
id: activities[lang],
theme: hasImage ? "image" : "primaryDark",
scriptedTopTitle: activitiesCard.scripted_title,
heading: activitiesCard.heading,
bodyText: activitiesCard.body_text,
backgroundImage: hasImage ? activitiesCard.background_image : undefined,
primaryButton: hasImage
? {
href: activitiesCard.contentPage.href,
title: activitiesCard.cta_text,
isExternal: false,
}
: undefined,
secondaryButton: hasImage
? undefined
: {
href: activitiesCard.contentPage.href,
title: activitiesCard.cta_text,
isExternal: false,
},
}
return (
<section id={updatedCard.id}>
<Grids.Stackable className={styles.desktopGrid}>
<Card {...updatedCard} className={styles.spanThree} />
</Grids.Stackable>
<Grids.Stackable className={styles.mobileGrid}>
<CardImage card={updatedCard} />
</Grids.Stackable>
</section>
)
}

View File

@@ -10,23 +10,23 @@
grid-column: span 3; grid-column: span 3;
} }
.desktopGrid { section .desktopGrid {
display: none !important; display: none;
} }
.mobileGrid { section .mobileGrid {
display: grid !important; display: grid;
gap: var(--Spacing-x-quarter); gap: var(--Spacing-x-quarter);
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
.desktopGrid { section .desktopGrid {
display: grid !important; display: grid;
gap: var(--Spacing-x1); gap: var(--Spacing-x1);
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
} }
.mobileGrid { section .mobileGrid {
display: none !important; display: none;
} }
} }

View File

@@ -1,39 +1,39 @@
import Card from "@/components/TempDesignSystem/Card" import Card from "@/components/TempDesignSystem/Card"
import CardImage from "@/components/TempDesignSystem/Card/CardImage" import CardImage from "@/components/TempDesignSystem/Card/CardImage"
import Grids from "@/components/TempDesignSystem/Grids" import Grids from "@/components/TempDesignSystem/Grids"
import { isFacilityCard } from "@/utils/facilityCards"
import { sortCards } from "@/utils/imageCard" import { sortCards } from "@/utils/imageCard"
import styles from "./cardGrid.module.css" import styles from "./cardGrid.module.css"
import type { CardGridProps } from "@/types/components/hotelPage/facilities" import type {
import type { CardProps } from "@/components/TempDesignSystem/Card/card" CardGridProps,
FacilityCardType,
} from "@/types/components/hotelPage/facilities"
export default function CardGrid({ facilityCardGid }: CardGridProps) { export default function FacilitiesCardGrid({
const imageCard = sortCards(facilityCardGid) facilitiesCardGrid,
const nrCards = facilityCardGid.length }: CardGridProps) {
const imageCard = sortCards(facilitiesCardGrid)
const nrCards = facilitiesCardGrid.length
function getCardClassName(card: CardProps): string { function getCardClassName(card: FacilityCardType): string {
if (nrCards === 1) { if (nrCards === 1) {
return styles.spanThree return styles.spanThree
} else if (nrCards === 2 && card.backgroundImage) { } else if (nrCards === 2 && !isFacilityCard(card)) {
return styles.spanTwo return styles.spanTwo
} }
return styles.spanOne return styles.spanOne
} }
return ( return (
<section id={imageCard.card?.id}> <section id={imageCard.card.id}>
<Grids.Stackable className={styles.desktopGrid}> <Grids.Stackable className={styles.desktopGrid}>
{facilityCardGid.map((card: CardProps) => ( {facilitiesCardGrid.map((card: FacilityCardType) => (
<Card <Card
theme={card.theme || "primaryDark"} {...card}
theme={card.theme}
key={card.id} key={card.id}
scriptedTopTitle={card.scriptedTopTitle}
heading={card.heading}
bodyText={card.bodyText}
secondaryButton={card.secondaryButton}
primaryButton={card.primaryButton}
backgroundImage={card.backgroundImage}
className={getCardClassName(card)} className={getCardClassName(card)}
/> />
))} ))}

View File

@@ -1,16 +1,17 @@
import SectionContainer from "@/components/Section/Container" import SectionContainer from "@/components/Section/Container"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import { setActivityCard, setFacilityCardGrids } from "@/utils/facilityCards" import { isFacilityCard, setFacilityCardGrids } from "@/utils/facilityCards"
import CardGrid from "./CardGrid" import ActivitiesCardGrid from "./CardGrid/ActivitiesCardGrid"
import FacilitiesCardGrid from "./CardGrid"
import styles from "./facilities.module.css" import styles from "./facilities.module.css"
import type { import type {
FacilitiesProps, FacilitiesProps,
FacilityCards, FacilityCardType,
FacilityGrid,
} from "@/types/components/hotelPage/facilities" } from "@/types/components/hotelPage/facilities"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export default async function Facilities({ export default async function Facilities({
facilities, facilities,
@@ -19,31 +20,27 @@ export default async function Facilities({
const intl = await getIntl() const intl = await getIntl()
const facilityCardGrids = setFacilityCardGrids(facilities) const facilityCardGrids = setFacilityCardGrids(facilities)
const updatedActivitiesCard =
activitiesCard && setActivityCard(activitiesCard)
facilityCardGrids.map((cardGrid: FacilityCards) => { facilityCardGrids.map((cardGrid: FacilityGrid) => {
cardGrid.map((card: CardProps) => { cardGrid.map((card: FacilityCardType) => {
card.heading = card.heading && intl.formatMessage({ id: card.heading }) if (isFacilityCard(card)) {
card.secondaryButton card.heading = intl.formatMessage({ id: card.heading })
? (card.secondaryButton.title = intl.formatMessage({ card.secondaryButton.title = intl.formatMessage({
id: card.secondaryButton.title, id: card.secondaryButton.title,
})) })
: null }
}) })
}) })
return ( return (
<SectionContainer className={styles.grid}> <SectionContainer className={styles.grid}>
{facilityCardGrids.map((cardGrid: FacilityCards) => ( {facilityCardGrids.map((cardGrid: FacilityGrid) => (
<CardGrid key={cardGrid[0].id} facilityCardGid={cardGrid} /> <FacilitiesCardGrid
))} key={cardGrid[0].id}
{updatedActivitiesCard && ( facilitiesCardGrid={cardGrid}
<CardGrid
key={updatedActivitiesCard.id}
facilityCardGid={[updatedActivitiesCard]}
/> />
)} ))}
{activitiesCard && <ActivitiesCardGrid {...activitiesCard} />}
</SectionContainer> </SectionContainer>
) )
} }

View File

@@ -14,7 +14,7 @@ export default function CardImage({
return ( return (
<article className={`${styles.container} ${className}`}> <article className={`${styles.container} ${className}`}>
<div className={styles.imageContainer}> <div className={styles.imageContainer}>
{imageCards.map( {imageCards?.map(
({ backgroundImage }) => ({ backgroundImage }) =>
backgroundImage && ( backgroundImage && (
<Image <Image

View File

@@ -1,6 +1,8 @@
import { FacilityCard, FacilityImage } from "./hotelPage/facilities"
import type { CardProps } from "@/components/TempDesignSystem/Card/card" import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export interface CardImageProps extends React.HTMLAttributes<HTMLDivElement> { export interface CardImageProps extends React.HTMLAttributes<HTMLDivElement> {
card?: CardProps card: FacilityCard | CardProps
imageCards: Pick<CardProps, "backgroundImage">[] imageCards?: FacilityImage[]
} }

View File

@@ -2,17 +2,36 @@ import type { Facility } from "@/types/hotel"
import type { ActivityCard } from "@/types/trpc/routers/contentstack/hotelPage" import type { ActivityCard } from "@/types/trpc/routers/contentstack/hotelPage"
import type { CardProps } from "@/components/TempDesignSystem/Card/card" import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export type FacilityCards = CardProps[]
export type Facilities = FacilityCards[]
export type FacilitiesProps = { export type FacilitiesProps = {
facilities: Facility[] facilities: Facility[]
activitiesCard?: ActivityCard activitiesCard?: ActivityCard
} }
export type FacilityImage = {
backgroundImage: CardProps["backgroundImage"]
theme: CardProps["theme"]
id: string
}
export type FacilityCard = {
secondaryButton: {
href: string
title: string
openInNewTab?: boolean
isExternal: boolean
}
heading: string
scriptedTopTitle: string
theme: CardProps["theme"]
id: string
}
export type FacilityCardType = FacilityImage | FacilityCard
export type FacilityGrid = FacilityCardType[]
export type Facilities = FacilityGrid[]
export type CardGridProps = { export type CardGridProps = {
facilityCardGid: FacilityCards facilitiesCardGrid: FacilityGrid
} }
export enum FacilityEnum { export enum FacilityEnum {

View File

@@ -1,5 +1,4 @@
import { import {
activities,
meetingsAndConferences, meetingsAndConferences,
restaurantAndBar, restaurantAndBar,
wellnessAndExercise, wellnessAndExercise,
@@ -9,60 +8,43 @@ import { getLang } from "@/i18n/serverContext"
import { import {
type Facilities, type Facilities,
type FacilityCard,
type FacilityCardType,
FacilityEnum, FacilityEnum,
type FacilityGrid,
FacilityIds, FacilityIds,
type FacilityImage,
RestaurantHeadings, RestaurantHeadings,
} from "@/types/components/hotelPage/facilities" } from "@/types/components/hotelPage/facilities"
import type { Amenities, Facility } from "@/types/hotel" import type { Amenities, Facility } from "@/types/hotel"
import { ActivityCard } from "@/types/trpc/routers/contentstack/hotelPage"
import type { CardProps } from "@/components/TempDesignSystem/Card/card" import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export function setActivityCard(activitiesCard: ActivityCard): CardProps { export function isFacilityCard(card: FacilityCardType): card is FacilityCard {
const lang = getLang() return (card as FacilityCard).heading != undefined
const hasImage = activitiesCard.background_image }
const updatedCard: CardProps = { export function isFacilityImage(card: FacilityCardType): card is FacilityCard {
id: activities[lang], return (card as FacilityImage).backgroundImage != undefined
theme: hasImage ? "image" : "primaryDark",
scriptedTopTitle: activitiesCard.scripted_title,
heading: activitiesCard.heading,
bodyText: activitiesCard.body_text,
backgroundImage: hasImage ? activitiesCard.background_image : undefined,
primaryButton: hasImage
? {
href: activitiesCard.contentPage.href,
title: activitiesCard.cta_text,
isExternal: false,
}
: undefined,
secondaryButton: hasImage
? undefined
: {
href: activitiesCard.contentPage.href,
title: activitiesCard.cta_text,
isExternal: false,
},
}
return updatedCard
} }
function setCardProps( function setCardProps(
theme: CardProps["theme"], theme: CardProps["theme"],
heading: string, heading: string,
buttonText: string, buttonText: string,
href: string href: string,
) { scriptedTopTitle: string
const card: CardProps = {} ): FacilityCard {
return {
card.theme = theme theme: theme,
card.id = href id: href,
card.heading = heading heading: heading,
card.secondaryButton = { scriptedTopTitle: scriptedTopTitle,
href: `?s=${href}`, secondaryButton: {
title: buttonText, href: `?s=${href}`,
isExternal: false, title: buttonText,
isExternal: false,
},
} }
return card
} }
export function setFacilityCardGrids(facilities: Facility[]): Facilities { export function setFacilityCardGrids(facilities: Facility[]): Facilities {
@@ -70,23 +52,24 @@ export function setFacilityCardGrids(facilities: Facility[]): Facilities {
const cards: Facilities = [] const cards: Facilities = []
facilities.forEach(async (facility) => { facilities.forEach(async (facility) => {
const grid: Array<CardProps> = [] const grid: FacilityGrid = []
let card: CardProps = {} let card: FacilityCard
facility.heroImages.slice(0, 2).forEach((image) => { facility.heroImages.slice(0, 2).forEach((image) => {
// Can be a maximum 2 images per grid // Can be a maximum 2 images per grid
const img: CardProps = {} const img: FacilityImage = {
img.id = image.imageSizes.large backgroundImage: {
;(img.backgroundImage = { url: image.imageSizes.large,
url: image.imageSizes.large, title: image.metaData.title,
title: image.metaData.title, meta: {
meta: { alt: image.metaData.altText,
alt: image.metaData.altText, caption: image.metaData.altText_En,
caption: image.metaData.altText_En, },
id: image.imageSizes.large,
}, },
theme: "image",
id: image.imageSizes.large, id: image.imageSizes.large,
}), }
(img.theme = "image")
grid.push(img) grid.push(img)
}) })
@@ -96,9 +79,9 @@ export function setFacilityCardGrids(facilities: Facility[]): Facilities {
"one", "one",
"Sauna and gym", "Sauna and gym",
"Read more about wellness & exercise", "Read more about wellness & exercise",
wellnessAndExercise[lang] wellnessAndExercise[lang],
facility.headingText
) )
card.scriptedTopTitle = facility.headingText
grid.unshift(card) grid.unshift(card)
break break
@@ -107,9 +90,9 @@ export function setFacilityCardGrids(facilities: Facility[]): Facilities {
"primaryDim", "primaryDim",
"Events that make an impression", "Events that make an impression",
"About meetings & conferences", "About meetings & conferences",
meetingsAndConferences[lang] meetingsAndConferences[lang],
facility.headingText
) )
card.scriptedTopTitle = facility.headingText
grid.push(card) grid.push(card)
break break
@@ -119,9 +102,9 @@ export function setFacilityCardGrids(facilities: Facility[]): Facilities {
"primaryDark", "primaryDark",
"Enjoy relaxed restaurant experiences", "Enjoy relaxed restaurant experiences",
"Read more & book a table", "Read more & book a table",
restaurantAndBar[lang] restaurantAndBar[lang],
facility.headingText
) )
card.scriptedTopTitle = facility.headingText
grid.unshift(card) grid.unshift(card)
break break
} }

View File

@@ -1,16 +1,27 @@
import type { FacilityCards } from "@/types/components/hotelPage/facilities" import { isFacilityImage } from "./facilityCards"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export function sortCards(cards: FacilityCards) { import type {
const sortedCards = cards.slice(0).sort((a: CardProps, b: CardProps) => { FacilityCard,
if (!a.backgroundImage && b.backgroundImage) { FacilityCardType,
return 1 FacilityGrid,
} FacilityImage,
if (a.backgroundImage && !b.backgroundImage) { } from "@/types/components/hotelPage/facilities"
return -1
}
return 0
})
return { card: sortedCards.pop(), images: sortedCards } export function sortCards(cards: FacilityGrid) {
const sortedCards = cards
.slice(0)
.sort((a: FacilityCardType, b: FacilityCardType) => {
if (!isFacilityImage(a) && isFacilityImage(b)) {
return 1
}
if (isFacilityImage(a) && !isFacilityImage(b)) {
return -1
}
return 0
})
return {
card: sortedCards.pop() as FacilityCard,
images: sortedCards as FacilityImage[],
}
} }