Merged in fix/mypages-clientside-menu (pull request #1344)

Fix/mypages clientside menu

* feat: move mypages menu to client side

* Merge branch 'master' of bitbucket.org:scandic-swap/web into fix/mypages-clientside-menu

* wip

* wip

* wip

* refactor: reorganize MyPages navigation logic and improve type definitions

* refactor: enhance MyPagesMobileDropdown with loading states and skeletons

* refactor: clean up header component and improve myPagesNavigation query structure

* Merge branch 'master' of bitbucket.org:scandic-swap/web into fix/mypages-clientside-menu


Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-02-17 07:47:33 +00:00
committed by Linus Flood
parent ef1d3ee065
commit 2791f07f67
18 changed files with 334 additions and 251 deletions

View File

@@ -0,0 +1,10 @@
type BaseLink = {
type: "link" | "withbadge"
text: string
href: string
}
type NormalLink = BaseLink & { type: "link" }
type LinkWithBadge = BaseLink & { type: "withbadge"; number: number }
export type MyPagesLink = NormalLink | LinkWithBadge

View File

@@ -0,0 +1,83 @@
import { cache } from "react"
import * as routes from "@/constants/routes/myPages"
import { env } from "@/env/server"
import { getIntl } from "@/i18n"
import { safeTry } from "@/utils/safeTry"
import type { Lang } from "@/constants/languages"
import type { MyPagesLink } from "./MyPagesLink"
export const getPrimaryLinks = cache(
async ({ lang }: { lang: Lang }): Promise<MyPagesLink[]> => {
const intl = await getIntl(lang)
const scandicSasPromise = safeTry(isScandicXSASActive())
const teamMemberPromise = safeTry(showTeamMemberCard())
const [showSASLink] = await scandicSasPromise
const [showTeamMemberLink] = await teamMemberPromise
const menuItems: MyPagesLink[] = [
{
type: "link",
text: intl.formatMessage({ id: "Overview" }),
href: routes.overview[lang],
},
{
type: "link",
text: intl.formatMessage({ id: "My Points" }),
href: routes.points[lang],
},
{
type: "link",
text: intl.formatMessage({ id: "My Stays" }),
href: routes.stays[lang],
},
{
type: "link",
text: intl.formatMessage({ id: "My Benefits" }),
href: routes.benefits[lang],
},
]
if (showSASLink) {
menuItems.push({
type: "link",
text: intl.formatMessage({ id: "Scandic ♥ SAS" }),
href: routes.scandicXSAS[lang],
})
}
if (showTeamMemberLink) {
menuItems.push({
type: "link",
text: intl.formatMessage({ id: "Team Member Card" }),
href: "#",
})
}
return menuItems
}
)
const isScandicXSASActive = cache(async () => {
async function checkIfLinked() {
// TODO: Implement this check
return true
}
const isLinked = await checkIfLinked()
return env.SAS_ENABLED && isLinked
})
const showTeamMemberCard = cache(async () => {
async function getIsTeamMember() {
// TODO: Implement this check
return false
}
const isTeamMember = await getIsTeamMember()
return isTeamMember
})

View File

@@ -0,0 +1,28 @@
import * as routes from "@/constants/routes/myPages"
import { getIntl } from "@/i18n"
import type { Lang } from "@/constants/languages"
import type { MyPagesLink } from "./MyPagesLink"
export async function getSecondaryLinks({
lang,
}: {
lang: Lang
}): Promise<MyPagesLink[]> {
const intl = await getIntl()
const menuItems: MyPagesLink[] = [
{
type: "link",
text: intl.formatMessage({ id: "About Scandic Friends" }),
href: routes.scandicFriends[lang],
},
{
type: "link",
text: intl.formatMessage({ id: "My Profile" }),
href: routes.profile[lang],
},
]
return menuItems
}

View File

@@ -0,0 +1,49 @@
import { TRPCError } from "@trpc/server"
import { z } from "zod"
import { Lang } from "@/constants/languages"
import { safeProtectedProcedure } from "@/server/trpc"
import { getPrimaryLinks } from "./getPrimaryLinks"
import { getSecondaryLinks } from "./getSecondaryLinks"
import type { MyPagesLink } from "./MyPagesLink"
export const myPagesNavigation = safeProtectedProcedure
.input(
z.object({
lang: z.nativeEnum(Lang).optional(),
})
)
.query(
async ({
ctx,
input,
}): Promise<{
primaryLinks: MyPagesLink[]
secondaryLinks: MyPagesLink[]
} | null> => {
if (!ctx.session) {
return null
}
const lang = input.lang || ctx.lang
if (!lang) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Language must be provided.",
})
}
const [primaryLinks, secondaryLinks] = await Promise.all([
getPrimaryLinks({ lang }),
getSecondaryLinks({ lang }),
])
return {
primaryLinks,
secondaryLinks,
}
}
)