feat: add SoonestStays

This commit is contained in:
Arvid Norlin
2024-04-22 13:34:57 +02:00
parent fc28e09df5
commit dff21b33cd
21 changed files with 235 additions and 107 deletions

View File

@@ -14,6 +14,7 @@ import NextLevelBenefitsBlock from "@/components/MyPages/Blocks/Benefits/NextLev
import Overview from "@/components/MyPages/Blocks/Overview"
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
import UpcomingStays from "@/components/MyPages/Blocks/Stays/Upcoming"
import SoonestStays from "@/components/MyPages/Blocks/Stays/Soonest"
import { renderOptions } from "@/components/JsonToHtml/renderOptions"
function DynamicComponent({
@@ -27,7 +28,8 @@ function DynamicComponent({
}) {
const componentProps = {
title: content.title,
preamble: content.preamble,
// TODO: rename preamble to subtitle in Contentstack
subtitle: content.preamble,
link: content.link.linkConnection.edges.length
? {
href: content.link.linkConnection.edges[0].node.url,
@@ -40,22 +42,14 @@ function DynamicComponent({
return <Overview user={user} />
case DynamicContentComponents.previous_stays:
return null
case DynamicContentComponents.soonest_stays:
return <SoonestStays lang={lang} {...componentProps} />
case DynamicContentComponents.upcoming_stays:
return <UpcomingStays lang={lang} {...componentProps} />
case DynamicContentComponents.current_benefits:
return (
<CurrentBenefitsBlock
title={content.title}
preamble={content.preamble}
/>
)
return <CurrentBenefitsBlock {...componentProps} />
case DynamicContentComponents.next_benefits:
return (
<NextLevelBenefitsBlock
title={content.title}
preamble={content.preamble}
/>
)
return <NextLevelBenefitsBlock {...componentProps} />
default:
return null
}
@@ -94,7 +88,6 @@ export default function Content({
/>
)
case ContentEntries.AccountPageContentTextContent:
console.log({ item })
return (
<JsonToHtml
embeds={[]}

View File

@@ -3,6 +3,10 @@
gap: 4px;
}
.header {
display: flex;
justify-content: space-between;
}
.title {
font-weight: 600;
}
@@ -11,7 +15,7 @@
color: var(--some-red-color, #ed2027);
}
.subtitle {
.cardSubtitle {
font-family: var(--ff-fira-sans);
font-size: 12px;
font-weight: 400;

View File

@@ -8,12 +8,14 @@ import styles from "./current.module.css"
export type CurrentLevelProps = {
title: string
preamble?: string
subtitle?: string
link: { text: string; href: string } | null
}
export default async function CurrentBenefitsBlock({
title,
preamble,
subtitle,
link,
}: CurrentLevelProps) {
const benefits = await serverClient().user.benefits.current()
@@ -23,8 +25,13 @@ export default async function CurrentBenefitsBlock({
<Title as="h4" level="h2" className={styles.title} uppercase>
{title}
</Title>
{preamble && <p className={styles.preamble}>{preamble}</p>}
{link && (
<Link className={styles.link} href={link.href}>
{link.text}
</Link>
)}
</header>
{subtitle && <p className={styles.subtitle}>{subtitle}</p>}
<div className={styles.cardContainer}>
{benefits.map((benefit) => (
@@ -33,7 +40,7 @@ export default async function CurrentBenefitsBlock({
<span className={styles.value}>{benefit.value}</span>{" "}
{benefit.explanation}
</Title>
<p className={styles.subtitle}>{benefit.subtitle}</p>
<p className={styles.cardSubtitle}>{benefit.subtitle}</p>
</Link>
))}
</div>

View File

@@ -10,12 +10,14 @@ import styles from "./next.module.css"
export type NextLevelProps = {
title: string
preamble?: string
subtitle?: string
link: { href: string; text: string } | null
}
export default async function NextLevelBenefitsBlock({
title,
preamble,
subtitle,
link,
}: NextLevelProps) {
const { nextLevel, perks } = await serverClient().user.benefits.nextLevel()
@@ -24,9 +26,14 @@ export default async function NextLevelBenefitsBlock({
<header className={styles.header}>
<Title as="h4" level="h2" uppercase className={styles.title}>
{title}
{link && (
<Link className={styles.link} href={link.href}>
{link.text}
</Link>
)}
</Title>
{preamble && <p className={styles.preamble}>{preamble}</p>}
</header>
{subtitle && <p className={styles.subtitle}>{subtitle}</p>}
<div className={styles.cardContainer}>
{perks.map((perk) => (
<article key={perk.id} className={styles.card}>
@@ -36,7 +43,7 @@ export default async function NextLevelBenefitsBlock({
</Button>
<div>
<span className={styles.level}>As our {nextLevel}</span>{" "}
<p className={styles.subtitle}>{perk.explanation}</p>
<p className={styles.cardSubtitle}>{perk.explanation}</p>
</div>
</article>
))}

View File

@@ -3,6 +3,10 @@
gap: 1.5rem;
}
.header {
display: flex;
justify-content: space-between;
}
.cardContainer {
display: grid;
gap: 0.4rem;
@@ -31,7 +35,7 @@
font-style: italic; /* font-family: var(--ff-biro-script-plus); */
}
.subtitle {
.cardSubtitle {
font-size: var(--typography-Subtitle-Mobile-fontSize, 18px);
}
@@ -54,7 +58,7 @@
font-weight: var(--typography-Script-Desktop-fontWeight);
}
.subtitle {
.cardSubtitle {
font-size: var(--typography-Subtitle-Desktop-fontSize, 18px);
}
}

View File

@@ -2,3 +2,17 @@
display: grid;
gap: 0.5rem;
}
.subtitle {
padding-top: 0.5rem;
padding-bottom: 2.5rem;
margin: 0;
}
@media screen and (min-width: 950px) {
.subtitle {
width: 60%;
padding-top: 2.5rem;
padding-bottom: 5rem;
}
}

View File

@@ -1,18 +1,29 @@
import Link from "next/link"
import Title from "@/components/Title"
import styles from "./header.module.css"
import type { HeaderProps } from "@/types/components/myPages/myStays/title"
export default function Header({ title, subtitle }: HeaderProps) {
export default function Header({ title, subtitle, link }: HeaderProps) {
return (
<header className={styles.header}>
<Title as="h3" level="h2" weight="semiBold" uppercase>
{title}
</Title>
<Title as="h5" level="h3" weight="regular">
{subtitle}
</Title>
</header>
<>
<header className={styles.header}>
<Title className={styles.title} as="h3" weight="semiBold" uppercase>
{title}
</Title>
{link && (
<Link className={styles.link} href={link.href}>
{link.text}
</Link>
)}
</header>
{subtitle && (
<Title as="h5" weight="regular" className={styles.subtitle}>
{subtitle}
</Title>
)}
</>
)
}

View File

@@ -1,5 +1,6 @@
"use client"
import { Lang } from "@/constants/languages"
import { _ } from "@/lib/translation"
import { trpc } from "@/lib/trpc/client"
@@ -11,9 +12,20 @@ import StayList from "../StayList"
import EmptyPreviousStaysBlock from "./EmptyPreviousStays"
import type { Page } from "@/types/components/myPages/myStays/page"
import type { LangParams } from "@/types/params"
export default function PreviousStays({ lang }: LangParams) {
type PreviousStaysProps = {
lang: Lang
title: string
subtitle?: string
link: { href: string; text: string } | null
}
export default function PreviousStays({
lang,
title,
subtitle,
link,
}: PreviousStaysProps) {
const { data, isFetching, fetchNextPage, hasNextPage } =
trpc.user.stays.previous.useInfiniteQuery(
{},
@@ -28,12 +40,8 @@ export default function PreviousStays({ lang }: LangParams) {
return (
<Container>
<Header
title={_("Previous stays")}
subtitle={_(
"Revisit your stays and rekindle those our moments together, with ease."
)}
/>
<Header title={title} subtitle={subtitle} link={link} />
{data?.pages.length ? (
<ListContainer>
<StayList

View File

@@ -0,0 +1,25 @@
.button {
background-color: var(--some-red-color, #ed2027);
}
.link {
text-decoration: none;
}
.grayTitle {
color: var(--some-grey-color, #727272);
display: block;
}
.container {
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 25rem;
gap: 2.5rem;
background-color: var(--some-grey-color, #f2f2f2);
border-radius: 0.8rem;
margin-bottom: 0.5rem;
padding: 0 2rem;
}

View File

@@ -0,0 +1,27 @@
import Link from "next/link"
import { _ } from "@/lib/translation"
import Button from "@/components/TempDesignSystem/Button"
import Title from "@/components/Title"
import styles from "./emptyUpcomingStays.module.css"
export default function EmptyUpcomingStaysBlock() {
return (
<section className={styles.container}>
<Title level="h3" as="h5" uppercase>
{_(" You have no upcoming stays.")}
<span className={styles.grayTitle}>
{" "}
{_("Where should you go next?")}
</span>
</Title>
<Button intent="primary" bgcolor="quarternary" asChild type="button">
<Link className={styles.link} href={"#"} key="getInspired">
{_("Get inspired")}
</Link>
</Button>
</section>
)
}

View File

@@ -0,0 +1,35 @@
import { Lang } from "@/constants/languages"
import { serverClient } from "@/lib/trpc/server"
import Header from "../Header"
import StayList from "../StayList"
import EmptyUpcomingStaysBlock from "./EmptyUpcomingStays"
import styles from "./soonest.module.css"
type UpcomingStaysProps = {
lang: Lang
title: string
subtitle?: string
link: { text: string; href: string } | null
}
export default async function UpcomingStays({
lang,
title,
subtitle,
link,
}: UpcomingStaysProps) {
const stays = await serverClient().user.stays.soonestUpcoming()
return (
<section className={styles.container}>
<Header title={title} subtitle={subtitle} link={link}></Header>
{stays.length ? (
<StayList lang={lang} stays={stays} />
) : (
<EmptyUpcomingStaysBlock />
)}
</section>
)
}

View File

@@ -0,0 +1,3 @@
.container {
max-width: var(--max-width);
}

View File

@@ -1,5 +1,6 @@
"use client"
import { Lang } from "@/constants/languages"
import { _ } from "@/lib/translation"
import { trpc } from "@/lib/trpc/client"
@@ -11,9 +12,20 @@ import StayList from "../StayList"
import EmptyUpcomingStaysBlock from "./EmptyUpcomingStays"
import type { Page } from "@/types/components/myPages/myStays/page"
import type { LangParams } from "@/types/params"
export default function UpcomingStays({ lang }: LangParams) {
type UpcomingStaysProps = {
lang: Lang
title: string
subtitle?: string
link: { text: string; href: string } | null
}
export default function UpcomingStays({
lang,
title,
subtitle,
link,
}: UpcomingStaysProps) {
const { data, hasNextPage, isFetching, fetchNextPage } =
trpc.user.stays.upcoming.useInfiniteQuery(
{},
@@ -28,12 +40,8 @@ export default function UpcomingStays({ lang }: LangParams) {
return (
<Container>
<Header
title={_("Upcoming stays")}
subtitle={_(
"Excited about your next trip? So are we. Below are your upcoming stays with us, complete with all the details you need to make each visit perfect. Can't wait to welcome you back, friend!"
)}
/>
<Header title={title} subtitle={subtitle} link={link} />
{data?.pages.length ? (
<ListContainer>
<StayList

View File

@@ -1,37 +0,0 @@
import Link from "next/link"
import Stay from "./Stay"
import Title from "@/components/MyPages/Title"
import styles from "./upcoming.module.css"
import type { LangParams } from "@/types/params"
import type { StaysProps } from "@/types/components/myPages/myPage/stays"
export default function UpcomingStays({
lang,
stays,
title,
preamble,
link,
}: StaysProps & LangParams) {
return (
<section className={styles.container}>
<header className={styles.header}>
<Title level="h2" as="h4" uppercase>
{title}
</Title>
{link && (
<Link className={styles.link} href={link.href}>
{link.text}
</Link>
)}
</header>
{preamble}
<section className={styles.stays}>
{stays.map((stay) => (
<Stay key={stay.hotel} {...stay} lang={lang} />
))}
</section>
</section>
)
}