feat(SW-453) added filter options

This commit is contained in:
Pontus Dreij
2024-10-24 08:35:34 +02:00
parent aea963740b
commit fc63a8e5ca
16 changed files with 138 additions and 120 deletions

View File

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

View File

@@ -3,3 +3,9 @@
flex-direction: row;
justify-content: space-between;
}
.roomsFilter {
display: flex;
flex-direction: row;
gap: var(--Spacing-x3);
}

View File

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

View File

@@ -1,7 +0,0 @@
import { RegisterOptions } from "react-hook-form"
export interface CheckboxProps
extends React.InputHTMLAttributes<HTMLInputElement> {
name: string
registerOptions?: RegisterOptions
}

View File

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

View File

@@ -16,7 +16,7 @@
.checkboxContainer {
display: flex;
align-items: flex-start;
align-items: center;
gap: var(--Spacing-x-one-and-half);
}