feat: ilan ve ihale tarihi etiketli gosteriliyor + 'sadece acik ihaleler' filtresi gercekten calisiyor (varsayilan acik)

This commit is contained in:
2026-08-30 17:58:26 +03:00
parent 14f24e00f4
commit ac77146f73
5 changed files with 77 additions and 8 deletions
+35 -2
View File
@@ -8,6 +8,14 @@ import confetti from 'canvas-confetti';
// filtre büyük-küçük harf ve Türkçe karakter duyarlılığına takılmasın.
const normTr = (v) => String(v || '').trim().toLocaleUpperCase('tr-TR');
// "gg.aa.yyyy" → Date. Ayrıştırılamayanı GEÇMİŞ SAYMAYIZ: tarihi belirsiz bir
// ihaleyi sessizce gizlemek, geçmiş bir ihaleyi göstermekten daha kötüdür.
const ihaleGunu = (v) => {
const m = /^(\d{2})\.(\d{2})\.(\d{4})/.exec(String(v || '').trim());
if (!m) return null;
return new Date(Number(m[3]), Number(m[2]) - 1, Number(m[1]));
};
export const TenderList = () => {
const {
tenders,
@@ -19,6 +27,7 @@ export const TenderList = () => {
selectedKurumTipi,
quickFilter,
onlyValidOnly,
setOnlyValidOnly,
favoriteKurumlar
} = useApp();
@@ -30,6 +39,9 @@ export const TenderList = () => {
const [gosterilen, setGosterilen] = useState(SAYFA_ADIM);
const dipRef = useRef(null);
// Bugünün başlangıcı — "bugün ihalesi olan" listede kalsın.
const bugun = useMemo(() => { const d = new Date(); d.setHours(0, 0, 0, 0); return d; }, []);
// Filter logic
const filteredTenders = useMemo(() => {
return tenders.filter(tender => {
@@ -43,6 +55,13 @@ export const TenderList = () => {
if (!matchTitle && !matchKurum && !matchIkn && !matchItems) return false;
}
// Geçmiş ihaleler: varsayılan olarak GİZLİ. Kullanıcı "geçmişi de göster"
// derse (onlyValidOnly=false) hepsi gelir. Tarihi okunamayan kayıt gizlenmez.
if (onlyValidOnly) {
const gun = ihaleGunu(tender.tarih);
if (gun && gun < bugun) return false;
}
// Quick Filter
if (quickFilter === 'favori_kurumlar' && !(favoriteKurumlar || []).includes((tender.kurum || '').trim())) return false;
if (quickFilter === 'dogrudan_temin' && tender.alimTuru !== 'Doğrudan Temin') return false;
@@ -68,7 +87,7 @@ export const TenderList = () => {
if (sortBy === 'distant') return b.tarih.localeCompare(a.tarih);
return 0;
});
}, [tenders, searchQuery, selectedCity, selectedAlimTuru, selectedSektorler, selectedCpvler, selectedKurumTipi, quickFilter, sortBy]);
}, [tenders, searchQuery, selectedCity, selectedAlimTuru, selectedSektorler, selectedCpvler, selectedKurumTipi, quickFilter, sortBy, onlyValidOnly, bugun]);
const gorunenTenders = filteredTenders.slice(0, gosterilen);
const dahaVar = gosterilen < filteredTenders.length;
@@ -78,7 +97,7 @@ export const TenderList = () => {
// başına fırlardı.
useEffect(() => { setGosterilen(SAYFA_ADIM); }, [
searchQuery, selectedCity, selectedAlimTuru, selectedSektorler,
selectedCpvler, selectedKurumTipi, quickFilter, sortBy,
selectedCpvler, selectedKurumTipi, quickFilter, sortBy, onlyValidOnly,
]);
const dahaGoster = useCallback(() => {
@@ -136,6 +155,20 @@ export const TenderList = () => {
</div>
<div className="flex items-center gap-3 w-full sm:w-auto">
{/* Varsayılan: yalnızca ihale tarihi geçmemiş ilanlar */}
<label
className="flex items-center gap-1.5 text-xs font-semibold text-slate-700 cursor-pointer select-none whitespace-nowrap"
title="Kapalı: ihale tarihi geçmiş ilanlar da listelenir"
>
<input
type="checkbox"
checked={onlyValidOnly}
onChange={(e) => setOnlyValidOnly(e.target.checked)}
className="accent-blue-600"
/>
Sadece açık ihaleler
</label>
<select
value={sortBy}
onChange={(e) => setSortBy(e.target.value)}