Merged in feat/webviews (pull request #198)
Feat/webviews Approved-by: Michael Zetterberg
This commit is contained in:
26
components/ContentType/Webviews/AccountPage.tsx
Normal file
26
components/ContentType/Webviews/AccountPage.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
29
components/ContentType/Webviews/LoyaltyPage.tsx
Normal file
29
components/ContentType/Webviews/LoyaltyPage.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
5
components/ContentType/Webviews/accountPage.module.css
Normal file
5
components/ContentType/Webviews/accountPage.module.css
Normal file
@@ -0,0 +1,5 @@
|
||||
.blocks {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x5);
|
||||
padding: var(--Spacing-x2);
|
||||
}
|
||||
10
components/ContentType/Webviews/loyaltyPage.module.css
Normal file
10
components/ContentType/Webviews/loyaltyPage.module.css
Normal 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);
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
54
components/Loyalty/Blocks/WebView/index.tsx
Normal file
54
components/Loyalty/Blocks/WebView/index.tsx
Normal 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
|
||||
}
|
||||
})
|
||||
}
|
||||
101
components/MyPages/AccountPage/Webview/Content.tsx
Normal file
101
components/MyPages/AccountPage/Webview/Content.tsx
Normal 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
|
||||
}
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
18
components/Webviews/LinkToOverview/index.tsx
Normal file
18
components/Webviews/LinkToOverview/index.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
.overviewLink {
|
||||
font-size: var(--Spacing-x2);
|
||||
color: var(--Scandic-Brand-Burgundy, #4d001b);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
Reference in New Issue
Block a user