diff --git a/client/public/bva_logo.png b/client/public/bva_logo.png new file mode 100644 index 00000000..72c1dbd2 Binary files /dev/null and b/client/public/bva_logo.png differ diff --git a/client/src/components/nav/NavBar.tsx b/client/src/components/nav/NavBar.tsx index 978b8a80..86ac9757 100644 --- a/client/src/components/nav/NavBar.tsx +++ b/client/src/components/nav/NavBar.tsx @@ -6,7 +6,6 @@ import * as React from 'react'; import { AppBar, Box, Button, MenuItem, Toolbar, IconButton, Typography, Menu, Container } from '@mui/material'; import MenuIcon from '@mui/icons-material/Menu'; -import StarIcon from '@mui/icons-material/Star'; import { useRouter } from 'next/navigation'; import { keyframes } from '@mui/system'; import { usePathname } from 'next/navigation'; @@ -33,11 +32,10 @@ const links: Record = { 'Drop Box Locations': '/dropBoxLocations' }; - function NavBar() { const [anchorElNav, setAnchorElNav] = React.useState(null); - const router = useRouter() + const router = useRouter(); const handleOpenNavMenu = (event: React.MouseEvent) => { setAnchorElNav(event.currentTarget); @@ -51,6 +49,7 @@ function NavBar() { handleCloseNavMenu(); router.push(links[page]); }; + }; // Below is testing for active page link const currentPath = usePathname(); @@ -202,5 +201,5 @@ function NavBar() { ); } -export default NavBar; +export default NavBar; diff --git a/client/src/pages/candidateInfo/index.tsx b/client/src/pages/candidateInfo/index.tsx index f1f222d0..be731185 100644 --- a/client/src/pages/candidateInfo/index.tsx +++ b/client/src/pages/candidateInfo/index.tsx @@ -1,8 +1,5 @@ 'use client'; import React, { useEffect, useState } from 'react'; -import SubscribePopup from '../../components/subscribePopup/SubscribePopup'; -import { CandidateAPI } from '@/common'; // use this instead of hardcoded link -import { useRouter } from 'next/router'; interface Candidate { id: number; @@ -11,7 +8,6 @@ interface Candidate { District: string; Party: string; ElectionName: string; - Office: string; Bio?: string; CampaignSiteLink?: string; LinkedInLink?: string; @@ -24,27 +20,30 @@ const parties = ['Democrat', 'Republican', 'Independent', 'Non Partisan', 'Other const electionTypes = ['Federal Election', 'State Election', 'Municipal Election', 'Special Election', 'Primary Election', 'Ballot Questions/Referendum']; const districts = ['District 1', 'District 2', 'District 3', 'District 4']; // Example districts, replace with actual +// Component for Candidate Information Page export default function CandidateInfo() { const [candidates, setCandidates] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); + const [expandedCandidateId, setExpandedCandidateId] = useState(null); const [filteredCandidates, setFilteredCandidates] = useState([]); const [filters, setFilters] = useState({ party: '', electionType: '', district: '', }); - const [showPopup, setShowPopup] = useState(false); - - const router = useRouter(); useEffect(() => { const fetchCandidateData = async () => { + console.log("Fetching candidate data..."); try { const response = await fetch('https://pitne-voter-app-production.up.railway.app/api/candidates?populate=Headshot'); + console.log("API Response Status:", response.status); if (response.ok) { const data = await response.json(); + console.log("Fetched data:", data); + if (data.data && data.data.length > 0) { const fetchedCandidates: Candidate[] = data.data.map((candidate: any) => { const headshotUrl = candidate.attributes.Headshot?.data?.attributes?.url @@ -58,15 +57,19 @@ export default function CandidateInfo() { }, }; }); + console.log("Fetched Candidates with Headshot URL:", fetchedCandidates); setCandidates(fetchedCandidates); - setFilteredCandidates(fetchedCandidates); + setFilteredCandidates(fetchedCandidates); // Set initial filtered candidates } else { + console.warn("No candidate data available."); setError("No candidate data available."); } } else { + console.error('Failed to fetch candidate data', response.statusText); setError('Failed to fetch candidate data'); } - } catch { + } catch (fetchError) { + console.error('Error:', fetchError); setError('An error occurred while fetching candidate data'); } finally { setIsLoading(false); @@ -74,24 +77,10 @@ export default function CandidateInfo() { }; fetchCandidateData(); - - // Show popup after a delay (e.g., 1 seconds) - const popupTimer = setTimeout(() => { - setShowPopup(true); - }, 1000); - - // Cleanup timer when component unmounts - return () => clearTimeout(popupTimer); - }, []); - const handleClosePopup = () => { - setShowPopup(false); - }; - - const handleCandidateClick = (name: string) => { - const formattedName = name.replace(/\s+/g, '').toLowerCase(); // Ensure it matches profile URL structure - router.push(`/candidateInfo/${formattedName}`); // Navigate to the candidate's profile page + const toggleExpand = (candidateId: number) => { + setExpandedCandidateId(prevId => (prevId === candidateId ? null : candidateId)); }; const handleFilterChange = (e: React.ChangeEvent) => { @@ -102,14 +91,7 @@ export default function CandidateInfo() { })); }; - const handleResetFilters = () => { - setFilters({ - party: '', - electionType: '', - district: '', - }); - }; - + // Filter candidates based on selected filters useEffect(() => { const filtered = candidates.filter(candidate => { const matchesParty = filters.party ? candidate.attributes.Party === filters.party : true; @@ -126,124 +108,134 @@ export default function CandidateInfo() { return (
{/* Sidebar for Filters */} -
-

Filter Candidates

- -
- - {parties.map(party => ( ))}
- -
- - {electionTypes.map(type => ( ))}
- -
- - {districts.map(district => ( ))}
- - {/* Reset Filters Button */} -
{/* Main Content */}
{filteredCandidates.length > 0 ? ( filteredCandidates.map(candidate => ( -
toggleExpand(candidate.id)} > -
+ {/* Candidate Card Layout */} +
{candidate.attributes.PhotoURL && ( - {candidate.attributes.Name} )}
-

{candidate.attributes.Name}

-
-

- Party: {candidate.attributes.Party} -

-

- Office: {candidate.attributes.Role} -

-

- Election: {candidate.attributes.ElectionName} -

-

- District: {candidate.attributes.District} -

-
+

{candidate.attributes.Name}

+

Party: {candidate.attributes.Party}

+

Election: {candidate.attributes.ElectionName}

- + {/* Arrow Icon */} +
+ ▼ +
+ + {/* Expandable Details */} + {expandedCandidateId === candidate.id && ( +
+

District: {candidate.attributes.District}

+

Bio: {candidate.attributes.Bio}

+ +
+

Questionnaire

+ {Array.from({ length: 5 }, (_, index) => ( +
+ Question {index + 1}: +

{candidate.attributes[`Q${index + 1}`]}

+
+ ))} +
+
+ )}
)) ) : ( -

No candidates match the selected filters.

+

No candidates found matching the selected filters.

)}
- - {/* Subscribe Popup */} - {showPopup && } -
); -} \ No newline at end of file +}