feat(SW-285): ship support for dynamic content

This commit is contained in:
Chuma McPhoy
2024-09-02 20:01:48 +02:00
parent e88e4d92bf
commit 1c2a34591b
35 changed files with 5125 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
{
"levels": [
{
"level": 1,
"name": "New Friend",
"requiredPoints": 0,
"requiredNights": 0,
"benefits": [
{
"title": "Prisvenlige værelser"
},
{
"title": "10% weekendrabat på mad"
},
{
"title": "Gratis mocktail til børn under opholdet"
}
]
},
{
"level": 2,
"name": "Good Friend",
"requiredPoints": 5000,
"requiredNights": 0,
"benefits": [
{
"title": "15% weekendrabat på mad"
}
]
},
{
"level": 3,
"name": "Close Friend",
"requiredPoints": 10000,
"requiredNights": 0,
"benefits": [
{
"title": "Sen check ud 1 time, når tilgængeligt"
},
{
"title": "Voucher på DKK 50,-"
}
]
},
{
"level": 4,
"name": "Dear Friend",
"requiredPoints": 25000,
"requiredNights": 0,
"benefits": [
{
"title": "25% optjeningsrate"
},
{
"title": "Tidlig check ind, når tilgængeligt"
},
{
"title": "Voucher på DKK 75,-"
}
]
},
{
"level": 5,
"name": "Loyal Friend",
"requiredPoints": 100000,
"requiredNights": 0,
"benefits": [
{
"title": "Gratis opgraderinger, når tilgængelige"
},
{
"title": "Voucher på DKK 100,-"
},
{
"title": "2-for-1 morgenmad"
}
]
},
{
"level": 6,
"name": "True Friend",
"requiredPoints": 250000,
"requiredNights": 0,
"benefits": [
{
"title": "50% optjeningsrate"
},
{
"title": "Voucher på DKK 150,-"
},
{
"title": "48-timers værelsesgaranti"
},
{
"title": "Altid gratis morgenmad"
}
]
},
{
"level": 7,
"name": "Best Friend",
"requiredPoints": 400000,
"requiredNights": 100,
"benefits": [
{
"title": "Voucher på DKK 200,-"
},
{
"title": "Årlig eksklusiv gave"
},
{
"title": "Børneboost"
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"levels": [
{
"level": 1,
"name": "New Friend",
"requiredPoints": 0,
"requiredNights": 0,
"benefits": [
{
"title": "Freundschaftspreise für Hotelzimmer"
},
{
"title": "10 % Rabatt auf Speisen an den Wochenenden"
},
{
"title": "Kostenloser Kinder-Mocktail während des Aufenthalts"
}
]
},
{
"level": 2,
"name": "Good Friend",
"requiredPoints": 5000,
"requiredNights": 0,
"benefits": [
{
"title": "15 % Rabatt auf Speisen an den Wochenenden"
}
]
},
{
"level": 3,
"name": "Close Friend",
"requiredPoints": 10000,
"requiredNights": 0,
"benefits": [
{
"title": "Später Check-Out 1 Stunde, wenn verfügbar"
},
{
"title": "Gutschein über 5 EUR"
}
]
},
{
"level": 4,
"name": "Dear Friend",
"requiredPoints": 25000,
"requiredNights": 0,
"benefits": [
{
"title": "25 % mehr Punkte"
},
{
"title": "Früher Check-In 1 Stunde, wenn verfügbar"
},
{
"title": "Gutschein über 7,50 EUR"
}
]
},
{
"level": 5,
"name": "Loyal Friend",
"requiredPoints": 100000,
"requiredNights": 0,
"benefits": [
{
"title": "Kostenloses Zimmer-Upgrade, wenn verfügbar"
},
{
"title": "Gutschein über 10 EUR"
},
{
"title": "Frühstück für Zwei zum Preis von einem"
}
]
},
{
"level": 6,
"name": "True Friend",
"requiredPoints": 250000,
"requiredNights": 0,
"benefits": [
{
"title": "50 % mehr Punkte"
},
{
"title": "Gutschein über 15 EUR"
},
{
"title": "48-Stunden-Zimmergarantie"
},
{
"title": "Jederzeit ein kostenloses Frühstück"
}
]
},
{
"level": 7,
"name": "Best Friend",
"requiredPoints": 400000,
"requiredNights": 100,
"benefits": [
{
"title": "Gutschein über 20 EUR"
},
{
"title": "Ein exklusives Geschenk pro Jahr"
},
{
"title": "Ein Geschenk für Kinder"
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"levels": [
{
"level": 1,
"name": "New Friend",
"requiredPoints": 0,
"requiredNights": 0,
"benefits": [
{
"title": "Friendly room rates"
},
{
"title": "10% off on food on weekends"
},
{
"title": "Free kids mocktail during stay"
}
]
},
{
"level": 2,
"name": "Good Friend",
"requiredPoints": 5000,
"requiredNights": 0,
"benefits": [
{
"title": "15% on food on weekends"
}
]
},
{
"level": 3,
"name": "Close Friend",
"requiredPoints": 10000,
"requiredNights": 0,
"benefits": [
{
"title": "Late checkout - 1 hour when available"
},
{
"title": "5 EUR voucher"
}
]
},
{
"level": 4,
"name": "Dear Friend",
"requiredPoints": 25000,
"requiredNights": 0,
"benefits": [
{
"title": "25% earn rate"
},
{
"title": "Early check-in - 1 hour when available"
},
{
"title": "7.50 EUR voucher"
}
]
},
{
"level": 5,
"name": "Loyal Friend",
"requiredPoints": 100000,
"requiredNights": 0,
"benefits": [
{
"title": "Free room upgrade when available"
},
{
"title": "10 EUR voucher"
},
{
"title": "2-for-1 breakfast"
}
]
},
{
"level": 6,
"name": "True Friend",
"requiredPoints": 250000,
"requiredNights": 0,
"benefits": [
{
"title": "50% earn rate"
},
{
"title": "15 EUR voucher"
},
{
"title": "48h room guarantee"
},
{
"title": "Always free breakfast"
}
]
},
{
"level": 7,
"name": "Best Friend",
"requiredPoints": 400000,
"requiredNights": 100,
"benefits": [
{
"title": "20 EUR voucher"
},
{
"title": "Yearly exclusive gift"
},
{
"title": "Kid's boost"
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"levels": [
{
"level": 1,
"name": "New Friend",
"requiredPoints": 0,
"requiredNights": 0,
"benefits": [
{
"title": "Ystävälliset huonehinnat"
},
{
"title": "10 % alennusta ruoasta viikonloppuisin"
},
{
"title": "Maksuton lasten mocktail majoituksen aikana"
}
]
},
{
"level": 2,
"name": "Good Friend",
"requiredPoints": 5000,
"requiredNights": 0,
"benefits": [
{
"title": "15 % alennusta ruoasta viikonloppuisin"
}
]
},
{
"level": 3,
"name": "Close Friend",
"requiredPoints": 10000,
"requiredNights": 0,
"benefits": [
{
"title": "Myöhäinen uloskirjautuminen 1 tunti lisäaikaa varaustilanteen mukaan"
},
{
"title": "Ravintolakuponki (arvo 5 €)"
}
]
},
{
"level": 4,
"name": "Dear Friend",
"requiredPoints": 25000,
"requiredNights": 0,
"benefits": [
{
"title": "Ansaintakerroin +25 %"
},
{
"title": "Aikainen sisäänkirjautuminen 1 tunti lisäaikaa varaustilanteen mukaan"
},
{
"title": "Ravintolakuponki (arvo 7,50 €)"
}
]
},
{
"level": 5,
"name": "Loyal Friend",
"requiredPoints": 100000,
"requiredNights": 0,
"benefits": [
{
"title": "Maksuton huoneluokan korotus varaustilanteen mukaan"
},
{
"title": "Ravintolakuponki (arvo 10 €)"
},
{
"title": "Aamiainen kaksi yhden hinnalla"
}
]
},
{
"level": 6,
"name": "True Friend",
"requiredPoints": 250000,
"requiredNights": 0,
"benefits": [
{
"title": "Ansaintakerroin +50 %"
},
{
"title": "Ravintolakuponki (arvo 15 €)"
},
{
"title": "48 tunnin huonetakuu"
},
{
"title": "Aamiainen aina maksutta"
}
]
},
{
"level": 7,
"name": "Best Friend",
"requiredPoints": 400000,
"requiredNights": 100,
"benefits": [
{
"title": "Ravintolakuponki (arvo 20 €)"
},
{
"title": "Henkilökohtainen lahja vuosittain"
},
{
"title": "Tervetuliaislahja lapselle"
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"levels": [
{
"level": 1,
"name": "New Friend",
"requiredPoints": 0,
"requiredNights": 0,
"benefits": [
{
"title": "Vennlige rompriser"
},
{
"title": "10 % rabatt på mat i helger"
},
{
"title": "Gratis barne-mocktail under oppholdet"
}
]
},
{
"level": 2,
"name": "Good Friend",
"requiredPoints": 5000,
"requiredNights": 0,
"benefits": [
{
"title": "15 % rabatt på mat i helger"
}
]
},
{
"level": 3,
"name": "Close Friend",
"requiredPoints": 10000,
"requiredNights": 0,
"benefits": [
{
"title": "Sen utsjekking 1 time når tilgjengelig"
},
{
"title": "Kupong på 50 NOK"
}
]
},
{
"level": 4,
"name": "Dear Friend",
"requiredPoints": 25000,
"requiredNights": 0,
"benefits": [
{
"title": "25 % opptjeningsrate"
},
{
"title": "Tidlig innsjekk 1 time når tilgjengelig"
},
{
"title": "Kupong på 75 NOK"
}
]
},
{
"level": 5,
"name": "Loyal Friend",
"requiredPoints": 100000,
"requiredNights": 0,
"benefits": [
{
"title": "Gratis romoppgradering når tilgjengelig"
},
{
"title": "Kupong på 100 NOK"
},
{
"title": "2-for-1 frokost"
}
]
},
{
"level": 6,
"name": "True Friend",
"requiredPoints": 250000,
"requiredNights": 0,
"benefits": [
{
"title": "50 % opptjeningsrate"
},
{
"title": "Kupong på 150 NOK"
},
{
"title": "Romgaranti i 48 timer"
},
{
"title": "Alltid gratis frokost"
}
]
},
{
"level": 7,
"name": "Best Friend",
"requiredPoints": 400000,
"requiredNights": 100,
"benefits": [
{
"title": "Kupong på 200 NOK"
},
{
"title": "Årlig eksklusiv gave"
},
{
"title": "Boost for barn"
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"levels": [
{
"level": 1,
"name": "New Friend",
"requiredPoints": 0,
"requiredNights": 0,
"benefits": [
{
"title": "Friendspriser på rum"
},
{
"title": "10 % rabatt på mat under helger"
},
{
"title": "Fri mocktail för barn under vistelse"
}
]
},
{
"level": 2,
"name": "Good Friend",
"requiredPoints": 5000,
"requiredNights": 0,
"benefits": [
{
"title": "15 % rabatt på mat under helger"
}
]
},
{
"level": 3,
"name": "Close Friend",
"requiredPoints": 10000,
"requiredNights": 0,
"benefits": [
{
"title": "Sen utcheckning 1 timme, i mån av plats"
},
{
"title": "Kupong 50 kr"
}
]
},
{
"level": 4,
"name": "Dear Friend",
"requiredPoints": 25000,
"requiredNights": 0,
"benefits": [
{
"title": "25 % poängboost"
},
{
"title": "Tidig incheckning 1 timme, i mån av plats"
},
{
"title": "Kupong 75 kr"
}
]
},
{
"level": 5,
"name": "Loyal Friend",
"requiredPoints": 100000,
"requiredNights": 0,
"benefits": [
{
"title": "Kostnadsfri uppgradering av rum, i mån av plats"
},
{
"title": "Kupong 100 kr"
},
{
"title": "Frukost 2 för 1"
}
]
},
{
"level": 6,
"name": "True Friend",
"requiredPoints": 250000,
"requiredNights": 0,
"benefits": [
{
"title": "50 % poängboost"
},
{
"title": "Kupong 150 kr"
},
{
"title": "48 timmars rumsgaranti"
},
{
"title": "Alltid kostnadsfri frukost"
}
]
},
{
"level": 7,
"name": "Best Friend",
"requiredPoints": 400000,
"requiredNights": 100,
"benefits": [
{
"title": "Kupong 200 kr"
},
{
"title": "Spännande gåva varje år"
},
{
"title": "Boost för barn"
}
]
}
]
}

View File

@@ -0,0 +1,19 @@
import { Lang } from "@/constants/languages"
import DA from "./DA.json"
import DE from "./DE.json"
import EN from "./EN.json"
import FI from "./FI.json"
import NO from "./NO.json"
import SV from "./SV.json"
const levelsData = {
[Lang.en]: EN,
[Lang.sv]: SV,
[Lang.no]: NO,
[Lang.fi]: FI,
[Lang.da]: DA,
[Lang.de]: DE,
}
export default levelsData

View File

@@ -0,0 +1,119 @@
"use client"
import { notFound, useParams } from "next/navigation"
import { useIntl } from "react-intl"
import { Lang } from "@/constants/languages"
import { CheckIcon } from "@/components/Icons"
import {
BestFriend,
CloseFriend,
DearFriend,
GoodFriend,
LoyalFriend,
NewFriend,
TrueFriend,
} from "@/components/Levels"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import levelsData from "./data"
import styles from "./loyaltyLevels.module.css"
import type { Level, LevelCardProps } from "@/types/components/content/blocks"
export default function LoyaltyLevels() {
const params = useParams()
const lang = params.lang as Lang
const { formatMessage } = useIntl()
const { levels } = levelsData[lang]
return (
<section className={styles.cardContainer}>
{levels.map((level: Level) => (
<LevelCard
key={level.level}
formatMessage={formatMessage}
lang={lang}
level={level}
/>
))}
</section>
)
}
function LevelCard({ formatMessage, lang, level }: LevelCardProps) {
let Level = null
switch (level.level) {
case 1:
Level = NewFriend
break
case 2:
Level = GoodFriend
break
case 3:
Level = CloseFriend
break
case 4:
Level = DearFriend
break
case 5:
Level = LoyalFriend
break
case 6:
Level = TrueFriend
break
case 7:
Level = BestFriend
break
default: {
const loyaltyLevel = level.level as never
console.error(`Unsupported loyalty level given: ${loyaltyLevel}`)
notFound()
}
}
const pointsString = `${level.requiredPoints.toLocaleString(lang)} ${formatMessage({ id: "points" })} `
return (
<article className={styles.card}>
<header>
<BiroScript
type="two"
color="primaryLightOnSurfaceAccent"
tilted="large"
>
{formatMessage({ id: "Level" })} {level.level}
</BiroScript>
<Level color="red" />
</header>
<Title textAlign="center" level="h5">
{pointsString}
{level.requiredNights ? (
<span className={styles.redText}>
{formatMessage({ id: "or" })} {level.requiredNights}{" "}
{formatMessage({ id: "nights" })}
</span>
) : null}
</Title>
<div className={styles.textContainer}>
{level.benefits.map((benefit) => (
<Caption
className={styles.levelText}
key={benefit.title}
textAlign="center"
color="textMediumContrast"
>
<CheckIcon
className={styles.checkIcon}
color="primaryLightOnSurfaceAccent"
/>
{benefit.title}
</Caption>
))}
</div>
</article>
)
}

View File

@@ -0,0 +1,55 @@
.cardContainer {
display: grid;
gap: var(--Spacing-x2);
}
.link {
justify-self: center;
}
.card {
background-color: var(--Scandic-Brand-Pale-Peach);
border-radius: var(--Corner-radius-xLarge);
display: grid;
gap: var(--Spacing-x2);
min-height: 280px;
justify-items: center;
padding: var(--Spacing-x5) var(--Spacing-x1);
grid-template-rows: auto auto 1fr;
}
.textContainer {
align-content: flex-start;
display: flex;
gap: var(--Spacing-x-one-and-half);
width: 100%;
flex-wrap: wrap;
justify-content: center;
}
.redText {
color: var(--Base-Text-Accent);
}
.levelText {
margin: 0;
}
.checkIcon {
vertical-align: middle;
}
@media screen and (min-width: 1367px) {
.cardContainer {
display: grid;
grid-template-columns: repeat(12, 1fr);
}
.card:nth-of-type(-n + 3) {
grid-column: span 4;
}
.card:nth-of-type(n + 4) {
grid-column: span 3;
}
}