import React, { useState, useRef, useEffect } from 'react'; import { Link } from 'react-router-dom'; import { useTheme } from '../context/ThemeContext.jsx'; import { FileDiff, GitPullRequest, Network, ShieldCheck, Files, Database, History, Key, Search, User, LogOut, ExternalLink, ChevronDown, Layers, CheckCircle2, Copy, Lock, Cpu, Plus, RefreshCw, Sparkles, Terminal, Grid, ArrowLeft, Sun, Moon, Settings, Users, Globe } from 'lucide-react'; import NotificationsCenter from './NotificationsCenter'; export default function Navbar({ workspaces, currentWorkspace, onSelectWorkspace, onCreateWorkspace, activeTab, onSelectTab, stats, currentUser, onLogout, onRefresh, refreshing, proposals = [], diff = null, onOpenAccessModal, onOpenGlobalSearch, onOpenUserProfile, showToast = () => {} }) { const { theme, toggleTheme } = useTheme(); const [showWsDropdown, setShowWsDropdown] = useState(false); const [copiedApiKey, setCopiedApiKey] = useState(false); const handleCopyApiKey = () => { const tok = localStorage.getItem("diffweave_token") || localStorage.getItem("token") || ""; if (tok) { navigator.clipboard.writeText(tok); setCopiedApiKey(true); setTimeout(() => setCopiedApiKey(false), 2000); } else { alert("No active API token found. Please sign in."); } }; const [showCreateModal, setShowCreateModal] = useState(false); const [newWsName, setNewWsName] = useState(''); const [showUserDropdown, setShowUserDropdown] = useState(false); const wsDropdownRef = useRef(null); const userDropdownRef = useRef(null); // Close dropdowns when clicking anywhere outside useEffect(() => { function handleClickOutside(event) { if (wsDropdownRef.current && !wsDropdownRef.current.contains(event.target)) { setShowWsDropdown(false); } if (userDropdownRef.current && !userDropdownRef.current.contains(event.target)) { setShowUserDropdown(false); } } document.addEventListener('mousedown', handleClickOutside); document.addEventListener('touchstart', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('touchstart', handleClickOutside); }; }, []); const handleCreate = async (e) => { e.preventDefault(); const cleanName = newWsName.trim(); if (!cleanName) return; const isDuplicate = (workspaces || []).some( (w) => w.name && w.name.trim().toLowerCase() === cleanName.toLowerCase() ); if (isDuplicate) { alert(`A workspace named "${cleanName}" already exists. Workspace names must be unique.`); return; } await onCreateWorkspace(cleanName); setNewWsName(''); setShowCreateModal(false); }; const totalDocs = stats?.total_documents ?? currentWorkspace?.d_count ?? 0; const verifiedFacts = stats?.knowledge_items ?? stats?.total_knowledge_items ?? currentWorkspace?.k_count ?? 0; // Reactively compute pending PR count from live proposals prop const pendingProposalsCount = (proposals && proposals.length > 0) ? proposals.filter((p) => !p.status || p.status.toUpperCase() === 'PENDING').length : (stats?.pending_proposals ?? 0); // Reactively compute pending diff deltas from live diff prop const pendingDiffDeltasCount = diff ? ((diff.additions?.length || 0) + (diff.changes?.length || 0) + (diff.conflicts?.length || 0) + (diff.removals?.length || 0)) : pendingProposalsCount; const tabs = [ { id: 'diff', label: 'Semantic Diff', icon: FileDiff, badge: pendingDiffDeltasCount > 0 ? `${pendingDiffDeltasCount}` : null }, { id: 'prs', label: 'PR Review Deck', icon: GitPullRequest, badge: pendingProposalsCount > 0 ? `${pendingProposalsCount} pending` : null }, { id: 'graph', label: 'Knowledge Graph', icon: Network }, { id: 'staging', label: 'Ingestion Staging', icon: Files, badge: totalDocs > 0 ? `${totalDocs} docs` : null }, { id: 'rules', label: 'Policy Rules CI', icon: ShieldCheck }, { id: 'knowledge', label: 'Truth Register', icon: Database, badge: verifiedFacts > 0 ? `${verifiedFacts} facts` : null }, { id: 'audit', label: 'Audit & Provenance', icon: History }, { id: 'quickstart', label: 'CLI Quickstart', icon: Terminal }, ]; return (
{/* --------------------------------------------------------------------- */} {/* TIER 1: Global Platform Bar (#010409) */} {/* --------------------------------------------------------------------- */}
{/* Left: Brand Logo & Workspace Switcher */}
onSelectWorkspace && onSelectWorkspace(null)} className="flex items-center space-x-2.5 cursor-pointer group" title="Return to Workspaces Hub" >
DiffWeave Document Git Platform
/ {/* Hub Link Button */} onSelectWorkspace && onSelectWorkspace(null)} className={`hidden sm:flex items-center space-x-1.5 px-2.5 py-1 rounded-md border text-xs font-semibold transition ${ !currentWorkspace ? 'bg-emerald-500/10 border-emerald-500/30 text-emerald-400' : 'bg-[#161B22] hover:bg-[#21262D] border-[#30363D] text-slate-300 hover:text-white' }`} > Workspaces {/* Workspace Dropdown */}
{showWsDropdown && (
Document Workspaces ({workspaces.length})
{workspaces.map((w) => ( { setShowWsDropdown(false); onSelectWorkspace && onSelectWorkspace(w); }} className={`w-full text-left px-2.5 py-1.5 rounded text-xs transition flex items-center justify-between ${ currentWorkspace?.id === w.id ? 'bg-emerald-500/20 text-emerald-300 font-bold' : 'text-slate-300 hover:bg-[#21262D] hover:text-white' }`} >

{w.name}

{w.d_count ?? 0} docs • {w.k_count ?? 0} facts
{currentWorkspace?.id === w.id && ( )} ))}
setShowWsDropdown(false)} className="w-full text-left px-2 py-1.5 rounded text-xs text-emerald-400 hover:bg-[#21262D] font-semibold flex items-center space-x-1.5 no-underline" > New Document Workspace...
)}
{/* Right: Search, FastMCP Bridge status, Theme Quick Toggle & User Profile */}
{/* Global Search Trigger (Ctrl+K) */} {/* FastMCP Connected Pill */}
FastMCP: Active
{/* Dynamic Real-Time Notifications Center (YouTube style) */} {/* Quick Light/Dark Mode Toggle */} {/* User Menu */} {currentUser ? (
{showUserDropdown && (

{currentUser.username || 'User'}

{currentUser.email || 'user@docweave.io'}

setShowUserDropdown(false)} className="w-full text-left px-2 py-1.5 rounded text-slate-300 hover:bg-[#21262D] flex items-center space-x-2" > Workspaces Hub setShowUserDropdown(false)} className="w-full text-left px-2 py-1.5 rounded text-slate-300 hover:bg-[#21262D] flex items-center space-x-2" > Platform Settings
)}
) : ( Sign In )}
{/* --------------------------------------------------------------------- */} {/* TIER 2: Workspace Document Context Header (#0D1117) - If Workspace Active */} {/* --------------------------------------------------------------------- */} {currentWorkspace && ( <>
{/* Workspace Title & Badge */}
onSelectWorkspace && onSelectWorkspace(null)} className="p-1 rounded-md hover:bg-[#161B22] text-slate-400 hover:text-white transition" title="Back to All Workspaces" >
{currentWorkspace?.name} Deterministic RAG {/* Visibility Badge (Clickable to open Share/Access Modal) */}
{/* Real Document Platform KPI Badges & Access Controls */}
{/* Share / Access Management Button */}
Tracked Docs: {totalDocs}
Verified Truth: {verifiedFacts}
{/* ----------------------------------------------------------------- */} {/* TIER 3: Workspace Navigation Tabs (GitHub-style deep Link tabs) */} {/* ----------------------------------------------------------------- */} )}
); }