feat: SW-276 SW-565 Updated UI

This commit is contained in:
Hrishikesh Vaipurkar
2024-10-09 12:21:13 +02:00
parent 9dbd10afdd
commit ad42440817
10 changed files with 268 additions and 91 deletions

View File

@@ -1,9 +1,15 @@
.container {
display: grid;
grid-template-columns: repeat(4, auto);
display: flex;
justify-content: space-between;
align-items: center;
}
.textCenter {
text-align: center;
.counterContainer {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 20px;
}
.counterBtn {
width: 40px;
height: 40px;
}

View File

@@ -5,7 +5,9 @@ import { useIntl } from "react-intl"
import { guestsRoomsStore } from "@/stores/guests-rooms"
import { MinusIcon, PlusIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import styles from "./adult-selector.module.css"
@@ -50,26 +52,42 @@ export default function AdultSelector({ roomIndex = 0 }: AdultSelectorProps) {
return (
<section className={styles.container}>
<Caption>{adultsLabel}</Caption>
<Button
onClick={() => {
decreaseAdultsCount(roomIndex)
}}
intent="text"
size="small"
>
-
</Button>
<span className={styles.textCenter}>{adults}</span>
<Button
onClick={() => {
increaseAdultsCount(roomIndex)
}}
intent="text"
size="small"
>
+
</Button>
<Caption color="uiTextHighContrast" textTransform="bold">
{adultsLabel}
</Caption>
<div className={styles.counterContainer}>
<Button
className={styles.counterBtn}
intent="elevated"
onClick={() => {
decreaseAdultsCount(roomIndex)
}}
size="small"
theme="base"
variant="icon"
wrapping={true}
disabled={adults == 1}
>
<MinusIcon color="burgundy" />
</Button>
<Body color="textHighContrast" textAlign="center">
{adults}
</Body>
<Button
className={styles.counterBtn}
onClick={() => {
increaseAdultsCount(roomIndex)
}}
intent="elevated"
variant="icon"
theme="base"
wrapping={true}
size="small"
disabled={adults == 6}
>
<PlusIcon color="burgundy" />
</Button>
</div>
</section>
)
}

View File

@@ -1,9 +1,15 @@
"use client"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
import { guestsRoomsStore } from "@/stores/guests-rooms"
import { ErrorCircleIcon } from "@/components/Icons"
import Select from "@/components/TempDesignSystem/Select"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import styles from "./child-selector.module.css"
import { BedTypeEnum } from "@/types/components/bookingWidget/enums"
import {
@@ -96,36 +102,43 @@ export default function ChildInfoSelector({
return (
<>
<div>
<Select
required={true}
items={ageList}
label={ageLabel}
aria-label={ageLabel}
value={child.age}
onSelect={(key) => {
updateSelectedAge(parseInt(key.toString()))
}}
name={`rooms.${roomIndex}.children.${index}.age`}
placeholder={ageLabel}
/>
{isValidated && child.age < 0 ? <span>{ageReqdErrMsg}</span> : null}
</div>
<div>
{child.age !== -1 ? (
<div key={index} className={styles.childInfoContainer}>
<div>
<Select
items={getAvailableBeds(child.age)}
label={bedLabel}
aria-label={bedLabel}
value={child.bed}
required={true}
items={ageList}
label={ageLabel}
aria-label={ageLabel}
value={child.age}
onSelect={(key) => {
updateSelectedBed(parseInt(key.toString()))
updateSelectedAge(parseInt(key.toString()))
}}
name={`rooms.${roomIndex}.children.${index}.age`}
placeholder={bedLabel}
placeholder={ageLabel}
/>
) : null}
</div>
<div>
{child.age !== -1 ? (
<Select
items={getAvailableBeds(child.age)}
label={bedLabel}
aria-label={bedLabel}
value={child.bed}
onSelect={(key) => {
updateSelectedBed(parseInt(key.toString()))
}}
name={`rooms.${roomIndex}.children.${index}.age`}
placeholder={bedLabel}
/>
) : null}
</div>
</div>
{isValidated && child.age < 0 ? (
<Caption color="red" className={styles.error}>
<ErrorCircleIcon color="red" />
{intl.formatMessage({ id: "Child age is required" })}
</Caption>
) : null}
</>
)
}

View File

@@ -1,8 +1,21 @@
.container {
display: grid;
grid-template-columns: repeat(4, auto);
display: flex;
justify-content: space-between;
align-items: center;
}
.captionBold {
font-weight: 600;
}
.counterContainer {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 20px;
}
.counterBtn {
width: 40px;
height: 40px;
}
.childInfoContainer {
display: grid;
@@ -10,6 +23,8 @@
grid-template-columns: 1fr 2fr;
}
.textCenter {
text-align: center;
.error {
display: flex;
align-items: center;
gap: var(--Spacing-x1);
}

View File

@@ -1,9 +1,13 @@
"use client"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
import { guestsRoomsStore } from "@/stores/guests-rooms"
import { MinusIcon, PlusIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import ChildInfoSelector from "./ChildInfoSelector"
@@ -40,31 +44,50 @@ export default function ChildSelector({ roomIndex = 0 }: ChildSelectorProps) {
return (
<>
<section className={styles.container}>
<Caption>{childrenLabel}</Caption>
<Button
intent="text"
size="small"
onClick={() => decreaseChildrenCount(roomIndex)}
>
-
</Button>
<span className={styles.textCenter}>{children.length}</span>
<Button
intent="text"
size="small"
onClick={() => increaseChildrenCount(roomIndex)}
>
+
</Button>
<Caption color="uiTextHighContrast" textTransform="bold">
{childrenLabel}
</Caption>
<div className={styles.counterContainer}>
<Button
className={styles.counterBtn}
intent="elevated"
onClick={() => {
decreaseChildrenCount(roomIndex)
}}
size="small"
theme="base"
variant="icon"
wrapping={true}
disabled={children.length == 0}
>
<MinusIcon color="burgundy" />
</Button>
<Body color="textHighContrast" textAlign="center">
{children.length}
</Body>
<Button
className={styles.counterBtn}
onClick={() => {
increaseChildrenCount(roomIndex)
}}
intent="elevated"
variant="icon"
theme="base"
wrapping={true}
size="small"
disabled={children.length == 5}
>
<PlusIcon color="burgundy" />
</Button>
</div>
</section>
{children.map((child, index) => (
<div key={index} className={styles.childInfoContainer}>
<ChildInfoSelector
roomIndex={roomIndex}
index={index}
child={child}
/>
</div>
<ChildInfoSelector
roomIndex={roomIndex}
index={index}
child={child}
key={index}
/>
))}
</>
)

View File

@@ -4,6 +4,7 @@ import { useIntl } from "react-intl"
import { guestsRoomsStore } from "@/stores/guests-rooms"
import { guestRoomsSchema } from "../Forms/BookingWidget/schema"
import { CloseLarge } from "../Icons"
import Button from "../TempDesignSystem/Button"
import Divider from "../TempDesignSystem/Divider"
import Subtitle from "../TempDesignSystem/Text/Subtitle"
@@ -30,10 +31,15 @@ export default function GuestsRoomsPicker({
return (
<>
<header className={styles.header}>
<button type="button" className={styles.close} onClick={closePicker}>
<CloseLarge />
</button>
</header>
{guestsData.map((room, index) => (
<section className={styles.roomContainer} key={index}>
<section className={styles.roomDetailsContainer}>
<Subtitle>
<Subtitle type="two" className={styles.roomHeading}>
{roomLabel} {index + 1}
</Subtitle>
<AdultSelector roomIndex={index} />
@@ -45,7 +51,7 @@ export default function GuestsRoomsPicker({
Remove Room
</Button>
) : null} */}
<Divider />
<Divider color="primaryLightSubtle" />
</section>
))}
<footer className={styles.footer}>
@@ -55,7 +61,24 @@ export default function GuestsRoomsPicker({
Add Room
</Button>
) : null} */}
<Button onClick={closePicker} disabled={isInValid}>
<Button
onClick={closePicker}
disabled={isInValid}
className={styles.hideOnMobile}
intent="tertiary"
theme="base"
size="small"
>
{doneLabel}
</Button>
<Button
onClick={closePicker}
disabled={isInValid}
className={styles.hideOnDesktop}
intent="tertiary"
theme="base"
size="large"
>
{doneLabel}
</Button>
</footer>

View File

@@ -1,14 +1,13 @@
.container {
overflow: hidden;
position: relative;
z-index: 10;
&[data-isopen="true"] {
overflow: visible;
}
}
.roomContainer {
display: grid;
gap: var(--Spacing-x1);
gap: var(--Spacing-x2);
}
.roomDetailsContainer {
display: grid;
@@ -17,14 +16,9 @@
}
.hideWrapper {
background-color: var(--Main-Grey-White);
border-radius: var(--Corner-radius-Medium);
box-shadow: 0px 16px 24px 0px rgba(0, 0, 0, 0.08);
padding: var(--Spacing-x-one-and-half);
position: absolute;
/** BookingWidget padding + border-width */
top: calc(100% + var(--Spacing-x2) + 1px);
width: 360px;
max-width: 100vw; /* for small screens having view port width of 320px */
}
.roomHeading {
margin-bottom: var(--Spacing-x1);
}
.btn {
background: none;
@@ -41,5 +35,83 @@
display: grid;
gap: var(--Spacing-x1);
grid-template-columns: auto;
margin-top: 10px;
margin-top: var(--Spacing-x2);
}
@media screen and (max-width: 1366px) {
.hideWrapper {
bottom: 0;
left: 0;
overflow: auto;
position: fixed;
right: 0;
top: 100%;
transition: top 300ms ease;
z-index: 10002;
}
.container[data-isopen="true"] .hideWrapper {
top: 0;
}
.header {
background-color: var(--Main-Grey-White);
display: grid;
padding: var(--Spacing-x3) var(--Spacing-x2);
}
.close {
background: none;
border: none;
cursor: pointer;
display: flex;
justify-self: flex-end;
padding: 0;
}
.roomContainer {
padding: 0 var(--Spacing-x2);
}
.footer {
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0) 7.5%,
#ffffff 82.5%
);
padding: var(--Spacing-x1) var(--Spacing-x2) var(--Spacing-x7);
position: absolute;
bottom: 0;
width: 100%;
z-index: 10;
}
.footer button {
width: 100%;
}
.footer .hideOnMobile {
display: none;
}
}
@media screen and (min-width: 1367px) {
.hideWrapper {
border-radius: var(--Corner-radius-Large);
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
left: calc((var(--Spacing-x1) + var(--Spacing-x2)) * -1);
max-width: calc(100vw - 20px);
padding: var(--Spacing-x2) var(--Spacing-x3);
position: absolute;
top: calc(100% + var(--Spacing-x2) + 1px + var(--Spacing-x4));
width: 360px;
}
.header {
display: none;
}
.footer .hideOnDesktop {
display: none;
}
}

View File

@@ -56,6 +56,12 @@ a.text {
outline: none;
}
.elevated,
a.elevated {
border: none;
box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.1);
}
/* VARIANTS */
.default,
a.default {

View File

@@ -10,6 +10,7 @@ export const buttonVariants = cva(styles.btn, {
secondary: styles.secondary,
tertiary: styles.tertiary,
text: styles.text,
elevated: styles.elevated,
},
size: {
small: styles.small,

View File

@@ -10,7 +10,7 @@ p.caption {
.bold {
font-family: var(--typography-Caption-Bold-fontFamily);
font-size: var(--typography-Caption-Bold-fontSize);
font-weight: var(--typography-Caption-Bold-fontWeight);
font-weight: 500; /* var(--typography-Caption-Bold-fontWeight); /* Commented till figma values are fixed to 500 instead of medium */
letter-spacing: var(--typography-Caption-Bold-letterSpacing);
line-height: var(--typography-Caption-Bold-lineHeight);
text-decoration: var(--typography-Caption-Bold-textDecoration);