fix: make special requests block togglable
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { useState } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { ChevronDownIcon } from "@/components/Icons"
|
||||
import Divider from "@/components/TempDesignSystem/Divider"
|
||||
import Select from "@/components/TempDesignSystem/Form/Select"
|
||||
import TextArea from "@/components/TempDesignSystem/Form/TextArea"
|
||||
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||
|
||||
import { ElevatorPreference, FloorPreference } from "./../schema"
|
||||
|
||||
import styles from "./specialRequests.module.css"
|
||||
|
||||
export default function SpecialRequests() {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const intl = useIntl()
|
||||
|
||||
const noPreferenceItem = {
|
||||
value: "",
|
||||
label: intl.formatMessage({
|
||||
id: "No preference",
|
||||
}),
|
||||
}
|
||||
|
||||
function toggleRequests() {
|
||||
setIsOpen((prevVal) => !prevVal)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.requests} data-requests-open={isOpen}>
|
||||
<button className={styles.toggle} onClick={toggleRequests} type="button">
|
||||
<Footnote
|
||||
color="uiTextHighContrast"
|
||||
textTransform="uppercase"
|
||||
type="label"
|
||||
className={styles.header}
|
||||
textAlign="left"
|
||||
>
|
||||
{intl.formatMessage({ id: "Special requests" })}
|
||||
</Footnote>
|
||||
<ChevronDownIcon className={styles.chevron} />
|
||||
<Divider className={styles.divider} color="subtle" />
|
||||
</button>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.contentWrapper}>
|
||||
<Select
|
||||
label={intl.formatMessage({ id: "Floor preference" })}
|
||||
name="specialRequests.floorPreference"
|
||||
items={[
|
||||
noPreferenceItem,
|
||||
{
|
||||
value: FloorPreference.HIGH,
|
||||
label: intl.formatMessage({ id: "High level" }),
|
||||
},
|
||||
{
|
||||
value: FloorPreference.LOW,
|
||||
label: intl.formatMessage({ id: "Low level" }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
label={intl.formatMessage({ id: "Elevator preference" })}
|
||||
name="specialRequests.elevatorPreference"
|
||||
items={[
|
||||
noPreferenceItem,
|
||||
{
|
||||
value: ElevatorPreference.AWAY_FROM_ELEVATOR,
|
||||
label: intl.formatMessage({
|
||||
id: "Away from elevator",
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: ElevatorPreference.NEAR_ELEVATOR,
|
||||
label: intl.formatMessage({
|
||||
id: "Near elevator",
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<TextArea
|
||||
label={intl.formatMessage({
|
||||
id: "Is there anything else you would like us to know before your arrival?",
|
||||
})}
|
||||
name="specialRequests.comments"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
.requests {
|
||||
--header-height: 50px;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: var(--header-height) 0fr;
|
||||
transition: 0.3s ease-out;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"header chevron"
|
||||
"divider divider";
|
||||
grid-template-columns: 1fr auto;
|
||||
background-color: transparent;
|
||||
gap: var(--Spacing-x1);
|
||||
border: none;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
margin: var(--Spacing-x2) 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: header;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.chevron {
|
||||
grid-area: chevron;
|
||||
}
|
||||
|
||||
.divider {
|
||||
grid-area: divider;
|
||||
border-top: 1px solid var(--Color-gray-300);
|
||||
}
|
||||
|
||||
.requests[data-requests-open="true"] .chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.contentWrapper {
|
||||
padding-top: var(--Spacing-x3);
|
||||
display: grid;
|
||||
gap: var(--Spacing-x2);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.requests[data-requests-open="true"] {
|
||||
grid-template-rows: var(--header-height) 1fr;
|
||||
}
|
||||
@@ -10,18 +10,12 @@ import Button from "@/components/TempDesignSystem/Button"
|
||||
import CountrySelect from "@/components/TempDesignSystem/Form/Country"
|
||||
import Input from "@/components/TempDesignSystem/Form/Input"
|
||||
import Phone from "@/components/TempDesignSystem/Form/Phone"
|
||||
import Select from "@/components/TempDesignSystem/Form/Select"
|
||||
import TextArea from "@/components/TempDesignSystem/Form/TextArea"
|
||||
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||
|
||||
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
||||
import {
|
||||
ElevatorPreference,
|
||||
FloorPreference,
|
||||
guestDetailsSchema,
|
||||
signedInDetailsSchema,
|
||||
} from "./schema"
|
||||
import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
|
||||
import Signup from "./Signup"
|
||||
import SpecialRequests from "./SpecialRequests"
|
||||
|
||||
import styles from "./details.module.css"
|
||||
|
||||
@@ -57,13 +51,6 @@ export default function Details({ user, memberPrice }: DetailsProps) {
|
||||
},
|
||||
})
|
||||
|
||||
const noPreferenceItem = {
|
||||
value: "",
|
||||
label: intl.formatMessage({
|
||||
id: "No preference",
|
||||
}),
|
||||
}
|
||||
|
||||
const onSubmit = useCallback(
|
||||
(values: DetailsSchema) => {
|
||||
updateDetails(values)
|
||||
@@ -130,57 +117,7 @@ export default function Details({ user, memberPrice }: DetailsProps) {
|
||||
<Signup name="join" />
|
||||
</div>
|
||||
)}
|
||||
<Footnote
|
||||
color="uiTextHighContrast"
|
||||
textTransform="uppercase"
|
||||
type="label"
|
||||
className={styles.fullWidth}
|
||||
>
|
||||
{intl.formatMessage({ id: "Special requests" })}
|
||||
</Footnote>
|
||||
<Select
|
||||
className={styles.fullWidth}
|
||||
label={intl.formatMessage({ id: "Floor preference" })}
|
||||
name="specialRequests.floorPreference"
|
||||
items={[
|
||||
noPreferenceItem,
|
||||
{
|
||||
value: FloorPreference.HIGH,
|
||||
label: intl.formatMessage({ id: FloorPreference.HIGH }),
|
||||
},
|
||||
{
|
||||
value: FloorPreference.LOW,
|
||||
label: intl.formatMessage({ id: FloorPreference.LOW }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Select
|
||||
className={styles.fullWidth}
|
||||
label={intl.formatMessage({ id: "Elevator preference" })}
|
||||
name="specialRequests.elevatorPreference"
|
||||
items={[
|
||||
noPreferenceItem,
|
||||
{
|
||||
value: ElevatorPreference.AWAY_FROM_ELEVATOR,
|
||||
label: intl.formatMessage({
|
||||
id: ElevatorPreference.AWAY_FROM_ELEVATOR,
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: ElevatorPreference.NEAR_ELEVATOR,
|
||||
label: intl.formatMessage({
|
||||
id: ElevatorPreference.NEAR_ELEVATOR,
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<TextArea
|
||||
label={intl.formatMessage({
|
||||
id: "Is there anything else you would like us to know before your arrival?",
|
||||
})}
|
||||
name="specialRequests.comments"
|
||||
className={styles.fullWidth}
|
||||
/>
|
||||
<SpecialRequests />
|
||||
</div>
|
||||
<footer className={styles.footer}>
|
||||
<Button
|
||||
|
||||
@@ -20,8 +20,14 @@ export enum ElevatorPreference {
|
||||
|
||||
const specialRequestsSchema = z
|
||||
.object({
|
||||
floorPreference: z.nativeEnum(FloorPreference).optional(),
|
||||
elevatorPreference: z.nativeEnum(ElevatorPreference).optional(),
|
||||
floorPreference: z
|
||||
.nativeEnum(FloorPreference)
|
||||
.or(z.literal("").transform((_) => undefined))
|
||||
.optional(),
|
||||
elevatorPreference: z
|
||||
.nativeEnum(ElevatorPreference)
|
||||
.or(z.literal("").transform((_) => undefined))
|
||||
.optional(),
|
||||
comments: z.string().default(""),
|
||||
})
|
||||
.optional()
|
||||
|
||||
@@ -67,7 +67,11 @@ export default function SectionAccordion({
|
||||
const textColor =
|
||||
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
||||
return (
|
||||
<div className={styles.accordion} data-open={isOpen} data-step={step}>
|
||||
<div
|
||||
className={styles.accordion}
|
||||
data-section-open={isOpen}
|
||||
data-step={step}
|
||||
>
|
||||
<div className={styles.iconWrapper}>
|
||||
<div className={styles.circle} data-checked={isComplete}>
|
||||
{isComplete ? (
|
||||
|
||||
@@ -72,15 +72,15 @@
|
||||
background-color: var(--UI-Input-Controls-Fill-Selected);
|
||||
}
|
||||
|
||||
.accordion[data-open="true"] .circle[data-checked="false"] {
|
||||
.accordion[data-section-open="true"] .circle[data-checked="false"] {
|
||||
background-color: var(--UI-Text-Placeholder);
|
||||
}
|
||||
|
||||
.accordion[data-open="false"] .circle[data-checked="false"] {
|
||||
.accordion[data-section-open="false"] .circle[data-checked="false"] {
|
||||
background-color: var(--Base-Surface-Subtle-Hover);
|
||||
}
|
||||
|
||||
.accordion[data-open="true"] {
|
||||
.accordion[data-section-open="true"] {
|
||||
grid-template-rows: var(--header-height) 1fr;
|
||||
}
|
||||
|
||||
@@ -97,11 +97,11 @@
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
|
||||
.accordion[data-open="true"] .content {
|
||||
.accordion[data-section-open="true"] .content {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.content:has([data-open="true"]) {
|
||||
.content:has([data-section-open="true"]) {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user