Skip to content

Commit

Permalink
Merge branch 'main' into feature/190-pickup-multiselect
Browse files Browse the repository at this point in the history
  • Loading branch information
neozhixuan authored Dec 21, 2023
2 parents 38a2555 + f3e2660 commit 6746655
Show file tree
Hide file tree
Showing 103 changed files with 354 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,64 @@ import { useSheetyData } from "hooks/useSheetyData";
import { AccordionDisplayProps } from ".";
import InstructionsCarousel from "./InstructionsCarousel";
import { InstructionsTag } from "./InstructionsTag";
import { useState } from "react";

const DisplayAccordion = ({ items, handleAccordionClick, recyclable }: AccordionDisplayProps) => {
const DisplayAccordion = ({ items, recyclable }: AccordionDisplayProps) => {
const { getItemCategory } = useSheetyData();
const lastIndex = items.length - 1;

// Use an array of state variables to track hover and expanded state for each accordion
const [accordionStates, setAccordionStates] = useState(
items.map(() => ({ isHovered: false, isExpanded: false })),
);
// Function to handle accordion hover
const handleAccordionHover = (index: number, isHovered: boolean, isExpanded: boolean) => {
setAccordionStates((prevState) =>
prevState.map((state, i) => ({
...state,
isHovered: i === index ? isHovered : state.isHovered,
isExpanded: i === index ? isExpanded : state.isExpanded,
})),
);
};

return (
<Accordion allowMultiple allowToggle mt={1}>
<Accordion allowMultiple mt={1}>
{items.map((item, index) => {
const category = getItemCategory(item.title);
const { isHovered, isExpanded } = accordionStates[index];
return (
<AccordionItem key={index} border={"0px"}>
<h2>
<AccordionButton
roundedTop={index === 0 ? "lg" : "none"}
roundedBottom={index === lastIndex ? "lg" : "none"}
border={"1px"}
borderTop={index !== 0 ? "0px" : "1px"}
roundedTop={index === 0 ? "md" : "none"}
roundedBottom={
!isExpanded ? (index === lastIndex ? "md" : "none") : "none"
}
// borderTop={index !== 0 ? "1px" : "0px"}
borderColor={"gray.400"}
_expanded={{ bg: "teal", color: "white" }}
onClick={() => handleAccordionClick(index)}
onClick={() => {
handleAccordionHover(index, true, !isExpanded);
}}
_hover={{ bg: "teal", color: "white" }}
onMouseEnter={() => handleAccordionHover(index, true, isExpanded)}
onMouseLeave={() => handleAccordionHover(index, false, isExpanded)}
style={{
boxShadow:
index === 0 && index !== lastIndex
? "0px -5px 6px -6px rgba(0, 0, 0, 0.25), -5px 0px 6px -6px rgba(0, 0, 0, 0.25), 5px 0px 6px -6px rgba(0, 0, 0, 0.25)"
: "1px 2px 6px 0px rgb(0,0,0, 0.25)",
}}
>
<VStack as="span" flex="1" alignItems="flex-start">
<HStack textAlign="left">
<Image
src={`/icons/${category}.png`}
src={
isHovered || isExpanded
? `/whiteicons/${category}.png`
: `/icons/${category}.png`
}
w={5}
alt={`Icon for ${category}`}
/>
Expand All @@ -47,25 +79,28 @@ const DisplayAccordion = ({ items, handleAccordionClick, recyclable }: Accordion
</AccordionButton>
</h2>
<AccordionPanel
border="1px"
borderColor={"gray.400"}
borderInline="1px"
borderColor={"teal"}
borderTop="0px"
roundedBottom={index === lastIndex ? "lg" : "none"}
borderBottom="1px"
roundedBottom="md"
bgColor={"#E0F0EF"}
px={4}
pt={4}
pb={0}
>
{recyclable ? (
item.contents && (
<Box p={4}>
<InstructionsCarousel items={item.contents} />
<Box>
{recyclable ? (
item.contents && <InstructionsCarousel items={item.contents} />
) : (
<Box pb={5}>
<Text as={"b"}>Why cannot recycle?</Text>
<Text mb={5}>{item.reason}</Text>
<Text as={"b"}>How to dispose properly?</Text>
<Text>{item.suggestion}</Text>
</Box>
)
) : (
<Box p={4}>
<Text as={"b"}>Why cannot recycle?</Text>
<Text mb={5}>{item.reason}</Text>
<Text as={"b"}>How to dispose properly?</Text>
<Text>{item.suggestion}</Text>
</Box>
)}
)}
</Box>
</AccordionPanel>
</AccordionItem>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Box, Button, Center, Flex, Text } from "@chakra-ui/react";
import { ChevronLeftIcon, ChevronRightIcon } from "@chakra-ui/icons";
import { useState } from "react";

import { Carousel } from "react-responsive-carousel";
import "react-responsive-carousel/lib/styles/carousel.min.css";
import styles from "components/pickup/carousel.module.css";
import { SLIDES_INTERVAL_TIME } from "components/pickup/PickupCarousel";
const InstructionsCarousel = ({ items }: { items: string[] }) => {
const [currentIndex, setCurrentIndex] = useState(0);

Expand All @@ -14,24 +17,40 @@ const InstructionsCarousel = ({ items }: { items: string[] }) => {
};

return (
<>
<Flex align="center">
<Box flexGrow={1}>
<Text as="b" fontSize="lg">
Step {items.indexOf(items[currentIndex]) + 1} of {items.length}
</Text>
<Text>{items[currentIndex]}</Text>
</Box>
</Flex>
<Center>
<Button onClick={handlePrevClick} m={2}>
<ChevronLeftIcon />
</Button>
<Button onClick={handleNextClick} m={2}>
<ChevronRightIcon />
</Button>
</Center>
</>
<Carousel
showThumbs={false}
showStatus={false}
showArrows={false}
autoPlay
infiniteLoop
interval={SLIDES_INTERVAL_TIME}
renderIndicator={(clickHandler, isSelected, index) => {
return (
<li
onClick={clickHandler}
key={index}
role="button"
className={isSelected ? `${styles.ind} ${styles.active}` : styles.ind}
/>
);
}}
>
{items.map((item, idx) => {
return (
<Flex align="center" pb={10} key={idx}>
<Box flexGrow={1} width={"100%"}>
<Text textAlign={"left"}>
<Text as="b" fontSize="lg">
Step {idx + 1} of {items.length}
</Text>
</Text>

<Text textAlign={"left"}>{item}</Text>
</Box>
</Flex>
);
})}
</Carousel>
);
};

Expand Down
19 changes: 2 additions & 17 deletions client/components/instructions/InstructionsAccordion/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import DisplayAccordion from "./DisplayAccordion";

export type AccordionDisplayProps = {
items: AccordionProps[];
handleAccordionClick: (index: number) => void;
recyclable: boolean;
};

Expand All @@ -22,12 +21,6 @@ export type AccordionsProps = {
};

export const AccordionComp: React.FC<AccordionsProps> = ({ items }) => {
const [activeIndex, setActiveIndex] = useState<number | null>(null);

const handleAccordionClick = (index: number) => {
setActiveIndex((prevIndex) => (prevIndex === index ? null : index));
};

const unrecyclableItems = [] as AccordionProps[];
const recyclableItems = items.filter((item) => {
if (item.method === Methods.THROW) {
Expand All @@ -46,11 +39,7 @@ export const AccordionComp: React.FC<AccordionsProps> = ({ items }) => {
</Text>

{/* Non-recyclable accordion */}
<DisplayAccordion
items={unrecyclableItems}
handleAccordionClick={handleAccordionClick}
recyclable={false}
/>
<DisplayAccordion items={unrecyclableItems} recyclable={false} />
</Box>
)}
{recyclableItems.length > 0 && (
Expand All @@ -60,11 +49,7 @@ export const AccordionComp: React.FC<AccordionsProps> = ({ items }) => {
</Text>

{/* Recyclable accordion */}
<DisplayAccordion
items={recyclableItems}
handleAccordionClick={handleAccordionClick}
recyclable={true}
/>
<DisplayAccordion items={recyclableItems} recyclable={true} />
</Box>
)}
</>
Expand Down
10 changes: 1 addition & 9 deletions client/components/instructions/InstructionsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,13 @@ export const InstructionsHeader = ({ setPage }: Props) => {
<Box my={5}>
<HStack px={2} justifyContent={"space-between"} gap={5}>
<Button
w={"50%"}
w={"20%"}
leftIcon={<ArrowBackIcon />}
onClick={() => setPage(Pages.HOME)}
colorScheme="teal"
>
Back
</Button>
<Button
w={"50%"}
leftIcon={<RepeatIcon />}
onClick={() => setPage(Pages.HOME)}
colorScheme="teal"
>
Restart
</Button>
</HStack>
</Box>
);
Expand Down
31 changes: 22 additions & 9 deletions client/components/map/FilterPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { TItemSelection, TEmptyItem } from "app-context/SheetyContext/types";
import { OptionType } from "spa-pages";
import React, { ChangeEvent, PropsWithChildren } from "react";
import { Methods } from "api/sheety/enums";
import { useSheetyData } from "hooks/useSheetyData";

type FilterProps = {
isOpen: boolean;
Expand Down Expand Up @@ -79,9 +80,10 @@ export const FilterPanel = ({
/>
</FilterSection>

<FilterSection title="Sort by">
{/* Implementation still in consideration... */}
{/* <FilterSection title="Sort by">
<ChipRadioGroup items={["Nearest", "Most items"]} />
</FilterSection>
</FilterSection> */}

<FilterSection title="Max Distance" hideDivider={true}>
<HStack justify="space-between">
Expand Down Expand Up @@ -176,7 +178,9 @@ const ChipCheckbox = (props: CheckboxProps) => {
return (
<chakra.label {...htmlProps}>
<input {...getInputProps()} hidden />
<Chip isChecked={state.isChecked}>{props.value}</Chip>
<Chip value={props.value as string} isChecked={state.isChecked}>
{props.value}
</Chip>
</chakra.label>
);
};
Expand Down Expand Up @@ -219,15 +223,18 @@ const ChipRadio = (props: PropsWithChildren<UseRadioProps>) => {
};

const Chip = ({
value,
children,
isChecked,
darkBackground,
}: React.PropsWithChildren<{ isChecked: boolean; darkBackground?: boolean }>) => {
}: React.PropsWithChildren<{ isChecked: boolean; darkBackground?: boolean; value?: string }>) => {
const selectedColor = darkBackground ? "teal.500" : "teal.50";
const selectedTextColor = darkBackground ? "white" : "black";

const { getItemCategory } = useSheetyData();
const category = getItemCategory(value as string);
return (
<Text
<Flex
align="center"
bg="white"
borderRadius="full"
paddingX="10px"
Expand All @@ -237,9 +244,15 @@ const Chip = ({
border="1px solid #D6EAEA"
cursor="pointer"
whiteSpace="nowrap"
fontSize="12px"
>
{children}
</Text>
{category && (
<img
src={`/icons/${category}.png`}
alt={`${category} icon`}
style={{ width: "15px", height: "15px", marginRight: "8px" }}
/>
)}
<Text fontSize="12px">{children}</Text>
</Flex>
);
};
17 changes: 12 additions & 5 deletions client/components/map/Marker/MarkerIconWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ const MarkerIconWrapper = ({
{label && <Text className="marker-text">{label}</Text>}

{category && (
<Image
className="marker-image"
src={`/icons/${category}.png`}
alt={`${category} icon`}
/>
<>
<Image
className="marker-circle"
src={"/blueicons/icon_circle.png"}
alt="Circle behind category icon"
/>
<Image
className="marker-image"
src={`/blueicons/${category}.png`}
alt={`${category} icon`}
/>
</>
)}
</Box>
);
Expand Down
Loading

0 comments on commit 6746655

Please sign in to comment.