diff --git a/client/components/map/FilterPanel.tsx b/client/components/map/FilterPanel.tsx index 3b7bf5d..5ea37dd 100644 --- a/client/components/map/FilterPanel.tsx +++ b/client/components/map/FilterPanel.tsx @@ -1,117 +1,244 @@ import { Box, - VStack, HStack, - Spacer, - Button, Text, Slider, SliderTrack, SliderFilledTrack, SliderThumb, + Modal, + ModalContent, + ModalOverlay, Divider, - CheckboxGroup, - Checkbox, - Stack, + Button, + Flex, + useCheckbox, + chakra, + CheckboxProps, + useCheckboxGroup, + Spacer, + useRadio, + UseRadioProps, + useRadioGroup, } from "@chakra-ui/react"; -import { XButton } from "./Buttons"; import { COLORS } from "theme"; import { TItemSelection, TEmptyItem } from "app-context/SheetyContext/types"; import { OptionType } from "spa-pages"; -import { ChangeEvent } from "react"; +import React, { ChangeEvent, PropsWithChildren } from "react"; +import { Methods } from "api/sheety/enums"; type FilterProps = { - isMobile: boolean | undefined; - setFilterShow: () => void; + isOpen: boolean; filterApply: () => void; handleSliderChange: (val: number) => void; range: number; itemState: (TItemSelection | TEmptyItem)[]; selectOptions: OptionType[]; handleCheckboxChange: (e: ChangeEvent) => void; + selectAllItems: () => void; }; export const FilterPanel = ({ - isMobile, - setFilterShow, + isOpen, filterApply, handleSliderChange, range, itemState, selectOptions, handleCheckboxChange, + selectAllItems, }: FilterProps) => { + const selectedOptionsWithCheckedState = selectOptions.map((option) => { + const isChecked = itemState.some( + (item) => item.name === option.value && item.method === option.method, + ); + return { ...option, isChecked }; + }); + return ( - - - - - - - - - - - Distance - - + undefined}> + + + + Apply + + } + > + + + + + + + + + 3km 10km handleSliderChange(val)} > - + - + - - - - - Items - - item.name)} - > - - {selectOptions.map((item) => ( - handleCheckboxChange(e)} - key={item.idx} - data-key={item.idx} - value={item.value} - name={item.method} - > - {item.value} - - ))} - - - - + + + + ); +}; + +function FilterSection({ + title, + hideDivider, + button, + children, +}: React.PropsWithChildren<{ title: string; hideDivider?: boolean; button?: JSX.Element }>) { + return ( + + + {title} + {button} + + {children} + {hideDivider ? ( + + ) : ( + + )} + + ); +} + +const CheckboxGroup = ({ + items, + onChange, + onSelectAll, +}: { + items: Array<{ + value: string; + method?: Methods; + isChecked: boolean; + }>; + onChange: (item: any) => void; + onSelectAll: () => void; +}) => { + const { getCheckboxProps } = useCheckboxGroup({ + value: items.filter((item) => item.isChecked).map((item) => item.value), + }); + + return ( + + {items.map((item) => ( + + ))} + + Select All + + + ); +}; + +const ChipCheckbox = (props: CheckboxProps) => { + const { state, getInputProps, htmlProps } = useCheckbox(props); + + return ( + + + {props.value} + + ); +}; + +const ChipRadioGroup = ({ items }: { items: Array }) => { + const { getRootProps, getRadioProps } = useRadioGroup({ + name: "sortBy", + defaultValue: "Nearest", + }); + + const group = getRootProps(); + + return ( + + {items.map((value) => { + const radio = getRadioProps({ value }); + return ( + + {value} + + ); + })} + + ); +}; + +const ChipRadio = (props: PropsWithChildren) => { + const { getInputProps, getRadioProps, state } = useRadio(props); + + const input = getInputProps(); + + return ( + + + + {props.children} + ); }; + +const Chip = ({ + children, + isChecked, + darkBackground, +}: React.PropsWithChildren<{ isChecked: boolean; darkBackground?: boolean }>) => { + const selectedColor = darkBackground ? "teal.500" : "teal.50"; + const selectedTextColor = darkBackground ? "white" : "black"; + + return ( + + {children} + + ); +}; diff --git a/client/spa-pages/components/MapPage.tsx b/client/spa-pages/components/MapPage.tsx index ea621bf..37d0cca 100644 --- a/client/spa-pages/components/MapPage.tsx +++ b/client/spa-pages/components/MapPage.tsx @@ -1,6 +1,6 @@ // General Imports import { BasePage } from "layouts/BasePage"; -import { Flex, VStack, Box, IconButton } from "@chakra-ui/react"; +import { Flex, VStack, Box, IconButton, useDisclosure } from "@chakra-ui/react"; import { Dispatch, SetStateAction, useState } from "react"; import { Pages } from "spa-pages/pageEnums"; import { useUserInputs } from "hooks/useUserSelection"; @@ -78,7 +78,7 @@ const MapInner = ({ setPage }: Props) => { ////// States ////// // Filters - const [filterShow, setFilterShow] = useState(false); + const { isOpen: isFilterOpen, onOpen: onFilterOpen, onClose: onFilterClose } = useDisclosure(); const [range, setRange] = useState(60); // const [isExpanded, setIsExpanded] = useState(false); @@ -279,6 +279,23 @@ const MapInner = ({ setPage }: Props) => { setItemState(updatedItemState); }; + const selectAllItems = () => { + const selectOptions: OptionType[] = items.map((item) => ({ + value: item.name, + label: item.name, + method: item.method, + idx: index++, + })); + const itemState = items.map((item) => ({ + name: item.name, + method: item.method, + })); + + handleChangedLocation(itemState); + setItemState(itemState); + setSelectedOptions(selectOptions); + }; + // Handle the changes in distance selected in Filter panel const handleSliderChange = (val: number) => { const dist = val / 10; @@ -353,7 +370,7 @@ const MapInner = ({ setPage }: Props) => { { getMatchingFacility={getMatchingFacility} /> )} */} - {filterShow && ( - setFilterShow(true)} - filterApply={() => setFilterShow(false)} - handleSliderChange={handleSliderChange} - range={range} - itemState={itemState} - selectOptions={selectOptions} - handleCheckboxChange={handleCheckboxChange} - /> - )} + onFilterClose()} + handleSliderChange={handleSliderChange} + range={range} + itemState={itemState} + selectOptions={selectOptions} + selectAllItems={selectAllItems} + handleCheckboxChange={handleCheckboxChange} + /> ); }; @@ -423,15 +438,14 @@ export const MapPage = ({ setPage }: Props) => ( export const MapHeaderButtons = ({ setPage, - setFilterShow, selectedOptions, selectOptions, handleMultiselectOnChange, itemState, handleChangedLocation, + onFilterOpen, }: { setPage: Dispatch>; - setFilterShow: Dispatch>; selectedOptions: OptionType[]; selectOptions: OptionType[]; handleMultiselectOnChange: ( @@ -440,6 +454,7 @@ export const MapHeaderButtons = ({ ) => void; itemState: (TItemSelection | TEmptyItem)[]; handleChangedLocation: (itemEntry: (TItemSelection | TEmptyItem)[]) => void; + onFilterOpen: () => void; }) => { return ( - setFilterShow(true)} height="44px" /> + );