diff --git a/compass/components/FilterBox/ContainsDropdown.tsx b/compass/components/FilterBox/ContainsDropdown.tsx new file mode 100644 index 0000000..00889e2 --- /dev/null +++ b/compass/components/FilterBox/ContainsDropdown.tsx @@ -0,0 +1,53 @@ +import { useState } from "react"; +import { ChevronDownIcon } from "@heroicons/react/24/solid"; + +const mockTags = ["food relief", "period poverty", "nutrition education"]; + +type FilterType = "contains" | "does not contain" | "is empty" | "is not empty"; + +export const ContainsDropdown = ({ + isDropdownOpen, + setIsDropdownOpen, + filterType, + setFilterType, +}) => { + const handleFilterTypeChange = (type: FilterType) => { + setFilterType(type); + setIsDropdownOpen(false); + }; + + return ( +
+
+
handleFilterTypeChange("contains")} + > + Contains +
+
handleFilterTypeChange("does not contain")} + > + Does not contain +
+
handleFilterTypeChange("is empty")} + > + Is empty +
+
handleFilterTypeChange("is not empty")} + > + Is not empty +
+
+
+ ); +}; \ No newline at end of file diff --git a/compass/components/FilterBox/index.tsx b/compass/components/FilterBox/index.tsx new file mode 100644 index 0000000..5faf7d4 --- /dev/null +++ b/compass/components/FilterBox/index.tsx @@ -0,0 +1,93 @@ +// FilterBox.tsx +import { useState } from "react"; +import { ChevronDownIcon } from "@heroicons/react/24/solid"; +import { ContainsDropdown } from "./ContainsDropdown"; + +const mockTags = ["food relief", "period poverty", "nutrition education"]; + +type FilterType = "contains" | "does not contain" | "is empty" | "is not empty"; + +export const FilterBox = () => { + const [selectedTags, setSelectedTags] = useState([]); + const [searchTerm, setSearchTerm] = useState(""); + const [showContainsDropdown, setShowContainsDropdown] = useState(false); + const [filterType, setFilterType] = useState("contains"); + + const handleTagChange = (tag: string) => { + setSelectedTags((prevTags) => + prevTags.includes(tag) + ? prevTags.filter((t) => t !== tag) + : [...prevTags, tag] + ); + }; + + const handleSearchChange = (e: React.ChangeEvent) => { + setSearchTerm(e.target.value); + }; + + const renderSelectedTags = () => + selectedTags.map((tag) => ( +
+ {tag} + handleTagChange(tag)} + > + × + +
+ )); + + return ( +
+
+ + Tags{" "} + + +
+
+ {selectedTags.length > 0 && renderSelectedTags()} + +
+
+ {mockTags + .filter((tag) => + tag.toLowerCase().includes(searchTerm.toLowerCase()) + ) + .map((tag) => ( +
+ handleTagChange(tag)} + className="mr-2" + /> + +
+ ))} +
+ {showContainsDropdown && ( + + )} +
+ ); +}; diff --git a/compass/components/Table/Index.tsx b/compass/components/Table/Index.tsx index 59e56aa..82194b4 100644 --- a/compass/components/Table/Index.tsx +++ b/compass/components/Table/Index.tsx @@ -135,6 +135,7 @@ export const Table = () => { } // TODO: Filtering + // TODO: Sorting // added this fn for editing rows diff --git a/compass/components/Table/TableAction.tsx b/compass/components/Table/TableAction.tsx index e58e110..0b20d32 100644 --- a/compass/components/Table/TableAction.tsx +++ b/compass/components/Table/TableAction.tsx @@ -1,46 +1,64 @@ -/** The actions (Filter, Sort, Search) at the top of the table. */ +// TableAction.tsx import { MagnifyingGlassIcon } from "@heroicons/react/24/solid"; -import { ChangeEventHandler, Dispatch, FunctionComponent, SetStateAction, useRef, useState } from "react"; +import { ChangeEventHandler, FunctionComponent, useRef, useState } from "react"; +import { FilterBox } from "../FilterBox"; type TableActionProps = { - query: string - handleChange: ChangeEventHandler -} + query: string; + handleChange: ChangeEventHandler; +}; -export const TableAction: FunctionComponent = ({query, handleChange}) => { +export const TableAction: FunctionComponent = ({ + query, + handleChange, +}) => { const searchInput = useRef(null); const [searchActive, setSearchActive] = useState(false); + const [showFilterBox, setShowFilterBox] = useState(false); const activateSearch = () => { setSearchActive(true); - if (searchInput.current === null) { return; } + if (searchInput.current === null) { + return; + } searchInput.current.focus(); searchInput.current.addEventListener("focusout", () => { if (searchInput.current?.value.trim() === "") { searchInput.current.value = ""; deactivateSearch(); } - }) - } + }); + }; const deactivateSearch = () => setSearchActive(false); + const toggleFilterBox = () => setShowFilterBox((prev) => !prev); + return (
- Filter + + Filter + + {showFilterBox && } Sort - activateSearch()}> + + />
); -}; +}; \ No newline at end of file diff --git a/compass/components/resource/LandingSearchBar.tsx b/compass/components/resource/LandingSearchBar.tsx index f52b6ba..724131b 100644 --- a/compass/components/resource/LandingSearchBar.tsx +++ b/compass/components/resource/LandingSearchBar.tsx @@ -1,9 +1,12 @@ -import { MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/solid" +import { ChevronDownIcon, MagnifyingGlassIcon, XMarkIcon } from "@heroicons/react/24/solid" import React, { useState } from 'react'; import Image from 'next/image'; +import { FilterBox } from "../FilterBox"; export const LandingSearchBar: React.FC = () => { const [searchTerm, setSearchTerm] = useState(''); + const [showFilterBox, setShowFilterBox] = useState(false); + const toggleFilterBox = () => setShowFilterBox((prev) => !prev); const handleSearchChange = (event: React.ChangeEvent) => { setSearchTerm(event.target.value); @@ -34,7 +37,9 @@ export const LandingSearchBar: React.FC = () => {