Merged in feat/webviews (pull request #198)

Feat/webviews

Approved-by: Michael Zetterberg
This commit is contained in:
Christel Westerberg
2024-05-30 13:51:35 +00:00
committed by Michael Zetterberg
32 changed files with 561 additions and 127 deletions

View File

@@ -0,0 +1,26 @@
import "@/app/globals.css"
import "@scandic-hotels/design-system/style.css"
import { overview } from "@/constants/routes/webviews"
import { serverClient } from "@/lib/trpc/server"
import MaxWidth from "@/components/MaxWidth"
import Content from "@/components/MyPages/AccountPage/Webview/Content"
import LinkToOverview from "@/components/Webviews/LinkToOverview"
import styles from "./accountPage.module.css"
import { LangParams } from "@/types/params"
export default async function MyPages({ lang }: LangParams) {
const accountPage = await serverClient().contentstack.accountPage.get()
const linkToOverview = `/${lang}/webview${accountPage.url}` !== overview[lang]
return (
<MaxWidth className={styles.blocks} tag="main">
{linkToOverview ? <LinkToOverview lang={lang} /> : null}
<Content lang={lang} content={accountPage.content} />
</MaxWidth>
)
}

View File

@@ -0,0 +1,29 @@
import { serverClient } from "@/lib/trpc/server"
import { Blocks } from "@/components/Loyalty/Blocks/WebView"
import Sidebar from "@/components/Loyalty/Sidebar"
import MaxWidth from "@/components/MaxWidth"
import LinkToOverview from "@/components/Webviews/LinkToOverview"
import styles from "./loyaltyPage.module.css"
import { LangParams } from "@/types/params"
export default async function AboutScandicFriends({ lang }: LangParams) {
const loyaltyPage = await serverClient().contentstack.loyaltyPage.get()
return (
<section className={styles.content}>
<LinkToOverview lang={lang} />
{loyaltyPage.sidebar ? (
<section className={styles.sidebar}>
<Sidebar blocks={loyaltyPage.sidebar} />
</section>
) : null}
<MaxWidth tag="main">
<Blocks blocks={loyaltyPage.blocks} lang={lang} />
</MaxWidth>
</section>
)
}

View File

@@ -0,0 +1,5 @@
.blocks {
display: grid;
gap: var(--Spacing-x5);
padding: var(--Spacing-x2);
}

View File

@@ -0,0 +1,10 @@
.content {
display: grid;
padding: var(--Spacing-x2);
gap: var(--Spacing-x5);
}
.sidebar {
margin-left: calc(var(--Spacing-x2) * -1);
margin-right: calc(var(--Spacing-x2) * -1);
}

View File

@@ -26,7 +26,7 @@
width: 3px;
height: 9px;
border-radius: 20%;
background: var(--Brand-Main-Strong);
background: var(--Scandic-Brand-Burgundy);
}
.spinner div:nth-child(1) {

View File

@@ -0,0 +1,54 @@
import JsonToHtml from "@/components/JsonToHtml"
import DynamicContentBlock from "@/components/Loyalty/Blocks/DynamicContent"
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
import { modWebviewLink } from "@/utils/webviews"
import CardsGrid from "../CardsGrid"
import type { BlocksProps } from "@/types/components/loyalty/blocks"
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
import { LangParams } from "@/types/params"
export function Blocks({ lang, blocks }: BlocksProps & LangParams) {
return blocks.map((block) => {
switch (block.__typename) {
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
return <CardsGrid cards_grid={block.cards_grid} />
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent:
return (
<section>
<JsonToHtml
nodes={block.content.content.json.children}
embeds={block.content.content.embedded_itemsConnection.edges}
/>
</section>
)
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
const dynamicContent = {
...block.dynamic_content,
link: block.dynamic_content.link
? {
...block.dynamic_content.link,
href: modWebviewLink(block.dynamic_content.link.href, lang),
}
: undefined,
}
return <DynamicContentBlock dynamicContent={dynamicContent} />
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
const shortcuts = block.shortcuts.shortcuts.map((shortcut) => ({
...shortcut,
url: modWebviewLink(shortcut.url, lang),
}))
return (
<Shortcuts
shortcuts={shortcuts}
title={block.shortcuts.title}
subtitle={block.shortcuts.preamble}
/>
)
default:
return null
}
})
}

View File

@@ -0,0 +1,101 @@
import JsonToHtml from "@/components/JsonToHtml"
import Overview from "@/components/MyPages/Blocks/Overview"
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
import { modWebviewLink } from "@/utils/webviews"
import CurrentBenefitsBlock from "../../Blocks/Benefits/CurrentLevel"
import NextLevelBenefitsBlock from "../../Blocks/Benefits/NextLevel"
import CurrentPointsBalance from "../../Blocks/Points/CurrentPointsBalance"
import EarnAndBurn from "../../Blocks/Points/EarnAndBurn"
import {
AccountPageContentProps,
ContentProps,
} from "@/types/components/myPages/myPage/accountPage"
import {
ContentEntries,
DynamicContentComponents,
} from "@/types/components/myPages/myPage/enums"
function DynamicComponent({ component, props }: AccountPageContentProps) {
switch (component) {
case DynamicContentComponents.membership_overview:
return <Overview title={props.title} />
case DynamicContentComponents.current_benefits:
return <CurrentBenefitsBlock {...props} />
case DynamicContentComponents.next_benefits:
return <NextLevelBenefitsBlock {...props} />
case DynamicContentComponents.my_points:
return <CurrentPointsBalance {...props} />
case DynamicContentComponents.expiring_points:
// TODO: Add once available
// return <ExpiringPoints />
return null
case DynamicContentComponents.earn_and_burn:
return <EarnAndBurn {...props} />
default:
return null
}
}
export default function Content({ lang, content }: ContentProps) {
return (
<>
{content.map((item) => {
switch (item.__typename) {
case ContentEntries.AccountPageContentDynamicContent:
const link = item.dynamic_content.link.linkConnection.edges.length
? {
href:
item.dynamic_content.link.linkConnection.edges[0].node
.original_url ||
`/${lang}/webview${item.dynamic_content.link.linkConnection.edges[0].node.url}`,
text: item.dynamic_content.link.link_text,
}
: null
const componentProps = {
lang,
title: item.dynamic_content.title,
// TODO: rename preamble to subtitle in Contentstack?
subtitle: item.dynamic_content.preamble,
...(link && { link }),
}
return (
<DynamicComponent
component={item.dynamic_content.component}
props={componentProps}
/>
)
case ContentEntries.AccountPageContentShortcuts:
const shortcuts = item.shortcuts.shortcuts.map((shortcut) => {
return {
...shortcut,
url: modWebviewLink(shortcut.url, lang),
}
})
return (
<Shortcuts
shortcuts={shortcuts}
subtitle={item.shortcuts.preamble}
title={item.shortcuts.title}
/>
)
case ContentEntries.AccountPageContentTextContent:
return (
<section>
<JsonToHtml
embeds={
item.text_content.content.embedded_itemsConnection.edges
}
nodes={item.text_content.content.json.children}
/>
</section>
)
default:
return null
}
})}
</>
)
}

View File

@@ -1,15 +0,0 @@
import { serverClient } from "@/lib/trpc/server"
import styles from "./user.module.css"
export default async function User() {
const user = await serverClient().user.get()
return (
<div className={styles.user}>
{user.firstName[0].toUpperCase()}
{user.lastName[0].toUpperCase()}
<span className={styles.alert}>1</span>
</div>
)
}

View File

@@ -1,43 +0,0 @@
.user {
align-items: center;
background-color: var(--some-black-color, #000);
border-radius: 50%;
color: var(--some-white-color, #fff);
display: flex;
font-family: var(--ff-fira-sans);
font-size: 1.2rem;
font-weight: 600;
height: 3.5rem;
justify-content: center;
position: relative;
width: 3.5rem;
}
.alert {
align-items: center;
background-color: var(--some-red-color, #ed2027);
border-radius: 50%;
display: flex;
font-size: 1rem;
height: 2rem;
justify-content: center;
position: absolute;
right: -1rem;
top: -0.5rem;
width: 2rem;
}
@media screen and (min-width: 950px) {
.user {
height: 2.8rem;
width: 2.8rem;
}
.alert {
font-size: 0.6rem;
height: 1rem;
right: -0.2rem;
top: -0.1rem;
width: 1rem;
}
}

View File

@@ -0,0 +1,18 @@
import { ArrowLeft } from "react-feather"
import { overview } from "@/constants/routes/webviews"
import { _ } from "@/lib/translation"
import Link from "@/components/TempDesignSystem/Link"
import styles from "./linkToOverview.module.css"
import { LangParams } from "@/types/params"
export default function LinkToOverview({ lang }: LangParams) {
return (
<Link className={styles.overviewLink} href={overview[lang]}>
<ArrowLeft height={20} width={20} /> {_("Go back to overview")}
</Link>
)
}

View File

@@ -0,0 +1,7 @@
.overviewLink {
font-size: var(--Spacing-x2);
color: var(--Scandic-Brand-Burgundy, #4d001b);
display: flex;
align-items: center;
gap: 1rem;
}