fix: make special requests block togglable

This commit is contained in:
Christel Westerberg
2024-12-12 11:42:06 +01:00
parent 4872847ecb
commit a1a36e80d5
6 changed files with 166 additions and 74 deletions

View File

@@ -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>
)
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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 ? (

View File

@@ -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;
}