Merged in feat/LOY-584-L6-progressbar (pull request #3511)

Feat/LOY-584 L6 progressbar informational modal

* refactor(LOY-584): replace deprecated link

* feat(LOY-584): add info modal to progress bar

* fix(LOY-584): let labels overflow progress bar in mobile


Approved-by: Anton Gunnarsson
This commit is contained in:
Matilda Landström
2026-01-29 14:14:20 +00:00
parent dbacb650b6
commit 4d298b0b9b
6 changed files with 193 additions and 30 deletions

View File

@@ -0,0 +1,114 @@
"use client"
import { useIntl } from "react-intl"
import { dt } from "@scandic-hotels/common/dt"
import { IconButton } from "@scandic-hotels/design-system/IconButton" // client only
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Modal from "@scandic-hotels/design-system/Modal"
import { TextLink } from "@scandic-hotels/design-system/TextLink"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { compareAllLevels, faq } from "@/constants/webHrefs"
import useLang from "@/hooks/useLang"
import { getTierStartDate } from "@/utils/getTierStartDate"
import styles from "./l6progressModal.module.css"
type L6ProgressModalProps = {
tierExpires: string | null
}
export function L6ProgressModal({ tierExpires }: L6ProgressModalProps) {
const intl = useIntl()
const lang = useLang()
const tierStarts = getTierStartDate(tierExpires)
return (
<Modal
className={styles.dialog}
trigger={
<IconButton variant="Muted" emphasis iconName="info" size="sm" />
}
>
<div className={styles.levelProgressModal}>
<Typography variant="Title/Subtitle/lg">
<h2 id="l6-progress-modal-title" className={styles.title}>
{intl.formatMessage({
id: "myPages.l6progress.modal.title",
defaultMessage: "Level upgrade and membership year",
})}
</h2>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<span className={styles.content}>
<p>
{intl.formatMessage({
id: "myPages.l6progress.modal.yourLevelDuring",
defaultMessage:
"Your level during the current and next period is based on the points you earn during this 12-month period.",
})}
</p>
<p>
{intl.formatMessage({
id: "myPages.l6progress.modal.youCanAlsoReach",
defaultMessage:
"You can also reach Best Friend, our highest membership level, by staying 100 nights with us within a membership year.",
})}
</p>
</span>
</Typography>
<span>
<Typography variant="Body/Paragraph/mdBold">
<h3>
{intl.formatMessage({
id: "myPages.currentMemberYear",
defaultMessage: "Current member year",
})}
</h3>
</Typography>
<div>
<Typography variant="Body/Paragraph/mdRegular">
<span className={styles.dates}>
<time id="l6-progress-modal-start-date">
{dt(tierStarts).locale(lang).format("MMM, YYYY")}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
</time>
<time id="l6-progress-modal-end-date">
{dt(tierExpires).locale(lang).format("MMM D, YYYY")}
</time>
</span>
</Typography>
</div>
</span>
<TextLink
href={compareAllLevels[lang]}
className={styles.link}
theme="Primary"
target="_blank"
>
{intl.formatMessage({
id: "myPages.compareAllLevels",
defaultMessage: "Compare all levels",
})}
<MaterialIcon icon="arrow_forward" color="CurrentColor" size={24} />
</TextLink>
<TextLink
href={faq[lang]}
className={styles.link}
theme="Primary"
target="_blank"
>
{intl.formatMessage({
id: "common.scandicFriendsFaq",
defaultMessage: "Scandic Friends FAQ",
})}
<MaterialIcon icon="arrow_forward" color="CurrentColor" size={24} />
</TextLink>
</div>
</Modal>
)
}

View File

@@ -0,0 +1,41 @@
.infoButton {
grid-column: 2;
grid-row: 1 / 3;
align-self: start;
}
.levelProgressModal {
display: flex;
flex-direction: column;
gap: var(--Space-x2);
padding-bottom: var(--Space-x1);
}
.title {
display: flex;
flex-direction: column;
}
.dates {
display: flex;
align-items: center;
gap: var(--Space-x1);
}
.link {
display: flex;
gap: var(--Space-x05);
justify-content: left;
}
.content {
display: flex;
flex-direction: column;
gap: var(--Space-x2);
}
@media screen and (min-width: 768px) {
.dialog {
max-width: 560px;
}
}

View File

@@ -9,6 +9,7 @@ import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import { getTierStartDate } from "@/utils/getTierStartDate"
import { L6ProgressModal } from "./L6ProgressModal"
import { ProgressSection } from "./ProgressSection"
import styles from "./l6Progress.module.css"
@@ -58,17 +59,24 @@ export async function L6Progress() {
</h3>
</Typography>
{formattedStartDate && (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.since}>
{intl.formatMessage(
{
id: "previousStays.sinceDate",
defaultMessage: "Since {date}",
},
{ date: formattedStartDate }
)}
</p>
</Typography>
<>
<Typography variant="Body/Paragraph/mdRegular">
<span className={styles.sinceDate}>
<p className={styles.since}>
{intl.formatMessage(
{
id: "previousStays.sinceDate",
defaultMessage: "Since {date}",
},
{ date: formattedStartDate }
)}
</p>
<L6ProgressModal
tierExpires={user.membership.tierExpirationDate}
/>
</span>
</Typography>
</>
)}
</header>

View File

@@ -19,14 +19,19 @@
color: var(--Text-Secondary);
}
.sinceDate {
display: flex;
gap: var(--Space-x05);
}
.progressSection {
display: grid;
grid-template-columns: min-content 1fr auto;
gap: var(--Space-x05);
align-items: center;
grid-template-areas:
"startLabel . endLabel"
"startValue bar endValue";
"startLabel startLabel endLabel endLabel"
"startValue bar bar endValue";
}
.startLabelText {
@@ -69,7 +74,7 @@
.header {
flex-direction: row;
align-items: baseline;
align-items: center;
gap: var(--Space-x1);
}

View File

@@ -24,11 +24,8 @@
.link {
display: flex;
gap: var(--Space-x1);
}
.linkText {
text-decoration: underline;
gap: var(--Space-x05);
justify-content: left;
}
@media screen and (min-width: 768px) {

View File

@@ -7,7 +7,7 @@ import { dt } from "@scandic-hotels/common/dt"
import { IconButton } from "@scandic-hotels/design-system/IconButton" // client only
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Modal from "@scandic-hotels/design-system/Modal"
import Link from "@scandic-hotels/design-system/OldDSLink"
import { TextLink } from "@scandic-hotels/design-system/TextLink"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { compareAllLevels, faq } from "@/constants/webHrefs"
@@ -83,32 +83,30 @@ export default function LevelProgressModal({
})}
</p>
</Typography>
<Link
size="large"
<TextLink
href={compareAllLevels[lang]}
color="Text/Interactive/Secondary"
className={styles.link}
textDecoration="underline"
theme="Primary"
target="_blank"
>
{intl.formatMessage({
id: "myPages.compareAllLevels",
defaultMessage: "Compare all levels",
})}
<MaterialIcon icon="arrow_forward" color="CurrentColor" size={24} />
</Link>
<Link
size="large"
</TextLink>
<TextLink
href={faq[lang]}
color="Text/Interactive/Secondary"
className={styles.link}
textDecoration="underline"
theme="Primary"
target="_blank"
>
{intl.formatMessage({
id: "common.scandicFriendsFaq",
defaultMessage: "Scandic Friends FAQ",
})}
<MaterialIcon icon="arrow_forward" color="CurrentColor" size={24} />
</Link>
</TextLink>
</div>
</Modal>
)