Skip to content

Commit

Permalink
Restyle lodge booking page to be more robust (#770)
Browse files Browse the repository at this point in the history
* try out new style

* simplify the information screen

* improve docs and add the handler to book the lodge button

* rename image src props

* constrain image max width

* improve docs
  • Loading branch information
choden-dev authored Aug 29, 2024
1 parent 2e12fda commit 34683a5
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 73 deletions.
2 changes: 1 addition & 1 deletion client/src/app/bookings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const BookingPage = async () => {
enableNetworkRequests
lodgeInfoProps={{
children: <RenderedContent />,
images: processedImages
imageSrcs: processedImages
}}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Story = StoryObj<typeof LodgeInfo>
export const Default: Story = {
args: {
handleBookLodgeClick: () => console.log(""),
images: [
imageSrcs: [
"https://via.placeholder.com/400x400?text=Image+1",
"https://via.placeholder.com/400x400?text=I+SUPPORT+LGBT",
"https://via.placeholder.com/400x400?text=Image+3",
Expand All @@ -21,6 +21,10 @@ export const Default: Story = {
children: (
<>
<div className="flex flex-col gap-4">
<h2>
Visit for the Whakapapa Ski field status, lift, food and retail
status and status of other activities.
</h2>
<p>
The UASC Lodge is located in the Whakapapa Ski field and is just a
3-5 min walk from the bottom of the Sky Waka Gondola, meaning you
Expand Down
41 changes: 30 additions & 11 deletions client/src/components/composite/LodgeInfo/LodgeInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Button from "@/components/generic/FigmaButtons/FigmaButton"
import LodgeInfoComponent from "./LodgeInfoComponent/LodgeInfoComponent"
import LodgeInfoGallery from "./LodgeInfoGallery/LodgeInfoGallery"
import { ReactNode } from "react"
Expand All @@ -10,25 +11,43 @@ export interface ILodgeInfo {
/**
* List of image srcs
*/
images?: string[]
imageSrcs?: string[]
/**
* Handler to be called once the user clicks the call to action
*/
handleBookLodgeClick?: () => void
}

const LodgeInfo = ({ children, images, handleBookLodgeClick }: ILodgeInfo) => {
/**
* Component displaying information about the lodge before the user makes a booking
*
* Use case - if someone new to the club wants to know what the lodge is, or are unsure about
* how to prepare/find more information
*/
const LodgeInfo = ({
children,
imageSrcs,
handleBookLodgeClick
}: ILodgeInfo) => {
return (
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div>
<LodgeInfoGallery images={images || []}></LodgeInfoGallery>
<div className="flex w-full flex-col gap-2">
<div className="flex justify-center pt-3">
<Button variant="default" onClick={handleBookLodgeClick}>
Skip Information
</Button>
</div>
<div>
<LodgeInfoComponent
handleBookLodgeClick={() => handleBookLodgeClick?.()}
>
{children}
</LodgeInfoComponent>
<div className="grid grid-cols-1 gap-4">
<div>
<LodgeInfoComponent
handleBookLodgeClick={() => handleBookLodgeClick?.()}
>
{children}
</LodgeInfoComponent>
</div>

<div>
<LodgeInfoGallery imageSrcs={imageSrcs || []}></LodgeInfoGallery>
</div>
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,35 @@ import Button from "@/components/generic/FigmaButtons/FigmaButton"
import { ReactNode } from "react"

interface ILodgeInfoComponent {
/**
* The **pre-rendered** children that should be displayed in the the container
* (This should generally be text content)
*/
children: ReactNode
/**
* Handler to be called when call to action button is clicked
*
* @example
* () => navigateToActualBookLodgeScreen()
*/
handleBookLodgeClick: () => void
}

/**
* @deprecated do not consume directly on page, use `LodgeInfo` instead
*/
const LodgeInfoComponent = ({
children,
handleBookLodgeClick
}: ILodgeInfoComponent) => {
return (
<div className="border-gray-3 flex h-full w-full flex-col justify-center rounded border bg-white px-6 py-12 pb-8">
<div className="text-dark-blue-100 flex flex-col gap-4 lg:justify-center">
<div className="border-gray-3 flex h-full w-full flex-col justify-center rounded border bg-white px-2 py-12 pb-8 sm:px-3">
<div className="text-dark-blue-100 mb-3 flex flex-col gap-4 lg:justify-center">
{children}

<div className="flex justify-center pt-3">
<Button variant="default-sm" onClick={handleBookLodgeClick}>
Book The Lodge
</Button>
</div>
</div>
<Button variant="inverted-default-sm" onClick={handleBookLodgeClick}>
Book the lodge
</Button>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Story = StoryObj<typeof LodgeInfoGallery>

export const Default: Story = {
args: {
images: [
imageSrcs: [
"https://via.placeholder.com/400x400?text=Image+1",
"https://via.placeholder.com/400x400?text=Image+2",
"https://via.placeholder.com/400x400?text=Image+3",
Expand All @@ -23,14 +23,14 @@ export const Default: Story = {

export const SingleImage: Story = {
args: {
images: ["https://via.placeholder.com/400x400?text=Single+Image"]
imageSrcs: ["https://via.placeholder.com/400x400?text=Single+Image"]
},
tags: ["autodocs"]
}

export const NoImages: Story = {
args: {
images: []
imageSrcs: []
},
tags: ["autodocs"]
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,40 @@
import { useState, FC } from "react"
import Image from "next/image"
import RightArrow from "@/assets/icons/whitearrowright.svg"
import LeftArrow from "@/assets/icons/whitearrowleft.svg"

interface LodgeInfoGalleryProps {
images: string[]
interface ILodgeInfoGallery {
/**
* A list of srcs for all the images in the gallery.
*
* This should be **pre-sorted** and **unique**
*
* @example
* ['https://image-url-1.com', 'https://image-url-2.com', 'https://image-url-3.com']
*/
imageSrcs: string[]
}

const LodgeInfoGallery: FC<LodgeInfoGalleryProps> = ({ images }) => {
const [currentIndex, setCurrentIndex] = useState(0)

const handlePreviousClick = () => {
setCurrentIndex((prevIndex) =>
prevIndex === 0 ? images.length - 1 : prevIndex - 1
)
}

const handleNextClick = () => {
setCurrentIndex((prevIndex) =>
prevIndex === images.length - 1 ? 0 : prevIndex + 1
)
}

/**
* Simple photo gallery that displays images in a single row (can be scrolled horizontally)
*/
const LodgeInfoGallery = ({ imageSrcs = [] }: ILodgeInfoGallery) => {
return (
<div className="relative flex items-center justify-center overflow-hidden">
{images.length > 0 ? (
<Image
src={images[currentIndex]}
alt={`Lodge image ${currentIndex + 1}`}
width={500}
height={500}
objectFit="contain"
className="rounded-lg"
/>
) : (
<p>No images available</p>
)}
<button
onClick={handlePreviousClick}
className="absolute left-4 top-1/2 z-10 -translate-y-1/2 transform opacity-70 hover:opacity-100"
aria-label="Previous image"
>
<LeftArrow />
</button>

<button
onClick={handleNextClick}
className="absolute right-4 top-1/2 z-10 -translate-y-1/2 transform opacity-70 hover:opacity-100"
aria-label="Next image"
>
<RightArrow />
</button>
</div>
<>
<div className="flex space-x-4 overflow-x-auto p-2">
{imageSrcs.map((url, index) => (
<>
{/* We require a `max-width` style to constrain the image on smaller screens */}
<div key={url} className="max-w-[95vw] flex-shrink-0">
<Image
src={url}
alt={`Photo ${index + 1}`}
width={400}
height={400}
className="rounded-sm shadow-lg"
/>
</div>
</>
))}
</div>
</>
)
}

Expand Down

0 comments on commit 34683a5

Please sign in to comment.