refactor: zod validation and pr comments
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
.layout {
|
.layout {
|
||||||
--max-width: 101.4rem;
|
|
||||||
--header-height: 4.5rem;
|
--header-height: 4.5rem;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
.layout {
|
.layout {
|
||||||
--max-width: 101.4rem;
|
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
font-family: var(--ff-fira-sans);
|
font-family: var(--ff-fira-sans);
|
||||||
background-color: var(--Brand-Coffee-Subtle);
|
background-color: var(--Brand-Coffee-Subtle);
|
||||||
|
|||||||
@@ -26,5 +26,6 @@
|
|||||||
gap: 6.4rem;
|
gap: 6.4rem;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
|
grid-column: 2 / -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,8 @@ export default async function LoyaltyPage({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.content}>
|
<section className={styles.content}>
|
||||||
<aside>
|
{loyaltyPage.sidebar ? <Sidebar blocks={loyaltyPage.sidebar} /> : null}
|
||||||
{loyaltyPage.sidebar
|
|
||||||
? loyaltyPage.sidebar.map((block, i) => (
|
|
||||||
<Sidebar key={i} block={block} />
|
|
||||||
))
|
|
||||||
: null}
|
|
||||||
</aside>
|
|
||||||
<MaxWidth className={styles.blocks} tag="main">
|
<MaxWidth className={styles.blocks} tag="main">
|
||||||
<Blocks blocks={loyaltyPage.blocks} />
|
<Blocks blocks={loyaltyPage.blocks} />
|
||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
:root {
|
:root {
|
||||||
font-size: 62.5%;
|
font-size: 62.5%;
|
||||||
|
--max-width: 113.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import Title from "@/components/Title"
|
|||||||
|
|
||||||
import styles from "./cardGrid.module.css"
|
import styles from "./cardGrid.module.css"
|
||||||
|
|
||||||
import { CardGridProps, CardProps } from "@/types/components/loyalty/blocks"
|
import { CardGridProps } from "@/types/components/loyalty/blocks"
|
||||||
|
|
||||||
export default function CardGrid({ card_grid }: CardGridProps) {
|
export default function CardGrid({ card_grid }: CardGridProps) {
|
||||||
return (
|
return (
|
||||||
@@ -27,17 +27,15 @@ export default function CardGrid({ card_grid }: CardGridProps) {
|
|||||||
</header>
|
</header>
|
||||||
<div className={styles.cardContainer}>
|
<div className={styles.cardContainer}>
|
||||||
{card_grid.cards.map((card, i) => (
|
{card_grid.cards.map((card, i) => (
|
||||||
<CardWrapper key={`${card.title}+${i}`} card={card} />
|
<div className={styles.cardWrapper} key={`${card.title}+${i}`}>
|
||||||
|
<Card
|
||||||
|
subtitle={card.subtitle}
|
||||||
|
title={card.title}
|
||||||
|
link={card.link}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function CardWrapper({ card }: CardProps) {
|
|
||||||
return (
|
|
||||||
<div className={styles.cardWrapper}>
|
|
||||||
<Card subtitle={card.subtitle} title={card.title} link={card.link} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import styles from "./howItWorks.module.css"
|
|||||||
|
|
||||||
export default function HowItWorks() {
|
export default function HowItWorks() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<section className={styles.container}>
|
||||||
<Title level="h3" uppercase>
|
<Title level="h3" uppercase>
|
||||||
How it works Placeholder
|
How it works Placeholder
|
||||||
</Title>
|
</Title>
|
||||||
</div>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export default async function LoyaltyLevels() {
|
|||||||
|
|
||||||
function LevelCard({ level }: LevelCardProps) {
|
function LevelCard({ level }: LevelCardProps) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.card}>
|
<article className={styles.card}>
|
||||||
<Title level="h4">{level.tier}</Title>
|
<Title level="h4">{level.tier}</Title>
|
||||||
<Image src={level.logo} alt={level.name} width={140} height={54} />
|
<Image src={level.logo} alt={level.name} width={140} height={54} />
|
||||||
<p className={styles.qualifications}>
|
<p className={styles.qualifications}>
|
||||||
@@ -45,6 +45,6 @@ function LevelCard({ level }: LevelCardProps) {
|
|||||||
{benefit}
|
{benefit}
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
</div>
|
</article>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
.titleContainer {
|
.titleContainer {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas: "title link";
|
grid-template-areas: "title link" "subtitle subtitle";
|
||||||
grid-template-columns: 1fr max-content;
|
grid-template-columns: 1fr max-content;
|
||||||
padding-bottom: 0.8rem;
|
padding-bottom: 0.8rem;
|
||||||
}
|
}
|
||||||
@@ -25,4 +25,5 @@
|
|||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
grid-area: subtitle;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,25 +32,23 @@ export default function DynamicContent({
|
|||||||
}: DynamicContentProps) {
|
}: DynamicContentProps) {
|
||||||
return (
|
return (
|
||||||
<section className={styles.container}>
|
<section className={styles.container}>
|
||||||
<header>
|
<header className={styles.titleContainer}>
|
||||||
<div className={styles.titleContainer}>
|
{dynamicContent.title && (
|
||||||
{dynamicContent.title && (
|
<Title
|
||||||
<Title
|
as="h3"
|
||||||
as="h3"
|
level="h2"
|
||||||
level="h2"
|
className={styles.title}
|
||||||
className={styles.title}
|
weight="semiBold"
|
||||||
weight="semiBold"
|
uppercase
|
||||||
uppercase
|
>
|
||||||
>
|
{dynamicContent.title}
|
||||||
{dynamicContent.title}
|
</Title>
|
||||||
</Title>
|
)}
|
||||||
)}
|
{dynamicContent.link ? (
|
||||||
{dynamicContent.link ? (
|
<Link className={styles.link} href={dynamicContent.link.href}>
|
||||||
<Link className={styles.link} href={dynamicContent.link.href}>
|
{dynamicContent.link.text}
|
||||||
{dynamicContent.link.text}
|
</Link>
|
||||||
</Link>
|
) : null}
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
{dynamicContent.subtitle && (
|
{dynamicContent.subtitle && (
|
||||||
<Title
|
<Title
|
||||||
as="h5"
|
as="h5"
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ export function Blocks({ blocks }: BlocksProps) {
|
|||||||
return <CardGrid card_grid={block.card_grid} />
|
return <CardGrid card_grid={block.card_grid} />
|
||||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent:
|
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent:
|
||||||
return (
|
return (
|
||||||
<JsonToHtml
|
<section>
|
||||||
nodes={block.content.content.json.children}
|
<JsonToHtml
|
||||||
embeds={block.content.content.embedded_itemsConnection.edges}
|
nodes={block.content.content.json.children}
|
||||||
/>
|
embeds={block.content.content.embedded_itemsConnection.edges}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
)
|
)
|
||||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
|
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
|
||||||
return <DynamicContentBlock dynamicContent={block.dynamic_content} />
|
return <DynamicContentBlock dynamicContent={block.dynamic_content} />
|
||||||
|
|||||||
@@ -5,13 +5,9 @@ import { getValueFromContactConfig } from "@/utils/contactConfig"
|
|||||||
|
|
||||||
import styles from "./contactRow.module.css"
|
import styles from "./contactRow.module.css"
|
||||||
|
|
||||||
import type { ContactFields } from "@/types/requests/contactConfig"
|
import type { ContactRowProps } from "@/types/components/loyalty/sidebar"
|
||||||
|
|
||||||
export default async function ContactRow({
|
export default async function ContactRow({ contact }: ContactRowProps) {
|
||||||
contact,
|
|
||||||
}: {
|
|
||||||
contact: ContactFields
|
|
||||||
}) {
|
|
||||||
const data = await serverClient().contentstack.contactConfig.get({
|
const data = await serverClient().contentstack.contactConfig.get({
|
||||||
lang: Lang.en,
|
lang: Lang.en,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default async function Contact({ contactBlock }: ContactProps) {
|
|||||||
case JoinLoyaltyContactTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContactBlockContactContact:
|
case JoinLoyaltyContactTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContactBlockContactContact:
|
||||||
return (
|
return (
|
||||||
<ContactRow
|
<ContactRow
|
||||||
key={`${contact.display_text}-i`}
|
key={`${contact.display_text}-${i}`}
|
||||||
contact={contact}
|
contact={contact}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default function JoinLoyaltyContact({ block }: JoinLoyaltyContactProps) {
|
|||||||
<span>{_("Join Scandic Friends")}</span>
|
<span>{_("Join Scandic Friends")}</span>
|
||||||
</Button>
|
</Button>
|
||||||
<div className={styles.linkContainer}>
|
<div className={styles.linkContainer}>
|
||||||
<Link href="/login" className={styles.logoutLink}>
|
<Link href="/login" className={styles.loginLink}>
|
||||||
{_("Already a friend?")} <br />
|
{_("Already a friend?")} <br />
|
||||||
{_("Click here to log in")}
|
{_("Click here to log in")}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logoutLink {
|
.loginLink {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--some-black-color, #2e2e2e);
|
color: var(--some-black-color, #2e2e2e);
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
|||||||
@@ -7,20 +7,26 @@ import styles from "./sidebar.module.css"
|
|||||||
import { SidebarProps } from "@/types/components/loyalty/sidebar"
|
import { SidebarProps } from "@/types/components/loyalty/sidebar"
|
||||||
import { SidebarTypenameEnum } from "@/types/requests/loyaltyPage"
|
import { SidebarTypenameEnum } from "@/types/requests/loyaltyPage"
|
||||||
|
|
||||||
export default function SidebarLoyalty({ block }: SidebarProps) {
|
export default function SidebarLoyalty({ blocks }: SidebarProps) {
|
||||||
switch (block.__typename) {
|
return (
|
||||||
case SidebarTypenameEnum.LoyaltyPageSidebarContent:
|
<aside>
|
||||||
return (
|
{blocks.map((block) => {
|
||||||
<section className={styles.content}>
|
switch (block.__typename) {
|
||||||
<JsonToHtml
|
case SidebarTypenameEnum.LoyaltyPageSidebarContent:
|
||||||
embeds={block.content.content.embedded_itemsConnection.edges}
|
return (
|
||||||
nodes={block.content.content.json.children}
|
<section className={styles.content}>
|
||||||
/>
|
<JsonToHtml
|
||||||
</section>
|
embeds={block.content.content.embedded_itemsConnection.edges}
|
||||||
)
|
nodes={block.content.content.json.children}
|
||||||
case SidebarTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContact:
|
/>
|
||||||
return <JoinLoyaltyContact block={block.join_loyalty_contact} />
|
</section>
|
||||||
default:
|
)
|
||||||
return null
|
case SidebarTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContact:
|
||||||
}
|
return <JoinLoyaltyContact block={block.join_loyalty_contact} />
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
.content {
|
@media screen and (max-width: 950px) {
|
||||||
padding: 0 1.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 950px) {
|
|
||||||
.content {
|
.content {
|
||||||
padding: 0;
|
padding: 0 1.6rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default function Card({
|
|||||||
openInNewTab = false,
|
openInNewTab = false,
|
||||||
}: CardProps) {
|
}: CardProps) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.linkCard}>
|
<article className={styles.linkCard}>
|
||||||
{title ? (
|
{title ? (
|
||||||
<Title level="h3" weight="semiBold">
|
<Title level="h3" weight="semiBold">
|
||||||
{title}
|
{title}
|
||||||
@@ -33,6 +33,6 @@ export default function Card({
|
|||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</article>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
|
|||||||
all_loyalty_page(where: { url: $url, locale: $locale }) {
|
all_loyalty_page(where: { url: $url, locale: $locale }) {
|
||||||
items {
|
items {
|
||||||
blocks {
|
blocks {
|
||||||
|
__typename
|
||||||
... on LoyaltyPageBlocksDynamicContent {
|
... on LoyaltyPageBlocksDynamicContent {
|
||||||
__typename
|
|
||||||
dynamic_content {
|
dynamic_content {
|
||||||
title
|
title
|
||||||
subtitle
|
subtitle
|
||||||
@@ -28,7 +28,6 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on LoyaltyPageBlocksCardGrid {
|
... on LoyaltyPageBlocksCardGrid {
|
||||||
__typename
|
|
||||||
card_grid {
|
card_grid {
|
||||||
title
|
title
|
||||||
subtitle
|
subtitle
|
||||||
@@ -51,7 +50,6 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on LoyaltyPageBlocksContent {
|
... on LoyaltyPageBlocksContent {
|
||||||
__typename
|
|
||||||
content {
|
content {
|
||||||
content {
|
content {
|
||||||
json
|
json
|
||||||
@@ -70,8 +68,8 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
|
|||||||
}
|
}
|
||||||
title
|
title
|
||||||
sidebar {
|
sidebar {
|
||||||
|
__typename
|
||||||
... on LoyaltyPageSidebarJoinLoyaltyContact {
|
... on LoyaltyPageSidebarJoinLoyaltyContact {
|
||||||
__typename
|
|
||||||
join_loyalty_contact {
|
join_loyalty_contact {
|
||||||
title
|
title
|
||||||
preamble
|
preamble
|
||||||
@@ -87,7 +85,6 @@ query GetLoyaltyPage($locale: String!, $url: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on LoyaltyPageSidebarContent {
|
... on LoyaltyPageSidebarContent {
|
||||||
__typename
|
|
||||||
content {
|
content {
|
||||||
content {
|
content {
|
||||||
json
|
json
|
||||||
|
|||||||
5
server/routers/contentstack/contactConfig/input.ts
Normal file
5
server/routers/contentstack/contactConfig/input.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
|
||||||
|
export const getConfigInput = z.object({ lang: z.nativeEnum(Lang) })
|
||||||
60
server/routers/contentstack/contactConfig/output.ts
Normal file
60
server/routers/contentstack/contactConfig/output.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
// Help me write this zod schema based on the type ContactConfig
|
||||||
|
export const validateContactConfigSchema = z.object({
|
||||||
|
all_contact_config: z.object({
|
||||||
|
items: z.array(
|
||||||
|
z.object({
|
||||||
|
email: z.object({
|
||||||
|
name: z.string().nullable(),
|
||||||
|
address: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
email_loyalty: z.object({
|
||||||
|
name: z.string().nullable(),
|
||||||
|
address: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
mailing_address: z.object({
|
||||||
|
zip: z.string().nullable(),
|
||||||
|
street: z.string().nullable(),
|
||||||
|
name: z.string().nullable(),
|
||||||
|
city: z.string().nullable(),
|
||||||
|
country: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
phone: z.object({
|
||||||
|
number: z.string().nullable(),
|
||||||
|
name: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
phone_loyalty: z.object({
|
||||||
|
number: z.string().nullable(),
|
||||||
|
name: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
visiting_address: z.object({
|
||||||
|
zip: z.string().nullable(),
|
||||||
|
country: z.string().nullable(),
|
||||||
|
city: z.string().nullable(),
|
||||||
|
street: z.string().nullable(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export enum ContactFieldGroupsEnum {
|
||||||
|
email = "email",
|
||||||
|
email_loyalty = "email_loyalty",
|
||||||
|
mailing_address = "mailing_address",
|
||||||
|
phone = "phone",
|
||||||
|
phone_loyalty = "phone_loyalty",
|
||||||
|
visiting_address = "visiting_address",
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ContactFieldGroups = keyof typeof ContactFieldGroupsEnum
|
||||||
|
|
||||||
|
export type ContactConfigData = z.infer<typeof validateContactConfigSchema>
|
||||||
|
|
||||||
|
export type ContactConfig = ContactConfigData["all_contact_config"]["items"][0]
|
||||||
|
|
||||||
|
export type ContactFields = {
|
||||||
|
display_text?: string
|
||||||
|
contact_field: string
|
||||||
|
}
|
||||||
@@ -1,32 +1,34 @@
|
|||||||
import { z } from "zod"
|
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
||||||
|
import { request } from "@/lib/graphql/request"
|
||||||
import { badRequestError } from "@/server/errors/trpc"
|
import { badRequestError } from "@/server/errors/trpc"
|
||||||
import { publicProcedure, router } from "@/server/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 { getConfigInput } from "./input"
|
||||||
|
import { type ContactConfigData, validateContactConfigSchema } from "./output"
|
||||||
import type { GetContactConfigData } from "@/types/requests/contactConfig"
|
|
||||||
|
|
||||||
export const contactConfigQueryRouter = router({
|
export const contactConfigQueryRouter = router({
|
||||||
get: publicProcedure
|
get: publicProcedure.input(getConfigInput).query(async ({ input }) => {
|
||||||
.input(z.object({ lang: z.nativeEnum(Lang) }))
|
try {
|
||||||
.query(async ({ input }) => {
|
const contactConfig = await request<ContactConfigData>(GetContactConfig, {
|
||||||
const contactConfig = await request<GetContactConfigData>(
|
locale: input.lang,
|
||||||
GetContactConfig,
|
})
|
||||||
{
|
|
||||||
locale: input.lang,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tags: [`contact-config-${input.lang}`],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (contactConfig.data && contactConfig.data.all_contact_config.total) {
|
if (!contactConfig.data) {
|
||||||
return contactConfig.data.all_contact_config.items[0]
|
throw badRequestError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validatedContactConfigConfig =
|
||||||
|
validateContactConfigSchema.safeParse(contactConfig.data)
|
||||||
|
|
||||||
|
if (!validatedContactConfigConfig.success) {
|
||||||
|
console.error(validatedContactConfigConfig.error)
|
||||||
|
throw badRequestError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
throw badRequestError()
|
throw badRequestError()
|
||||||
}),
|
}
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { router } from "@/server/trpc"
|
import { router } from "@/server/trpc"
|
||||||
|
|
||||||
import { breadcrumbsRouter } from "./breadcrumbs"
|
import { breadcrumbsRouter } from "./breadcrumbs"
|
||||||
import { loyaltyPageRouter } from "./loyaltyPage"
|
|
||||||
import { contactConfigRouter } from "./contactConfig"
|
import { contactConfigRouter } from "./contactConfig"
|
||||||
|
import { loyaltyPageRouter } from "./loyaltyPage"
|
||||||
|
|
||||||
export const contentstackRouter = router({
|
export const contentstackRouter = router({
|
||||||
breadcrumbs: breadcrumbsRouter,
|
breadcrumbs: breadcrumbsRouter,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export const loyaltyPageQueryRouter = router({
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!validatedLoyaltyPage.success) {
|
if (!validatedLoyaltyPage.success) {
|
||||||
|
console.error(validatedLoyaltyPage.error)
|
||||||
throw badRequestError()
|
throw badRequestError()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,15 +69,13 @@ export const loyaltyPageQueryRouter = router({
|
|||||||
cards: block.card_grid.cards.map((card) => {
|
cards: block.card_grid.cards.map((card) => {
|
||||||
return {
|
return {
|
||||||
...card,
|
...card,
|
||||||
link:
|
link: card.referenceConnection.totalCount
|
||||||
card.referenceConnection.totalCount > 0
|
? {
|
||||||
? {
|
href: card.referenceConnection.edges[0].node.url,
|
||||||
href: card.referenceConnection.edges[0].node
|
title:
|
||||||
.url,
|
card.referenceConnection.edges[0].node.title,
|
||||||
title:
|
}
|
||||||
card.referenceConnection.edges[0].node.title,
|
: undefined,
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@@ -86,17 +85,16 @@ export const loyaltyPageQueryRouter = router({
|
|||||||
...block,
|
...block,
|
||||||
dynamic_content: {
|
dynamic_content: {
|
||||||
...block.dynamic_content,
|
...block.dynamic_content,
|
||||||
link:
|
link: block.dynamic_content.link.pageConnection.totalCount
|
||||||
block.dynamic_content.link.pageConnection.totalCount > 0
|
? {
|
||||||
? {
|
text: block.dynamic_content.link.text,
|
||||||
text: block.dynamic_content.link.text,
|
href: block.dynamic_content.link.pageConnection
|
||||||
href: block.dynamic_content.link.pageConnection
|
.edges[0].node.url,
|
||||||
.edges[0].node.url,
|
title:
|
||||||
title:
|
block.dynamic_content.link.pageConnection.edges[0]
|
||||||
block.dynamic_content.link.pageConnection.edges[0]
|
.node.title,
|
||||||
.node.title,
|
}
|
||||||
}
|
: undefined,
|
||||||
: undefined,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent:
|
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent:
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { initTRPC } from "@trpc/server"
|
import { initTRPC } from "@trpc/server"
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { transformer } from "./transformer"
|
|
||||||
import { unauthorizedError } from "./errors/trpc"
|
|
||||||
|
|
||||||
import type { Context } from "./context"
|
import { unauthorizedError } from "./errors/trpc"
|
||||||
|
import { transformer } from "./transformer"
|
||||||
|
|
||||||
import type { Meta } from "@/types/trpc/meta"
|
import type { Meta } from "@/types/trpc/meta"
|
||||||
|
import type { Context } from "./context"
|
||||||
|
|
||||||
const t = initTRPC.context<Context>().meta<Meta>().create({ transformer })
|
const t = initTRPC.context<Context>().meta<Meta>().create({ transformer })
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Block,
|
Block,
|
||||||
CardGrid,
|
CardGrid,
|
||||||
CardGridCard,
|
|
||||||
DynamicContent,
|
DynamicContent,
|
||||||
RteBlockContent,
|
RteBlockContent,
|
||||||
} from "@/server/routers/contentstack/loyaltyPage/output"
|
} from "@/server/routers/contentstack/loyaltyPage/output"
|
||||||
@@ -18,8 +17,6 @@ export type DynamicComponentProps = {
|
|||||||
component: DynamicContent["dynamic_content"]["component"]
|
component: DynamicContent["dynamic_content"]["component"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CardProps = { card: CardGridCard }
|
|
||||||
|
|
||||||
export type CardGridProps = Pick<CardGrid, "card_grid">
|
export type CardGridProps = Pick<CardGrid, "card_grid">
|
||||||
|
|
||||||
export type Content = { content: RteBlockContent["content"]["content"] }
|
export type Content = { content: RteBlockContent["content"]["content"] }
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import { ContactFields } from "@/server/routers/contentstack/contactConfig/output"
|
||||||
import {
|
import {
|
||||||
JoinLoyaltyContact,
|
JoinLoyaltyContact,
|
||||||
Sidebar,
|
Sidebar,
|
||||||
} from "@/server/routers/contentstack/loyaltyPage/output"
|
} from "@/server/routers/contentstack/loyaltyPage/output"
|
||||||
|
|
||||||
export type SidebarProps = {
|
export type SidebarProps = {
|
||||||
block: Sidebar
|
blocks: Sidebar[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type JoinLoyaltyContactProps = {
|
export type JoinLoyaltyContactProps = {
|
||||||
@@ -14,3 +15,7 @@ export type JoinLoyaltyContactProps = {
|
|||||||
export type ContactProps = {
|
export type ContactProps = {
|
||||||
contactBlock: JoinLoyaltyContact["join_loyalty_contact"]["contact"]
|
contactBlock: JoinLoyaltyContact["join_loyalty_contact"]["contact"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ContactRowProps = {
|
||||||
|
contact: ContactFields
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
import { AllRequestResponse } from "./utils/all"
|
|
||||||
|
|
||||||
export type ContactConfig = {
|
|
||||||
email: {
|
|
||||||
name?: string
|
|
||||||
address?: string
|
|
||||||
}
|
|
||||||
email_loyalty: {
|
|
||||||
name?: string
|
|
||||||
address?: string
|
|
||||||
}
|
|
||||||
mailing_address: {
|
|
||||||
zip?: string
|
|
||||||
street?: string
|
|
||||||
name?: string
|
|
||||||
city?: string
|
|
||||||
country?: string
|
|
||||||
}
|
|
||||||
phone: {
|
|
||||||
number?: string
|
|
||||||
name?: string
|
|
||||||
}
|
|
||||||
phone_loyalty: {
|
|
||||||
number?: string
|
|
||||||
name?: string
|
|
||||||
}
|
|
||||||
visiting_address: {
|
|
||||||
zip?: string
|
|
||||||
country?: string
|
|
||||||
city?: string
|
|
||||||
street?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ContactFieldGroupsEnum {
|
|
||||||
email = "email",
|
|
||||||
email_loyalty = "email_loyalty",
|
|
||||||
mailing_address = "mailing_address",
|
|
||||||
phone = "phone",
|
|
||||||
phone_loyalty = "phone_loyalty",
|
|
||||||
visiting_address = "visiting_address",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ContactFieldGroups = keyof typeof ContactFieldGroupsEnum
|
|
||||||
|
|
||||||
export type GetContactConfigData = {
|
|
||||||
all_contact_config: AllRequestResponse<ContactConfig>
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ContactFields = {
|
|
||||||
display_text?: string
|
|
||||||
contact_field: string
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
export type GetContentTypeUidType = {
|
import z from "zod"
|
||||||
all_content_page: {
|
|
||||||
total: number
|
export const validateContentTypeUid = z.object({
|
||||||
}
|
all_content_page: z.object({
|
||||||
all_loyalty_page: {
|
total: z.number(),
|
||||||
total: number
|
}),
|
||||||
}
|
all_loyalty_page: z.object({
|
||||||
all_current_blocks_page: {
|
total: z.number(),
|
||||||
total: number
|
}),
|
||||||
}
|
all_current_blocks_page: z.object({
|
||||||
}
|
total: z.number(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
ContactConfig,
|
ContactConfig,
|
||||||
ContactFieldGroups,
|
ContactFieldGroups,
|
||||||
} from "@/types/requests/contactConfig"
|
} from "@/server/routers/contentstack/contactConfig/output"
|
||||||
|
|
||||||
export function getValueFromContactConfig(
|
export function getValueFromContactConfig(
|
||||||
keyString: string,
|
keyString: string,
|
||||||
@@ -16,4 +16,5 @@ export function getValueFromContactConfig(
|
|||||||
|
|
||||||
return fieldGroup[key]
|
return fieldGroup[key]
|
||||||
}
|
}
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { DocumentNode } from "graphql"
|
import { DocumentNode, print } from "graphql"
|
||||||
|
|
||||||
import { Lang } from "@/constants/languages"
|
import { Lang } from "@/constants/languages"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import GetContentTypeUid from "@/lib/graphql/Query/ContentTypeUid.graphql"
|
import { GetContentTypeUid } from "@/lib/graphql/Query/ContentTypeUid.graphql"
|
||||||
|
|
||||||
import type { GetContentTypeUidType } from "@/types/requests/contentTypeUid"
|
import { validateContentTypeUid } from "@/types/requests/contentTypeUid"
|
||||||
|
|
||||||
export enum PageTypeEnum {
|
export enum PageTypeEnum {
|
||||||
CurrentBlocksPage = "CurrentBlocksPage",
|
CurrentBlocksPage = "CurrentBlocksPage",
|
||||||
@@ -16,7 +16,6 @@ export async function getContentTypeByPathName(
|
|||||||
pathNameWithoutLang: string,
|
pathNameWithoutLang: string,
|
||||||
lang = Lang.en
|
lang = Lang.en
|
||||||
) {
|
) {
|
||||||
const print = (await import("graphql/language/printer")).print
|
|
||||||
const result = await fetch(env.CMS_URL, {
|
const result = await fetch(env.CMS_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
@@ -33,7 +32,17 @@ export async function getContentTypeByPathName(
|
|||||||
})
|
})
|
||||||
|
|
||||||
const pageTypeData = await result.json()
|
const pageTypeData = await result.json()
|
||||||
const pageType = pageTypeData.data as GetContentTypeUidType
|
|
||||||
|
const validatedContentTypeUid = validateContentTypeUid.safeParse(
|
||||||
|
pageTypeData.data
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!validatedContentTypeUid.success) {
|
||||||
|
console.error(validatedContentTypeUid.error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageType = validatedContentTypeUid.data
|
||||||
|
|
||||||
if (pageType.all_content_page.total) {
|
if (pageType.all_content_page.total) {
|
||||||
return PageTypeEnum.ContentPage
|
return PageTypeEnum.ContentPage
|
||||||
|
|||||||
Reference in New Issue
Block a user