diff --git a/components/Content/Blocks/DynamicContent/HowItWorks/howItWorks.module.css b/components/Content/Blocks/DynamicContent/HowItWorks/howItWorks.module.css new file mode 100644 index 000000000..b9a1afac8 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/HowItWorks/howItWorks.module.css @@ -0,0 +1,9 @@ +.container { + align-items: center; + background-color: var(--UI-Grey-10); + border-radius: var(--Corner-radius-xLarge); + display: flex; + height: 370px; + justify-content: center; + width: 100%; +} diff --git a/components/Content/Blocks/DynamicContent/HowItWorks/index.tsx b/components/Content/Blocks/DynamicContent/HowItWorks/index.tsx new file mode 100644 index 000000000..447a4fb1e --- /dev/null +++ b/components/Content/Blocks/DynamicContent/HowItWorks/index.tsx @@ -0,0 +1,13 @@ +import Title from "@/components/TempDesignSystem/Text/Title" +import { getIntl } from "@/i18n" + +import styles from "./howItWorks.module.css" + +export default async function HowItWorks() { + const { formatMessage } = await getIntl() + return ( +
+ {formatMessage({ id: "How it works" })} +
+ ) +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/DA.json b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/DA.json new file mode 100644 index 000000000..4587fde60 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/DA.json @@ -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" + } + ] + } + ] +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/DE.json b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/DE.json new file mode 100644 index 000000000..64d2a3923 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/DE.json @@ -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" + } + ] + } + ] +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/EN.json b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/EN.json new file mode 100644 index 000000000..958d9c4cb --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/EN.json @@ -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" + } + ] + } + ] +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/FI.json b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/FI.json new file mode 100644 index 000000000..dcd499757 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/FI.json @@ -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" + } + ] + } + ] +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/NO.json b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/NO.json new file mode 100644 index 000000000..f4fa72f19 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/NO.json @@ -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" + } + ] + } + ] +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/SV.json b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/SV.json new file mode 100644 index 000000000..c543b884a --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/SV.json @@ -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" + } + ] + } + ] +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/index.ts b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/index.ts new file mode 100644 index 000000000..04054d3fd --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/data/index.ts @@ -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 diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/index.tsx b/components/Content/Blocks/DynamicContent/LoyaltyLevels/index.tsx new file mode 100644 index 000000000..11de6b89d --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/index.tsx @@ -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 ( +
+ {levels.map((level: Level) => ( + + ))} +
+ ) +} + +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 ( +
+
+ + {formatMessage({ id: "Level" })} {level.level} + + +
+ + {pointsString} + {level.requiredNights ? ( + <span className={styles.redText}> + {formatMessage({ id: "or" })} {level.requiredNights}{" "} + {formatMessage({ id: "nights" })} + </span> + ) : null} + +
+ {level.benefits.map((benefit) => ( + + + {benefit.title} + + ))} +
+
+ ) +} diff --git a/components/Content/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css b/components/Content/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css new file mode 100644 index 000000000..13b379c8e --- /dev/null +++ b/components/Content/Blocks/DynamicContent/LoyaltyLevels/loyaltyLevels.module.css @@ -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; + } +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/BenefitCard/benefitCard.module.css b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitCard/benefitCard.module.css new file mode 100644 index 000000000..ae643de29 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitCard/benefitCard.module.css @@ -0,0 +1,56 @@ +.benefitCard { + padding-bottom: var(--Spacing-x-one-and-half); + z-index: 2; + grid-column: 1/3; +} + +.benefitCardHeader { + display: grid; + grid-template-columns: 1fr auto; +} + +.benefitCardDescription { + font-size: var(--typography-Caption-Regular-fontSize); + line-height: 150%; + padding-right: var(--Spacing-x4); +} + +.benefitInfo { + padding-bottom: var(--Spacing-x-one-and-half); +} + +.benefitComparison { + display: grid; + grid-template-columns: 1fr 1fr; +} + +.comparisonItem { + display: flex; + justify-content: center; + align-items: center; + padding-top: var(--Spacing-x-one-and-half); +} + +.details[open] .chevron { + transform: rotate(180deg); +} + +.chevron { + display: flex; + align-items: center; + color: var(--UI-Grey-80); +} + +.summary::-webkit-details-marker { + display: none; +} + +.summary { + list-style: none; +} + +@media screen and (min-width: 950px) { + .benefitComparison { + grid-template-columns: 1fr 1fr 1fr; + } +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/BenefitCard/index.tsx b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitCard/index.tsx new file mode 100644 index 000000000..ee02753a7 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitCard/index.tsx @@ -0,0 +1,53 @@ +import { ChevronDown } from "react-feather" + +import Title from "@/components/TempDesignSystem/Text/Title" + +import BenefitValue from "../BenefitValue" + +import styles from "./benefitCard.module.css" + +import type { BenefitCardProps } from "@/types/components/loyalty/blocks" + +export default function BenefitCard({ + comparedValues, + title, + description, +}: BenefitCardProps) { + return ( +
+
+
+ +
+ + {title} + + + + +
+
+

+

+
+
+ {comparedValues.map((benefit, idx) => ( +
+ +
+ ))} +
+
+ ) +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/BenefitList/benefitList.module.css b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitList/benefitList.module.css new file mode 100644 index 000000000..dba0dd085 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitList/benefitList.module.css @@ -0,0 +1,19 @@ +.benefitCardWrapper { + border-bottom: 1px solid var(--Base-Border-Subtle); + position: relative; + display: grid; + grid-template-columns: 1fr 1fr; + grid-column: 1/3; + padding-top: 0; + margin: var(--Spacing-x1) var(--Spacing-x2); +} + +.benefitCardWrapper:last-child { + border: none; +} + +@media screen and (min-width: 950px) { + .benefitCardWrapper { + grid-column: 1/4; + } +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/BenefitList/index.tsx b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitList/index.tsx new file mode 100644 index 000000000..dc947bfe0 --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitList/index.tsx @@ -0,0 +1,31 @@ +import { findBenefit, getUnlockedBenefits } from "@/utils/loyaltyTable" + +import BenefitCard from "../BenefitCard" + +import styles from "./benefitList.module.css" + +import type { BenefitListProps } from "@/types/components/loyalty/blocks" + +export default function BenefitList({ levels }: BenefitListProps) { + return getUnlockedBenefits(levels).map((benefit) => { + const levelBenefits = levels.map((level) => { + return findBenefit(benefit, level) + }) + return ( +
+ { + return { + key: `${benefit.name}-${idx}`, + value: benefit.value, + unlocked: benefit.unlocked, + valueDetails: benefit.valueDetails, + } + })} + /> +
+ ) + }) +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/BenefitValue/benefitValue.module.css b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitValue/benefitValue.module.css new file mode 100644 index 000000000..c72e3dd7f --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitValue/benefitValue.module.css @@ -0,0 +1,19 @@ +.benefitValueContainer { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--Spacing-x-half); + padding: 0 var(--Spacing-x4) 0 var(--Spacing-x4); + text-wrap: balance; +} + +.benefitValue { + font-size: var(--typography-Body-Bold-fontSize); + font-weight: var(--typography-Body-Bold-fontWeight); +} + +.benefitValueDetails { + font-size: var(--typography-Footnote-Regular-fontSize); + text-align: center; + color: var(--UI-Grey-80); +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/BenefitValue/index.tsx b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitValue/index.tsx new file mode 100644 index 000000000..e22b8f70e --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/BenefitValue/index.tsx @@ -0,0 +1,26 @@ +import { Minus } from "react-feather" + +import CheckCircle from "@/components/Icons/CheckCircle" + +import styles from "./benefitValue.module.css" + +import type { BenefitValueProps } from "@/types/components/loyalty/blocks" + +export default function BenefitValue({ benefit }: BenefitValueProps) { + if (!benefit.unlocked) { + return + } + if (!benefit.value) { + return + } + return ( +
+ {benefit.value} + {benefit.valueDetails && ( + + {benefit.valueDetails} + + )} +
+ ) +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/LargeTable/DesktopHeader/desktopHeader.module.css b/components/Content/Blocks/DynamicContent/OverviewTable/LargeTable/DesktopHeader/desktopHeader.module.css new file mode 100644 index 000000000..32ed2be4d --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/LargeTable/DesktopHeader/desktopHeader.module.css @@ -0,0 +1,28 @@ +.iconRow { + border-bottom: none; + position: sticky; + top: 0; + z-index: 1; +} + +.verticalTableHeader { + min-width: 242px; +} + +.iconTh { + padding: var(--Spacing-x5) var(--Spacing-x2) var(--Spacing-x2); + font-weight: var(--typography-Caption-Regular-fontWeight); + vertical-align: bottom; +} + +.summaryTh { + font-size: var(--typography-Caption-Regular-fontSize); + font-weight: var(--typography-Caption-Regular-fontWeight); + padding: 0 var(--Spacing-x2) var(--Spacing-x2); + vertical-align: top; +} + +.select { + font-weight: var(--typography-Caption-Regular-fontWeight); + padding: 0 var(--Spacing-x2) var(--Spacing-x2); +} diff --git a/components/Content/Blocks/DynamicContent/OverviewTable/LargeTable/DesktopHeader/index.tsx b/components/Content/Blocks/DynamicContent/OverviewTable/LargeTable/DesktopHeader/index.tsx new file mode 100644 index 000000000..edb176eba --- /dev/null +++ b/components/Content/Blocks/DynamicContent/OverviewTable/LargeTable/DesktopHeader/index.tsx @@ -0,0 +1,63 @@ +import Image from "@/components/Image" + +import LevelSummary from "../../LevelSummary" +import YourLevel from "../../YourLevelScript" + +import styles from "./desktopHeader.module.css" + +import type { + DesktopSelectColumns, + LargeTableProps, +} from "@/types/components/loyalty/blocks" + +export default function DesktopHeader({ + levels, + activeLevel, + Select, +}: LargeTableProps) { + return ( + + + + {levels.map((level, idx) => { + return ( + + {activeLevel === level.level ? : null} + {level.name} + + ) + })} + + + + {levels.map((level, idx) => { + return ( + + + + ) + })} + + {Select && ( + + + {["A", "B", "C"].map((column, idx) => { + return ( + + + + ) + } + + function SelectDesktop({ column }: DesktopSelectColumns) { + let selectedLevelDesktop: ComparisonLevel + let actionEnumDesktop: overviewTableActionsEnum + switch (column) { + case "A": + selectedLevelDesktop = selectionState.selectedLevelADesktop + actionEnumDesktop = + overviewTableActionsEnum.SET_SELECTED_LEVEL_A_DESKTOP + break + case "B": + selectedLevelDesktop = selectionState.selectedLevelBDesktop + actionEnumDesktop = + overviewTableActionsEnum.SET_SELECTED_LEVEL_B_DESKTOP + break + case "C": + selectedLevelDesktop = selectionState.selectedLevelCDesktop + actionEnumDesktop = + overviewTableActionsEnum.SET_SELECTED_LEVEL_C_DESKTOP + break + default: + return null + } + return ( +