feat(WEB-250): overview hero final ui
This commit is contained in:
@@ -37,6 +37,8 @@ const breadcrumbsRefsItems = z.object({
|
||||
),
|
||||
})
|
||||
|
||||
export type BreadcrumbsRefsItems = z.infer<typeof breadcrumbsRefsItems>
|
||||
|
||||
export const validateMyPagesBreadcrumbsRefsContentstackSchema = z.object({
|
||||
all_account_page: breadcrumbsRefsItems,
|
||||
})
|
||||
@@ -45,37 +47,39 @@ export const validateLoyaltyPageBreadcrumbsRefsContentstackSchema = z.object({
|
||||
all_loyalty_page: breadcrumbsRefsItems,
|
||||
})
|
||||
|
||||
const breadcrumbsItems = z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
web: z.object({
|
||||
breadcrumbs: z.object({
|
||||
title: z.string(),
|
||||
parentsConnection: z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: z.object({
|
||||
web: z.object({
|
||||
breadcrumbs: z.object({
|
||||
title: z.string(),
|
||||
}),
|
||||
}),
|
||||
system: z.object({
|
||||
locale: z.nativeEnum(Lang),
|
||||
uid: z.string(),
|
||||
}),
|
||||
url: z.string(),
|
||||
const page = z.object({
|
||||
web: z.object({
|
||||
breadcrumbs: z.object({
|
||||
title: z.string(),
|
||||
parentsConnection: z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: z.object({
|
||||
web: z.object({
|
||||
breadcrumbs: z.object({
|
||||
title: z.string(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
system: z.object({
|
||||
locale: z.nativeEnum(Lang),
|
||||
uid: z.string(),
|
||||
}),
|
||||
url: z.string(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
system: z.object({
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
}),
|
||||
system: z.object({
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
|
||||
export type Page = z.infer<typeof page>
|
||||
|
||||
const breadcrumbsItems = z.object({
|
||||
items: z.array(page),
|
||||
})
|
||||
|
||||
export const validateMyPagesBreadcrumbsContentstackSchema = z.object({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
import {
|
||||
GetLoyaltyPageBreadcrumbs,
|
||||
GetLoyaltyPageBreadcrumbsRefs,
|
||||
@@ -7,25 +6,22 @@ import {
|
||||
GetMyPagesBreadcrumbs,
|
||||
GetMyPagesBreadcrumbsRefs,
|
||||
} from "@/lib/graphql/Query/BreadcrumbsMyPages.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
import { internalServerError } from "@/server/errors/trpc"
|
||||
import { contentstackProcedure, router } from "@/server/trpc"
|
||||
|
||||
import {
|
||||
generateRefsResponseTag,
|
||||
generateTag,
|
||||
generateTags,
|
||||
} from "@/utils/generateTag"
|
||||
import { removeMultipleSlashes } from "@/utils/url"
|
||||
|
||||
import {
|
||||
getBreadcrumbsSchema,
|
||||
validateLoyaltyPageBreadcrumbsContentstackSchema,
|
||||
validateLoyaltyPageBreadcrumbsRefsContentstackSchema,
|
||||
validateMyPagesBreadcrumbsContentstackSchema,
|
||||
validateMyPagesBreadcrumbsRefsContentstackSchema,
|
||||
} from "./output"
|
||||
import { affix, getConnections, homeBreadcrumbs } from "./utils"
|
||||
import {
|
||||
getBreadcrumbs,
|
||||
getRefsResponse,
|
||||
getResponse,
|
||||
getTags,
|
||||
Variables,
|
||||
} from "./utils"
|
||||
|
||||
import type {
|
||||
GetLoyaltyPageBreadcrumbsData,
|
||||
@@ -35,23 +31,11 @@ import type {
|
||||
} from "@/types/requests/myPages/breadcrumbs"
|
||||
import { PageTypeEnum } from "@/types/requests/pageType"
|
||||
|
||||
type fetchBreadcrumbs = {
|
||||
lang: Lang
|
||||
pathname: string
|
||||
}
|
||||
async function getLoyaltyPageBreadcrumbs({ lang, pathname }: fetchBreadcrumbs) {
|
||||
const refsResponse = await request<GetLoyaltyPageBreadcrumbsRefsData>(
|
||||
async function getLoyaltyPageBreadcrumbs(variables: Variables) {
|
||||
const refsResponse = await getRefsResponse<GetLoyaltyPageBreadcrumbsRefsData>(
|
||||
GetLoyaltyPageBreadcrumbsRefs,
|
||||
{ locale: lang, url: pathname },
|
||||
{
|
||||
next: {
|
||||
tags: [generateRefsResponseTag(lang, pathname, affix)],
|
||||
},
|
||||
}
|
||||
variables
|
||||
)
|
||||
if (!refsResponse.data) {
|
||||
throw notFound(refsResponse)
|
||||
}
|
||||
|
||||
const validatedRefsData =
|
||||
validateLoyaltyPageBreadcrumbsRefsContentstackSchema.safeParse(
|
||||
@@ -62,19 +46,13 @@ async function getLoyaltyPageBreadcrumbs({ lang, pathname }: fetchBreadcrumbs) {
|
||||
throw internalServerError(validatedRefsData.error)
|
||||
}
|
||||
|
||||
const connections = getConnections(validatedRefsData.data.all_loyalty_page)
|
||||
const tags = generateTags(lang, connections)
|
||||
const page = validatedRefsData.data.all_loyalty_page.items[0]
|
||||
tags.push(generateTag(lang, page.system.uid, affix))
|
||||
const tags = getTags(validatedRefsData.data.all_loyalty_page, variables)
|
||||
|
||||
const response = await request<GetLoyaltyPageBreadcrumbsData>(
|
||||
const response = await getResponse<GetLoyaltyPageBreadcrumbsData>(
|
||||
GetLoyaltyPageBreadcrumbs,
|
||||
{ locale: lang, url: pathname },
|
||||
{ next: { tags } }
|
||||
variables,
|
||||
tags
|
||||
)
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
const validatedBreadcrumbsData =
|
||||
validateLoyaltyPageBreadcrumbsContentstackSchema.safeParse(response.data)
|
||||
@@ -83,43 +61,17 @@ async function getLoyaltyPageBreadcrumbs({ lang, pathname }: fetchBreadcrumbs) {
|
||||
throw internalServerError(validatedBreadcrumbsData.error)
|
||||
}
|
||||
|
||||
const parentBreadcrumbs =
|
||||
validatedBreadcrumbsData.data.all_loyalty_page.items[0].web.breadcrumbs.parentsConnection.edges.map(
|
||||
(breadcrumb) => {
|
||||
return {
|
||||
href: removeMultipleSlashes(
|
||||
`/${breadcrumb.node.system.locale}/${breadcrumb.node.url}`
|
||||
),
|
||||
title: breadcrumb.node.web.breadcrumbs.title,
|
||||
uid: breadcrumb.node.system.uid,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const pageBreadcrumb =
|
||||
validatedBreadcrumbsData.data.all_loyalty_page.items.map((breadcrumb) => {
|
||||
return {
|
||||
title: breadcrumb.web.breadcrumbs.title,
|
||||
uid: breadcrumb.system.uid,
|
||||
}
|
||||
})
|
||||
|
||||
return [pageBreadcrumb, parentBreadcrumbs]
|
||||
return getBreadcrumbs(
|
||||
validatedBreadcrumbsData.data.all_loyalty_page.items[0],
|
||||
variables.locale
|
||||
)
|
||||
}
|
||||
|
||||
async function getMyPagesBreadcrumbs({ lang, pathname }: fetchBreadcrumbs) {
|
||||
const refsResponse = await request<GetMyPagesBreadcrumbsRefsData>(
|
||||
async function getMyPagesBreadcrumbs(variables: Variables) {
|
||||
const refsResponse = await getRefsResponse<GetMyPagesBreadcrumbsRefsData>(
|
||||
GetMyPagesBreadcrumbsRefs,
|
||||
{ locale: lang, url: pathname },
|
||||
{
|
||||
next: {
|
||||
tags: [generateRefsResponseTag(lang, pathname, affix)],
|
||||
},
|
||||
}
|
||||
variables
|
||||
)
|
||||
if (!refsResponse.data) {
|
||||
throw notFound(refsResponse)
|
||||
}
|
||||
|
||||
const validatedRefsData =
|
||||
validateMyPagesBreadcrumbsRefsContentstackSchema.safeParse(
|
||||
@@ -129,19 +81,12 @@ async function getMyPagesBreadcrumbs({ lang, pathname }: fetchBreadcrumbs) {
|
||||
throw internalServerError(validatedRefsData.error)
|
||||
}
|
||||
|
||||
const connections = getConnections(validatedRefsData.data.all_account_page)
|
||||
const tags = generateTags(lang, connections)
|
||||
const page = validatedRefsData.data.all_account_page.items[0]
|
||||
tags.push(generateTag(lang, page.system.uid, affix))
|
||||
|
||||
const response = await request<GetMyPagesBreadcrumbsData>(
|
||||
const tags = getTags(validatedRefsData.data.all_account_page, variables)
|
||||
const response = await getResponse<GetMyPagesBreadcrumbsData>(
|
||||
GetMyPagesBreadcrumbs,
|
||||
{ locale: lang, url: pathname },
|
||||
{ next: { tags } }
|
||||
variables,
|
||||
tags
|
||||
)
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
const validatedBreadcrumbsData =
|
||||
validateMyPagesBreadcrumbsContentstackSchema.safeParse(response.data)
|
||||
@@ -150,62 +95,26 @@ async function getMyPagesBreadcrumbs({ lang, pathname }: fetchBreadcrumbs) {
|
||||
throw internalServerError(validatedBreadcrumbsData.error)
|
||||
}
|
||||
|
||||
const parentBreadcrumbs =
|
||||
validatedBreadcrumbsData.data.all_account_page.items[0].web.breadcrumbs.parentsConnection.edges.map(
|
||||
(breadcrumb) => {
|
||||
return {
|
||||
href: removeMultipleSlashes(
|
||||
`/${breadcrumb.node.system.locale}/${breadcrumb.node.url}`
|
||||
),
|
||||
title: breadcrumb.node.web.breadcrumbs.title,
|
||||
uid: breadcrumb.node.system.uid,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const pageBreadcrumb =
|
||||
validatedBreadcrumbsData.data.all_account_page.items.map((breadcrumb) => {
|
||||
return {
|
||||
title: breadcrumb.web.breadcrumbs.title,
|
||||
uid: breadcrumb.system.uid,
|
||||
}
|
||||
})
|
||||
|
||||
return [pageBreadcrumb, parentBreadcrumbs]
|
||||
return getBreadcrumbs(
|
||||
validatedBreadcrumbsData.data.all_account_page.items[0],
|
||||
variables.locale
|
||||
)
|
||||
}
|
||||
|
||||
export const breadcrumbsQueryRouter = router({
|
||||
get: contentstackProcedure.query(async ({ ctx }) => {
|
||||
let pageBreadcrumb, parentBreadcrumbs
|
||||
const variables = {
|
||||
locale: ctx.lang,
|
||||
url: ctx.pathname,
|
||||
}
|
||||
|
||||
switch (ctx.contentType) {
|
||||
case PageTypeEnum.accountPage:
|
||||
;[pageBreadcrumb, parentBreadcrumbs] = await getMyPagesBreadcrumbs({
|
||||
lang: ctx.lang,
|
||||
pathname: ctx.pathname,
|
||||
})
|
||||
break
|
||||
return await getMyPagesBreadcrumbs(variables)
|
||||
case PageTypeEnum.loyaltyPage:
|
||||
;[pageBreadcrumb, parentBreadcrumbs] = await getLoyaltyPageBreadcrumbs({
|
||||
lang: ctx.lang,
|
||||
pathname: ctx.pathname,
|
||||
})
|
||||
break
|
||||
return await getLoyaltyPageBreadcrumbs(variables)
|
||||
default:
|
||||
return []
|
||||
}
|
||||
|
||||
const breadcrumbs = [
|
||||
homeBreadcrumbs[ctx.lang],
|
||||
parentBreadcrumbs,
|
||||
pageBreadcrumb,
|
||||
].flat()
|
||||
|
||||
const validatedBreadcrumbs = getBreadcrumbsSchema.safeParse(breadcrumbs)
|
||||
if (!validatedBreadcrumbs.success) {
|
||||
throw internalServerError(validatedBreadcrumbs.error)
|
||||
}
|
||||
|
||||
return validatedBreadcrumbs.data
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
|
||||
import {
|
||||
generateRefsResponseTag,
|
||||
generateTag,
|
||||
generateTags,
|
||||
} from "@/utils/generateTag"
|
||||
import { removeMultipleSlashes } from "@/utils/url"
|
||||
|
||||
import { BreadcrumbsRefsItems, getBreadcrumbsSchema,Page } from "./output"
|
||||
|
||||
import type { GetBreadcrumbsItems } from "@/types/requests/myPages/breadcrumbs"
|
||||
import type { Edges } from "@/types/requests/utils/edges"
|
||||
@@ -47,3 +58,73 @@ export const homeBreadcrumbs = {
|
||||
uid: "sv",
|
||||
},
|
||||
}
|
||||
|
||||
export type Variables = {
|
||||
locale: Lang
|
||||
url: string
|
||||
}
|
||||
|
||||
export async function getRefsResponse<T>(query: string, variables: Variables) {
|
||||
const refsResponse = await request<T>(query, variables, {
|
||||
next: {
|
||||
tags: [generateRefsResponseTag(variables.locale, variables.url, affix)],
|
||||
},
|
||||
})
|
||||
if (!refsResponse.data) {
|
||||
throw notFound(refsResponse)
|
||||
}
|
||||
|
||||
return refsResponse
|
||||
}
|
||||
|
||||
export function getTags(page: BreadcrumbsRefsItems, variables: Variables) {
|
||||
const connections = getConnections(page)
|
||||
const tags = generateTags(variables.locale, connections)
|
||||
tags.push(generateTag(variables.locale, page.items[0].system.uid, affix))
|
||||
return tags
|
||||
}
|
||||
|
||||
export async function getResponse<T>(
|
||||
query: string,
|
||||
variables: Variables,
|
||||
tags: string[]
|
||||
) {
|
||||
const response = await request<T>(query, variables, { next: { tags } })
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
export function getBreadcrumbs(page: Page, lang: Lang) {
|
||||
const parentBreadcrumbs = page.web.breadcrumbs.parentsConnection.edges.map(
|
||||
(breadcrumb) => {
|
||||
return {
|
||||
href: removeMultipleSlashes(
|
||||
`/${breadcrumb.node.system.locale}/${breadcrumb.node.url}`
|
||||
),
|
||||
title: breadcrumb.node.web.breadcrumbs.title,
|
||||
uid: breadcrumb.node.system.uid,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const pageBreadcrumb = {
|
||||
title: page.web.breadcrumbs.title,
|
||||
uid: page.system.uid,
|
||||
}
|
||||
|
||||
const breadcrumbs = [
|
||||
homeBreadcrumbs[lang],
|
||||
parentBreadcrumbs,
|
||||
pageBreadcrumb,
|
||||
].flat()
|
||||
|
||||
const validatedBreadcrumbs = getBreadcrumbsSchema.safeParse(breadcrumbs)
|
||||
if (!validatedBreadcrumbs.success) {
|
||||
throw internalServerError(validatedBreadcrumbs.error)
|
||||
}
|
||||
|
||||
return validatedBreadcrumbs.data
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import { z } from "zod"
|
||||
|
||||
export const staysInput = z
|
||||
.object({
|
||||
cursor: z.string().optional(),
|
||||
limit: z.number().min(0).default(6),
|
||||
cursor: z.number().nullish(),
|
||||
})
|
||||
.default({})
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export const userQueryRouter = router({
|
||||
params.set("limit", limit.toString())
|
||||
|
||||
if (cursor) {
|
||||
params.set("offset", cursor.toString())
|
||||
params.set("offset", cursor)
|
||||
}
|
||||
|
||||
const apiResponse = await api.get(
|
||||
@@ -111,6 +111,7 @@ export const userQueryRouter = router({
|
||||
}
|
||||
|
||||
const apiJson = await apiResponse.json()
|
||||
|
||||
const verifiedData = getStaysSchema.safeParse(apiJson)
|
||||
if (!verifiedData.success) {
|
||||
throw internalServerError(verifiedData.error)
|
||||
@@ -118,7 +119,7 @@ export const userQueryRouter = router({
|
||||
|
||||
const nextCursor =
|
||||
verifiedData.data.links &&
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
@@ -137,7 +138,7 @@ export const userQueryRouter = router({
|
||||
params.set("limit", limit.toString())
|
||||
|
||||
if (cursor) {
|
||||
params.set("offset", cursor.toString())
|
||||
params.set("offset", cursor)
|
||||
}
|
||||
|
||||
const apiResponse = await api.get(
|
||||
@@ -171,7 +172,7 @@ export const userQueryRouter = router({
|
||||
|
||||
const nextCursor =
|
||||
verifiedData.data.links &&
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
@@ -235,7 +236,7 @@ export const userQueryRouter = router({
|
||||
|
||||
const nextCursor =
|
||||
verifiedData.data.links &&
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
verifiedData.data.links.offset < verifiedData.data.links.totalCount
|
||||
? verifiedData.data.links.offset
|
||||
: undefined
|
||||
|
||||
|
||||
Reference in New Issue
Block a user