Merged develop into feat/sw-700-designglitch-divider
This commit is contained in:
@@ -4,7 +4,7 @@ import { z } from "zod"
|
|||||||
|
|
||||||
import { ApiLang } from "@/constants/languages"
|
import { ApiLang } from "@/constants/languages"
|
||||||
import * as api from "@/lib/api"
|
import * as api from "@/lib/api"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
import { protectedServerActionProcedure } from "@/server/trpc"
|
import { protectedServerActionProcedure } from "@/server/trpc"
|
||||||
|
|
||||||
import { editProfileSchema } from "@/components/Forms/Edit/Profile/schema"
|
import { editProfileSchema } from "@/components/Forms/Edit/Profile/schema"
|
||||||
@@ -68,7 +68,7 @@ export const editProfile = protectedServerActionProcedure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const profile = await serverClient().user.get()
|
const profile = await getProfile()
|
||||||
if (!profile || "error" in profile) {
|
if (!profile || "error" in profile) {
|
||||||
console.error(
|
console.error(
|
||||||
"editProfile profile fetch error",
|
"editProfile profile fetch error",
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import { Suspense } from "react"
|
||||||
|
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs"
|
import Breadcrumbs from "@/components/Breadcrumbs"
|
||||||
|
import BreadcrumbsSkeleton from "@/components/Breadcrumbs/BreadcrumbsSkeleton"
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
@@ -6,5 +9,9 @@ import { LangParams, PageArgs } from "@/types/params"
|
|||||||
export default function AllBreadcrumbs({ params }: PageArgs<LangParams>) {
|
export default function AllBreadcrumbs({ params }: PageArgs<LangParams>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
return <Breadcrumbs />
|
return (
|
||||||
|
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
||||||
|
<Breadcrumbs />
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { Suspense } from "react"
|
||||||
|
|
||||||
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
import Sidebar from "@/components/MyPages/Sidebar"
|
import Sidebar from "@/components/MyPages/Sidebar"
|
||||||
|
|
||||||
// import Surprises from "@/components/MyPages/Surprises"
|
// import Surprises from "@/components/MyPages/Surprises"
|
||||||
@@ -14,7 +17,9 @@ export default async function MyPagesLayout({
|
|||||||
<section className={styles.layout}>
|
<section className={styles.layout}>
|
||||||
{breadcrumbs}
|
{breadcrumbs}
|
||||||
<section className={styles.content}>
|
<section className={styles.content}>
|
||||||
<Sidebar />
|
<Suspense fallback={<LoadingSpinner />}>
|
||||||
|
<Sidebar />
|
||||||
|
</Suspense>
|
||||||
{children}
|
{children}
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getMembershipCards } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { PlusCircleIcon } from "@/components/Icons"
|
import { PlusCircleIcon } from "@/components/Icons"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
@@ -16,7 +16,7 @@ export default async function MembershipCardSlot({
|
|||||||
}: PageArgs<LangParams>) {
|
}: PageArgs<LangParams>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const membershipCards = await serverClient().user.membershipCards()
|
const membershipCards = await getMembershipCards()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.container}>
|
<section className={styles.container}>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import { Suspense } from "react"
|
||||||
|
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs"
|
import Breadcrumbs from "@/components/Breadcrumbs"
|
||||||
|
import BreadcrumbsSkeleton from "@/components/Breadcrumbs/BreadcrumbsSkeleton"
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
@@ -6,5 +9,9 @@ import { LangParams, PageArgs } from "@/types/params"
|
|||||||
export default function PageBreadcrumbs({ params }: PageArgs<LangParams>) {
|
export default function PageBreadcrumbs({ params }: PageArgs<LangParams>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
return <Breadcrumbs />
|
return (
|
||||||
|
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
||||||
|
<Breadcrumbs />
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
|
|
||||||
export { generateMetadata } from "@/utils/generateMetadata"
|
export { generateMetadata } from "@/utils/generateMetadata"
|
||||||
|
|
||||||
export default async function ContentTypePage({
|
export default function ContentTypePage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|||||||
5
app/[lang]/webview/loading.tsx
Normal file
5
app/[lang]/webview/loading.tsx
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <LoadingSpinner />
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getMembershipLevelSafely } from "@/lib/trpc/memoizedRequests"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import SectionWrapper from "../SectionWrapper"
|
import SectionWrapper from "../SectionWrapper"
|
||||||
@@ -9,8 +10,11 @@ export default async function OverviewTable({
|
|||||||
dynamic_content,
|
dynamic_content,
|
||||||
firstItem,
|
firstItem,
|
||||||
}: OverviewTableProps) {
|
}: OverviewTableProps) {
|
||||||
const levels = await serverClient().contentstack.rewards.all()
|
const [levels, membershipLevel] = await Promise.all([
|
||||||
const membershipLevel = await serverClient().user.safeMembershipLevel()
|
serverClient().contentstack.rewards.all(),
|
||||||
|
getMembershipLevelSafely(),
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionWrapper dynamic_content={dynamic_content} firstItem={firstItem}>
|
<SectionWrapper dynamic_content={dynamic_content} firstItem={firstItem}>
|
||||||
<OverviewTableClient
|
<OverviewTableClient
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getMembershipLevel } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import SectionContainer from "@/components/Section/Container"
|
import SectionContainer from "@/components/Section/Container"
|
||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
@@ -12,7 +12,7 @@ export default async function ExpiringPoints({
|
|||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const membershipLevel = await serverClient().user.membershipLevel()
|
const membershipLevel = await getMembershipLevel()
|
||||||
|
|
||||||
if (!membershipLevel?.pointsToExpire || !membershipLevel?.pointsExpiryDate) {
|
if (!membershipLevel?.pointsToExpire || !membershipLevel?.pointsExpiryDate) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Lock } from "react-feather"
|
import { Lock } from "react-feather"
|
||||||
|
|
||||||
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
||||||
|
import { getMembershipLevel } from "@/lib/trpc/memoizedRequests"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import SectionContainer from "@/components/Section/Container"
|
import SectionContainer from "@/components/Section/Container"
|
||||||
@@ -22,7 +23,7 @@ export default async function NextLevelRewardsBlock({
|
|||||||
link,
|
link,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
const membershipLevel = await serverClient().user.membershipLevel()
|
const membershipLevel = await getMembershipLevel()
|
||||||
|
|
||||||
if (!membershipLevel || !membershipLevel?.nextLevel) {
|
if (!membershipLevel || !membershipLevel?.nextLevel) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Suspense } from "react"
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
|
|
||||||
import HowItWorks from "@/components/Blocks/DynamicContent/HowItWorks"
|
import HowItWorks from "@/components/Blocks/DynamicContent/HowItWorks"
|
||||||
@@ -14,14 +16,21 @@ import SignUpVerification from "@/components/Blocks/DynamicContent/SignUpVerific
|
|||||||
import PreviousStays from "@/components/Blocks/DynamicContent/Stays/Previous"
|
import PreviousStays from "@/components/Blocks/DynamicContent/Stays/Previous"
|
||||||
import SoonestStays from "@/components/Blocks/DynamicContent/Stays/Soonest"
|
import SoonestStays from "@/components/Blocks/DynamicContent/Stays/Soonest"
|
||||||
import UpcomingStays from "@/components/Blocks/DynamicContent/Stays/Upcoming"
|
import UpcomingStays from "@/components/Blocks/DynamicContent/Stays/Upcoming"
|
||||||
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
|
|
||||||
import type { DynamicContentProps } from "@/types/components/blocks/dynamicContent"
|
import type { DynamicContentProps } from "@/types/components/blocks/dynamicContent"
|
||||||
import { DynamicContentEnum } from "@/types/enums/dynamicContent"
|
import { DynamicContentEnum } from "@/types/enums/dynamicContent"
|
||||||
|
|
||||||
export default async function DynamicContent({
|
export default function DynamicContent(props: DynamicContentProps) {
|
||||||
dynamic_content,
|
return (
|
||||||
firstItem,
|
<Suspense fallback={<LoadingSpinner />}>
|
||||||
}: DynamicContentProps) {
|
<DynamicContentBlocks {...props} />
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function DynamicContentBlocks(props: DynamicContentProps) {
|
||||||
|
const { dynamic_content, firstItem } = props
|
||||||
switch (dynamic_content.component) {
|
switch (dynamic_content.component) {
|
||||||
case DynamicContentEnum.Blocks.components.current_benefits:
|
case DynamicContentEnum.Blocks.components.current_benefits:
|
||||||
return <CurrentRewardsBlock {...dynamic_content} />
|
return <CurrentRewardsBlock {...dynamic_content} />
|
||||||
|
|||||||
25
components/Breadcrumbs/BreadcrumbsSkeleton.tsx
Normal file
25
components/Breadcrumbs/BreadcrumbsSkeleton.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { ChevronRightIcon, HouseIcon } from "@/components/Icons"
|
||||||
|
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||||
|
|
||||||
|
import styles from "./breadcrumbs.module.css"
|
||||||
|
|
||||||
|
export default function BreadcrumbsSkeleton() {
|
||||||
|
return (
|
||||||
|
<nav className={styles.breadcrumbs}>
|
||||||
|
<ul className={styles.list}>
|
||||||
|
<li className={styles.listItem}>
|
||||||
|
<span className={styles.homeLink} color="peach80">
|
||||||
|
<HouseIcon color="peach80" />
|
||||||
|
</span>
|
||||||
|
<ChevronRightIcon aria-hidden="true" color="peach80" />
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li className={styles.listItem}>
|
||||||
|
<Footnote color="burgundy" type="bold">
|
||||||
|
...
|
||||||
|
</Footnote>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { homeHrefs } from "@/constants/homeHrefs"
|
import { homeHrefs } from "@/constants/homeHrefs"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getCurrentHeader } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { getLang } from "@/i18n/serverContext"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
@@ -11,9 +11,7 @@ import TopMenu from "../TopMenu"
|
|||||||
import styles from "../header.module.css"
|
import styles from "../header.module.css"
|
||||||
|
|
||||||
export default async function HeaderFallback() {
|
export default async function HeaderFallback() {
|
||||||
const data = await serverClient().contentstack.base.currentHeader({
|
const data = await getCurrentHeader(getLang())
|
||||||
lang: getLang(),
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!data?.header) {
|
if (!data?.header) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { logout } from "@/constants/routes/handleAuth"
|
import { logout } from "@/constants/routes/handleAuth"
|
||||||
import { overview } from "@/constants/routes/myPages"
|
import { overview } from "@/constants/routes/myPages"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getName } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
@@ -23,7 +23,7 @@ export default async function TopMenu({
|
|||||||
languageSwitcher,
|
languageSwitcher,
|
||||||
}: TopMenuProps) {
|
}: TopMenuProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const user = await serverClient().user.name()
|
const user = await getName()
|
||||||
return (
|
return (
|
||||||
<div className={styles.topMenu}>
|
<div className={styles.topMenu}>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { homeHrefs } from "@/constants/homeHrefs"
|
import { homeHrefs } from "@/constants/homeHrefs"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { getLanguageSwitcher } from "@/lib/trpc/memoizedRequests"
|
import {
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
getCurrentHeader,
|
||||||
|
getLanguageSwitcher,
|
||||||
|
getMyPagesNavigation,
|
||||||
|
getName,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { getLang } from "@/i18n/serverContext"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
@@ -15,12 +19,10 @@ import styles from "./header.module.css"
|
|||||||
|
|
||||||
export default async function Header() {
|
export default async function Header() {
|
||||||
const [data, user, languages, navigation] = await Promise.all([
|
const [data, user, languages, navigation] = await Promise.all([
|
||||||
serverClient().contentstack.base.currentHeader({
|
getCurrentHeader(getLang()),
|
||||||
lang: getLang(),
|
getName(),
|
||||||
}),
|
|
||||||
serverClient().user.name(),
|
|
||||||
getLanguageSwitcher(),
|
getLanguageSwitcher(),
|
||||||
serverClient().contentstack.myPages.navigation.get(),
|
getMyPagesNavigation(),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (!navigation || !languages || !data?.header) {
|
if (!navigation || !languages || !data?.header) {
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
||||||
import { myPages } from "@/constants/routes/myPages"
|
import { myPages } from "@/constants/routes/myPages"
|
||||||
|
import {
|
||||||
|
getMembershipLevelSafely,
|
||||||
|
getMyPagesNavigation,
|
||||||
|
getName,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
@@ -16,9 +21,9 @@ export default async function MyPagesMenuWrapper() {
|
|||||||
const lang = getLang()
|
const lang = getLang()
|
||||||
const [intl, myPagesNavigation, user, membership] = await Promise.all([
|
const [intl, myPagesNavigation, user, membership] = await Promise.all([
|
||||||
getIntl(),
|
getIntl(),
|
||||||
serverClient().contentstack.myPages.navigation.get(),
|
getMyPagesNavigation(),
|
||||||
serverClient().user.name(),
|
getName(),
|
||||||
serverClient().user.safeMembershipLevel(),
|
getMembershipLevelSafely(),
|
||||||
])
|
])
|
||||||
|
|
||||||
const membershipLevel = membership?.membershipLevel
|
const membershipLevel = membership?.membershipLevel
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Fragment } from "react"
|
import { Fragment } from "react"
|
||||||
|
|
||||||
import { logout } from "@/constants/routes/handleAuth"
|
import { logout } from "@/constants/routes/handleAuth"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getMyPagesNavigation } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import Divider from "@/components/TempDesignSystem/Divider"
|
import Divider from "@/components/TempDesignSystem/Divider"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
@@ -12,7 +12,7 @@ import { getLang } from "@/i18n/serverContext"
|
|||||||
import styles from "./sidebar.module.css"
|
import styles from "./sidebar.module.css"
|
||||||
|
|
||||||
export default async function SidebarMyPages() {
|
export default async function SidebarMyPages() {
|
||||||
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
const navigation = await getMyPagesNavigation()
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getName } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import LoginButton from "@/components/Current/Header/LoginButton"
|
import LoginButton from "@/components/Current/Header/LoginButton"
|
||||||
import ArrowRight from "@/components/Icons/ArrowRight"
|
import ArrowRight from "@/components/Icons/ArrowRight"
|
||||||
@@ -19,7 +19,7 @@ export default async function JoinLoyaltyContact({
|
|||||||
block,
|
block,
|
||||||
}: JoinLoyaltyContactProps) {
|
}: JoinLoyaltyContactProps) {
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
const user = await serverClient().user.name()
|
const user = await getName()
|
||||||
|
|
||||||
// Check if we have user, that means we are logged in.
|
// Check if we have user, that means we are logged in.
|
||||||
if (user) {
|
if (user) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getName } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import MyPagesSidebar from "@/components/MyPages/Sidebar"
|
import MyPagesSidebar from "@/components/MyPages/Sidebar"
|
||||||
|
|
||||||
export default async function MyPagesNavigation() {
|
export default async function MyPagesNavigation() {
|
||||||
const user = await serverClient().user.name()
|
const user = await getName()
|
||||||
|
|
||||||
// Check if we have user, that means we are logged in andt the My Pages menu can show.
|
// Check if we have user, that means we are logged in andt the My Pages menu can show.
|
||||||
if (!user) {
|
if (!user) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export default function Alert({
|
|||||||
<span> {phoneContact.displayText} </span>
|
<span> {phoneContact.displayText} </span>
|
||||||
<Link
|
<Link
|
||||||
color="burgundy"
|
color="burgundy"
|
||||||
href={`tel:${phoneContact.phoneNumber}`}
|
href={`tel:${phoneContact.phoneNumber.replace(/ /g, "")}`}
|
||||||
>
|
>
|
||||||
{phoneContact.phoneNumber}
|
{phoneContact.phoneNumber}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getUserTracking } from "@/lib/trpc/memoizedRequests"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import RouterTransition from "@/components/TrackingSDK/RouterTransition"
|
import RouterTransition from "@/components/TrackingSDK/RouterTransition"
|
||||||
@@ -7,7 +8,7 @@ import TrackingSDKClient from "./Client"
|
|||||||
import { TrackingSDKPageData } from "@/types/components/tracking"
|
import { TrackingSDKPageData } from "@/types/components/tracking"
|
||||||
|
|
||||||
export const preloadUserTracking = () => {
|
export const preloadUserTracking = () => {
|
||||||
void serverClient().user.tracking()
|
void getUserTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function TrackingSDK({
|
export default async function TrackingSDK({
|
||||||
@@ -15,7 +16,7 @@ export default async function TrackingSDK({
|
|||||||
}: {
|
}: {
|
||||||
pageData: TrackingSDKPageData
|
pageData: TrackingSDKPageData
|
||||||
}) {
|
}) {
|
||||||
const userTrackingData = await serverClient().user.tracking()
|
const userTrackingData = await getUserTracking()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { cache } from "react"
|
import { cache } from "react"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
|
||||||
import { serverClient } from "../server"
|
import { serverClient } from "../server"
|
||||||
|
|
||||||
export const getLocations = cache(async function getMemoizedLocations() {
|
export const getLocations = cache(async function getMemoizedLocations() {
|
||||||
@@ -10,6 +12,10 @@ export const getProfile = cache(async function getMemoizedProfile() {
|
|||||||
return serverClient().user.get()
|
return serverClient().user.get()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const getName = cache(async function getMemoizedName() {
|
||||||
|
return serverClient().user.name()
|
||||||
|
})
|
||||||
|
|
||||||
export const getProfileSafely = cache(
|
export const getProfileSafely = cache(
|
||||||
async function getMemoizedProfileSafely() {
|
async function getMemoizedProfileSafely() {
|
||||||
return serverClient().user.getSafely()
|
return serverClient().user.getSafely()
|
||||||
@@ -22,6 +28,28 @@ export const getCreditCardsSafely = cache(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const getMembershipLevel = cache(
|
||||||
|
async function getMemoizedMembershipLevel() {
|
||||||
|
return serverClient().user.membershipLevel()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const getMembershipLevelSafely = cache(
|
||||||
|
async function getMemoizedMembershipLevelSafely() {
|
||||||
|
return serverClient().user.safeMembershipLevel()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const getMembershipCards = cache(
|
||||||
|
async function getMemoizedMembershipCards() {
|
||||||
|
return serverClient().user.membershipCards()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const getUserTracking = cache(async function getMemoizedUserTracking() {
|
||||||
|
return serverClient().user.tracking()
|
||||||
|
})
|
||||||
|
|
||||||
export const getHotelData = cache(async function getMemoizedHotelData(
|
export const getHotelData = cache(async function getMemoizedHotelData(
|
||||||
hotelId: string,
|
hotelId: string,
|
||||||
language: string
|
language: string
|
||||||
@@ -40,6 +68,18 @@ export const getHeader = cache(async function getMemoizedHeader() {
|
|||||||
return serverClient().contentstack.base.header()
|
return serverClient().contentstack.base.header()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const getCurrentHeader = cache(async function getMemoizedCurrentHeader(
|
||||||
|
lang: Lang
|
||||||
|
) {
|
||||||
|
return serverClient().contentstack.base.currentHeader({ lang })
|
||||||
|
})
|
||||||
|
|
||||||
|
export const getMyPagesNavigation = cache(
|
||||||
|
async function getMemoizedMyPagesNavigation() {
|
||||||
|
return serverClient().contentstack.myPages.navigation.get()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export const getLanguageSwitcher = cache(
|
export const getLanguageSwitcher = cache(
|
||||||
async function getMemoizedLanguageSwitcher() {
|
async function getMemoizedLanguageSwitcher() {
|
||||||
return serverClient().contentstack.languageSwitcher.get()
|
return serverClient().contentstack.languageSwitcher.get()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { cache } from "react"
|
||||||
|
|
||||||
import { Lang } from "@/constants/languages"
|
import { Lang } from "@/constants/languages"
|
||||||
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
|
||||||
import {
|
import {
|
||||||
@@ -92,7 +94,7 @@ import type {
|
|||||||
GetSiteConfigRefData,
|
GetSiteConfigRefData,
|
||||||
} from "@/types/trpc/routers/contentstack/siteConfig"
|
} from "@/types/trpc/routers/contentstack/siteConfig"
|
||||||
|
|
||||||
async function getContactConfig(lang: Lang) {
|
const getContactConfig = cache(async (lang: Lang) => {
|
||||||
getContactConfigCounter.add(1, { lang })
|
getContactConfigCounter.add(1, { lang })
|
||||||
console.info(
|
console.info(
|
||||||
"contentstack.contactConfig start",
|
"contentstack.contactConfig start",
|
||||||
@@ -153,7 +155,7 @@ async function getContactConfig(lang: Lang) {
|
|||||||
JSON.stringify({ query: { lang } })
|
JSON.stringify({ query: { lang } })
|
||||||
)
|
)
|
||||||
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
return validatedContactConfigConfig.data.all_contact_config.items[0]
|
||||||
}
|
})
|
||||||
|
|
||||||
export const baseQueryRouter = router({
|
export const baseQueryRouter = router({
|
||||||
contact: contentstackBaseProcedure.query(async ({ ctx }) => {
|
contact: contentstackBaseProcedure.query(async ({ ctx }) => {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { metrics } from "@opentelemetry/api"
|
import { metrics } from "@opentelemetry/api"
|
||||||
|
import { cache } from "react"
|
||||||
|
|
||||||
import * as api from "@/lib/api"
|
import * as api from "@/lib/api"
|
||||||
import {
|
import {
|
||||||
@@ -80,86 +81,87 @@ const getCreditCardsFailCounter = meter.createCounter(
|
|||||||
"trpc.user.creditCards-fail"
|
"trpc.user.creditCards-fail"
|
||||||
)
|
)
|
||||||
|
|
||||||
export async function getVerifiedUser({ session }: { session: Session }) {
|
export const getVerifiedUser = cache(
|
||||||
const now = Date.now()
|
async ({ session }: { session: Session }) => {
|
||||||
|
const now = Date.now()
|
||||||
if (session.token.expires_at && session.token.expires_at < now) {
|
if (session.token.expires_at && session.token.expires_at < now) {
|
||||||
return { error: true, cause: "token_expired" } as const
|
return { error: true, cause: "token_expired" } as const
|
||||||
}
|
}
|
||||||
getVerifiedUserCounter.add(1)
|
getVerifiedUserCounter.add(1)
|
||||||
console.info("api.user.profile getVerifiedUser start", JSON.stringify({}))
|
console.info("api.user.profile getVerifiedUser start", JSON.stringify({}))
|
||||||
const apiResponse = await api.get(api.endpoints.v1.profile, {
|
const apiResponse = await api.get(api.endpoints.v1.profile, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${session.token.access_token}`,
|
Authorization: `Bearer ${session.token.access_token}`,
|
||||||
},
|
},
|
||||||
})
|
|
||||||
|
|
||||||
if (!apiResponse.ok) {
|
|
||||||
const text = await apiResponse.text()
|
|
||||||
getVerifiedUserFailCounter.add(1, {
|
|
||||||
error_type: "http_error",
|
|
||||||
error: JSON.stringify({
|
|
||||||
status: apiResponse.status,
|
|
||||||
statusText: apiResponse.statusText,
|
|
||||||
text,
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
console.error(
|
|
||||||
"api.user.profile getVerifiedUser error",
|
if (!apiResponse.ok) {
|
||||||
JSON.stringify({
|
const text = await apiResponse.text()
|
||||||
error: {
|
getVerifiedUserFailCounter.add(1, {
|
||||||
|
error_type: "http_error",
|
||||||
|
error: JSON.stringify({
|
||||||
status: apiResponse.status,
|
status: apiResponse.status,
|
||||||
statusText: apiResponse.statusText,
|
statusText: apiResponse.statusText,
|
||||||
text,
|
text,
|
||||||
},
|
}),
|
||||||
})
|
})
|
||||||
)
|
console.error(
|
||||||
if (apiResponse.status === 401) {
|
"api.user.profile getVerifiedUser error",
|
||||||
return { error: true, cause: "unauthorized" } as const
|
JSON.stringify({
|
||||||
} else if (apiResponse.status === 403) {
|
error: {
|
||||||
return { error: true, cause: "forbidden" } as const
|
status: apiResponse.status,
|
||||||
} else if (apiResponse.status === 404) {
|
statusText: apiResponse.statusText,
|
||||||
return { error: true, cause: "notfound" } as const
|
text,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
if (apiResponse.status === 401) {
|
||||||
|
return { error: true, cause: "unauthorized" } as const
|
||||||
|
} else if (apiResponse.status === 403) {
|
||||||
|
return { error: true, cause: "forbidden" } as const
|
||||||
|
} else if (apiResponse.status === 404) {
|
||||||
|
return { error: true, cause: "notfound" } as const
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
error: true,
|
||||||
|
cause: "unknown",
|
||||||
|
status: apiResponse.status,
|
||||||
|
} as const
|
||||||
}
|
}
|
||||||
return {
|
|
||||||
error: true,
|
|
||||||
cause: "unknown",
|
|
||||||
status: apiResponse.status,
|
|
||||||
} as const
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiJson = await apiResponse.json()
|
const apiJson = await apiResponse.json()
|
||||||
if (!apiJson.data?.attributes) {
|
if (!apiJson.data?.attributes) {
|
||||||
getVerifiedUserFailCounter.add(1, {
|
getVerifiedUserFailCounter.add(1, {
|
||||||
error_type: "data_error",
|
error_type: "data_error",
|
||||||
})
|
|
||||||
console.error(
|
|
||||||
"api.user.profile getVerifiedUser data error",
|
|
||||||
JSON.stringify({
|
|
||||||
apiResponse: apiJson,
|
|
||||||
})
|
})
|
||||||
)
|
console.error(
|
||||||
return null
|
"api.user.profile getVerifiedUser data error",
|
||||||
}
|
JSON.stringify({
|
||||||
|
apiResponse: apiJson,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const verifiedData = getUserSchema.safeParse(apiJson)
|
const verifiedData = getUserSchema.safeParse(apiJson)
|
||||||
if (!verifiedData.success) {
|
if (!verifiedData.success) {
|
||||||
getVerifiedUserFailCounter.add(1, {
|
getVerifiedUserFailCounter.add(1, {
|
||||||
error_type: "validation_error",
|
error_type: "validation_error",
|
||||||
error: JSON.stringify(verifiedData.error),
|
error: JSON.stringify(verifiedData.error),
|
||||||
})
|
|
||||||
console.error(
|
|
||||||
"api.user.profile validation error",
|
|
||||||
JSON.stringify({
|
|
||||||
errors: verifiedData.error,
|
|
||||||
})
|
})
|
||||||
)
|
console.error(
|
||||||
return null
|
"api.user.profile validation error",
|
||||||
|
JSON.stringify({
|
||||||
|
errors: verifiedData.error,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
getVerifiedUserSuccessCounter.add(1)
|
||||||
|
console.info("api.user.profile getVerifiedUser success", JSON.stringify({}))
|
||||||
|
return verifiedData
|
||||||
}
|
}
|
||||||
getVerifiedUserSuccessCounter.add(1)
|
)
|
||||||
console.info("api.user.profile getVerifiedUser success", JSON.stringify({}))
|
|
||||||
return verifiedData
|
|
||||||
}
|
|
||||||
|
|
||||||
function parsedUser(data: User, isMFA: boolean) {
|
function parsedUser(data: User, isMFA: boolean) {
|
||||||
const country = countries.find((c) => c.code === data.address.countryCode)
|
const country = countries.find((c) => c.code === data.address.countryCode)
|
||||||
|
|||||||
Reference in New Issue
Block a user