Files
ihaleist/src/components/SummaryCards.jsx
T

105 lines
3.6 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useDeadlineClock } from '../hooks/useDeadlineClock';
import React, { useMemo } from 'react';
import { useApp } from '../context/AppContext';
import { Layers, CalendarPlus, Star, BellRing, EyeOff } from 'lucide-react';
import { acikIhale, hizliFiltreGecer } from '../services/ihaleTarih';
export const SummaryCards = () => {
const now = useDeadlineClock();
const { tenders, quickFilter, setQuickFilter, setActiveTab, oncekiGiris, favoriteKurumlar } = useApp();
// Sayımlar listedeki filtreyle AYNI ölçütü kullanır (ihaleTarih.js); karta
// tıklayınca gelen liste ile karttaki sayı birbirini tutar.
const sayim = useMemo(() => {
const secenek = { favoriteKurumlar: favoriteKurumlar || [], oncekiGirisMs: oncekiGiris };
const say = (id) => tenders.filter((t) => acikIhale(t, now) && hizliFiltreGecer(t, id, secenek)).length;
return {
all: say('all'),
bugun_eklenenler: say('bugun_eklenenler'),
takiptekiler: say('takiptekiler'),
son_giris: say('son_giris'),
incelenmedi: say('incelenmedi'),
};
}, [tenders, oncekiGiris, favoriteKurumlar, now]);
const cards = [
{
id: 'all',
label: 'AKTİF İHALELER',
count: sayim.all,
icon: Layers,
color: 'blue'
},
{
id: 'bugun_eklenenler',
label: 'BUGÜN EKLENENLER',
count: sayim.bugun_eklenenler,
icon: CalendarPlus,
color: 'emerald'
},
{
id: 'takiptekiler',
label: 'TAKİP ETTİKLERİM',
count: sayim.takiptekiler,
icon: Star,
color: 'amber'
},
{
id: 'son_giris',
label: 'SON GİRİŞTEN BERİ',
count: sayim.son_giris,
icon: BellRing,
color: 'purple',
title: oncekiGiris
? `Önceki ziyaretinizden (${new Date(oncekiGiris).toLocaleString('tr-TR')}) sonra yayımlanan ilanlar`
: 'İlk ziyaretiniz — bugün yayımlanan ilanlar gösteriliyor'
},
{
id: 'incelenmedi',
label: 'İNCELENMEMİŞ',
count: sayim.incelenmedi,
icon: EyeOff,
color: 'rose'
}
];
return (
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3.5 my-4">
{cards.map(card => {
const Icon = card.icon;
const isSelected = quickFilter === card.id;
return (
<div
key={card.id}
title={card.title}
onClick={() => {
setQuickFilter(card.id);
setActiveTab('list');
}}
className={`bg-white rounded-xl p-4 border transition-all cursor-pointer select-none shadow-xs flex flex-wrap gap-2 items-center justify-between group hover:shadow-md ${
isSelected
? 'border-blue-600 ring-2 ring-blue-500/20 bg-blue-50/20'
: 'border-slate-200 hover:border-slate-300'
}`}
>
<div>
<p className="text-[11px] font-bold tracking-wider text-slate-500 uppercase">{card.label}</p>
<p className="text-2xl font-black text-slate-900 mt-1">{card.count.toLocaleString('tr-TR')}</p>
</div>
<div className={`w-11 h-11 rounded-xl flex items-center justify-center transition-transform group-hover:scale-105 ${
card.color === 'blue' ? 'bg-blue-100 text-blue-600' :
card.color === 'emerald' ? 'bg-emerald-100 text-emerald-600' :
card.color === 'amber' ? 'bg-amber-100 text-amber-600' :
card.color === 'purple' ? 'bg-purple-100 text-purple-600' :
'bg-rose-100 text-rose-600'
}`}>
<Icon className="w-5 h-5" />
</div>
</div>
);
})}
</div>
);
};