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 CountrySelect from "@/components/TempDesignSystem/Form/Country"
|
||||||
import Input from "@/components/TempDesignSystem/Form/Input"
|
import Input from "@/components/TempDesignSystem/Form/Input"
|
||||||
import Phone from "@/components/TempDesignSystem/Form/Phone"
|
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 Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
||||||
|
|
||||||
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
import JoinScandicFriendsCard from "./JoinScandicFriendsCard"
|
||||||
import {
|
import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
|
||||||
ElevatorPreference,
|
|
||||||
FloorPreference,
|
|
||||||
guestDetailsSchema,
|
|
||||||
signedInDetailsSchema,
|
|
||||||
} from "./schema"
|
|
||||||
import Signup from "./Signup"
|
import Signup from "./Signup"
|
||||||
|
import SpecialRequests from "./SpecialRequests"
|
||||||
|
|
||||||
import styles from "./details.module.css"
|
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(
|
const onSubmit = useCallback(
|
||||||
(values: DetailsSchema) => {
|
(values: DetailsSchema) => {
|
||||||
updateDetails(values)
|
updateDetails(values)
|
||||||
@@ -130,57 +117,7 @@ export default function Details({ user, memberPrice }: DetailsProps) {
|
|||||||
<Signup name="join" />
|
<Signup name="join" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Footnote
|
<SpecialRequests />
|
||||||
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}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<footer className={styles.footer}>
|
<footer className={styles.footer}>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -20,8 +20,14 @@ export enum ElevatorPreference {
|
|||||||
|
|
||||||
const specialRequestsSchema = z
|
const specialRequestsSchema = z
|
||||||
.object({
|
.object({
|
||||||
floorPreference: z.nativeEnum(FloorPreference).optional(),
|
floorPreference: z
|
||||||
elevatorPreference: z.nativeEnum(ElevatorPreference).optional(),
|
.nativeEnum(FloorPreference)
|
||||||
|
.or(z.literal("").transform((_) => undefined))
|
||||||
|
.optional(),
|
||||||
|
elevatorPreference: z
|
||||||
|
.nativeEnum(ElevatorPreference)
|
||||||
|
.or(z.literal("").transform((_) => undefined))
|
||||||
|
.optional(),
|
||||||
comments: z.string().default(""),
|
comments: z.string().default(""),
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
|
|||||||
@@ -67,7 +67,11 @@ export default function SectionAccordion({
|
|||||||
const textColor =
|
const textColor =
|
||||||
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
isComplete || isOpen ? "uiTextHighContrast" : "baseTextDisabled"
|
||||||
return (
|
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.iconWrapper}>
|
||||||
<div className={styles.circle} data-checked={isComplete}>
|
<div className={styles.circle} data-checked={isComplete}>
|
||||||
{isComplete ? (
|
{isComplete ? (
|
||||||
|
|||||||
@@ -72,15 +72,15 @@
|
|||||||
background-color: var(--UI-Input-Controls-Fill-Selected);
|
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);
|
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);
|
background-color: var(--Base-Surface-Subtle-Hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion[data-open="true"] {
|
.accordion[data-section-open="true"] {
|
||||||
grid-template-rows: var(--header-height) 1fr;
|
grid-template-rows: var(--header-height) 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,11 +97,11 @@
|
|||||||
transition: opacity 0.2s linear;
|
transition: opacity 0.2s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion[data-open="true"] .content {
|
.accordion[data-section-open="true"] .content {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content:has([data-open="true"]) {
|
.content:has([data-section-open="true"]) {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user