feat(SW-453) added filter options
This commit is contained in:
@@ -1,32 +1,93 @@
|
||||
"use client"
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useRef } from "react"
|
||||
import { FormProvider, useForm } from "react-hook-form"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Checkbox from "@/components/TempDesignSystem/Checkbox"
|
||||
import { roomFilterSchema } from "@/server/routers/hotels/schemas/room"
|
||||
|
||||
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
|
||||
import styles from "./roomFilter.module.css"
|
||||
|
||||
import { RoomFilterProps } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
import {
|
||||
RoomFilterFormData,
|
||||
RoomFilterProps,
|
||||
} from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
|
||||
function RoomFilter({ numberOfRooms }: RoomFilterProps) {
|
||||
const intl = useIntl()
|
||||
const methods = useForm<RoomFilterFormData>({
|
||||
defaultValues: {
|
||||
allergyFriendly: false,
|
||||
petFriendly: false,
|
||||
accessibility: false,
|
||||
},
|
||||
mode: "all",
|
||||
reValidateMode: "onChange",
|
||||
resolver: zodResolver(roomFilterSchema),
|
||||
})
|
||||
|
||||
const formRef = useRef<HTMLFormElement | null>(null)
|
||||
const { watch, setValue } = methods
|
||||
const petFriendly = watch("petFriendly")
|
||||
const allergyFriendly = watch("allergyFriendly")
|
||||
|
||||
const onSubmit = (data: RoomFilterFormData) => {
|
||||
if (data.petFriendly) {
|
||||
setValue("allergyFriendly", false)
|
||||
} else if (data.allergyFriendly) {
|
||||
setValue("petFriendly", false)
|
||||
}
|
||||
console.log("Form submitted with data:", data)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Body color="uiTextHighContrast">
|
||||
{numberOfRooms}{" "}
|
||||
{intl.formatMessage(
|
||||
{ id: "Room types available" },
|
||||
{ numberOfRooms: numberOfRooms }
|
||||
)}
|
||||
{intl.formatMessage({ id: "Room types available" }, { numberOfRooms })}
|
||||
</Body>
|
||||
<div className={styles.roomsFilter}>
|
||||
<div>
|
||||
<Checkbox name="accessibilty" />
|
||||
<Caption color="uiTextHighContrast">Accessibility room</Caption>
|
||||
</div>
|
||||
</div>
|
||||
<FormProvider {...methods}>
|
||||
<form ref={formRef} onSubmit={methods.handleSubmit(onSubmit)}>
|
||||
<div className={styles.roomsFilter}>
|
||||
<Checkbox
|
||||
name="accessibility"
|
||||
onChange={() => formRef.current?.requestSubmit()}
|
||||
>
|
||||
<Caption color="uiTextHighContrast">
|
||||
{intl.formatMessage({ id: "Accessibility room" })}
|
||||
</Caption>
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
name="petFriendly"
|
||||
onChange={() => {
|
||||
setValue("petFriendly", !petFriendly)
|
||||
formRef.current?.requestSubmit()
|
||||
}}
|
||||
registerOptions={{ disabled: allergyFriendly }}
|
||||
>
|
||||
<Caption color="uiTextHighContrast">
|
||||
{intl.formatMessage({ id: "Pet room" })}
|
||||
</Caption>
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
name="allergyFriendly"
|
||||
onChange={() => {
|
||||
setValue("allergyFriendly", !allergyFriendly)
|
||||
formRef.current?.requestSubmit()
|
||||
}}
|
||||
registerOptions={{ disabled: petFriendly }}
|
||||
>
|
||||
<Caption color="uiTextHighContrast">
|
||||
{intl.formatMessage({ id: "Allergy room" })}
|
||||
</Caption>
|
||||
</Checkbox>
|
||||
</div>
|
||||
</form>
|
||||
</FormProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,3 +3,9 @@
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.roomsFilter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.container[data-selected] .checkbox {
|
||||
border: none;
|
||||
background: var(--UI-Input-Controls-Fill-Selected);
|
||||
}
|
||||
|
||||
.checkboxContainer {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
min-width: 24px;
|
||||
background-color: var(--UI-Input-Controls-Surface-Normal);
|
||||
border: 2px solid var(--UI-Input-Controls-Border-Normal);
|
||||
border-radius: var(--Corner-radius-Small);
|
||||
transition: all 200ms;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 200ms;
|
||||
forced-color-adjust: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.error {
|
||||
align-items: center;
|
||||
color: var(--Scandic-Red-60);
|
||||
display: flex;
|
||||
gap: var(--Spacing-x-half);
|
||||
margin-top: var(--Spacing-x1);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export interface CheckboxProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
name: string
|
||||
registerOptions?: RegisterOptions
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import { Checkbox as AriaCheckbox } from "react-aria-components"
|
||||
import { useController, useFormContext } from "react-hook-form"
|
||||
|
||||
import { InfoCircleIcon } from "@/components/Icons"
|
||||
import CheckIcon from "@/components/Icons/Check"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
|
||||
import { CheckboxProps } from "./checkbox"
|
||||
|
||||
import styles from "./checkbox.module.css"
|
||||
|
||||
export default function Checkbox({
|
||||
name,
|
||||
children,
|
||||
registerOptions,
|
||||
}: React.PropsWithChildren<CheckboxProps>) {
|
||||
const { control } = useFormContext()
|
||||
const { field, fieldState } = useController({
|
||||
control,
|
||||
name,
|
||||
rules: registerOptions,
|
||||
})
|
||||
|
||||
return (
|
||||
<AriaCheckbox
|
||||
className={styles.container}
|
||||
isSelected={field.value}
|
||||
onChange={field.onChange}
|
||||
data-testid={name}
|
||||
>
|
||||
{({ isSelected }) => (
|
||||
<>
|
||||
<div className={styles.checkboxContainer}>
|
||||
<div className={styles.checkbox}>
|
||||
{isSelected && <CheckIcon color="white" />}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
{children && fieldState.error ? (
|
||||
<Caption className={styles.error}>
|
||||
<InfoCircleIcon color="red" />
|
||||
{fieldState.error.message}
|
||||
</Caption>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</AriaCheckbox>
|
||||
)
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
.checkboxContainer {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user