diff --git a/src/components/Home/DonorDashboard/index.tsx b/src/components/Home/DonorDashboard/index.tsx
index 0b85633..0170d2a 100644
--- a/src/components/Home/DonorDashboard/index.tsx
+++ b/src/components/Home/DonorDashboard/index.tsx
@@ -1,43 +1,93 @@
import { Box, Typography } from '@mui/material';
-import { filter, lowerCase, some } from 'es-toolkit/compat';
-import { useState } from 'react';
+import { useState, useMemo } from 'react';
import OrganizationCard from './OrganizationCard';
import { useOrganizationStore } from '@/stores';
-import { SearchBar } from '@/components/common';
+import { SearchBar, Filters } from '@/components/common';
const DonorDashboard = () => {
const [searchQuery, setSearchQuery] = useState('');
+ const [needsQuery, setNeedsQuery] = useState('');
+ const [descriptionQuery, setDescriptionQuery] = useState('');
+ const [locationQuery, setLocationQuery] = useState('');
const organizationProfiles = useOrganizationStore(
(state) => state.organizationProfiles
);
- // Filtered organizations based on search query
- const filteredOrganizations = filter(organizationProfiles, (org) => {
- if (!org.name) return false;
- const searchTerm = lowerCase(searchQuery);
- return (
- lowerCase(org.name).includes(searchTerm) ||
- lowerCase(org.location).includes(searchTerm) ||
- some(org.needs, (need) => lowerCase(need).includes(searchTerm))
- );
- });
+ const filteredOrganizations = useMemo(() => {
+ return organizationProfiles.filter((org) => {
+ const matchesSearch = searchQuery
+ ? org.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
+ org.location.toLowerCase().includes(searchQuery.toLowerCase()) ||
+ (org.needs || []).some((need) =>
+ need.itemName.toLowerCase().includes(searchQuery.toLowerCase())
+ )
+ : true;
+
+ const matchesNeeds = needsQuery
+ ? (org.needs || []).some((need) =>
+ need.itemName.toLowerCase().includes(needsQuery.toLowerCase())
+ )
+ : true;
+
+ const matchesDescription = descriptionQuery
+ ? org.description
+ ?.toLowerCase()
+ .includes(descriptionQuery.toLowerCase())
+ : true;
+
+ const matchesLocation = locationQuery
+ ? org.location.toLowerCase().includes(locationQuery.toLowerCase())
+ : true;
+
+ return (
+ matchesSearch && matchesNeeds && matchesDescription && matchesLocation
+ );
+ });
+ }, [
+ organizationProfiles,
+ searchQuery,
+ needsQuery,
+ descriptionQuery,
+ locationQuery,
+ ]);
return organizationProfiles.length > 0 ? (
-
-
-
- {filteredOrganizations.map((org) => (
-
- ))}
+
+
+
+
-
+
+ {filteredOrganizations.map((org) => (
+
+ ))}
+
) : (
void;
+ descriptionQuery: string;
+ setDescriptionQuery: (query: string) => void;
+ locationQuery: string;
+ setLocationQuery: (query: string) => void;
+}
+
+const Filters = ({
+ needsQuery,
+ setNeedsQuery,
+ descriptionQuery,
+ setDescriptionQuery,
+ locationQuery,
+ setLocationQuery,
+}: FiltersProps) => {
+ const organizationProfiles = useOrganizationStore(
+ (state) => state.organizationProfiles
+ );
+
+ const [anchorElement, setAnchorElement] = useState(null);
+
+ const handleClose = () => {
+ setAnchorElement(null);
+ };
+
+ const open = Boolean(anchorElement);
+ const id = open ? 'filters-popover' : undefined;
+
+ const needsOptions = [
+ ...new Set(
+ organizationProfiles.flatMap(
+ (org) => org.needs?.flatMap((need) => need.itemName) || []
+ )
+ ),
+ ].filter(Boolean);
+
+ return (
+
+
+
+
+ {/* Needs dropdown */}
+
+ Filter by Needs
+
+
+
+ {/* Description text field */}
+ setDescriptionQuery(event_.target.value)}
+ />
+
+ {/* Location text field */}
+ setLocationQuery(event_.target.value)}
+ />
+
+
+
+ );
+};
+
+export default Filters;
diff --git a/src/components/common/SearchBar.tsx b/src/components/common/SearchBar.tsx
index 1f07e2d..0a7b74c 100644
--- a/src/components/common/SearchBar.tsx
+++ b/src/components/common/SearchBar.tsx
@@ -1,6 +1,6 @@
import type { ChangeEvent } from 'react';
import { useCallback, useMemo, useEffect, useState } from 'react';
-import { TextField, Box, Button } from '@mui/material';
+import { TextField } from '@mui/material';
import { useSearchParams } from 'react-router-dom';
import { debounce } from 'es-toolkit/compat';
@@ -42,22 +42,14 @@ const SearchBar = ({ onSearchChange }: SearchBarProps) => {
}, [searchParams, onSearchChange]);
return (
-
-
-
-
+
);
};
diff --git a/src/components/common/index.tsx b/src/components/common/index.tsx
index 28914be..91b687e 100644
--- a/src/components/common/index.tsx
+++ b/src/components/common/index.tsx
@@ -5,3 +5,4 @@ export { default as ProtectedRoute } from './ProtectedRoute';
export { default as CustomDialog } from './CustomDialog';
export { default as RoleSelectionModal } from './RoleSelectionModal';
export { default as Layout } from './Layout';
+export { default as Filters } from './Filters';