adding base project

This commit is contained in:
Azmat-7860
2026-10-07 09:07:57 +05:30
commit dc69f693f0
43 changed files with 5193 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
import React, { useState, useRef, useEffect } from 'react';
import { Menu, Search, Bell, User as UserIcon, LogOut, ShieldCheck, ChevronDown } from 'lucide-react';
import { useAuth } from '../../context/AuthContext';
import { ThemeToggle } from './ThemeToggle';
import './layout.css';
export function Header({ setMobileOpen }) {
const { user, logout, isDemoMode } = useAuth();
const [dropdownOpen, setDropdownOpen] = useState(false);
const dropdownRef = useRef(null);
// Close dropdown on click outside
useEffect(() => {
function handleClickOutside(event) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setDropdownOpen(false);
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
return (
<header className="dashboard-header">
{/* Left: Mobile hamburger & Search */}
<div className="header-left">
<button
className="mobile-menu-btn"
onClick={() => setMobileOpen(true)}
aria-label="Open navigation menu"
>
<Menu size={22} />
</button>
<div className="header-search">
<Search size={18} className="header-search-icon" />
<input
type="text"
className="header-search-input"
placeholder="Search workspaces, logs, users..."
/>
</div>
</div>
{/* Right: Actions, Theme, User */}
<div className="header-right">
{/* Backend Connectivity Status Badge */}
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '6px',
fontSize: '0.8rem',
padding: '4px 10px',
borderRadius: 'var(--radius-full)',
background: isDemoMode ? 'var(--color-warning-bg)' : 'var(--color-success-bg)',
color: isDemoMode ? 'var(--color-warning)' : 'var(--color-success)',
border: `1px solid ${isDemoMode ? 'rgba(245, 158, 11, 0.3)' : 'rgba(16, 185, 129, 0.3)'}`,
}}
title={isDemoMode ? 'Running in Standalone Demo Mode' : 'Connected to Spring Boot API'}
>
<span
style={{
width: 7,
height: 7,
borderRadius: '50%',
backgroundColor: isDemoMode ? 'var(--color-warning)' : 'var(--color-success)',
}}
/>
<span>{isDemoMode ? 'Demo Sandbox' : 'Backend Live'}</span>
</div>
{/* Theme Switcher */}
<ThemeToggle />
{/* Notifications */}
<button className="header-btn" title="Recent security alerts">
<Bell size={18} />
<span className="header-badge-dot" />
</button>
{/* User Dropdown */}
<div className="profile-dropdown-wrapper" ref={dropdownRef}>
<button
className="profile-trigger-btn"
onClick={() => setDropdownOpen(!dropdownOpen)}
aria-expanded={dropdownOpen}
>
<div className="sidebar-user-avatar" style={{ width: 30, height: 30, fontSize: '0.75rem' }}>
{(user?.firstName?.[0] || 'A')}
</div>
<span style={{ fontSize: '0.85rem', fontWeight: 600 }}>
{user?.firstName || 'User'}
</span>
<ChevronDown size={14} color="var(--text-muted)" />
</button>
{dropdownOpen && (
<div className="profile-dropdown-menu animate-fade-in">
<div style={{ padding: '8px 12px', borderBottom: '1px solid var(--border-subtle)' }}>
<p style={{ fontSize: '0.825rem', fontWeight: 700 }}>{user?.fullname || user?.firstName}</p>
<p style={{ fontSize: '0.75rem', color: 'var(--text-muted)' }}>{user?.email}</p>
</div>
<div className="dropdown-item" onClick={() => setDropdownOpen(false)}>
<UserIcon size={16} />
<span>Profile Settings</span>
</div>
<div className="dropdown-item" onClick={() => setDropdownOpen(false)}>
<ShieldCheck size={16} />
<span>Security Token Info</span>
</div>
<div
className="dropdown-item danger"
onClick={() => {
setDropdownOpen(false);
logout();
}}
>
<LogOut size={16} />
<span>Sign Out</span>
</div>
</div>
)}
</div>
</div>
</header>
);
}