feat: static my stays

This commit is contained in:
Michael Zetterberg
2024-04-19 17:07:23 +02:00
parent 837604e6ea
commit 2f6500f46d
33 changed files with 576 additions and 77 deletions
@@ -0,0 +1,9 @@
.container {
align-items: center;
display: flex;
justify-content: center;
min-height: 25rem;
background-color: var(--some-grey-color, #f2f2f2);
border-radius: 0.8rem;
max-width: var(--max-width);
}
@@ -0,0 +1,12 @@
import Title from "@/components/MyPages/Title"
import styles from "./emptyPreviousStays.module.css"
export default function EmptyPreviousStaysBlock() {
return (
<section className={styles.container}>
<Title level="h3" as="h5" uppercase>
You have no previous stays.
</Title>
</section>
)
}
@@ -0,0 +1,26 @@
.button {
background-color: var(--some-red-color, #ed2027);
}
.link {
text-decoration: none;
}
.redTitle {
color: var(--some-red-color, #ed2027);
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;
max-width: var(--max-width);
margin-bottom: 0.5rem;
padding: 0 2rem;
}
@@ -0,0 +1,25 @@
import Title from "@/components/MyPages/Title"
import Button from "@/components/TempDesignSystem/Button"
import styles from "./emptyUpcomingStays.module.css"
import Link from "next/link"
export default function EmptyUpcomingStaysBlock() {
return (
<section className={styles.container}>
<Title level="h3" as="h5" uppercase>
You have no upcoming stays.
<span className={styles.redTitle}> Where should you go next?</span>
</Title>
<Button
intent={"primary"}
className={styles.button}
asChild
type="button"
>
<Link className={styles.link} href={"#"} key={"getInspired"}>
Get inspired
</Link>
</Button>
</section>
)
}
@@ -0,0 +1,13 @@
.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;
}
}
@@ -0,0 +1,18 @@
import Title from "@/components/MyPages/Title"
import styles from "./header.module.css"
import { HeaderProps } from "@/types/components/myPages/stays/title"
export default function Header({ title, subtitle }: HeaderProps) {
return (
<header className={styles.header}>
<Title as="h3" weight="semiBold" uppercase>
{title}
</Title>
<Title as="h5" weight="regular" className={styles.subtitle}>
{subtitle}
</Title>
</header>
)
}
@@ -0,0 +1,28 @@
import { serverClient } from "@/lib/trpc/server"
import EmptyPreviousStaysBlock from "../EmptyPreviousStays"
import Header from "../Header"
import StayList from "../StayList"
import styles from "./previous.module.css"
import type { LangParams } from "@/types/params"
export default async function PreviousStays({ lang }: LangParams) {
const stays = await serverClient().user.stays.previous()
return (
<section className={styles.container}>
<Header
title="Your previous stays."
subtitle="Revisit your stays and rekindle those our moments together, with ease."
></Header>
{stays.length ? (
<StayList lang={lang} stays={stays} />
) : (
<EmptyPreviousStaysBlock />
)}
</section>
)
}
@@ -0,0 +1,3 @@
.container {
max-width: var(--max-width);
}
@@ -0,0 +1,72 @@
import { dt } from "@/lib/dt"
import Image from "@/components/Image"
import styles from "./stay.module.css"
import Title from "@/components/MyPages/Title"
import type { StayCardProps } from "@/types/components/myPages/stays/stayCard"
export default function StayCard({
stay,
lang,
showDayCount = false,
}: StayCardProps) {
const { dateArrive, dateDepart, guests, hotel } = stay
const daysUntilArrival = dt(dateArrive).diff(dt(), "days")
const arrival = dt(dateArrive).locale(lang)
const arrivalDate = arrival.format("DD MMM")
const arrivalDateTime = arrival.format("YYYY-MM-DD")
const depart = dt(dateDepart).locale(lang)
const departDate = depart.format("DD MMM YYYY")
const departDateTime = depart.format("YYYY-MM-DD")
return (
<article className={styles.stay}>
<div className={styles.imageContainer}>
{showDayCount ? (
<div className={styles.badge}>
<time className={styles.time}>In {daysUntilArrival} days</time>
</div>
) : null}
<Image
alt="Placeholder image flower"
height={73}
src="/_static/icons/flower-image.svg"
width={73}
/>
</div>
<footer className={styles.footer}>
<Title as="h5" level="h3" uppercase className={styles.hotel}>
{hotel}
</Title>
<section className={styles.container}>
<div className={styles.date}>
<Image
alt="Calendar Icon"
height={20}
src="/_static/icons/calendar_month.svg"
width={20}
/>
<p>
<time dateTime={arrivalDateTime}>{arrivalDate}</time>
{" - "}
<time dateTime={departDateTime}>{departDate}</time>
</p>
</div>
<div className={styles.guests}>
<Image
alt="Guests Icon"
height={20}
src="/_static/icons/person.svg"
width={20}
/>
<span>
{guests} guest{guests > 1 ? "s" : ""}
</span>
</div>
</section>
</footer>
</article>
)
}
@@ -0,0 +1,69 @@
.stay {
background-color: var(--some-grey-color, #ababab);
border-radius: 0.8rem;
display: grid;
flex-grow: 1;
flex-shrink: 0;
flex-basis: 32rem;
grid-template-rows: 1fr 9rem;
height: 28rem;
}
.imageContainer {
align-items: center;
display: grid;
justify-content: center;
position: relative;
}
.badge {
background-color: var(--some-white-color, #fff);
border-radius: 4rem;
left: 1.5rem;
padding: 0.6rem 1.4rem;
position: absolute;
top: 1.5rem;
}
.time {
color: var(--some-black-color, #000);
font-family: var(--ff-fira-sans);
font-size: 1.2rem;
font-weight: 400;
}
.footer {
background-color: var(--some-white-color, #fff);
border-bottom: 0.1rem solid var(--some-grey-color, #d9d9d9);
border-left: 0.1rem solid var(--some-grey-color, #d9d9d9);
border-right: 0.1rem solid var(--some-grey-color, #d9d9d9);
border-radius: 0 0 0.8rem 0.8rem;
display: inline-block;
height: 9rem;
padding: 1.5rem 2rem;
overflow: hidden;
}
.hotel {
overflow: hidden;
text-wrap: nowrap;
text-overflow: ellipsis;
font-size: 1.5rem;
padding: 0;
margin: 0;
}
.container {
align-items: center;
display: grid;
gap: 2rem;
grid-template-columns: auto 1fr;
justify-content: flex-start;
}
.date,
.guests {
align-items: center;
display: flex;
gap: 0.6rem;
}
@@ -0,0 +1,28 @@
import Button from "@/components/TempDesignSystem/Button"
import StayCard from "../StayCard"
import styles from "./stayList.module.css"
import { StayListProps } from "@/types/components/myPages/stays/stayList"
export default function StayList({ lang, stays }: StayListProps) {
return (
<section>
<section className={styles.stays}>
{stays.map((stay) => (
<StayCard
key={stay.uid}
stay={stay}
lang={lang}
showDayCount={true}
/>
))}
</section>
<div className={styles.buttonContainer}>
<Button intent="primary" type="button">
Show more
</Button>
</div>
</section>
)
}
@@ -0,0 +1,32 @@
.stays {
display: grid;
row-gap: 1.5rem;
column-gap: 2.2rem;
grid-template-columns: auto;
/* Hide scrollbar IE and Edge */
-ms-overflow-style: none;
/* Hide Scrollbar Firefox */
scrollbar-width: none;
}
/* Hide Scrollbar Chrome, Safari and Opera */
.stays::-webkit-scrollbar {
display: none;
}
.buttonContainer {
display: flex;
justify-content: center;
margin-top: 2rem;
}
@media screen and (min-width: 950px) {
.stays {
grid-template-columns: repeat(auto-fit, minmax(25rem, 1fr));
}
.buttonContainer {
margin-top: 4rem;
}
}
@@ -0,0 +1,29 @@
import { serverClient } from "@/lib/trpc/server"
import EmptyUpcomingStaysBlock from "../EmptyUpcomingStays"
import Header from "../Header"
import StayList from "../StayList"
import styles from "./upcoming.module.css"
import type { LangParams } from "@/types/params"
export default async function UpcomingStays({ lang }: LangParams) {
const stays = await serverClient().user.stays.upcoming()
return (
<section className={styles.container}>
<Header
title="Your 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>
{stays.length ? (
<StayList lang={lang} stays={stays} />
) : (
<EmptyUpcomingStaysBlock />
)}
</section>
)
}
@@ -0,0 +1,3 @@
.container {
max-width: var(--max-width);
}