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 = () => {
)}
-
+
+
+ {showFilterBox && }
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..b5bb348
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "compass",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}