feat: tüm mock veriyi kaldır + Resend e-posta entegrasyonu
- mockTenders.js silindi; referans listeleri (sektör/il/kurum) constants.js'e taşındı - AppContext: tenders/liveStats/competitorWatchlist/vaultDocuments/notifications/ savedFilters/apiKeys/scrapedCapabilities → gerçek/boş; sahte Math.random online sayacı kaldırıldı; competitor & belge kasası artık localStorage - LiveStatsBar: gerçek alanlar (canlı havuz/yüklü/bugün/kalem/takibimdeki) - AnalyticsDashboard: KPI'lar (katılım/kazanma oranı/kazanılan bedel) + aylık hacim + sektörel dağılım gerçek companyStats/monthlyStats/sectorStats'tan; ciro hedefi kullanıcı tarafından belirlenir; veri yoksa dürüst boş durum - ContractSearch & Rakip Radar: gerçek firmStats - analytics.js: companyStats/monthlyStats/parseDateTR eklendi - Resend: server/email.mjs + /api/notify/email/config + /api/notify/email/test (auth'lu, kullanıcının kendi adresine); PwaSettings gerçek e-posta test kartı
This commit is contained in:
@@ -1,42 +1,39 @@
|
||||
import React from 'react';
|
||||
import { useApp } from '../context/AppContext';
|
||||
import { Database, PlusCircle, Eye } from 'lucide-react';
|
||||
import { Database, PlusCircle, Eye, Layers } from 'lucide-react';
|
||||
|
||||
export const LiveStatsBar = () => {
|
||||
const { liveStats } = useApp();
|
||||
const { liveStats, tenders } = useApp();
|
||||
|
||||
const yukluIhale = tenders.length;
|
||||
const takibimdeki = tenders.filter((t) => t.takipte).length;
|
||||
const kalemSayisi = tenders.reduce((s, t) => s + (t.items?.length || 0), 0);
|
||||
|
||||
const stats = [
|
||||
{ deger: liveStats.toplamIhale, etiket: 'Canlı İhale Havuzu', renk: 'text-white', dot: true },
|
||||
{ deger: yukluIhale, etiket: 'Yüklü İhale', renk: 'text-white', icon: Database, iconRenk: 'text-blue-400' },
|
||||
{ deger: liveStats.bugunEklenen, etiket: 'Bugün Eklenen', renk: 'text-emerald-400', icon: PlusCircle, iconRenk: 'text-emerald-400' },
|
||||
{ deger: kalemSayisi, etiket: 'Kalem', renk: 'text-white', icon: Layers, iconRenk: 'text-indigo-400' },
|
||||
{ deger: takibimdeki, etiket: 'Takibimdeki', renk: 'text-white', icon: Eye, iconRenk: 'text-amber-400' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="bg-[#111827] text-slate-300 py-1.5 px-4 text-xs font-medium border-b border-slate-800 shadow-inner">
|
||||
<div className="max-w-[1600px] mx-auto flex items-center justify-center gap-6 sm:gap-10 flex-wrap">
|
||||
|
||||
{/* Online Kullanıcı */}
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span className="font-bold text-white tracking-wide">{liveStats.onlineKullanici.toLocaleString('tr-TR')}</span>
|
||||
<span className="text-slate-400">Online Kullanıcı</span>
|
||||
</div>
|
||||
|
||||
{/* Toplam Kalem */}
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Database className="w-3.5 h-3.5 text-blue-400" />
|
||||
<span className="font-bold text-white tracking-wide">{liveStats.toplamKalem.toLocaleString('tr-TR')}</span>
|
||||
<span className="text-slate-400">Toplam Kalem</span>
|
||||
</div>
|
||||
|
||||
{/* Bugün Eklenen */}
|
||||
<div className="flex items-center gap-1.5">
|
||||
<PlusCircle className="w-3.5 h-3.5 text-emerald-400" />
|
||||
<span className="font-bold text-emerald-400 tracking-wide">{liveStats.bugunEklenen.toLocaleString('tr-TR')}</span>
|
||||
<span className="text-slate-400">Bugün Eklenen</span>
|
||||
</div>
|
||||
|
||||
{/* Aktif Takip */}
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Eye className="w-3.5 h-3.5 text-amber-400" />
|
||||
<span className="font-bold text-white tracking-wide">{liveStats.aktifTakip.toLocaleString('tr-TR')}</span>
|
||||
<span className="text-slate-400">Aktif Takip</span>
|
||||
</div>
|
||||
|
||||
{stats.map((s) => {
|
||||
const Icon = s.icon;
|
||||
return (
|
||||
<div key={s.etiket} className="flex items-center gap-1.5">
|
||||
{s.dot ? (
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
) : (
|
||||
<Icon className={`w-3.5 h-3.5 ${s.iconRenk}`} />
|
||||
)}
|
||||
<span className={`font-bold ${s.renk} tracking-wide`}>{(s.deger || 0).toLocaleString('tr-TR')}</span>
|
||||
<span className="text-slate-400">{s.etiket}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user