diff --git a/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx b/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx index 44dbe0d734..bd56c2f0d0 100644 --- a/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx +++ b/src/components/HGNHelpSkillsDashboard/CommunityMembersPage.jsx @@ -1,10 +1,39 @@ -import { useState } from 'react'; -import RankedUserList from './RankedUserList'; // wherever your RankedUserList is +import { useEffect, useMemo, useState } from 'react'; +import axios from 'axios'; +import RankedUserList from './RankedUserList'; +import styles from './style/CommunityMembersPage.module.css'; const availableSkills = ['React', 'Redux', 'HTML', 'CSS', 'MongoDB', 'Database', 'Agile']; +const RANKED_USERS_ENDPOINT = 'http://localhost:4500/api/hgnform/ranked'; function CommunityMembersPage() { const [selectedSkills, setSelectedSkills] = useState([]); + const [searchTerm, setSearchTerm] = useState(''); + const [sortOrder, setSortOrder] = useState('asc'); + const [showFilters, setShowFilters] = useState(false); + const [rankedUsers, setRankedUsers] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchRankedUsers = async () => { + setLoading(true); + try { + const params = { + skills: (selectedSkills.length ? selectedSkills : availableSkills).join(','), + }; + const response = await axios.get(RANKED_USERS_ENDPOINT, { params }); + setRankedUsers(response.data); + setError(null); + } catch (err) { + setError('Unable to load community members right now. Please try again later.'); + } finally { + setLoading(false); + } + }; + + fetchRankedUsers(); + }, [selectedSkills]); const handleCheckboxChange = skill => { setSelectedSkills(prev => @@ -12,23 +41,114 @@ function CommunityMembersPage() { ); }; + const toggleSortOrder = () => { + setSortOrder(prev => (prev === 'asc' ? 'desc' : 'asc')); + }; + + const clearFilters = () => { + setSelectedSkills([]); + }; + + const filteredUsers = useMemo(() => { + const normalizedSearch = searchTerm.trim().toLowerCase(); + const normalizedSelectedSkills = selectedSkills.map(skill => skill.toLowerCase()); + let result = rankedUsers; + + if (normalizedSearch) { + result = rankedUsers.filter(user => { + const nameMatches = user.name?.toLowerCase().includes(normalizedSearch); + const skillMatches = Array.isArray(user.topSkills) + ? user.topSkills.some(skill => skill.toLowerCase().includes(normalizedSearch)) + : false; + return nameMatches || skillMatches; + }); + } + + if (normalizedSelectedSkills.length) { + result = result.filter(user => { + if (!Array.isArray(user.topSkills) || user.topSkills.length === 0) return false; + return user.topSkills.some(skill => + normalizedSelectedSkills.includes((skill || '').toLowerCase()), + ); + }); + } + + return [...result].sort((a, b) => { + const first = a.name || ''; + const second = b.name || ''; + return sortOrder === 'asc' ? first.localeCompare(second) : second.localeCompare(first); + }); + }, [rankedUsers, searchTerm, sortOrder, selectedSkills]); + + const emptyMessage = + searchTerm || selectedSkills.length + ? 'No community members match your current filters.' + : 'No community members available yet.'; + return ( -
+ When multiple filters are selected, the score represents the average value, and the options + are ranked based on their scoring. Click each profile to learn more details. +
+ +Loading community members...
; + } - useEffect(() => { - if (!selectedSkills || selectedSkills.length === 0) return; + if (error) { + return{error}
; + } - const fetchRankedUsers = async () => { - setLoading(true); - try { - const response = await axios.get('http://localhost:4500/api/hgnform/ranked', { - params: { skills: selectedSkills.join(',') }, - }); - setRankedUsers(response.data); - } catch (err) { - // console.error('Error fetching ranked users:', err); - } finally { - setLoading(false); - } - }; - - fetchRankedUsers(); - }, [selectedSkills]); - - if (loading) returnLoading ranked users...
; + if (!users.length) { + return{emptyMessage}
; + } return ( -