Group navigation by discovery preparation market and management

This commit is contained in:
2026-09-06 13:28:31 +03:00
parent 30ce6e3a6c
commit ff3fa2c3ab
4 changed files with 50 additions and 6 deletions
+23 -4
View File
@@ -27,6 +27,13 @@ const RENK = {
};
const RENK_VARSAYILAN = { ikon: 'text-slate-500', aktif: 'border-blue-200 bg-blue-50 text-blue-700', hover: 'hover:bg-slate-50' };
const NAV_GROUPS = [
{id:'discover',label:'Keşfet',tabs:['list','bulten','takvim','ted_eu']},
{id:'prepare',label:'Hazırlan',tabs:['kanban','dokuman_deposu','kdv','sinir','kik_kararlari']},
{id:'market',label:'Pazar',tabs:['sonuc','sozlesme','fiyat','rakip_radar','analitik_dashboard','kirmizi_bayrak']},
{id:'manage',label:'Yönetim',tabs:['planlar','api_webhooks','pwa_settings','ai_ayarlari']},
];
export const TopNavigation = () => {
const { activeTab, setActiveTab, isAdmin } = useApp();
@@ -66,6 +73,9 @@ export const TopNavigation = () => {
{ id: 'pwa_settings', label: 'Mobil PWA', icon: Smartphone }
];
const activeGroup=NAV_GROUPS.find(group=>group.tabs.includes(bekleyen || activeTab)) || NAV_GROUPS[0];
const visibleItems=activeGroup.tabs.map(id=>navItems.find(item=>item.id===id)).filter(Boolean);
// 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.
@@ -97,7 +107,8 @@ export const TopNavigation = () => {
useEffect(() => {
const el = seritRef.current?.querySelector(`[data-tab="${activeTab}"]`);
el?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
}, [activeTab]);
tasmaHesapla();
}, [activeTab, activeGroup.id, tasmaHesapla]);
const kaydir = (yon) => {
seritRef.current?.scrollBy({ left: yon * 280, behavior: 'smooth' });
@@ -105,6 +116,13 @@ export const TopNavigation = () => {
return (
<div className="bg-white border-b border-slate-200 shadow-xs sticky top-16 z-30">
<nav aria-label="Çalışma alanları" className="max-w-[1600px] mx-auto px-4 pt-2 flex flex-wrap gap-2">
{NAV_GROUPS.map(group=><button key={group.id} type="button" aria-pressed={group.id===activeGroup.id}
onClick={()=>{if(group.id!==activeGroup.id)sekmeSec(group.tabs.find(id=>navItems.some(item=>item.id===id)));}}
className={`px-4 py-2 rounded-lg text-sm font-bold border ${group.id===activeGroup.id ? 'bg-slate-900 text-white border-slate-900' : 'border-slate-200 text-slate-700 hover:bg-slate-50'}`}>
{group.label}
</button>)}
</nav>
<div className="max-w-[1600px] mx-auto px-4 relative">
{tasma.sol && (
<button
@@ -126,8 +144,8 @@ export const TopNavigation = () => {
<ChevronRight className="w-4 h-4" />
</button>
)}
<div ref={seritRef} className="flex items-center gap-1 overflow-x-auto py-1 scrollbar-none scroll-smooth">
{navItems.map(item => {
<nav aria-label={`${activeGroup.label} araçları`} ref={seritRef} className="flex items-center gap-1 overflow-x-auto py-1 scrollbar-none scroll-smooth">
{visibleItems.map(item => {
const Icon = item.icon;
const renk = RENK[item.id] || RENK_VARSAYILAN;
const isActive = bekleyen ? bekleyen === item.id : activeTab === item.id;
@@ -136,6 +154,7 @@ export const TopNavigation = () => {
<button
key={item.id}
data-tab={item.id}
aria-current={isActive ? 'page' : undefined}
aria-busy={yukleniyor || undefined}
onClick={() => sekmeSec(item.id)}
className={`flex items-center gap-2 px-3.5 py-2 rounded-lg border text-xs font-semibold whitespace-nowrap transition-all select-none ${
@@ -156,7 +175,7 @@ export const TopNavigation = () => {
</button>
);
})}
</div>
</nav>
</div>
</div>
);