import React, { useRef, useState, useEffect, useCallback, useTransition } from 'react'; import { useApp } from '../context/AppContext'; import { Newspaper, Trophy, CalendarDays, FileCheck2, Calculator, TrendingUp, LayoutGrid, Kanban, Radar, FolderKanban, BarChart3, Webhook, Smartphone, Cpu, ShieldAlert, Globe2, Gavel, CreditCard, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react'; export const TopNavigation = () => { const { activeTab, setActiveTab, isAdmin } = useApp(); // Ağır sekmeler (10 bin+ kayıtlı havuzda Kanban, analiz vb.) tıklamadan // sonra saniyelerce hiçbir tepki vermiyordu — kullanıcı "tıklanmıyor" sanıyordu. // Sekme değişimi geçiş (transition) olarak yapılır: tıklanan sekme ANINDA // vurgulanır ve dönen simge gösterilir, ağır görünüm arka planda hazırlanır. const [isPending, startTransition] = useTransition(); const [hedefTab, setHedefTab] = useState(null); const sekmeSec = (id) => { if (id === activeTab) return; setHedefTab(id); startTransition(() => setActiveTab(id)); }; const bekleyen = isPending ? hedefTab : null; const navItems = [ { id: 'list', label: 'Ana İhale Listesi', icon: LayoutGrid }, { id: 'bulten', label: 'Günlük Bülten', icon: Newspaper }, { id: 'sonuc', label: 'Sonuç Sorgula', icon: Trophy }, { id: 'takvim', label: 'İhale Takvimi', icon: CalendarDays }, { id: 'sozlesme', label: 'Sözleşme Sorgula', icon: FileCheck2 }, { id: 'kdv', label: 'KDV Hesapla', icon: Calculator }, { id: 'sinir', label: 'Sınır Değer', icon: Calculator }, { id: 'fiyat', label: 'Fiyat Analizi', icon: TrendingUp }, { id: 'kanban', label: 'Kanban Pano', icon: Kanban, badge: 'Sürükle Takip' }, { id: 'rakip_radar', label: 'Rakip Radar', icon: Radar, badge: 'Canlı Uyar' }, { id: 'dokuman_deposu', label: 'Doküman Deposu', icon: FolderKanban }, { id: 'analitik_dashboard', label: 'Analitik Dashboard', icon: BarChart3 }, { id: 'kirmizi_bayrak', label: 'Kırmızı Bayrak', icon: ShieldAlert, badge: 'Şeffaflık' }, { id: 'kik_kararlari', label: 'KİK Kurul Kararları', icon: Gavel }, { id: 'ted_eu', label: 'AB İhaleleri (TED)', icon: Globe2 }, { id: 'planlar', label: 'Planlar', icon: CreditCard }, { id: 'api_webhooks', label: 'API & Webhooks', icon: Webhook }, // Sadece admin: AI Model Ayarları ...(isAdmin ? [{ id: 'ai_ayarlari', label: 'AI Model Ayarları', icon: Cpu, badge: 'Admin' }] : []), { id: 'pwa_settings', label: 'Mobil PWA', icon: Smartphone } ]; // 18 sekme çoğu ekrana sığmıyor. Kaydırma çubuğu gizli olduğu için sondaki // sekmeler (Planlar, API & Webhooks, Mobil PWA) görünmez kalıyordu; taşma // olduğunda ok düğmeleri gösterilir ve etkin sekme görünür alana kaydırılır. const seritRef = useRef(null); const [tasma, setTasma] = useState({ sol: false, sag: false }); const tasmaHesapla = useCallback(() => { const el = seritRef.current; if (!el) return; setTasma({ sol: el.scrollLeft > 4, sag: el.scrollLeft + el.clientWidth < el.scrollWidth - 4, }); }, []); useEffect(() => { tasmaHesapla(); const el = seritRef.current; if (!el) return; el.addEventListener('scroll', tasmaHesapla, { passive: true }); window.addEventListener('resize', tasmaHesapla); return () => { el.removeEventListener('scroll', tasmaHesapla); window.removeEventListener('resize', tasmaHesapla); }; }, [tasmaHesapla]); // Etkin sekme (ör. menüden 'Planlar' seçilince) görünür alana getirilir. useEffect(() => { const el = seritRef.current?.querySelector(`[data-tab="${activeTab}"]`); el?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' }); }, [activeTab]); const kaydir = (yon) => { seritRef.current?.scrollBy({ left: yon * 280, behavior: 'smooth' }); }; return (
{tasma.sol && ( )} {tasma.sag && ( )}
{navItems.map(item => { const Icon = item.icon; const isActive = bekleyen ? bekleyen === item.id : activeTab === item.id; const yukleniyor = bekleyen === item.id; return ( ); })}
); };