Skip to content

Commit eddc711

Browse files
committed
Enhance HackathonList component with smooth scrolling and highlight feature for hash links
1 parent 9710656 commit eddc711

1 file changed

Lines changed: 45 additions & 24 deletions

File tree

src/Page/OpportunitiesHub/HackathonList.jsx

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect, useRef } from 'react';
22
import styled from 'styled-components';
3-
import { useEffect } from 'react';
43
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
54
import { faFlag, faMapMarkerAlt, faCalendarAlt, faShareAlt } from '@fortawesome/free-solid-svg-icons';
65

@@ -682,9 +681,9 @@ const StyledHackathonCard = styled.div`
682681
}
683682
`;
684683

685-
const HackathonCardComponent = ({ organizer, title, location, date, domains, applyLink, poster, shareLink }) => {
686-
return (
687-
<StyledHackathonCard id={shareLink.substring(1)}>
684+
const HackathonCardComponent = React.forwardRef(
685+
({ organizer, title, location, date, domains, applyLink, poster, shareLink }, ref) => (
686+
<StyledHackathonCard id={shareLink.substring(1)} ref={ref}>
688687
{/* <div className="dot"></div> */}
689688
<div className="flex items-center justify-between p-2">
690689
<span className="text-sm font-semibold text-white">
@@ -744,8 +743,8 @@ const HackathonCardComponent = ({ organizer, title, location, date, domains, app
744743
))}
745744
</div>
746745
</StyledHackathonCard>
747-
);
748-
};
746+
),
747+
);
749748

750749
<style>
751750
{`
@@ -821,22 +820,10 @@ const HackathonList = () => {
821820
const [locationFilter, setLocationFilter] = useState('');
822821
const [monthFilter, setMonthFilter] = useState('');
823822
const [domainFilter, setDomainFilter] = useState('');
823+
const [highlightId, setHighlightId] = useState(null);
824+
const cardRefs = useRef({});
824825

825-
useEffect(() => {
826-
if (window.location.hash) {
827-
const id = window.location.hash.substring(1);
828-
const el = document.getElementById(id);
829-
if (el) {
830-
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
831-
el.style.boxShadow = '0 0 0 4px #00a6fb, 0 0 20px #00a6fb';
832-
el.style.transition = 'box-shadow 0.5s';
833-
setTimeout(() => {
834-
el.style.boxShadow = '';
835-
}, 2000);
836-
}
837-
}
838-
}, []);
839-
826+
// Filter logic
840827
const filteredHackathons = hackathons.filter((hackathon) => {
841828
const matchesLocation = locationFilter
842829
? hackathon.location.toLowerCase().includes(locationFilter.toLowerCase())
@@ -850,6 +837,36 @@ const HackathonList = () => {
850837
return matchesLocation && matchesMonth && matchesDomain;
851838
});
852839

840+
// Always include the card with the hash if present
841+
let displayHackathons = filteredHackathons;
842+
let hashId = null;
843+
if (typeof window !== 'undefined' && window.location.hash) {
844+
hashId = window.location.hash.substring(1);
845+
const exists = filteredHackathons.some((h) => h.shareLink.substring(1) === hashId);
846+
if (!exists) {
847+
const card = hackathons.find((h) => h.shareLink.substring(1) === hashId);
848+
if (card) displayHackathons = [card, ...filteredHackathons];
849+
}
850+
}
851+
852+
useEffect(() => {
853+
if (typeof window !== 'undefined' && window.location.hash) {
854+
setHighlightId(window.location.hash.substring(1));
855+
}
856+
}, [locationFilter, monthFilter, domainFilter]);
857+
858+
useEffect(() => {
859+
if (highlightId && cardRefs.current[highlightId]) {
860+
const el = cardRefs.current[highlightId];
861+
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
862+
el.style.boxShadow = '0 0 0 4px #00a6fb, 0 0 20px #00a6fb';
863+
el.style.transition = 'box-shadow 0.5s';
864+
setTimeout(() => {
865+
el.style.boxShadow = '';
866+
}, 2000);
867+
}
868+
}, [highlightId, displayHackathons.length]);
869+
853870
return (
854871
<>
855872
<FilterContainer>
@@ -882,8 +899,12 @@ const HackathonList = () => {
882899
/>
883900
</FilterContainer>
884901
<HackathonListContainer>
885-
{filteredHackathons.map((hackathon, idx) => (
886-
<HackathonCardComponent key={idx} {...hackathon} />
902+
{displayHackathons.map((hackathon) => (
903+
<HackathonCardComponent
904+
key={hackathon.shareLink}
905+
ref={(el) => (cardRefs.current[hackathon.shareLink.substring(1)] = el)}
906+
{...hackathon}
907+
/>
887908
))}
888909
</HackathonListContainer>
889910
</>

0 commit comments

Comments
 (0)