feat: added RoomCard and CardContainer component to HotelPage

This commit is contained in:
Erik Tiekstra
2024-07-04 10:35:23 +02:00
committed by Chuma McPhoy
parent 6b5606fc8b
commit 68f40a144e
16 changed files with 294 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
.cardContainer {
display: grid;
gap: var(--Spacing-x3);
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.cardContainer.twoColumns {
grid-template-columns: repeat(2, 1fr);
}
.cardContainer.threeColumns {
grid-template-columns: repeat(3, 1fr);
}
.cardContainer.fourColumns {
grid-template-columns: repeat(4, 1fr);
}

View File

@@ -0,0 +1,7 @@
import { VariantProps } from "class-variance-authority"
import { cardContainerVariants } from "./variants"
export interface CardContainerProps
extends React.PropsWithChildren<React.HTMLAttributes<HTMLElement>>,
VariantProps<typeof cardContainerVariants> {}

View File

@@ -0,0 +1,18 @@
import { CardContainerProps } from "./cardContainer"
import { cardContainerVariants } from "./variants"
export function CardContainer({
children,
className,
columns,
...props
}: CardContainerProps) {
return (
<section
className={cardContainerVariants({ className, columns })}
{...props}
>
{children}
</section>
)
}

View File

@@ -0,0 +1,16 @@
import { cva } from "class-variance-authority"
import styles from "./cardContainer.module.css"
export const cardContainerVariants = cva(styles.cardContainer, {
variants: {
columns: {
2: styles.twoColumns,
3: styles.threeColumns,
4: styles.fourColumns,
},
},
defaultVariants: {
columns: 3,
},
})

View File

@@ -0,0 +1,52 @@
"use client"
import { ImageIcon } from "@/components/Icons"
import Image from "@/components/Image"
import Body from "@/components/TempDesignSystem/Text/Body"
import Title from "@/components/TempDesignSystem/Text/Title"
import { RoomCardProps } from "./roomCard"
import styles from "./roomCard.module.css"
export function RoomCard({
badgeText,
title,
subtitle,
cta,
image,
imageCount,
imageClick,
}: RoomCardProps) {
return (
<article className={styles.roomCard}>
<button className={styles.imageWrapper} onClick={imageClick}>
{badgeText && <span className={styles.badge}>{badgeText}</span>}
{imageCount && (
<span className={styles.imageCount}>
<ImageIcon color="white" />
{imageCount}
</span>
)}
<Image
className={styles.image}
src={image.src}
alt={image.alt}
height={image.height}
width={image.width}
/>
</button>
<div className={styles.content}>
<div className={styles.innerContent}>
<Title as="h4" level="h3" textTransform="capitalize" color="black">
{title}
</Title>
<Body color="grey">{subtitle}</Body>
</div>
<button className={styles.cta} onClick={cta.callback}>
{cta.text}
</button>
</div>
</article>
)
}

View File

@@ -0,0 +1,90 @@
.roomCard {
border-radius: var(--Corner-radius-Medium);
background-color: var(--Base-Surface-Primary-Normal);
border: 1px solid var(--Base-Border-Subtle);
display: grid;
}
.badge {
position: absolute;
top: var(--Spacing-x1);
left: var(--Spacing-x1);
background-color: var(--Scandic-Blue-100);
padding: var(--Spacing-x-half) var(--Spacing-x1);
border-radius: var(--Corner-radius-Medium);
color: var(--Tertiary-Dark-On-Surface-Text, #fff0c2);
text-transform: uppercase;
font-family: var(--typography-Title-5-fontFamily);
font-size: var(--typography-Footnote-Regular-fontSize);
font-weight: var(--typography-Footnote-Regular-fontWeight);
}
.imageCount {
position: absolute;
right: var(--Spacing-x1);
bottom: var(--Spacing-x1);
display: flex;
gap: var(--Spacing-x-half);
align-items: center;
background-color: color-mix(
in srgb,
var(--Scandic-Beige-80) 80%,
transparent
);
color: white;
padding: var(--Spacing-x-half) var(--Spacing-x1);
border-radius: var(--Corner-radius-Medium);
}
.content {
display: grid;
justify-items: center;
gap: var(--Spacing-x-one-and-half);
padding: var(--Spacing-x2);
}
.innerContent {
display: grid;
justify-items: center;
gap: var(--Spacing-x1);
}
.imageWrapper {
position: relative;
background-color: transparent;
border-width: 0;
cursor: pointer;
margin: 0;
padding: 0;
display: flex;
}
.image {
width: 100%;
object-fit: cover;
border-top-left-radius: var(--Corner-radius-Medium);
border-top-right-radius: var(--Corner-radius-Medium);
}
.subtitle {
color: var(--UI-Text-Placeholder, #787472);
}
.cta {
background-color: transparent;
border-width: 0;
cursor: pointer;
margin: 0;
padding: 0;
display: flex;
align-items: center;
gap: var(--Spacing-x-half);
color: var(--Base-Text-Medium-contrast, #8f4350);
font-family: var(--typography-Body-Bold-fontFamily);
font-size: var(--typography-Body-Bold-fontSize);
font-weight: 600;
text-decoration: underline;
}
.cta:hover {
color: var(--Base-Text-High-contrast, #4d001b);
}

View File

@@ -0,0 +1,16 @@
import { ImageProps } from "next/image"
interface RoomCardCtaProps {
text: string
callback: () => void
}
export interface RoomCardProps {
image: ImageProps
imageCount: number
imageClick: () => void
title: string
subtitle: string
cta: RoomCardCtaProps
badgeText?: string
}