Merged in feat/LOY-276-sas-hero-image (pull request #2411)
feat(LOY-276): add hero image to account page Approved-by: Erik Tiekstra
This commit is contained in:
@@ -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 {
|
.blocks {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Spacing-x5);
|
gap: var(--Space-x5);
|
||||||
max-width: var(--max-width-page);
|
max-width: var(--max-width-page);
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
@media screen and (min-width: 768px) {
|
||||||
.blocks {
|
.blocks {
|
||||||
gap: var(--Spacing-x7);
|
gap: var(--Space-x7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1367px) {
|
@media screen and (min-width: 1367px) {
|
||||||
|
.header {
|
||||||
|
height: 480px;
|
||||||
|
padding-bottom: 150px;
|
||||||
|
}
|
||||||
.blocks {
|
.blocks {
|
||||||
gap: var(--Spacing-x7);
|
gap: var(--Space-x7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import Blocks from "@/components/Blocks"
|
import Blocks from "@/components/Blocks"
|
||||||
|
import Image from "@/components/Image"
|
||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
import TrackingSDK from "@/components/TrackingSDK"
|
import TrackingSDK from "@/components/TrackingSDK"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
@@ -23,17 +26,37 @@ export default async function MyPages({}: PageArgs<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { tracking, accountPage } = accountPageRes
|
const { tracking, accountPage } = accountPageRes
|
||||||
const { heading, preamble, content } = accountPage
|
const { heading, preamble, hero_image, hero_image_active, content } =
|
||||||
|
accountPage
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<main className={styles.blocks}>
|
<main className={styles.blocks}>
|
||||||
<SectionHeader
|
{hero_image_active ? (
|
||||||
title={heading}
|
<header className={styles.header}>
|
||||||
preamble={preamble}
|
<Typography variant="Title/lg">
|
||||||
headingAs="h1"
|
<h1 className={styles.heading}>{heading}</h1>
|
||||||
headingLevel="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 ? (
|
{content?.length ? (
|
||||||
<Blocks blocks={content} />
|
<Blocks blocks={content} />
|
||||||
|
|||||||
@@ -47,11 +47,9 @@ export default async function SASLinkedAccount({
|
|||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<SectionHeader link={link} preamble={subtitle} title={title} />
|
<SectionHeader link={link} preamble={subtitle} title={title} />
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
<section className={styles.cardsContainer}>
|
<Suspense fallback={<MatchedAccountInfoSkeleton />}>
|
||||||
<Suspense fallback={<MatchedAccountInfoSkeleton />}>
|
<MatchedAccountInfo />
|
||||||
<MatchedAccountInfo />
|
</Suspense>
|
||||||
</Suspense>
|
|
||||||
</section>
|
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
<div className={styles.mutationSection}>
|
<div className={styles.mutationSection}>
|
||||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||||
@@ -98,7 +96,7 @@ async function MatchedAccountInfo() {
|
|||||||
const matchState = calculateMatchState(user.loyalty)
|
const matchState = calculateMatchState(user.loyalty)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.matchedAccountSection}>
|
<div className={styles.matchedAccountSection}>
|
||||||
<div className={styles.accountDetails}>
|
<div className={styles.accountDetails}>
|
||||||
<div className={styles.stack}>
|
<div className={styles.stack}>
|
||||||
<Label>
|
<Label>
|
||||||
@@ -148,7 +146,7 @@ async function MatchedAccountInfo() {
|
|||||||
scandicExpirationDate={scandicExpirationDate}
|
scandicExpirationDate={scandicExpirationDate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +154,7 @@ async function MatchedAccountInfoSkeleton() {
|
|||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.matchedAccountSection}>
|
<div className={styles.matchedAccountSection}>
|
||||||
<div className={styles.accountDetails}>
|
<div className={styles.accountDetails}>
|
||||||
<div className={styles.stack}>
|
<div className={styles.stack}>
|
||||||
<Label>
|
<Label>
|
||||||
@@ -192,7 +190,7 @@ async function MatchedAccountInfoSkeleton() {
|
|||||||
<div className={styles.tierMatchStatus}>
|
<div className={styles.tierMatchStatus}>
|
||||||
<TierMatchMessageSkeleton />
|
<TierMatchMessageSkeleton />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
.mutationSection {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ query GetAccountPage($locale: String!, $uid: String!) {
|
|||||||
account_page(locale: $locale, uid: $uid) {
|
account_page(locale: $locale, uid: $uid) {
|
||||||
heading
|
heading
|
||||||
preamble
|
preamble
|
||||||
|
hero_image
|
||||||
|
hero_image_active
|
||||||
title
|
title
|
||||||
url
|
url
|
||||||
content {
|
content {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
shortcutsSchema,
|
shortcutsSchema,
|
||||||
} from "../schemas/blocks/shortcuts"
|
} from "../schemas/blocks/shortcuts"
|
||||||
import { textContentSchema } from "../schemas/blocks/textContent"
|
import { textContentSchema } from "../schemas/blocks/textContent"
|
||||||
|
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
|
||||||
import { systemSchema } from "../schemas/system"
|
import { systemSchema } from "../schemas/system"
|
||||||
|
|
||||||
import { AccountPageEnum } from "@/types/enums/accountPage"
|
import { AccountPageEnum } from "@/types/enums/accountPage"
|
||||||
@@ -44,6 +45,11 @@ export const accountPageSchema = z.object({
|
|||||||
content: discriminatedUnionArray(blocksSchema.options),
|
content: discriminatedUnionArray(blocksSchema.options),
|
||||||
heading: z.string().nullable(),
|
heading: z.string().nullable(),
|
||||||
preamble: z.string().nullable(),
|
preamble: z.string().nullable(),
|
||||||
|
hero_image: tempImageVaultAssetSchema,
|
||||||
|
hero_image_active: z
|
||||||
|
.boolean()
|
||||||
|
.nullable()
|
||||||
|
.transform((val) => val ?? false),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
url: z.string(),
|
url: z.string(),
|
||||||
system: systemSchema.merge(
|
system: systemSchema.merge(
|
||||||
|
|||||||
Reference in New Issue
Block a user