Files
TimeTrack/templates/layout.html
Jens Luedicke 462d91c3a8 Merge website-branding feature and adjust for compatibility
- Resolved conflicts in models.py, app.py, and template files
- Added branding checks to prevent errors when g.branding is None
- Updated all template references to use conditional branding
- Added BrandingSettings to migrations
- Created branding uploads directory
- Integrated branding with existing comment and task management features
2025-07-06 16:58:29 +02:00

237 lines
12 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }} - {{ g.branding.app_name if g.branding else 'TimeTrack' }}{% if g.company %} - {{ g.company.name }}{% endif %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/fonts.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
{% if not g.user %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/splash.css') }}">
{% endif %}
{% if g.branding and g.branding.favicon_filename %}
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='uploads/branding/' + g.branding.favicon_filename) }}">
{% endif %}
<style>
:root {
--primary-color: {{ g.branding.primary_color if g.branding else '#007bff' }};
}
.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-primary:hover {
background-color: {{ (g.branding.primary_color if g.branding else '#007bff') + 'dd' }};
border-color: {{ (g.branding.primary_color if g.branding else '#007bff') + 'dd' }};
}
.nav-icon {
color: var(--primary-color);
}
a:hover {
color: var(--primary-color);
}
.mobile-logo {
max-height: 30px;
max-width: 150px;
object-fit: contain;
}
.sidebar-logo {
max-height: 32px;
max-width: 160px;
object-fit: contain;
}
.mobile-nav-brand a {
display: flex;
align-items: center;
}
.sidebar-header h2 a {
display: flex;
align-items: center;
color: inherit;
text-decoration: none;
}
</style>
</head>
<body{% if g.user %} class="has-user"{% endif %}>
<!-- Mobile header -->
{% if g.user %}
<header class="mobile-header">
<div class="mobile-nav-brand">
<a href="{{ url_for('home') }}">
{% if g.branding and g.branding.logo_filename %}
<img src="{{ url_for('static', filename='uploads/branding/' + g.branding.logo_filename) }}"
alt="{{ g.branding.logo_alt_text }}"
class="mobile-logo">
{% else %}
{{ g.branding.app_name if g.branding else 'TimeTrack' }}
{% endif %}
</a>
{% if g.company %}
<small class="company-name">{{ g.company.name }}</small>
{% endif %}
</div>
<button class="mobile-nav-toggle" id="mobile-nav-toggle">
<span></span>
<span></span>
<span></span>
</button>
</header>
{% endif %}
<!-- Sidebar navigation -->
{% if g.user %}
<aside class="sidebar" id="sidebar">
<div class="sidebar-header">
<h2>
<a href="{{ url_for('home') }}">
{% if g.branding and g.branding.logo_filename %}
<img src="{{ url_for('static', filename='uploads/branding/' + g.branding.logo_filename) }}"
alt="{{ g.branding.logo_alt_text }}"
class="sidebar-logo">
{% else %}
{{ g.branding.app_name if g.branding else 'TimeTrack' }}
{% endif %}
</a>
</h2>
{% if g.company %}
<div class="company-info">
<small class="text-muted">{{ g.company.name }}</small>
</div>
{% endif %}
<button class="sidebar-toggle" id="sidebar-toggle">
<span></span>
<span></span>
<span></span>
</button>
{% if g.user %}
<!-- User Account Menu -->
<a href="#" class="user-dropdown-toggle" id="user-dropdown-toggle" data-tooltip="{{ g.user.username }}">
<img src="{{ g.user.get_avatar_url(32) }}" alt="{{ g.user.username }}" class="user-avatar">
<span class="nav-text">{{ g.user.username }}<span class="dropdown-arrow"></span></span>
</a>
<!-- User Dropdown Context Menu -->
<div class="user-dropdown-modal" id="user-dropdown-modal">
<div class="user-dropdown-header">
<img src="{{ g.user.get_avatar_url(64) }}" alt="{{ g.user.username }}" class="user-avatar-large">
<h3>{{ g.user.username }}</h3>
<div class="user-info">
{% if g.user.email %}
{{ g.user.email }}
{% endif %}
</div>
</div>
<div class="user-dropdown-menu">
<ul>
<li><a href="{{ url_for('profile') }}"><i class="nav-icon">👤</i>Profile</a></li>
<li><a href="{{ url_for('config') }}"><i class="nav-icon">⚙️</i>Settings</a></li>
<li class="user-dropdown-divider"></li>
<li><a href="{{ url_for('logout') }}"><i class="nav-icon">🚪</i>Logout</a></li>
</ul>
</div>
</div>
{% endif %}
</div>
<nav class="sidebar-nav">
<ul>
{% if g.user %}
<li><a href="{{ url_for('home') }}" data-tooltip="Home"><i class="nav-icon">🏠</i><span class="nav-text">Home</span></a></li>
<li><a href="{{ url_for('dashboard') }}" data-tooltip="Dashboard"><i class="nav-icon">📊</i><span class="nav-text">Dashboard</span></a></li>
<li><a href="{{ url_for('unified_task_management') }}" data-tooltip="Task Management"><i class="nav-icon">📋</i><span class="nav-text">Task Management</span></a></li>
<li><a href="{{ url_for('sprint_management') }}" data-tooltip="Sprint Management"><i class="nav-icon">🏃‍♂️</i><span class="nav-text">Sprints</span></a></li>
<li><a href="{{ url_for('analytics') }}" data-tooltip="Time Analytics"><i class="nav-icon">📊</i><span class="nav-text">Analytics</span></a></li>
<!-- Role-based menu items -->
{% if g.user.role == Role.ADMIN or g.user.role == Role.SYSTEM_ADMIN %}
<li class="nav-divider">Admin</li>
<li><a href="{{ url_for('dashboard') }}" data-tooltip="Dashboard"><i class="nav-icon">📈</i><span class="nav-text">Dashboard</span></a></li>
<li><a href="{{ url_for('admin_company') }}" data-tooltip="Company"><i class="nav-icon">🏢</i><span class="nav-text">Company</span></a></li>
<li><a href="{{ url_for('admin_users') }}" data-tooltip="Manage Users"><i class="nav-icon">👥</i><span class="nav-text">Manage Users</span></a></li>
<li><a href="{{ url_for('admin_teams') }}" data-tooltip="Manage Teams"><i class="nav-icon">🏭</i><span class="nav-text">Manage Teams</span></a></li>
<li><a href="{{ url_for('admin_projects') }}" data-tooltip="Manage Projects"><i class="nav-icon">📝</i><span class="nav-text">Manage Projects</span></a></li>
<li><a href="{{ url_for('admin_work_policies') }}" data-tooltip="Work Policies"><i class="nav-icon">⚖️</i><span class="nav-text">Work Policies</span></a></li>
<li><a href="{{ url_for('admin_settings') }}" data-tooltip="System Settings"><i class="nav-icon">🔧</i><span class="nav-text">System Settings</span></a></li>
{% if g.user.role == Role.SYSTEM_ADMIN %}
<li class="nav-divider">System Admin</li>
<li><a href="{{ url_for('system_admin_dashboard') }}" data-tooltip="System Dashboard"><i class="nav-icon">🌐</i><span class="nav-text">System Dashboard</span></a></li>
<li><a href="{{ url_for('system_admin_announcements') }}" data-tooltip="Announcements"><i class="nav-icon">📢</i><span class="nav-text">Announcements</span></a></li>
{% endif %}
{% elif g.user.role in [Role.TEAM_LEADER, Role.SUPERVISOR] %}
<li class="nav-divider">Team</li>
<li><a href="{{ url_for('dashboard') }}" data-tooltip="Dashboard"><i class="nav-icon">📈</i><span class="nav-text">Dashboard</span></a></li>
{% if g.user.role == Role.SUPERVISOR %}
<li><a href="{{ url_for('admin_projects') }}" data-tooltip="Manage Projects"><i class="nav-icon">📝</i><span class="nav-text">Manage Projects</span></a></li>
{% endif %}
{% endif %}
{% else %}
<li><a href="{{ url_for('about') }}" data-tooltip="About"><i class="nav-icon"></i><span class="nav-text">About</span></a></li>
<li><a href="{{ url_for('login') }}" data-tooltip="Login"><i class="nav-icon">🔑</i><span class="nav-text">Login</span></a></li>
<li><a href="{{ url_for('register') }}" data-tooltip="Register"><i class="nav-icon">📝</i><span class="nav-text">Register</span></a></li>
{% endif %}
</ul>
</nav>
</aside>
{% endif %}
<!-- Mobile overlay -->
{% if g.user %}
<div class="mobile-overlay" id="mobile-overlay"></div>
{% endif %}
<main class="main-content">
<!-- System Announcements -->
{% if active_announcements %}
<div class="announcements">
{% for announcement in active_announcements %}
<div class="alert alert-{{ announcement.announcement_type }}{% if announcement.is_urgent %} alert-urgent{% endif %}">
<div class="announcement-header">
<strong>{{ announcement.title }}</strong>
{% if announcement.is_urgent %}
<span class="urgent-badge">URGENT</span>
{% endif %}
</div>
<div class="announcement-content">
{{ announcement.content|safe }}
</div>
{% if announcement.created_at %}
<small class="announcement-date">
Posted: {{ announcement.created_at.strftime('%Y-%m-%d %H:%M') }}
</small>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-messages">
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
<footer>
<p>&copy; {{ current_year }} {{ g.branding.app_name }}. All rights reserved.</p>
</footer>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
<script src="{{ url_for('static', filename='js/sidebar.js') }}"></script>
<script src="{{ url_for('static', filename='js/password-strength.js') }}"></script>
{% if g.user %}
<script src="{{ url_for('static', filename='js/user-dropdown.js') }}"></script>
{% else %}
<script src="{{ url_for('static', filename='js/splash.js') }}"></script>
{% endif %}
<!-- Custom Tracking Script -->
{% if tracking_script_enabled and tracking_script_code %}
{{ tracking_script_code|safe }}
{% endif %}
</body>
</html>