feat: Add admin bar with grouped dropdowns, clean user menu

- Add dark admin bar below main navigation (visible only for admins)
- Group admin functions into 3 dropdowns: Zarządzanie, Audyty, Analityka
- Remove admin links from user dropdown menu
- Keep user menu clean with only personal items

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-09 20:18:58 +01:00
parent 2035f46f07
commit 23aefe1054

View File

@ -369,6 +369,127 @@
color: var(--primary); color: var(--primary);
} }
/* Admin Bar */
.admin-bar {
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
border-bottom: 1px solid rgba(255,255,255,0.1);
padding: 0 var(--spacing-md);
}
.admin-bar-inner {
max-width: 1400px;
margin: 0 auto;
display: flex;
align-items: center;
gap: var(--spacing-xs);
}
.admin-bar-label {
display: flex;
align-items: center;
gap: 6px;
color: rgba(255,255,255,0.7);
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 10px 12px 10px 0;
border-right: 1px solid rgba(255,255,255,0.15);
margin-right: var(--spacing-xs);
}
.admin-bar-label svg {
width: 14px;
height: 14px;
opacity: 0.8;
}
.admin-dropdown {
position: relative;
}
.admin-dropdown-trigger {
display: flex;
align-items: center;
gap: 4px;
padding: 10px 14px;
color: rgba(255,255,255,0.85);
font-size: 13px;
font-weight: 500;
background: transparent;
border: none;
cursor: pointer;
transition: all 0.15s ease;
border-radius: var(--radius);
}
.admin-dropdown-trigger:hover {
background: rgba(255,255,255,0.1);
color: #fff;
}
.admin-dropdown-trigger svg {
width: 12px;
height: 12px;
opacity: 0.6;
transition: transform 0.15s ease;
}
.admin-dropdown:hover .admin-dropdown-trigger svg {
transform: rotate(180deg);
}
.admin-dropdown-menu {
display: none;
position: absolute;
top: 100%;
left: 0;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
min-width: 180px;
padding: var(--spacing-xs) 0;
z-index: 300;
}
.admin-dropdown:hover .admin-dropdown-menu {
display: block;
}
.admin-dropdown-menu a {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
color: var(--text-primary);
text-decoration: none;
font-size: 13px;
transition: all 0.15s ease;
}
.admin-dropdown-menu a:hover {
background: var(--background);
color: var(--primary);
}
.admin-dropdown-menu a svg {
width: 16px;
height: 16px;
color: var(--text-secondary);
flex-shrink: 0;
}
.admin-dropdown-menu a:hover svg {
color: var(--primary);
}
@media (max-width: 768px) {
.admin-bar {
display: none;
}
}
/* Mobile menu toggle */ /* Mobile menu toggle */
.nav-toggle { .nav-toggle {
display: none; display: none;
@ -851,21 +972,6 @@
Wiadomości Wiadomości
<span class="user-menu-badge" id="userMenuUnreadBadge" style="display: none;">0</span> <span class="user-menu-badge" id="userMenuUnreadBadge" style="display: none;">0</span>
</a> </a>
{% if current_user.is_admin %}
<div class="user-menu-divider"></div>
<div class="user-menu-section">Admin</div>
<a href="{{ url_for('admin_users') }}" class="user-menu-item">Użytkownicy</a>
<a href="{{ url_for('admin_recommendations') }}" class="user-menu-item">Rekomendacje</a>
<a href="{{ url_for('admin_fees') }}" class="user-menu-item">Składki członkowskie</a>
<a href="{{ url_for('admin_calendar') }}" class="user-menu-item">Kalendarz</a>
<a href="{{ url_for('admin_social_media') }}" class="user-menu-item">Social Media</a>
<a href="{{ url_for('admin_seo') }}" class="user-menu-item">Audyt SEO</a>
<a href="{{ url_for('admin_it_audit') }}" class="user-menu-item">Audyt IT</a>
<a href="{{ url_for('admin_gbp_audit') }}" class="user-menu-item">Audyt GBP</a>
<a href="{{ url_for('admin_social_audit') }}" class="user-menu-item">Audyt Social</a>
<a href="{{ url_for('chat_analytics') }}" class="user-menu-item">Analityka Chatu</a>
<a href="{{ url_for('debug_panel') }}" class="user-menu-item">Debug Panel</a>
{% endif %}
<div class="user-menu-divider"></div> <div class="user-menu-divider"></div>
<a href="{{ url_for('release_notes') }}" class="user-menu-item"> <a href="{{ url_for('release_notes') }}" class="user-menu-item">
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@ -890,6 +996,123 @@
</div> </div>
</header> </header>
{% if current_user.is_authenticated and current_user.is_admin %}
<!-- Admin Bar -->
<div class="admin-bar">
<div class="admin-bar-inner">
<div class="admin-bar-label">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
</svg>
Admin
</div>
<!-- Zarządzanie -->
<div class="admin-dropdown">
<button class="admin-dropdown-trigger">
Zarządzanie
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
<div class="admin-dropdown-menu">
<a href="{{ url_for('admin_users') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
</svg>
Użytkownicy
</a>
<a href="{{ url_for('admin_fees') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
Składki
</a>
<a href="{{ url_for('admin_recommendations') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"/>
</svg>
Rekomendacje
</a>
<a href="{{ url_for('admin_calendar') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
Kalendarz
</a>
<a href="{{ url_for('admin_social_media') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 4v16M17 4v16M3 8h4m10 0h4M3 12h18M3 16h4m10 0h4M4 20h16a1 1 0 001-1V5a1 1 0 00-1-1H4a1 1 0 00-1 1v14a1 1 0 001 1z"/>
</svg>
Social Media
</a>
</div>
</div>
<!-- Audyty -->
<div class="admin-dropdown">
<button class="admin-dropdown-trigger">
Audyty
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
<div class="admin-dropdown-menu">
<a href="{{ url_for('admin_seo') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</svg>
Audyt SEO
</a>
<a href="{{ url_for('admin_it_audit') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
Audyt IT
</a>
<a href="{{ url_for('admin_gbp_audit') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
Audyt GBP
</a>
<a href="{{ url_for('admin_social_audit') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z"/>
</svg>
Audyt Social
</a>
</div>
</div>
<!-- Analityka -->
<div class="admin-dropdown">
<button class="admin-dropdown-trigger">
Analityka
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
<div class="admin-dropdown-menu">
<a href="{{ url_for('chat_analytics') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
Chat AI
</a>
<a href="{{ url_for('debug_panel') }}">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
</svg>
Debug Panel
</a>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Development Notice Banner --> <!-- Development Notice Banner -->
<div class="dev-notice" id="devNotice"> <div class="dev-notice" id="devNotice">
<span class="dev-notice-icon">🚧</span> <span class="dev-notice-icon">🚧</span>