diff --git a/src/App.jsx b/src/App.jsx index 75b20e9..5e1a327 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -15,15 +15,39 @@ import './App.css'; const AppContent = ({ currentPage, setCurrentPage }) => { const location = useLocation(); const isEditProfilePage = location.pathname === '/edit-profile'; + const isHomePage = location.pathname === '/'; // Check if we are on the HomePage + + const [isFilterOpen, setIsFilterOpen] = useState(false); // State for the filter visibility + + const handleFilterToggle = (forceClose = null) => { + if (forceClose === false) { + setIsFilterOpen(false); // Force close the filter + } else { + setIsFilterOpen((prev) => !prev); // Toggle the filter + } + }; return ( - {!isEditProfilePage &&
} + {!isEditProfilePage && ( +
+ )}
- } /> + + } + /> } /> - {/* TBD
} /> */} } /> } /> } /> diff --git a/src/components/Home/StudentFilter.jsx b/src/components/Home/StudentFilter.jsx index 46a0fdc..47f3cef 100644 --- a/src/components/Home/StudentFilter.jsx +++ b/src/components/Home/StudentFilter.jsx @@ -2,17 +2,7 @@ import React from 'react'; import useCourses from '@data/useCourses'; import useMajors from '@data/useMajors'; -import { - Box, - Autocomplete, - TextField, - FormControl, - InputLabel, - Select, - MenuItem, - Chip, - OutlinedInput, -} from '@mui/material'; +import { Box, Autocomplete, TextField } from '@mui/material'; export default function StudentFilter({ selectedMajors, @@ -50,40 +40,28 @@ export default function StudentFilter({ renderInput={(params) => ( )} - filterOptions={(options, { inputValue }) => { - // Convert inputValue to lowercase for case-insensitive matching - const lowercasedInput = inputValue.toLowerCase(); + // filterOptions={(options, { inputValue }) => { + // // Convert inputValue to lowercase for case-insensitive matching + // const lowercasedInput = inputValue.toLowerCase(); - // Only include options that start with the input - return options.filter((option) => option.toLowerCase().startsWith(lowercasedInput)); - }} + // // Only include options that start with the input + // return options.filter((option) => option.toLowerCase().startsWith(lowercasedInput)); + // }} sx={{ flex: 1, mb: 2, minWidth: 200, maxWidth: '100%' }} - freeSolo /> {/* 3. Year filter */} - - Filter by Year(s) - - + option} + value={selectedYears} + onChange={(event, newValue) => setSelectedYears(newValue)} + renderInput={(params) => ( + + )} + sx={{ flex: 1, mb: 2, minWidth: 200, maxWidth: '100%' }} + /> ); } diff --git a/src/components/Home/StudentList.jsx b/src/components/Home/StudentList.jsx index dfe4e64..e4dc790 100644 --- a/src/components/Home/StudentList.jsx +++ b/src/components/Home/StudentList.jsx @@ -17,18 +17,25 @@ export default function StudentList({ selectedYears, }) { const studentData = useStudentData(); + const filteredStudentData = studentData?.filter((profile) => { + const profileCourses = profile.listOfCourses || []; // Ensure profile has courses + // eslint-disable-next-line max-len + const normalizedSelectedCourses = selectedCourses.map((course) => course.toLowerCase()); // Normalize selected courses to lowercase - const filteredStudentData = studentData?.filter( - (profile) => - profile.uid !== userProfile.uid && - !matchedUserUids.has(profile.uid) && - profile.major !== '' && - profile.year !== '' && - (selectedMajors.length === 0 || selectedMajors.includes(profile.major)) && - (selectedCourses.length === 0 || - profile.courses?.some((course) => selectedCourses.includes(course))) && - (selectedYears.length === 0 || selectedYears.includes(profile.year)), - ); + // Ensure filtering conditions for majors, courses, and years + return ( + profile.uid !== userProfile.uid && // Exclude current user + !matchedUserUids.has(profile.uid) && // Exclude already matched users + profile.major !== '' && // Ensure major is defined + profile.year !== '' && // Ensure year is defined + (selectedMajors.length === 0 || selectedMajors.includes(profile.major)) && // Filter by major + (selectedCourses.length === 0 || // Filter by courses (case-insensitive match) + profileCourses.some((course) => + normalizedSelectedCourses.includes(course.toLowerCase()), + )) && + (selectedYears.length === 0 || selectedYears.includes(profile.year)) // Filter by year + ); + }); const { currentData: studentsToDisplay, diff --git a/src/components/HomePage.jsx b/src/components/HomePage.jsx index 4b33138..b02baef 100644 --- a/src/components/HomePage.jsx +++ b/src/components/HomePage.jsx @@ -1,22 +1,49 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { useAuthState } from '@auth/useAuthState'; -import StudentFilter from '@components/Home/StudentFilter'; import StudentList from '@components/Home/StudentList'; import useUserProfile from '@data/useUserProfile'; import { Box, CircularProgress, Typography } from '@mui/material'; import { useNavigate } from 'react-router-dom'; -export default function HomePage() { +import StudentFilter from './Home/StudentFilter'; + +export default function HomePage({ isFilterOpen, handleFilterToggle }) { + // Receive props from AppContent const [user] = useAuthState(); const { userProfile, requestedUsers, setRequestedUsers, matchedUserUids, loading } = useUserProfile(user, true); const [selectedMajors, setSelectedMajors] = useState([]); const [selectedCourses, setSelectedCourses] = useState([]); const [selectedYears, setSelectedYears] = useState([]); + const filterRef = useRef(null); // Reference to the filter component const navigate = useNavigate(); - // Redirect user to edit-profile if the profile is incomplete + // Close the filter if clicked outside + const handleClickOutside = (event) => { + // Check if the click is inside the filter or inside the dropdown (Autocomplete or Select) + if ( + filterRef.current && + !filterRef.current.contains(event.target) && + !document.querySelector('.MuiAutocomplete-popper')?.contains(event.target) && // For Autocomplete dropdowns + !document.querySelector('.MuiPopover-root')?.contains(event.target) // For Select dropdowns + ) { + handleFilterToggle(false); // Close the filter only when clicked outside + } + }; + + useEffect(() => { + if (isFilterOpen) { + document.addEventListener('mousedown', handleClickOutside); // or use 'pointerdown' instead of 'mousedown' + } else { + document.removeEventListener('mousedown', handleClickOutside); + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside); // Cleanup the listener + }; + }, [isFilterOpen]); + useEffect(() => { if (userProfile && (!userProfile.major || !userProfile.year || !userProfile.phoneNumber)) { navigate('/edit-profile'); @@ -41,33 +68,38 @@ export default function HomePage() { ); } - // Render the StudentFilter and StudentList only if the userProfile is complete if (!userProfile || !userProfile.major || !userProfile.year || !userProfile.phoneNumber) { return null; } return ( - - - + {/* Render the filter section only if it's open */} + {isFilterOpen && ( + + + + )} { - // If we came from edit-profile or a similar page, navigate home instead of going back. if (location.state?.fromEditProfile) { navigate('/'); // Redirect to the home page } else if (window.history.length > 2) { @@ -32,16 +32,26 @@ export default function Header() { return ( - {/* Left side: Back button or placeholder */} - {!isRootPage ? ( - - - - ) : ( - - )} + + {showFilter && ( + + + + )} + {!isRootPage ? ( + + + + ) : ( + // Placeholder if no back button is needed + )} + - {/* Centered text */} - {/* Right side: Sign In button or user avatar */} {!isProfilePage ? ( user ? (