33import React , { useEffect , useState , useCallback , useRef , useMemo , Suspense } from "react" ;
44import InfiniteScroll from "@components/infinit-scroll" ;
55import { Spinner } from "@components/ui/loading" ;
6- import { ProjectHero } from "@components/heros/project-hero" ;
76import { ProjectCard } from "@components/cards/project-card" ;
87import { Project } from "../../lib/types/interfaces" ;
98import { BlurFade } from '@components/ui/blur-fade' ;
109import { NavigationBar } from "@components/navbar/navbar" ;
1110import ProjectsStructuredData from "@components/projects-structured-data" ;
1211import { useSearchParams , useRouter } from "next/navigation" ;
12+ import dynamic from "next/dynamic" ;
1313import { Button } from "src/components/ui" ;
1414import { cn } from "@lib/utils" ;
15- import Footer from "src/components/layouts/footer" ;
15+
16+ const ProjectHero = dynamic (
17+ ( ) => import ( "@components/heros/project-hero" ) . then ( ( mod ) => mod . ProjectHero ) ,
18+ { ssr : false }
19+ ) ;
1620
1721const ProjectsContent = ( ) => {
1822 const router = useRouter ( ) ;
@@ -26,14 +30,17 @@ const ProjectsContent = () => {
2630 const [ selectedTag , setSelectedTag ] = useState ( "" ) ;
2731 const [ availableTags , setAvailableTags ] = useState < string [ ] > ( [ ] ) ;
2832 const hasFetched = useRef ( false ) ;
33+ const isFetchingRef = useRef ( false ) ;
2934
3035 const next = useCallback ( async ( ) => {
31- if ( loading ) return ;
36+ if ( isFetchingRef . current || ! hasMore ) return ;
3237
38+ isFetchingRef . current = true ;
3339 setLoading ( true ) ;
40+ const currentPage = page ;
3441
3542 try {
36- const response = await fetch ( `/api/projects?page=${ page } &limit=${ limit } ` ) ;
43+ const response = await fetch ( `/api/projects?page=${ currentPage } &limit=${ limit } ` ) ;
3744
3845 if ( ! response . ok ) {
3946 throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
@@ -56,9 +63,10 @@ const ProjectsContent = () => {
5663 console . error ( 'Error fetching projects:' , error ) ;
5764 setHasMore ( false ) ;
5865 } finally {
66+ isFetchingRef . current = false ;
5967 setLoading ( false ) ;
6068 }
61- } , [ loading , page , limit ] ) ;
69+ } , [ hasMore , page , limit ] ) ;
6270
6371 useEffect ( ( ) => {
6472 if ( ! hasFetched . current ) {
@@ -142,7 +150,7 @@ const ProjectsContent = () => {
142150 { availableTags . length > 0 && (
143151 < div className = "max-w-5xl mx-auto w-full px-5 mb-4" >
144152 < div className = "flex flex-wrap max-sm:justify-center items-center gap-1.5" >
145- < p className = "text-xs font-medium" > Tag: </ p >
153+ { /* <p className="text-xs font-medium">Tag: </p> */ }
146154 < Button
147155 className = { cn ( "mt-0 py-1 sm:py-2 px-2.5 h-fit! text-xs leading-4 text-foreground/80 hover:text-primary transition-all" , ! selectedTag && "ring-1 px-4! bg-primary/5 text-primary" ) }
148156 onClick = { ( ) => handleTagChange ( "" ) }
0 commit comments