feat:(SW-219): content card component WIP
This commit is contained in:
@@ -74,7 +74,7 @@ export function RoomCard({
|
|||||||
onClick={handleRoomCtaClick}
|
onClick={handleRoomCtaClick}
|
||||||
>
|
>
|
||||||
{intl.formatMessage({ id: "See room details" })}
|
{intl.formatMessage({ id: "See room details" })}
|
||||||
<ChevronRightIcon className={styles.chevron} />
|
<ChevronRightIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -63,3 +63,10 @@
|
|||||||
align-items: end;
|
align-items: end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add this to your existing styles */
|
||||||
|
.contentCardContainer {
|
||||||
|
margin: var(--Spacing-x4) 0;
|
||||||
|
display: grid;
|
||||||
|
gap: var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
|
import ContentCard from "@/components/TempDesignSystem/ContentCard"
|
||||||
|
|
||||||
import { MOCK_FACILITIES } from "./Facilities/mockData"
|
import { MOCK_FACILITIES } from "./Facilities/mockData"
|
||||||
import { setActivityCard } from "./Facilities/utils"
|
import { setActivityCard } from "./Facilities/utils"
|
||||||
import DynamicMap from "./Map/DynamicMap"
|
import DynamicMap from "./Map/DynamicMap"
|
||||||
@@ -65,6 +67,34 @@ export default async function HotelPage() {
|
|||||||
</div>
|
</div>
|
||||||
<Rooms rooms={roomCategories} />
|
<Rooms rooms={roomCategories} />
|
||||||
<Facilities facilities={facilities} />
|
<Facilities facilities={facilities} />
|
||||||
|
|
||||||
|
{/* Add ContentCard here */}
|
||||||
|
<ContentCard
|
||||||
|
title="Special Offer"
|
||||||
|
description="Enjoy a luxurious stay with our exclusive package."
|
||||||
|
primaryCTA={{
|
||||||
|
label: "Book Now",
|
||||||
|
href: "/booking",
|
||||||
|
}}
|
||||||
|
secondaryCTA={{
|
||||||
|
label: "Learn More",
|
||||||
|
href: "/offers",
|
||||||
|
openInNewTab: true,
|
||||||
|
}}
|
||||||
|
style="featured"
|
||||||
|
backgroundImage="https://www.scandichotels.com/imageVault/publishedmedia/sixadhu91jy67aal2pla/Scandic_Downtown_Camper_cocktail_lounge_bar_the_ne.jpg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Example of ContentCard with SidePeek */}
|
||||||
|
<ContentCard
|
||||||
|
title="Explore Facilities"
|
||||||
|
description="Discover all the amenities our hotel has to offer."
|
||||||
|
sidePeekCTA={{
|
||||||
|
label: "View Facilities",
|
||||||
|
onClick: true,
|
||||||
|
}}
|
||||||
|
style="default"
|
||||||
|
/>
|
||||||
</main>
|
</main>
|
||||||
{googleMapsApiKey ? (
|
{googleMapsApiKey ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
.card {
|
||||||
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 399px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default {
|
||||||
|
background-color: var(--Base-Surface-Subtle-Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.featured {
|
||||||
|
background-color: var(--Main-Grey-White);
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageContainer {
|
||||||
|
width: 100%;
|
||||||
|
height: 12.58625rem; /* 201.38px / 16 = 12.58625rem */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backgroundImage {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--Base-Text-Medium-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaContainer {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
margin-top: var(--Spacing-x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidePeekCTA {
|
||||||
|
/* TODO: Create ticket to remove padding on "link" buttons,
|
||||||
|
align w. design on this. */
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
85
components/TempDesignSystem/ContentCard/index.tsx
Normal file
85
components/TempDesignSystem/ContentCard/index.tsx
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
import { ChevronRightIcon } from "@/components/Icons"
|
||||||
|
import Image from "@/components/Image"
|
||||||
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
|
|
||||||
|
import Subtitle from "../Text/Subtitle"
|
||||||
|
import { contentCardVariants } from "./variants"
|
||||||
|
|
||||||
|
import styles from "./contentCard.module.css"
|
||||||
|
|
||||||
|
import type { ContentCardProps } from "@/types/components/contentCard"
|
||||||
|
|
||||||
|
export default function ContentCard({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
primaryCTA,
|
||||||
|
secondaryCTA,
|
||||||
|
sidePeekCTA,
|
||||||
|
backgroundImage,
|
||||||
|
style = "default",
|
||||||
|
className,
|
||||||
|
}: ContentCardProps) {
|
||||||
|
const cardClasses = contentCardVariants({ style, className })
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cardClasses}>
|
||||||
|
{backgroundImage && (
|
||||||
|
<div className={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
src={backgroundImage}
|
||||||
|
alt=""
|
||||||
|
className={styles.backgroundImage}
|
||||||
|
width={399}
|
||||||
|
height={201}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className={styles.content}>
|
||||||
|
<Subtitle textAlign="left" type="two" color="black">
|
||||||
|
{title}
|
||||||
|
</Subtitle>
|
||||||
|
<Body color="black">{description}</Body>
|
||||||
|
{sidePeekCTA ? (
|
||||||
|
<Button
|
||||||
|
// onClick={sidePeekCTA.onClick}
|
||||||
|
theme="base"
|
||||||
|
variant="icon"
|
||||||
|
intent="text"
|
||||||
|
size="small"
|
||||||
|
className={styles.sidePeekCTA}
|
||||||
|
>
|
||||||
|
{sidePeekCTA.label}
|
||||||
|
<ChevronRightIcon />
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<div className={styles.ctaContainer}>
|
||||||
|
{primaryCTA && (
|
||||||
|
<Button asChild intent="primary" size="small">
|
||||||
|
<Link
|
||||||
|
href={primaryCTA.href}
|
||||||
|
target={primaryCTA.openInNewTab ? "_blank" : undefined}
|
||||||
|
>
|
||||||
|
{primaryCTA.label}
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{secondaryCTA && (
|
||||||
|
<Button asChild intent="secondary" size="small">
|
||||||
|
<Link
|
||||||
|
href={secondaryCTA.href}
|
||||||
|
target={secondaryCTA.openInNewTab ? "_blank" : undefined}
|
||||||
|
>
|
||||||
|
{secondaryCTA.label}
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
15
components/TempDesignSystem/ContentCard/variants.ts
Normal file
15
components/TempDesignSystem/ContentCard/variants.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { cva } from "class-variance-authority"
|
||||||
|
|
||||||
|
import styles from "./contentCard.module.css"
|
||||||
|
|
||||||
|
export const contentCardVariants = cva(styles.card, {
|
||||||
|
variants: {
|
||||||
|
style: {
|
||||||
|
default: styles.default,
|
||||||
|
featured: styles.featured,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
style: "default",
|
||||||
|
},
|
||||||
|
})
|
||||||
26
types/components/contentCard.ts
Normal file
26
types/components/contentCard.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { contentCardVariants } from "@/components/TempDesignSystem/ContentCard/variants"
|
||||||
|
|
||||||
|
export interface CTA {
|
||||||
|
label: string
|
||||||
|
href: string
|
||||||
|
openInNewTab?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SidePeekCTA {
|
||||||
|
label: string
|
||||||
|
// onClick: () => void
|
||||||
|
onClick: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContentCardProps
|
||||||
|
extends VariantProps<typeof contentCardVariants> {
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
primaryCTA?: CTA
|
||||||
|
secondaryCTA?: CTA
|
||||||
|
sidePeekCTA?: SidePeekCTA
|
||||||
|
backgroundImage?: string
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user