diff --git a/src/components/TenderList.jsx b/src/components/TenderList.jsx index c0c35be..2c658af 100644 --- a/src/components/TenderList.jsx +++ b/src/components/TenderList.jsx @@ -1,7 +1,7 @@ -import React, { useState, useMemo } from 'react'; +import React, { useState, useMemo, useEffect, useRef, useCallback } from 'react'; import { useApp } from '../context/AppContext'; import { TenderCard } from './TenderCard'; -import { Download, SlidersHorizontal, Layers, ChevronLeft, ChevronRight } from 'lucide-react'; +import { Download, SlidersHorizontal, Layers, Loader2 } from 'lucide-react'; import confetti from 'canvas-confetti'; // İl adları kaynaklar arasında farklı yazılabiliyor (Ankara / ANKARA); @@ -23,8 +23,12 @@ export const TenderList = () => { } = useApp(); const [sortBy, setSortBy] = useState('newest'); // 'newest', 'urgent', 'distant' - const [currentPage, setCurrentPage] = useState(1); - const itemsPerPage = 10; + + // Sonsuz kaydırma: sayfa yerine aşağı indikçe liste büyür. + // (Sayfalama 10 bin kayıtta 1000+ sayfa düğmesi basıyordu.) + const SAYFA_ADIM = 20; + const [gosterilen, setGosterilen] = useState(SAYFA_ADIM); + const dipRef = useRef(null); // Filter logic const filteredTenders = useMemo(() => { @@ -66,8 +70,33 @@ export const TenderList = () => { }); }, [tenders, searchQuery, selectedCity, selectedAlimTuru, selectedSektorler, selectedCpvler, selectedKurumTipi, quickFilter, sortBy]); - const totalPages = Math.max(1, Math.ceil(filteredTenders.length / itemsPerPage)); - const paginatedTenders = filteredTenders.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage); + const gorunenTenders = filteredTenders.slice(0, gosterilen); + const dahaVar = gosterilen < filteredTenders.length; + + // Baştan başlama YALNIZCA filtre/sıralama değişiminde olmalı. filteredTenders + // dizisine bağlansaydı havuz her yenilendiğinde (10 dk) kullanıcı listenin + // başına fırlardı. + useEffect(() => { setGosterilen(SAYFA_ADIM); }, [ + searchQuery, selectedCity, selectedAlimTuru, selectedSektorler, + selectedCpvler, selectedKurumTipi, quickFilter, sortBy, + ]); + + const dahaGoster = useCallback(() => { + setGosterilen((n) => Math.min(n + SAYFA_ADIM, filteredTenders.length)); + }, [filteredTenders.length]); + + // Dipteki işaretçi görünür olunca yükle. IntersectionObserver yoksa + // (eski tarayıcı) aşağıdaki "Daha fazla göster" düğmesi devreye girer. + useEffect(() => { + const el = dipRef.current; + if (!el || !dahaVar || typeof IntersectionObserver === 'undefined') return; + const gozlemci = new IntersectionObserver( + (girisler) => { if (girisler[0]?.isIntersecting) dahaGoster(); }, + { rootMargin: '600px 0px' }, // ekrana girmeden önce yükle + ); + gozlemci.observe(el); + return () => gozlemci.disconnect(); + }, [dahaVar, dahaGoster]); const handleExportExcel = () => { confetti({ particleCount: 80, spread: 60, origin: { y: 0.6 } }); @@ -128,7 +157,7 @@ export const TenderList = () => { {/* Tender Cards List */} - {paginatedTenders.length === 0 ? ( + {gorunenTenders.length === 0 ? (
+ Tüm kayıtlar gösterildi — {filteredTenders.length.toLocaleString('tr-TR')} ihale +
+ )}