feat(LOY-276): add hero image to account page

This commit is contained in:
Christian Andolf
2025-06-23 16:48:03 +02:00
parent f08d3330b9
commit 3f6127b861
6 changed files with 87 additions and 30 deletions

View File

@@ -1,18 +1,57 @@
.header {
height: 400px;
position: relative;
display: flex;
align-items: flex-end;
justify-content: center;
padding: var(--Space-x4);
border-radius: var(--Corner-radius-lg);
overflow: hidden;
&::after {
content: "";
position: absolute;
inset: 0;
z-index: 2;
background: linear-gradient(
180deg,
color-mix(in srgb, transparent, var(--Text-Brand-OnPrimary-1-Default) 8%)
13%,
color-mix(in srgb, transparent, var(--Text-Brand-OnPrimary-1-Heading) 40%)
100%
);
}
}
.heading {
position: relative;
z-index: 3;
color: var(--Text-Inverted);
}
.image {
z-index: 1;
}
.blocks {
display: grid;
gap: var(--Spacing-x5);
gap: var(--Space-x5);
max-width: var(--max-width-page);
align-content: flex-start;
}
@media screen and (min-width: 768px) {
.blocks {
gap: var(--Spacing-x7);
gap: var(--Space-x7);
}
}
@media screen and (min-width: 1367px) {
.header {
height: 480px;
padding-bottom: 150px;
}
.blocks {
gap: var(--Spacing-x7);
gap: var(--Space-x7);
}
}

View File

@@ -1,6 +1,9 @@
import { Typography } from "@scandic-hotels/design-system/Typography"
import { serverClient } from "@/lib/trpc/server"
import Blocks from "@/components/Blocks"
import Image from "@/components/Image"
import SectionHeader from "@/components/Section/Header"
import TrackingSDK from "@/components/TrackingSDK"
import { getIntl } from "@/i18n"
@@ -23,17 +26,37 @@ export default async function MyPages({}: PageArgs<
}
const { tracking, accountPage } = accountPageRes
const { heading, preamble, content } = accountPage
const { heading, preamble, hero_image, hero_image_active, content } =
accountPage
return (
<>
<main className={styles.blocks}>
<SectionHeader
title={heading}
preamble={preamble}
headingAs="h1"
headingLevel="h1"
/>
{hero_image_active ? (
<header className={styles.header}>
<Typography variant="Title/lg">
<h1 className={styles.heading}>{heading}</h1>
</Typography>
{hero_image ? (
<Image
className={styles.image}
alt={hero_image.meta.alt || hero_image.meta.caption || ""}
src={hero_image.url}
focalPoint={hero_image.focalPoint}
sizes="100vw"
fill
priority
/>
) : null}
</header>
) : (
<SectionHeader
title={heading}
preamble={preamble}
headingAs="h1"
headingLevel="h1"
/>
)}
{content?.length ? (
<Blocks blocks={content} />

View File

@@ -47,11 +47,9 @@ export default async function SASLinkedAccount({
<SectionContainer>
<SectionHeader link={link} preamble={subtitle} title={title} />
<SectionLink link={link} variant="mobile" />
<section className={styles.cardsContainer}>
<Suspense fallback={<MatchedAccountInfoSkeleton />}>
<MatchedAccountInfo />
</Suspense>
</section>
<Suspense fallback={<MatchedAccountInfoSkeleton />}>
<MatchedAccountInfo />
</Suspense>
</SectionContainer>
<div className={styles.mutationSection}>
<Typography variant="Body/Supporting text (caption)/smRegular">
@@ -98,7 +96,7 @@ async function MatchedAccountInfo() {
const matchState = calculateMatchState(user.loyalty)
return (
<section className={styles.matchedAccountSection}>
<div className={styles.matchedAccountSection}>
<div className={styles.accountDetails}>
<div className={styles.stack}>
<Label>
@@ -148,7 +146,7 @@ async function MatchedAccountInfo() {
scandicExpirationDate={scandicExpirationDate}
/>
</div>
</section>
</div>
)
}
@@ -156,7 +154,7 @@ async function MatchedAccountInfoSkeleton() {
const intl = await getIntl()
return (
<section className={styles.matchedAccountSection}>
<div className={styles.matchedAccountSection}>
<div className={styles.accountDetails}>
<div className={styles.stack}>
<Label>
@@ -192,7 +190,7 @@ async function MatchedAccountInfoSkeleton() {
<div className={styles.tierMatchStatus}>
<TierMatchMessageSkeleton />
</div>
</section>
</div>
)
}

View File

@@ -12,17 +12,6 @@
}
}
.cardsContainer {
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
justify-content: flex-start;
@media screen and (min-width: 768px) {
flex-direction: row;
}
}
.mutationSection {
display: flex;
flex-direction: column;

View File

@@ -8,6 +8,8 @@ query GetAccountPage($locale: String!, $uid: String!) {
account_page(locale: $locale, uid: $uid) {
heading
preamble
hero_image
hero_image_active
title
url
content {

View File

@@ -11,6 +11,7 @@ import {
shortcutsSchema,
} from "../schemas/blocks/shortcuts"
import { textContentSchema } from "../schemas/blocks/textContent"
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
import { systemSchema } from "../schemas/system"
import { AccountPageEnum } from "@/types/enums/accountPage"
@@ -44,6 +45,11 @@ export const accountPageSchema = z.object({
content: discriminatedUnionArray(blocksSchema.options),
heading: z.string().nullable(),
preamble: z.string().nullable(),
hero_image: tempImageVaultAssetSchema,
hero_image_active: z
.boolean()
.nullable()
.transform((val) => val ?? false),
title: z.string(),
url: z.string(),
system: systemSchema.merge(