feat(WEB-304): remaning UI from design system primitives
This commit is contained in:
@@ -188,24 +188,3 @@ export const validateAccountPageRefsSchema = z.object({
|
||||
export type AccountPageRefsDataRaw = z.infer<
|
||||
typeof validateAccountPageRefsSchema
|
||||
>
|
||||
|
||||
export const validateLanguageSwitcherData = z.object({
|
||||
en: z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable(),
|
||||
da: z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable(),
|
||||
de: z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable(),
|
||||
fi: z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable(),
|
||||
sv: z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable(),
|
||||
no: z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable(),
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
} from "@/lib/graphql/Query/AccountPage.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
import { contentstackProcedure, router } from "@/server/trpc"
|
||||
import { contentstackExtendedProcedureUID, router } from "@/server/trpc"
|
||||
|
||||
import {
|
||||
generateRefsResponseTag,
|
||||
@@ -27,7 +27,7 @@ import { Edges } from "@/types/requests/utils/edges"
|
||||
import { RTEDocument } from "@/types/rte/node"
|
||||
|
||||
export const accountPageQueryRouter = router({
|
||||
get: contentstackProcedure.query(async ({ ctx }) => {
|
||||
get: contentstackExtendedProcedureUID.query(async ({ ctx }) => {
|
||||
const { lang, uid } = ctx
|
||||
|
||||
const refsResponse = await request<AccountPageRefsDataRaw>(
|
||||
|
||||
5
server/routers/contentstack/base/index.ts
Normal file
5
server/routers/contentstack/base/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { mergeRouters } from "@/server/trpc"
|
||||
|
||||
import { baseQueryRouter } from "./query"
|
||||
|
||||
export const baseRouter = mergeRouters(baseQueryRouter)
|
||||
@@ -254,12 +254,3 @@ const validateFooterRefConfigSchema = z.object({
|
||||
})
|
||||
|
||||
export type FooterRefDataRaw = z.infer<typeof validateFooterRefConfigSchema>
|
||||
|
||||
export const validateLanguageSwitcherData = z.object({
|
||||
en: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
|
||||
da: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
|
||||
de: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
|
||||
fi: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
|
||||
sv: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
|
||||
no: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
|
||||
})
|
||||
123
server/routers/contentstack/base/query.ts
Normal file
123
server/routers/contentstack/base/query.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
||||
import {
|
||||
GetCurrentFooter,
|
||||
GetCurrentFooterRef,
|
||||
} from "@/lib/graphql/Query/CurrentFooter.graphql"
|
||||
import {
|
||||
GetCurrentHeader,
|
||||
GetCurrentHeaderRef,
|
||||
} from "@/lib/graphql/Query/CurrentHeader.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
import { contentstackBaseProcedure, router } from "@/server/trpc"
|
||||
|
||||
import { generateTag } from "@/utils/generateTag"
|
||||
|
||||
import {
|
||||
type ContactConfigData,
|
||||
FooterDataRaw,
|
||||
FooterRefDataRaw,
|
||||
HeaderData,
|
||||
HeaderDataRaw,
|
||||
HeaderRefDataRaw,
|
||||
validateContactConfigSchema,
|
||||
validateFooterConfigSchema,
|
||||
validateHeaderConfigSchema,
|
||||
} from "./output"
|
||||
|
||||
export const baseQueryRouter = router({
|
||||
contact: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||
const { lang } = ctx
|
||||
|
||||
const response = await request<ContactConfigData>(GetContactConfig, {
|
||||
locale: lang,
|
||||
})
|
||||
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
const validatedContactConfigConfig = validateContactConfigSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedContactConfigConfig.success) {
|
||||
throw internalServerError(validatedContactConfigConfig.error)
|
||||
}
|
||||
|
||||
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
||||
}),
|
||||
header: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||
const responseRef = await request<HeaderRefDataRaw>(GetCurrentHeaderRef, {
|
||||
locale: ctx.lang,
|
||||
})
|
||||
|
||||
const response = await request<HeaderDataRaw>(
|
||||
GetCurrentHeader,
|
||||
{ locale: ctx.lang },
|
||||
{
|
||||
next: {
|
||||
tags: [
|
||||
generateTag(
|
||||
ctx.lang,
|
||||
responseRef.data.all_current_header.items[0].system.uid
|
||||
),
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
const validatedHeaderConfig = validateHeaderConfigSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedHeaderConfig.success) {
|
||||
throw internalServerError(validatedHeaderConfig.error)
|
||||
}
|
||||
|
||||
const logo =
|
||||
validatedHeaderConfig.data.all_current_header.items[0].logoConnection
|
||||
.edges?.[0]?.node
|
||||
|
||||
return {
|
||||
...validatedHeaderConfig.data.all_current_header.items[0],
|
||||
logo,
|
||||
} as HeaderData
|
||||
}),
|
||||
footer: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||
const responseRef = await request<FooterRefDataRaw>(GetCurrentFooterRef, {
|
||||
locale: ctx.lang,
|
||||
})
|
||||
|
||||
const response = await request<FooterDataRaw>(
|
||||
GetCurrentFooter,
|
||||
{
|
||||
locale: ctx.lang,
|
||||
},
|
||||
{
|
||||
next: {
|
||||
tags: [
|
||||
generateTag(
|
||||
ctx.lang,
|
||||
responseRef.data.all_current_footer.items[0].system.uid
|
||||
),
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const validatedFooterConfig = validateFooterConfigSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedFooterConfig.success) {
|
||||
throw internalServerError(validatedFooterConfig.error)
|
||||
}
|
||||
|
||||
return validatedFooterConfig.data.all_current_footer.items[0]
|
||||
}),
|
||||
})
|
||||
@@ -48,10 +48,18 @@ export const validateMyPagesBreadcrumbsRefsContentstackSchema = z.object({
|
||||
all_account_page: breadcrumbsRefsItems,
|
||||
})
|
||||
|
||||
export type GetMyPagesBreadcrumbsRefsData = z.infer<
|
||||
typeof validateMyPagesBreadcrumbsRefsContentstackSchema
|
||||
>
|
||||
|
||||
export const validateLoyaltyPageBreadcrumbsRefsContentstackSchema = z.object({
|
||||
all_loyalty_page: breadcrumbsRefsItems,
|
||||
})
|
||||
|
||||
export type GetLoyaltyPageBreadcrumbsRefsData = z.infer<
|
||||
typeof validateLoyaltyPageBreadcrumbsContentstackSchema
|
||||
>
|
||||
|
||||
const page = z.object({
|
||||
web: z.object({
|
||||
breadcrumbs: z.object({
|
||||
@@ -91,6 +99,14 @@ export const validateMyPagesBreadcrumbsContentstackSchema = z.object({
|
||||
all_account_page: breadcrumbsItems,
|
||||
})
|
||||
|
||||
export type GetMyPagesBreadcrumbsData = z.infer<
|
||||
typeof validateMyPagesBreadcrumbsContentstackSchema
|
||||
>
|
||||
|
||||
export const validateLoyaltyPageBreadcrumbsContentstackSchema = z.object({
|
||||
all_loyalty_page: breadcrumbsItems,
|
||||
})
|
||||
|
||||
export type GetLoyaltyPageBreadcrumbsData = z.infer<
|
||||
typeof validateLoyaltyPageBreadcrumbsContentstackSchema
|
||||
>
|
||||
|
||||
@@ -7,9 +7,13 @@ import {
|
||||
GetMyPagesBreadcrumbsRefs,
|
||||
} from "@/lib/graphql/Query/BreadcrumbsMyPages.graphql"
|
||||
import { internalServerError } from "@/server/errors/trpc"
|
||||
import { contentstackProcedure, router } from "@/server/trpc"
|
||||
import { contentstackExtendedProcedureUID, router } from "@/server/trpc"
|
||||
|
||||
import {
|
||||
type GetLoyaltyPageBreadcrumbsData,
|
||||
type GetLoyaltyPageBreadcrumbsRefsData,
|
||||
type GetMyPagesBreadcrumbsData,
|
||||
type GetMyPagesBreadcrumbsRefsData,
|
||||
validateLoyaltyPageBreadcrumbsContentstackSchema,
|
||||
validateLoyaltyPageBreadcrumbsRefsContentstackSchema,
|
||||
validateMyPagesBreadcrumbsContentstackSchema,
|
||||
@@ -23,12 +27,6 @@ import {
|
||||
Variables,
|
||||
} from "./utils"
|
||||
|
||||
import type {
|
||||
GetLoyaltyPageBreadcrumbsData,
|
||||
GetLoyaltyPageBreadcrumbsRefsData,
|
||||
GetMyPagesBreadcrumbsData,
|
||||
GetMyPagesBreadcrumbsRefsData,
|
||||
} from "@/types/requests/myPages/breadcrumbs"
|
||||
import { PageTypeEnum } from "@/types/requests/pageType"
|
||||
|
||||
async function getLoyaltyPageBreadcrumbs(variables: Variables) {
|
||||
@@ -111,7 +109,7 @@ async function getMyPagesBreadcrumbs(variables: Variables) {
|
||||
}
|
||||
|
||||
export const breadcrumbsQueryRouter = router({
|
||||
get: contentstackProcedure.query(async ({ ctx }) => {
|
||||
get: contentstackExtendedProcedureUID.query(async ({ ctx }) => {
|
||||
const variables = {
|
||||
locale: ctx.lang,
|
||||
url: ctx.pathname,
|
||||
|
||||
@@ -9,13 +9,12 @@ import {
|
||||
} from "@/utils/generateTag"
|
||||
import { removeMultipleSlashes } from "@/utils/url"
|
||||
|
||||
import { BreadcrumbsRefsItems, getBreadcrumbsSchema, Page } from "./output"
|
||||
import { type BreadcrumbsRefsItems, getBreadcrumbsSchema, Page } from "./output"
|
||||
|
||||
import type { GetBreadcrumbsItems } from "@/types/requests/myPages/breadcrumbs"
|
||||
import type { Edges } from "@/types/requests/utils/edges"
|
||||
import type { NodeRefs } from "@/types/requests/utils/refs"
|
||||
|
||||
export function getConnections(refs: GetBreadcrumbsItems) {
|
||||
export function getConnections(refs: BreadcrumbsRefsItems) {
|
||||
const connections: Edges<NodeRefs>[] = []
|
||||
|
||||
refs.items.forEach((ref) => {
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import { mergeRouters } from "@/server/trpc"
|
||||
|
||||
import { configQueryRouter } from "./query"
|
||||
|
||||
export const configRouter = mergeRouters(configQueryRouter)
|
||||
@@ -1,258 +0,0 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
import { batchRequest } from "@/lib/graphql/batchRequest"
|
||||
import {
|
||||
GetDaDeEnUrlsAccountPage,
|
||||
GetFiNoSvUrlsAccountPage,
|
||||
} from "@/lib/graphql/Query/AccountPage.graphql"
|
||||
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
||||
import {
|
||||
GetCurrentFooter,
|
||||
GetCurrentFooterRef,
|
||||
} from "@/lib/graphql/Query/CurrentFooter.graphql"
|
||||
import {
|
||||
GetCurrentHeader,
|
||||
GetCurrentHeaderRef,
|
||||
} from "@/lib/graphql/Query/CurrentHeader.graphql"
|
||||
import {
|
||||
GetDaDeEnUrlsCurrentBlocksPage,
|
||||
GetFiNoSvUrlsCurrentBlocksPage,
|
||||
} from "@/lib/graphql/Query/LanguageSwitcherCurrent.graphql"
|
||||
import {
|
||||
GetDaDeEnUrlsLoyaltyPage,
|
||||
GetFiNoSvUrlsLoyaltyPage,
|
||||
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
import { contentstackProcedure, publicProcedure, router } from "@/server/trpc"
|
||||
|
||||
import { generateTag } from "@/utils/generateTag"
|
||||
|
||||
import {
|
||||
type ContactConfigData,
|
||||
FooterDataRaw,
|
||||
FooterRefDataRaw,
|
||||
HeaderData,
|
||||
HeaderDataRaw,
|
||||
HeaderRefDataRaw,
|
||||
validateContactConfigSchema,
|
||||
validateFooterConfigSchema,
|
||||
validateHeaderConfigSchema,
|
||||
validateLanguageSwitcherData,
|
||||
} from "./output"
|
||||
import { languageSwitcherAffix } from "./utils"
|
||||
|
||||
import {
|
||||
LanguageSwitcherData,
|
||||
LanguageSwitcherQueryDataRaw,
|
||||
} from "@/types/requests/languageSwitcher"
|
||||
import { PageTypeEnum } from "@/types/requests/pageType"
|
||||
|
||||
export const configQueryRouter = router({
|
||||
contact: contentstackProcedure.query(async ({ ctx }) => {
|
||||
const { lang } = ctx
|
||||
|
||||
const response = await request<ContactConfigData>(GetContactConfig, {
|
||||
locale: lang,
|
||||
})
|
||||
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
const validatedContactConfigConfig = validateContactConfigSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedContactConfigConfig.success) {
|
||||
throw internalServerError(validatedContactConfigConfig.error)
|
||||
}
|
||||
|
||||
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
||||
}),
|
||||
header: publicProcedure.query(async ({ ctx }) => {
|
||||
const responseRef = await request<HeaderRefDataRaw>(GetCurrentHeaderRef, {
|
||||
locale: ctx.lang,
|
||||
})
|
||||
|
||||
const response = await request<HeaderDataRaw>(
|
||||
GetCurrentHeader,
|
||||
{ locale: ctx.lang },
|
||||
{
|
||||
next: {
|
||||
tags: [
|
||||
generateTag(
|
||||
ctx.lang,
|
||||
responseRef.data.all_current_header.items[0].system.uid
|
||||
),
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (!response.data) {
|
||||
throw notFound(response)
|
||||
}
|
||||
|
||||
const validatedHeaderConfig = validateHeaderConfigSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedHeaderConfig.success) {
|
||||
throw internalServerError(validatedHeaderConfig.error)
|
||||
}
|
||||
|
||||
const logo =
|
||||
validatedHeaderConfig.data.all_current_header.items[0].logoConnection
|
||||
.edges?.[0]?.node
|
||||
|
||||
return {
|
||||
...validatedHeaderConfig.data.all_current_header.items[0],
|
||||
logo,
|
||||
} as HeaderData
|
||||
}),
|
||||
footer: contentstackProcedure.query(async ({ ctx }) => {
|
||||
const responseRef = await request<FooterRefDataRaw>(GetCurrentFooterRef, {
|
||||
locale: ctx.lang,
|
||||
})
|
||||
|
||||
const response = await request<FooterDataRaw>(
|
||||
GetCurrentFooter,
|
||||
{
|
||||
locale: ctx.lang,
|
||||
},
|
||||
{
|
||||
next: {
|
||||
tags: [
|
||||
generateTag(
|
||||
ctx.lang,
|
||||
responseRef.data.all_current_footer.items[0].system.uid
|
||||
),
|
||||
],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const validatedFooterConfig = validateFooterConfigSchema.safeParse(
|
||||
response.data
|
||||
)
|
||||
|
||||
if (!validatedFooterConfig.success) {
|
||||
throw internalServerError(validatedFooterConfig.error)
|
||||
}
|
||||
|
||||
return validatedFooterConfig.data.all_current_footer.items[0]
|
||||
}),
|
||||
languageSwitcher: contentstackProcedure.query(async ({ ctx }) => {
|
||||
const variables = { uid: ctx.uid, locale: ctx.lang }
|
||||
let urls: LanguageSwitcherData
|
||||
|
||||
const tagsDaDeEn = [
|
||||
generateTag(Lang.da, ctx.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.de, ctx.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.en, ctx.uid, languageSwitcherAffix),
|
||||
]
|
||||
const tagsFiNoSv = [
|
||||
generateTag(Lang.fi, ctx.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.no, ctx.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.sv, ctx.uid, languageSwitcherAffix),
|
||||
]
|
||||
|
||||
switch (ctx.contentType) {
|
||||
case PageTypeEnum.accountPage:
|
||||
const accountPageRes = await batchRequest<LanguageSwitcherQueryDataRaw>(
|
||||
[
|
||||
{
|
||||
document: GetDaDeEnUrlsAccountPage,
|
||||
variables,
|
||||
tags: tagsDaDeEn,
|
||||
},
|
||||
{
|
||||
document: GetFiNoSvUrlsAccountPage,
|
||||
variables,
|
||||
tags: tagsFiNoSv,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
const accountPageUrls = Object.keys(
|
||||
accountPageRes.data
|
||||
).reduce<LanguageSwitcherData>((acc, key) => {
|
||||
const item = accountPageRes.data[key as Lang]?.items?.[0]
|
||||
const url = item
|
||||
? { url: `/${key}${item.url}`, isExternal: false }
|
||||
: undefined
|
||||
return { ...acc, [key]: url }
|
||||
}, {} as LanguageSwitcherData)
|
||||
|
||||
const validatedAccountLanguageSwitcherData =
|
||||
validateLanguageSwitcherData.safeParse(accountPageUrls)
|
||||
|
||||
if (!validatedAccountLanguageSwitcherData.success) {
|
||||
throw internalServerError(validatedAccountLanguageSwitcherData.error)
|
||||
}
|
||||
|
||||
urls = validatedAccountLanguageSwitcherData.data
|
||||
break
|
||||
case PageTypeEnum.loyaltyPage:
|
||||
const loyaltyPageRes = await batchRequest<LanguageSwitcherQueryDataRaw>(
|
||||
[
|
||||
{
|
||||
document: GetDaDeEnUrlsLoyaltyPage,
|
||||
variables,
|
||||
tags: tagsDaDeEn,
|
||||
},
|
||||
{
|
||||
document: GetFiNoSvUrlsLoyaltyPage,
|
||||
variables,
|
||||
tags: tagsFiNoSv,
|
||||
},
|
||||
]
|
||||
)
|
||||
const loyaltyPageUrls = Object.keys(
|
||||
loyaltyPageRes.data
|
||||
).reduce<LanguageSwitcherData>((acc, key) => {
|
||||
const item = loyaltyPageRes.data[key as Lang]?.items?.[0]
|
||||
const url = item
|
||||
? {
|
||||
url: item.web?.original_url || `/${key}${item.url}`,
|
||||
isExternal: !!item?.web?.original_url,
|
||||
}
|
||||
: undefined
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[key]: url,
|
||||
}
|
||||
}, {} as LanguageSwitcherData)
|
||||
|
||||
const validatedLoyaltyLanguageSwitcherData =
|
||||
validateLanguageSwitcherData.safeParse(loyaltyPageUrls)
|
||||
|
||||
if (!validatedLoyaltyLanguageSwitcherData.success) {
|
||||
throw internalServerError(validatedLoyaltyLanguageSwitcherData.error)
|
||||
}
|
||||
|
||||
urls = validatedLoyaltyLanguageSwitcherData.data
|
||||
break
|
||||
case PageTypeEnum.currentBlocksPage:
|
||||
const { data } = await batchRequest<LanguageSwitcherData>([
|
||||
{
|
||||
document: GetDaDeEnUrlsCurrentBlocksPage,
|
||||
variables,
|
||||
tags: tagsDaDeEn,
|
||||
},
|
||||
{
|
||||
document: GetFiNoSvUrlsCurrentBlocksPage,
|
||||
variables,
|
||||
tags: tagsFiNoSv,
|
||||
},
|
||||
])
|
||||
|
||||
urls = data
|
||||
break
|
||||
default:
|
||||
urls = [] as unknown as LanguageSwitcherData
|
||||
}
|
||||
return { urls, lang: ctx.lang }
|
||||
}),
|
||||
})
|
||||
@@ -1,15 +1,17 @@
|
||||
import { router } from "@/server/trpc"
|
||||
|
||||
import { accountPageRouter } from "./accountPage"
|
||||
import { baseRouter } from "./base"
|
||||
import { breadcrumbsRouter } from "./breadcrumbs"
|
||||
import { configRouter } from "./config"
|
||||
import { languageSwitcherRouter } from "./languageSwitcher"
|
||||
import { loyaltyPageRouter } from "./loyaltyPage"
|
||||
import { myPagesRouter } from "./myPages"
|
||||
|
||||
export const contentstackRouter = router({
|
||||
breadcrumbs: breadcrumbsRouter,
|
||||
accountPage: accountPageRouter,
|
||||
config: configRouter,
|
||||
base: baseRouter,
|
||||
breadcrumbs: breadcrumbsRouter,
|
||||
languageSwitcher: languageSwitcherRouter,
|
||||
loyaltyPage: loyaltyPageRouter,
|
||||
myPages: myPagesRouter,
|
||||
})
|
||||
|
||||
5
server/routers/contentstack/languageSwitcher/index.ts
Normal file
5
server/routers/contentstack/languageSwitcher/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { mergeRouters } from "@/server/trpc"
|
||||
|
||||
import { languageSwitcherQueryRouter } from "./query"
|
||||
|
||||
export const languageSwitcherRouter = mergeRouters(languageSwitcherQueryRouter)
|
||||
14
server/routers/contentstack/languageSwitcher/output.ts
Normal file
14
server/routers/contentstack/languageSwitcher/output.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { z } from "zod"
|
||||
|
||||
const link = z
|
||||
.object({ url: z.string().optional(), isExternal: z.boolean() })
|
||||
.nullable()
|
||||
|
||||
export const validateLanguageSwitcherData = z.object({
|
||||
da: link,
|
||||
de: link,
|
||||
en: link,
|
||||
fi: link,
|
||||
no: link,
|
||||
sv: link,
|
||||
})
|
||||
127
server/routers/contentstack/languageSwitcher/query.ts
Normal file
127
server/routers/contentstack/languageSwitcher/query.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { Lang } from "@/constants/languages"
|
||||
import { batchRequest } from "@/lib/graphql/batchRequest"
|
||||
import {
|
||||
GetDaDeEnUrlsAccountPage,
|
||||
GetFiNoSvUrlsAccountPage,
|
||||
} from "@/lib/graphql/Query/AccountPage.graphql"
|
||||
import {
|
||||
GetDaDeEnUrlsCurrentBlocksPage,
|
||||
GetFiNoSvUrlsCurrentBlocksPage,
|
||||
} from "@/lib/graphql/Query/LanguageSwitcherCurrent.graphql"
|
||||
import {
|
||||
GetDaDeEnUrlsLoyaltyPage,
|
||||
GetFiNoSvUrlsLoyaltyPage,
|
||||
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
|
||||
import { internalServerError } from "@/server/errors/trpc"
|
||||
import { contentstackExtendedProcedureUID, router } from "@/server/trpc"
|
||||
|
||||
import { generateTag } from "@/utils/generateTag"
|
||||
|
||||
import { validateLanguageSwitcherData } from "./output"
|
||||
import { languageSwitcherAffix } from "./utils"
|
||||
|
||||
import type {
|
||||
LanguageSwitcherData,
|
||||
LanguageSwitcherQueryDataRaw,
|
||||
} from "@/types/requests/languageSwitcher"
|
||||
import { PageTypeEnum } from "@/types/requests/pageType"
|
||||
|
||||
interface LanguageSwitcherVariables {
|
||||
contentType: string
|
||||
uid: string
|
||||
}
|
||||
|
||||
async function getLanguageSwitcher(options: LanguageSwitcherVariables) {
|
||||
const variables = { uid: options.uid }
|
||||
const tagsDaDeEn = [
|
||||
generateTag(Lang.da, options.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.de, options.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.en, options.uid, languageSwitcherAffix),
|
||||
]
|
||||
const tagsFiNoSv = [
|
||||
generateTag(Lang.fi, options.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.no, options.uid, languageSwitcherAffix),
|
||||
generateTag(Lang.sv, options.uid, languageSwitcherAffix),
|
||||
]
|
||||
switch (options.contentType) {
|
||||
case PageTypeEnum.accountPage:
|
||||
return await batchRequest<LanguageSwitcherQueryDataRaw>([
|
||||
{
|
||||
document: GetDaDeEnUrlsAccountPage,
|
||||
variables,
|
||||
tags: tagsDaDeEn,
|
||||
},
|
||||
{
|
||||
document: GetFiNoSvUrlsAccountPage,
|
||||
variables,
|
||||
tags: tagsFiNoSv,
|
||||
},
|
||||
])
|
||||
case PageTypeEnum.currentBlocksPage:
|
||||
return await batchRequest<LanguageSwitcherQueryDataRaw>([
|
||||
{
|
||||
document: GetDaDeEnUrlsCurrentBlocksPage,
|
||||
variables,
|
||||
tags: tagsDaDeEn,
|
||||
},
|
||||
{
|
||||
document: GetFiNoSvUrlsCurrentBlocksPage,
|
||||
variables,
|
||||
tags: tagsFiNoSv,
|
||||
},
|
||||
])
|
||||
case PageTypeEnum.loyaltyPage:
|
||||
return await batchRequest<LanguageSwitcherQueryDataRaw>([
|
||||
{
|
||||
document: GetDaDeEnUrlsLoyaltyPage,
|
||||
variables,
|
||||
tags: tagsDaDeEn,
|
||||
},
|
||||
{
|
||||
document: GetFiNoSvUrlsLoyaltyPage,
|
||||
variables,
|
||||
tags: tagsFiNoSv,
|
||||
},
|
||||
])
|
||||
default:
|
||||
console.info(`type: [${options.contentType}]`)
|
||||
console.error(`Trying to get a content type that is not supported`)
|
||||
throw internalServerError()
|
||||
}
|
||||
}
|
||||
|
||||
export const languageSwitcherQueryRouter = router({
|
||||
get: contentstackExtendedProcedureUID.query(async ({ ctx }) => {
|
||||
const res = await getLanguageSwitcher({
|
||||
contentType: ctx.contentType!,
|
||||
uid: ctx.uid,
|
||||
})
|
||||
|
||||
const urls = Object.keys(res.data).reduce<LanguageSwitcherData>(
|
||||
(acc, key) => {
|
||||
const item = res.data[key as Lang]?.items[0]
|
||||
const url = item
|
||||
? item.web?.original_url || `/${key}${item.url}`
|
||||
: undefined
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[key]: { url, isExternal: !!item?.web?.original_url },
|
||||
}
|
||||
},
|
||||
{} as LanguageSwitcherData
|
||||
)
|
||||
|
||||
const validatedLanguageSwitcherData =
|
||||
validateLanguageSwitcherData.safeParse(urls)
|
||||
|
||||
if (!validatedLanguageSwitcherData.success) {
|
||||
throw internalServerError(validatedLanguageSwitcherData.error)
|
||||
}
|
||||
|
||||
return {
|
||||
lang: ctx.lang,
|
||||
urls,
|
||||
}
|
||||
}),
|
||||
})
|
||||
@@ -23,9 +23,8 @@ const loyaltyPageDynamicContent = z.object({
|
||||
component: z.nativeEnum(LoyaltyComponentEnum),
|
||||
link: z
|
||||
.object({
|
||||
text: z.string().nullable(),
|
||||
text: z.string(),
|
||||
href: z.string(),
|
||||
title: z.string(),
|
||||
})
|
||||
.optional(),
|
||||
}),
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
import { contentstackProcedure, router } from "@/server/trpc"
|
||||
import { contentstackExtendedProcedureUID, router } from "@/server/trpc"
|
||||
|
||||
import {
|
||||
generateRefsResponseTag,
|
||||
@@ -35,16 +35,16 @@ function makeButtonObject(button: any) {
|
||||
href:
|
||||
button.is_contentstack_link && button.linkConnection.edges.length
|
||||
? button.linkConnection.edges[0].node.web?.original_url ||
|
||||
removeMultipleSlashes(
|
||||
`/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}`
|
||||
)
|
||||
removeMultipleSlashes(
|
||||
`/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}`
|
||||
)
|
||||
: button.external_link.href,
|
||||
isExternal: !button.is_contentstack_link,
|
||||
}
|
||||
}
|
||||
|
||||
export const loyaltyPageQueryRouter = router({
|
||||
get: contentstackProcedure.query(async ({ ctx }) => {
|
||||
get: contentstackExtendedProcedureUID.query(async ({ ctx }) => {
|
||||
const { lang, uid } = ctx
|
||||
|
||||
const refsResponse = await request<LoyaltyPageRefsDataRaw>(
|
||||
@@ -99,66 +99,66 @@ export const loyaltyPageQueryRouter = router({
|
||||
|
||||
const blocks = response.data.loyalty_page.blocks
|
||||
? response.data.loyalty_page.blocks.map((block: any) => {
|
||||
switch (block.__typename) {
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
|
||||
return {
|
||||
...block,
|
||||
dynamic_content: {
|
||||
...block.dynamic_content,
|
||||
link: block.dynamic_content.link.pageConnection.edges.length
|
||||
? {
|
||||
text: block.dynamic_content.link.text,
|
||||
href: removeMultipleSlashes(
|
||||
`/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}`
|
||||
),
|
||||
title:
|
||||
block.dynamic_content.link.pageConnection.edges[0]
|
||||
.node.title,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
|
||||
return {
|
||||
...block,
|
||||
shortcuts: {
|
||||
...block.shortcuts,
|
||||
shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({
|
||||
text: shortcut.text,
|
||||
openInNewTab: shortcut.open_in_new_tab,
|
||||
...shortcut.linkConnection.edges[0].node,
|
||||
url:
|
||||
shortcut.linkConnection.edges[0].node.web?.original_url ||
|
||||
removeMultipleSlashes(
|
||||
`/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}`
|
||||
),
|
||||
})),
|
||||
},
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
|
||||
return {
|
||||
...block,
|
||||
cards_grid: {
|
||||
...block.cards_grid,
|
||||
cards: block.cards_grid.cardConnection.edges.map(
|
||||
({ node: card }: { node: any }) => {
|
||||
return {
|
||||
...card,
|
||||
primaryButton: card.has_primary_button
|
||||
? makeButtonObject(card.primary_button)
|
||||
: undefined,
|
||||
secondaryButton: card.has_secondary_button
|
||||
? makeButtonObject(card.secondary_button)
|
||||
: undefined,
|
||||
switch (block.__typename) {
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
|
||||
return {
|
||||
...block,
|
||||
dynamic_content: {
|
||||
...block.dynamic_content,
|
||||
link: block.dynamic_content.link.pageConnection.edges.length
|
||||
? {
|
||||
text: block.dynamic_content.link.text,
|
||||
href: removeMultipleSlashes(
|
||||
`/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}`
|
||||
),
|
||||
title:
|
||||
block.dynamic_content.link.pageConnection.edges[0]
|
||||
.node.title,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
|
||||
return {
|
||||
...block,
|
||||
shortcuts: {
|
||||
...block.shortcuts,
|
||||
shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({
|
||||
text: shortcut.text,
|
||||
openInNewTab: shortcut.open_in_new_tab,
|
||||
...shortcut.linkConnection.edges[0].node,
|
||||
url:
|
||||
shortcut.linkConnection.edges[0].node.web?.original_url ||
|
||||
removeMultipleSlashes(
|
||||
`/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}`
|
||||
),
|
||||
})),
|
||||
},
|
||||
}
|
||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
|
||||
return {
|
||||
...block,
|
||||
cards_grid: {
|
||||
...block.cards_grid,
|
||||
cards: block.cards_grid.cardConnection.edges.map(
|
||||
({ node: card }: { node: any }) => {
|
||||
return {
|
||||
...card,
|
||||
primaryButton: card.has_primary_button
|
||||
? makeButtonObject(card.primary_button)
|
||||
: undefined,
|
||||
secondaryButton: card.has_secondary_button
|
||||
? makeButtonObject(card.secondary_button)
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
default:
|
||||
return block
|
||||
}
|
||||
})
|
||||
),
|
||||
},
|
||||
}
|
||||
default:
|
||||
return block
|
||||
}
|
||||
})
|
||||
: null
|
||||
|
||||
const loyaltyPage = {
|
||||
|
||||
@@ -4,18 +4,47 @@ import { Lang } from "@/constants/languages"
|
||||
|
||||
import { PageLinkEnum } from "@/types/requests/pageLinks"
|
||||
|
||||
const node = z.object({
|
||||
system: z.object({
|
||||
locale: z.nativeEnum(Lang),
|
||||
uid: z.string(),
|
||||
}),
|
||||
title: z.string(),
|
||||
url: z.string(),
|
||||
})
|
||||
|
||||
const web = z.object({
|
||||
original_url: z.string().optional(),
|
||||
})
|
||||
|
||||
const accountPageLink = z
|
||||
.object({
|
||||
__typename: z.literal(PageLinkEnum.AccountPage),
|
||||
})
|
||||
.merge(node)
|
||||
|
||||
const contentPageLink = z
|
||||
.object({
|
||||
__typename: z.literal(PageLinkEnum.ContentPage),
|
||||
web,
|
||||
})
|
||||
.merge(node)
|
||||
|
||||
const loyaltyPageLink = z
|
||||
.object({
|
||||
__typename: z.literal(PageLinkEnum.LoyaltyPage),
|
||||
web,
|
||||
})
|
||||
.merge(node)
|
||||
|
||||
const pageConnection = z.object({
|
||||
edges: z.array(
|
||||
z.object({
|
||||
node: z.object({
|
||||
__typename: z.nativeEnum(PageLinkEnum),
|
||||
system: z.object({
|
||||
locale: z.nativeEnum(Lang),
|
||||
uid: z.string(),
|
||||
}),
|
||||
title: z.string(),
|
||||
url: z.string(),
|
||||
}),
|
||||
node: z.discriminatedUnion("__typename", [
|
||||
accountPageLink,
|
||||
contentPageLink,
|
||||
loyaltyPageLink,
|
||||
]),
|
||||
})
|
||||
),
|
||||
})
|
||||
@@ -36,78 +65,58 @@ const pageConnectionRefs = z.object({
|
||||
|
||||
export const navigationRefsPayloadSchema = z.object({
|
||||
all_navigation_my_pages: z.object({
|
||||
items: z
|
||||
.array(
|
||||
z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
__typename: z.string(),
|
||||
item: z.object({
|
||||
sub_items: z.array(
|
||||
z.object({
|
||||
__typename: z.string(),
|
||||
item: z.object({
|
||||
pageConnection: pageConnectionRefs,
|
||||
}),
|
||||
})
|
||||
),
|
||||
pageConnection: pageConnectionRefs,
|
||||
}),
|
||||
})
|
||||
),
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.refine(
|
||||
(input) => {
|
||||
return input.length === 1
|
||||
},
|
||||
{
|
||||
message: `Expected all_navigation_my_pages items to only contain 1 in navigationRefsPayloadSchema`,
|
||||
}
|
||||
),
|
||||
items: z.array(
|
||||
z.object({
|
||||
menu_items: z.array(
|
||||
z.object({
|
||||
links: z.array(
|
||||
z.object({
|
||||
page: pageConnectionRefs,
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
system: z.object({
|
||||
content_type_uid: z.string(),
|
||||
uid: z.string(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
})
|
||||
|
||||
export type GetNavigationMyPagesRefsData = z.infer<
|
||||
typeof navigationRefsPayloadSchema
|
||||
>
|
||||
|
||||
const menuItems = z.array(
|
||||
z.object({
|
||||
display_sign_out_link: z.boolean(),
|
||||
links: z.array(
|
||||
z.object({
|
||||
link_text: z.string().default(""),
|
||||
page: pageConnection,
|
||||
})
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
export type MenuItems = z.infer<typeof menuItems>
|
||||
|
||||
export const navigationPayloadSchema = z.object({
|
||||
all_navigation_my_pages: z.object({
|
||||
items: z
|
||||
.array(
|
||||
z.object({
|
||||
items: z.array(
|
||||
z.object({
|
||||
item: z.object({
|
||||
link_text: z.string().default(""),
|
||||
pageConnection,
|
||||
sub_items: z.array(
|
||||
z.object({
|
||||
item: z.object({
|
||||
link_text: z.string().default(""),
|
||||
pageConnection,
|
||||
}),
|
||||
})
|
||||
),
|
||||
}),
|
||||
})
|
||||
),
|
||||
title: z.string(),
|
||||
})
|
||||
)
|
||||
.refine(
|
||||
(input) => {
|
||||
return input.length === 1
|
||||
},
|
||||
{
|
||||
message: `Expected all_navigation_my_pages items to only contain 1 in navigationPayloadSchema`,
|
||||
}
|
||||
),
|
||||
items: z.array(
|
||||
z.object({
|
||||
menu_items: menuItems,
|
||||
title: z.string(),
|
||||
})
|
||||
),
|
||||
}),
|
||||
})
|
||||
|
||||
const baseMenuItem = z.object({
|
||||
export type GetNavigationMyPagesData = z.infer<typeof navigationPayloadSchema>
|
||||
|
||||
const link = z.object({
|
||||
lang: z.nativeEnum(Lang),
|
||||
linkText: z.string(),
|
||||
uid: z.string(),
|
||||
@@ -116,12 +125,11 @@ const baseMenuItem = z.object({
|
||||
})
|
||||
|
||||
export const getNavigationSchema = z.object({
|
||||
items: z.array(
|
||||
z
|
||||
.object({
|
||||
subItems: z.array(baseMenuItem),
|
||||
})
|
||||
.merge(baseMenuItem)
|
||||
menuItems: z.array(
|
||||
z.object({
|
||||
display_sign_out_link: z.boolean(),
|
||||
links: z.array(link),
|
||||
})
|
||||
),
|
||||
title: z.string(),
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
} from "@/lib/graphql/Query/NavigationMyPages.graphql"
|
||||
import { request } from "@/lib/graphql/request"
|
||||
import { internalServerError, notFound } from "@/server/errors/trpc"
|
||||
import { contentstackProcedure, publicProcedure, router } from "@/server/trpc"
|
||||
import { contentstackBaseProcedure, router } from "@/server/trpc"
|
||||
|
||||
import {
|
||||
generateRefsResponseTag,
|
||||
@@ -14,40 +14,46 @@ import {
|
||||
import { removeMultipleSlashes } from "@/utils/url"
|
||||
|
||||
import {
|
||||
type GetNavigationMyPagesData,
|
||||
type GetNavigationMyPagesRefsData,
|
||||
getNavigationSchema,
|
||||
type MenuItems,
|
||||
navigationPayloadSchema,
|
||||
navigationRefsPayloadSchema,
|
||||
} from "./output"
|
||||
import { getConnections } from "./utils"
|
||||
|
||||
import type {
|
||||
GetNavigationMyPagesData,
|
||||
GetNavigationMyPagesRefsData,
|
||||
MenuItem,
|
||||
NavigationItem,
|
||||
} from "@/types/requests/myPages/navigation"
|
||||
import { PageLinkEnum } from "@/types/requests/pageLinks"
|
||||
|
||||
export function mapMenuItems(navigationItems: NavigationItem[]) {
|
||||
return navigationItems.map(({ item }): MenuItem => {
|
||||
const { node } = item.pageConnection.edges[0]
|
||||
|
||||
const menuItem: MenuItem = {
|
||||
lang: node.system.locale,
|
||||
linkText: item.link_text || node.title,
|
||||
uid: node.system.uid,
|
||||
url: removeMultipleSlashes(`/${node.system.locale}/${node.url}`),
|
||||
export function mapMenuItems(menuItems: MenuItems) {
|
||||
return menuItems.map((menuItem) => {
|
||||
return {
|
||||
...menuItem,
|
||||
links: menuItem.links.map((link) => {
|
||||
const page = link.page.edges[0].node
|
||||
let originalUrl = undefined
|
||||
if (
|
||||
page.__typename === PageLinkEnum.ContentPage ||
|
||||
page.__typename === PageLinkEnum.LoyaltyPage
|
||||
) {
|
||||
if (page.web.original_url) {
|
||||
originalUrl = page.web.original_url
|
||||
}
|
||||
}
|
||||
return {
|
||||
lang: page.system.locale,
|
||||
linkText: link.link_text ? link.link_text : page.title,
|
||||
uid: page.system.uid,
|
||||
url: removeMultipleSlashes(`/${page.system.locale}/${page.url}`),
|
||||
originalUrl,
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
if ("sub_items" in item) {
|
||||
menuItem.subItems = mapMenuItems(item.sub_items)
|
||||
}
|
||||
|
||||
return menuItem
|
||||
})
|
||||
}
|
||||
|
||||
export const navigationQueryRouter = router({
|
||||
get: contentstackProcedure.query(async function ({ ctx }) {
|
||||
get: contentstackBaseProcedure.query(async function ({ ctx }) {
|
||||
const { lang } = ctx
|
||||
|
||||
const refsResponse = await request<GetNavigationMyPagesRefsData>(
|
||||
@@ -102,7 +108,7 @@ export const navigationQueryRouter = router({
|
||||
validatedMyPagesNavigation.data.all_navigation_my_pages.items[0]
|
||||
|
||||
const nav = {
|
||||
items: mapMenuItems(menuItem.items),
|
||||
menuItems: mapMenuItems(menuItem.menu_items),
|
||||
title: menuItem.title,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import type { GetNavigationMyPagesRefsData } from "@/types/requests/myPages/navigation"
|
||||
import type { Edges } from "@/types/requests/utils/edges"
|
||||
import type { NodeRefs } from "@/types/requests/utils/refs"
|
||||
import type { GetNavigationMyPagesRefsData } from "./output"
|
||||
|
||||
export function getConnections(refs: GetNavigationMyPagesRefsData) {
|
||||
const connections: Edges<NodeRefs>[] = []
|
||||
refs.all_navigation_my_pages.items.forEach((ref) => {
|
||||
ref.items.forEach(({ item }) => {
|
||||
connections.push(item.pageConnection)
|
||||
|
||||
item.sub_items.forEach(({ item: subItem }) => {
|
||||
connections.push(subItem.pageConnection)
|
||||
ref.menu_items.forEach((menuItem) => {
|
||||
menuItem.links.map((link) => {
|
||||
connections.push(link.page)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import { mergeRouters } from "@/server/trpc"
|
||||
|
||||
import { lotaltyQueryRouter } from "./query"
|
||||
|
||||
export const loyaltyRouter = mergeRouters(lotaltyQueryRouter)
|
||||
@@ -1,28 +0,0 @@
|
||||
import { protectedProcedure, publicProcedure, router } from "@/server/trpc"
|
||||
|
||||
import { allLevels } from "./temp"
|
||||
|
||||
function fakingRequest<T>(payload: T): Promise<T> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(payload)
|
||||
}, 1500)
|
||||
})
|
||||
}
|
||||
|
||||
export const lotaltyQueryRouter = router({
|
||||
levels: router({
|
||||
all: publicProcedure.query(async function ({ ctx }) {
|
||||
// TODO: Make request to get user data from Scandic API
|
||||
return await fakingRequest<typeof allLevels>(allLevels)
|
||||
}),
|
||||
current: protectedProcedure.query(async function (opts) {
|
||||
// TODO: Make request to get user data from Scandic API
|
||||
return await fakingRequest<(typeof allLevels)[number]>(allLevels[1])
|
||||
}),
|
||||
next: protectedProcedure.query(async function (opts) {
|
||||
// TODO: Make request to get user data from Scandic API
|
||||
return await fakingRequest<(typeof allLevels)[number]>(allLevels[2])
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -1,86 +0,0 @@
|
||||
export const allLevels = [
|
||||
{
|
||||
tier: 1,
|
||||
name: "New Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/new-friend.svg",
|
||||
},
|
||||
{
|
||||
tier: 2,
|
||||
name: "Good Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/good-friend.svg",
|
||||
},
|
||||
{
|
||||
tier: 3,
|
||||
name: "Close Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/close-friend.svg",
|
||||
},
|
||||
{
|
||||
tier: 4,
|
||||
name: "Dear Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/dear-friend.svg",
|
||||
},
|
||||
{
|
||||
tier: 5,
|
||||
name: "Loyal Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/loyal-friend.svg",
|
||||
},
|
||||
{
|
||||
tier: 6,
|
||||
name: "True Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/true-friend.svg",
|
||||
},
|
||||
{
|
||||
tier: 7,
|
||||
name: "Best Friend",
|
||||
requiredPoints: 50000,
|
||||
requiredNights: "X",
|
||||
benefits: [
|
||||
"15% on food on weekends",
|
||||
"Always best price",
|
||||
"Book reward nights with points",
|
||||
],
|
||||
logo: "/_static/icons/loyaltyLevels/best-friend.svg",
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user