feat: add JoinLoyalty component

This commit is contained in:
Christel Westerberg
2024-04-19 13:11:02 +02:00
parent b57665ce62
commit 3a0c8610dc
15 changed files with 238 additions and 38 deletions

View File

@@ -6,4 +6,5 @@
font-family: var(--ff-fira-sans); font-family: var(--ff-fira-sans);
grid-template-rows: var(--header-height) auto 1fr; grid-template-rows: var(--header-height) auto 1fr;
min-height: 100dvh; min-height: 100dvh;
background-color: var(--Brand-Coffee-Subtle);
} }

View File

@@ -6,6 +6,13 @@
position: relative; position: relative;
} }
.blocks {
display: grid;
gap: 4.2rem;
padding-left: 2rem;
padding-right: 2rem;
}
@media screen and (min-width: 950px) { @media screen and (min-width: 950px) {
.content { .content {
gap: 10rem; gap: 10rem;
@@ -15,4 +22,10 @@
padding-right: 2.4rem; padding-right: 2.4rem;
padding-top: 5.8rem; padding-top: 5.8rem;
} }
.blocks {
gap: 6.4rem;
padding-left: 0;
padding-right: 0;
}
} }

View File

@@ -6,6 +6,7 @@ import { LangParams, PageArgs, UriParams } from "@/types/params"
import { notFound } from "next/navigation" import { notFound } from "next/navigation"
import styles from "./page.module.css" import styles from "./page.module.css"
import Sidebar from "@/components/Loyalty/Sidebar"
export default async function LoyaltyPage({ export default async function LoyaltyPage({
params, params,
@@ -22,13 +23,19 @@ export default async function LoyaltyPage({
}) })
return ( return (
<main className={styles.content}> <MaxWidth className={styles.content} tag="main">
<aside>{loyaltyPage.sidebar ? <></> : null}</aside> <aside>
<MaxWidth> {loyaltyPage.sidebar
<Title>{loyaltyPage.title}</Title> ? loyaltyPage.sidebar.map((block, i) => (
<Sidebar key={i} block={block} />
))
: null}
</aside>
<section className={styles.blocks}>
<Title as="h3">{loyaltyPage.title}</Title>
<Content content={loyaltyPage.content} /> <Content content={loyaltyPage.content} />
</MaxWidth> </section>
</main> </MaxWidth>
) )
} catch (err) { } catch (err) {
return notFound() return notFound()

View File

@@ -29,6 +29,10 @@ function extractPossibleAttributes(attrs: Attributes) {
props.className = attrs["class-name"] props.className = attrs["class-name"]
} else if (attrs.classname) { } else if (attrs.classname) {
props.className = attrs.classname props.className = attrs.classname
} else if (attrs?.style?.["text-align"]) {
props.style = {
textAlign: attrs?.style?.["text-align"],
}
} }
return props return props
@@ -250,6 +254,11 @@ export const renderOptions: RenderOptions = {
const image = embeds?.[node?.attrs?.["asset-uid"]] const image = embeds?.[node?.attrs?.["asset-uid"]]
if (image.node.__typename === EmbedEnum.SysAsset) { if (image.node.__typename === EmbedEnum.SysAsset) {
const alt = image?.node?.title ?? node.attrs.alt const alt = image?.node?.title ?? node.attrs.alt
const alignment = node.attrs?.style?.["text-align"]
? {
alignSelf: node.attrs?.style?.["text-align"],
}
: {}
return ( return (
<Image <Image
key={node.uid} key={node.uid}
@@ -258,6 +267,7 @@ export const renderOptions: RenderOptions = {
height={image.node.dimension.height} height={image.node.dimension.height}
src={image?.node?.url} src={image?.node?.url}
width={image.node.dimension.width} width={image.node.dimension.width}
style={alignment}
/> />
) )
} }

View File

@@ -0,0 +1,8 @@
import { Lang } from "@/constants/languages"
import { serverClient } from "@/lib/trpc/server"
export default function Contact({ lang }: { lang: Lang }) {
const data = serverClient().contentstack.contactConfig.get({ lang })
return <div></div>
}

View File

@@ -0,0 +1,37 @@
import Title from "@/components/Title"
import JsonToHtml from "@/components/JsonToHtml"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import styles from "./joinLoyalty.module.css"
import type { JoinLoyaltyContact } from "@/types/requests/loyaltyPage"
export default function JoinLoyaltyContact({
block,
}: {
block: JoinLoyaltyContact["join_loyalty_contact"]
}) {
return (
<div className={styles.container}>
<div className={styles.wrapper}>
<JsonToHtml
embeds={block.body.embedded_itemsConnection.edges}
nodes={block.body.json.children}
/>
<Button intent="primary">
<span>{block.login_button_text}</span>
</Button>
<div className={styles.linkContainer}>
<Link href="/login" className={styles.logoutLink}>
Already a friend? <br />
Click here to log in
</Link>
</div>
</div>
<section className={styles.contactContainer}>
<Title level="h5">Contact</Title>
</section>
</div>
)
}

View File

@@ -0,0 +1,42 @@
.container {
display: grid;
font-weight: 600;
background-color: var(--Base-Background-Elevated);
border-radius: 32px 4px 4px 32px;
}
.wrapper {
display: flex;
align-items: center;
flex-direction: column;
gap: 2rem;
padding: 4rem 2rem;
}
.logoutLink {
text-decoration: none;
color: var(--some-black-color, #2e2e2e);
font-size: 1.2rem;
}
.linkContainer {
text-align: center;
}
.contactContainer {
display: none;
}
@media screen and (min-width: 950px) {
.wrapper {
gap: 3rem;
}
.contactContainer {
display: block;
border-top: 0.5px solid var(--Base-Border-Disabled);
display: flex;
justify-content: center;
padding: 3.4rem;
}
}

View File

@@ -0,0 +1,20 @@
import JsonToHtml from "@/components/JsonToHtml"
import JoinLoyaltyContact from "./JoinLoyalty"
import { Sidebar, SidebarTypenameEnum } from "@/types/requests/loyaltyPage"
export default function SidebarLoyalty({ block }: { block: Sidebar }) {
switch (block.__typename) {
case SidebarTypenameEnum.LoyaltyPageSidebarContent:
return (
<JsonToHtml
embeds={block.content.embedded_itemsConnection.edges}
nodes={block.content.json.children}
/>
)
case SidebarTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContact:
return <JoinLoyaltyContact block={block.join_loyalty_contact} />
default:
return null
}
}

View File

@@ -0,0 +1,37 @@
query GetContactConfig($locale: String!) {
all_contact_config(locale: $locale) {
items {
email {
address
name
}
email_loyalty {
address
name
}
mailing_address {
name
street
zip
country
city
}
phone {
number
name
}
phone_loyalty {
name
number
}
title
visiting_address {
country
city
street
zip
}
}
total
}
}

View File

@@ -1,3 +1,5 @@
#import "../Fragments/Image.graphql"
query GetLoyaltyPage($locale: String!, $url: String!) { query GetLoyaltyPage($locale: String!, $url: String!) {
all_loyalty_page(where: { url: $url, locale: $locale }) { all_loyalty_page(where: { url: $url, locale: $locale }) {
items { items {
@@ -56,12 +58,12 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
} }
title title
sidebar { sidebar {
... on LoyaltyPageSidebarLoyaltyJoinContact { ... on LoyaltyPageSidebarJoinLoyaltyContact {
__typename __typename
loyalty_join_contact { join_loyalty_contact {
title title
contact { contact {
... on LoyaltyPageSidebarLoyaltyJoinContactBlockContactContact { ... on LoyaltyPageSidebarJoinLoyaltyContactBlockContactContact {
__typename __typename
contact { contact {
contact_fields contact_fields
@@ -71,19 +73,11 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
login_button_text login_button_text
body { body {
json json
embedded_itemsConnection { embedded_itemsConnection(limit: 30) {
edges { edges {
node { node {
... on SysAsset { __typename
title ...Image
dimension {
width
height
}
file_size
filename
url
}
} }
} }
} }
@@ -98,16 +92,7 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
embedded_itemsConnection { embedded_itemsConnection {
edges { edges {
node { node {
... on SysAsset { ...Image
title
url
file_size
filename
dimension {
width
height
}
}
} }
} }
} }
@@ -123,7 +108,6 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
title title
} }
} }
original_url
seo_metadata { seo_metadata {
description description
title title

View File

@@ -0,0 +1,5 @@
import { mergeRouters } from "@/server/trpc"
import { contactConfigQueryRouter } from "./query"
export const contactConfigRouter = mergeRouters(contactConfigQueryRouter)

View File

@@ -0,0 +1,32 @@
import { z } from "zod"
import { badRequestError } from "@/server/errors/trpc"
import { publicProcedure, router } from "@/server/trpc"
import { request } from "@/lib/graphql/request"
import { Lang } from "@/constants/languages"
import GetContactConfig from "@/lib/graphql/Query/ContactConfig.graphql"
import type { GetContactConfigData } from "@/types/requests/contactConfig"
export const contactConfigQueryRouter = router({
get: publicProcedure
.input(z.object({ lang: z.nativeEnum(Lang) }))
.query(async ({ input }) => {
const contactConfig = await request<GetContactConfigData>(
GetContactConfig,
{
locale: input.lang,
},
{
tags: [`contact-config-${input.lang}`],
}
)
if (contactConfig.data && contactConfig.data.all_contact_config.total) {
return contactConfig.data.all_contact_config.items[0]
}
throw badRequestError()
}),
})

View File

@@ -2,8 +2,10 @@ import { router } from "@/server/trpc"
import { breadcrumbsRouter } from "./breadcrumbs" import { breadcrumbsRouter } from "./breadcrumbs"
import { loyaltyPageRouter } from "./loyaltyPage" import { loyaltyPageRouter } from "./loyaltyPage"
import { contactConfigRouter } from "./contactConfig"
export const contentstackRouter = router({ export const contentstackRouter = router({
breadcrumbs: breadcrumbsRouter, breadcrumbs: breadcrumbsRouter,
loyaltyPage: loyaltyPageRouter, loyaltyPage: loyaltyPageRouter,
contactConfig: contactConfigRouter,
}) })

View File

@@ -1,16 +1,18 @@
import { PageLink } from "./myPages/navigation" import { PageLink } from "./myPages/navigation"
import { Edges } from "./utils/edges"
import type { AllRequestResponse } from "./utils/all" import type { AllRequestResponse } from "./utils/all"
import type { Typename } from "./utils/typename" import type { Typename } from "./utils/typename"
import { Edges } from "./utils/edges"
import type { RTEDocument } from "../rte/node" import type { RTEDocument } from "../rte/node"
import type { Embeds } from "./embeds" import type { Embeds } from "./embeds"
import type { ContactField } from "./contactConfig" import type { ContactField } from "./contactConfig"
enum SidebarTypenameEnum { export enum SidebarTypenameEnum {
LoyaltyPageSidebarLoyaltyJoinContact = "LoyaltyPageSidebarLoyaltyJoinContact", LoyaltyPageSidebarJoinLoyaltyContact = "LoyaltyPageSidebarJoinLoyaltyContact",
LoyaltyPageSidebarContent = "LoyaltyPageSidebarContent", LoyaltyPageSidebarContent = "LoyaltyPageSidebarContent",
} }
export type SidebarTypename = keyof typeof SidebarTypenameEnum
type SidebarContent = { type SidebarContent = {
content: { content: {
embedded_itemsConnection: Edges<Embeds> embedded_itemsConnection: Edges<Embeds>
@@ -24,8 +26,8 @@ type Contact = {
} }
} }
type LoyaltyJoinContact = { export type JoinLoyaltyContact = {
loyalty_join_contact: { join_loyalty_contact: {
title: string title: string
contact: Typename< contact: Typename<
Contact, Contact,
@@ -42,8 +44,8 @@ type LoyaltyJoinContact = {
export type Sidebar = export type Sidebar =
| Typename<SidebarContent, SidebarTypenameEnum.LoyaltyPageSidebarContent> | Typename<SidebarContent, SidebarTypenameEnum.LoyaltyPageSidebarContent>
| Typename< | Typename<
LoyaltyJoinContact, JoinLoyaltyContact,
SidebarTypenameEnum.LoyaltyPageSidebarLoyaltyJoinContact SidebarTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContact
> >
enum ContentBlocks { enum ContentBlocks {