diff --git a/apps/frontend/src/containers/approvePantries.tsx b/apps/frontend/src/containers/approvePantries.tsx index 9d06a8bc5..9292c807c 100644 --- a/apps/frontend/src/containers/approvePantries.tsx +++ b/apps/frontend/src/containers/approvePantries.tsx @@ -1,44 +1,43 @@ import React, { useEffect, useState } from 'react'; -import { useNavigate, useSearchParams } from 'react-router-dom'; +import { useSearchParams } from 'react-router-dom'; import { - Center, Table, Button, + Box, + Heading, + VStack, + Checkbox, + Pagination, + ButtonGroup, + IconButton, Link, - NativeSelect, - NativeSelectIndicator, } from '@chakra-ui/react'; import ApiClient from '@api/apiClient'; import { Pantry } from 'types/types'; -import { formatDate } from '@utils/utils'; -import { FloatingAlert } from '@components/floatingAlert'; +import { + ArrowDownUp, + ChevronLeft, + ChevronRight, + CircleCheck, + Funnel, +} from 'lucide-react'; import { useAlert } from '../hooks/alert'; +import { FloatingAlert } from '@components/floatingAlert'; const ApprovePantries: React.FC = () => { - const navigate = useNavigate(); - const [pendingPantries, setPendingPantries] = useState([]); - const [sortedPantries, setSortedPantries] = useState([]); - const [sort, setSort] = useState(''); + const [pantries, setPantries] = useState([]); + const [sortAsc, setSortAsc] = useState(true); + const [selectedPantries, setSelectedPantries] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [isFilterOpen, setIsFilterOpen] = useState(false); const [searchParams, setSearchParams] = useSearchParams(); const [alertState, setAlertMessage] = useAlert(); - const updatePantry = async ( - pantryId: number, - decision: 'approve' | 'deny', - ) => { - try { - await ApiClient.updatePantry(pantryId, decision); - setPendingPantries((prev) => prev.filter((p) => p.pantryId !== pantryId)); - } catch { - setAlertMessage(`Error ${decision} pantry`); - } - }; - useEffect(() => { const fetchPantries = async () => { try { const data = await ApiClient.getAllPendingPantries(); - setPendingPantries(data); + setPantries(data); } catch { setAlertMessage('Error fetching pantries'); } @@ -48,26 +47,53 @@ const ApprovePantries: React.FC = () => { }, [setAlertMessage]); useEffect(() => { - const sorted = [...pendingPantries]; - - if (sort === 'name') { - sorted.sort((a, b) => a.pantryName.localeCompare(b.pantryName)); - } else if (sort === 'name-reverse') { - sorted.sort((a, b) => b.pantryName.localeCompare(a.pantryName)); - } else if (sort === 'date-recent') { - sorted.sort( - (a, b) => - new Date(b.dateApplied).getTime() - new Date(a.dateApplied).getTime(), - ); - } else if (sort === 'date-oldest') { - sorted.sort( - (a, b) => - new Date(a.dateApplied).getTime() - new Date(b.dateApplied).getTime(), - ); + setCurrentPage(1); + }, [selectedPantries]); + + const pantryOptions = [ + ...new Set( + pantries + .map((p) => p.pantryName) + .filter((name): name is string => !!name), + ), + ].sort((a, b) => a.localeCompare(b)); + + const handleFilterChange = (pantry: string, checked: boolean) => { + if (checked) { + setSelectedPantries([...selectedPantries, pantry]); + } else { + setSelectedPantries(selectedPantries.filter((p) => p !== pantry)); } + }; + + const filteredPantries = pantries + .filter((p) => { + const matchesFilter = + selectedPantries.length === 0 || + selectedPantries.includes(p.pantryName); + return matchesFilter; + }) + .sort((a, b) => + sortAsc + ? new Date(a.dateApplied).getTime() - new Date(b.dateApplied).getTime() + : new Date(b.dateApplied).getTime() - new Date(a.dateApplied).getTime(), + ); + + const itemsPerPage = 10; + const totalPages = Math.ceil(filteredPantries.length / itemsPerPage); + const paginatedPantries = filteredPantries.slice( + (currentPage - 1) * itemsPerPage, + currentPage * itemsPerPage, + ); - setSortedPantries(sorted); - }, [sort, pendingPantries]); + const tableHeaderStyles = { + borderBottom: '1px solid', + borderColor: 'neutral.100', + color: 'neutral.800', + fontFamily: 'inter', + fontWeight: '600', + fontSize: 'sm', + }; useEffect(() => { const action = searchParams.get('action'); @@ -85,7 +111,10 @@ const ApprovePantries: React.FC = () => { }, [searchParams, setSearchParams, setAlertMessage]); return ( -
+ + + Application Review + {alertState && ( { timeout={6000} /> )} - - setSort(e.target.value)} + {filteredPantries.length === 0 ? ( + - - - - - - - - - - - {sortedPantries.map((pantry) => ( - - {pantry.pantryId} - - + + {isFilterOpen && ( + <> + setIsFilterOpen(false)} + zIndex={10} + /> + + + {pantryOptions.map((pantry) => ( + + handleFilterChange(pantry, e.checked) + } + color="black" + size="sm" + > + + + {pantry} + + ))} + + + + )} + + + + + + + - {pantry.pantryName} - - - {formatDate(pantry.dateApplied)} - - - - - - - - ))} - - -
+ Date Applied + + + Actions + + + + + {paginatedPantries.map((pantry, index) => ( + + + {pantry.pantryId} + + + {pantry.pantryName} + + + {new Date(pantry.dateApplied).toLocaleDateString('en-US', { + month: '2-digit', + day: '2-digit', + year: 'numeric', + })} + + + + View Details + + + + ))} + + + + {totalPages > 1 && ( + setCurrentPage(e.page)} + > + + + + + + ( + + {page.value} + + )} + /> + + + + + + + )} + + )} + ); };