- Updated index.html to extend base template and improve structure. - Added new styles and search/filter functionality in the Sager list view. - Created a backup of the old index.html as index_old.html. - Updated navigation links in base.html for consistency. - Included new dashboard API router in main.py. - Added test scripts for customer and sag queries to validate database interactions.
351 lines
11 KiB
HTML
351 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="da">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Sager - BMC Hub</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--primary-color: #0f4c75;
|
|
--secondary-color: #3282b8;
|
|
--accent-color: #00a8e8;
|
|
--bg-light: #f7f9fc;
|
|
--bg-dark: #1a1a2e;
|
|
--text-light: #333;
|
|
--text-dark: #f0f0f0;
|
|
--border-color: #ddd;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--bg-light);
|
|
color: var(--text-light);
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
}
|
|
|
|
body.dark-mode {
|
|
background-color: var(--bg-dark);
|
|
color: var(--text-dark);
|
|
}
|
|
|
|
.navbar {
|
|
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.navbar-brand {
|
|
font-weight: 600;
|
|
font-size: 1.4rem;
|
|
}
|
|
|
|
.content-wrapper {
|
|
padding: 2rem 0;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.page-header {
|
|
margin-bottom: 2rem;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.page-header h1 {
|
|
font-size: 2rem;
|
|
font-weight: 700;
|
|
color: var(--primary-color);
|
|
margin: 0;
|
|
}
|
|
|
|
body.dark-mode .page-header h1 {
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.btn-new {
|
|
background-color: var(--accent-color);
|
|
color: white;
|
|
border: none;
|
|
padding: 0.6rem 1.5rem;
|
|
border-radius: 6px;
|
|
font-weight: 500;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-new:hover {
|
|
background-color: var(--secondary-color);
|
|
color: white;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0,168,232,0.3);
|
|
}
|
|
|
|
.filter-section {
|
|
background: white;
|
|
padding: 1.5rem;
|
|
border-radius: 8px;
|
|
margin-bottom: 2rem;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
|
}
|
|
|
|
body.dark-mode .filter-section {
|
|
background-color: #2a2a3e;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.filter-section label {
|
|
font-weight: 600;
|
|
color: var(--primary-color);
|
|
margin-bottom: 0.5rem;
|
|
display: block;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
body.dark-mode .filter-section label {
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.filter-section select,
|
|
.filter-section input {
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 4px;
|
|
padding: 0.5rem;
|
|
font-size: 0.95rem;
|
|
}
|
|
|
|
body.dark-mode .filter-section select,
|
|
body.dark-mode .filter-section input {
|
|
background-color: #3a3a4e;
|
|
color: var(--text-dark);
|
|
border-color: #555;
|
|
}
|
|
|
|
.sag-card {
|
|
background: white;
|
|
border-radius: 8px;
|
|
padding: 1.5rem;
|
|
margin-bottom: 1rem;
|
|
border-left: 4px solid var(--primary-color);
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
|
text-decoration: none;
|
|
color: inherit;
|
|
display: block;
|
|
}
|
|
|
|
body.dark-mode .sag-card {
|
|
background-color: #2a2a3e;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.sag-card:hover {
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
transform: translateY(-2px);
|
|
border-left-color: var(--accent-color);
|
|
}
|
|
|
|
body.dark-mode .sag-card:hover {
|
|
box-shadow: 0 4px 12px rgba(0,168,232,0.2);
|
|
}
|
|
|
|
.sag-title {
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
color: var(--primary-color);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
body.dark-mode .sag-title {
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.sag-meta {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 1rem;
|
|
font-size: 0.9rem;
|
|
color: #666;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
body.dark-mode .sag-meta {
|
|
color: #aaa;
|
|
}
|
|
|
|
.status-badge {
|
|
display: inline-block;
|
|
padding: 0.3rem 0.7rem;
|
|
border-radius: 20px;
|
|
font-size: 0.8rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.status-åben {
|
|
background-color: #ffeaa7;
|
|
color: #d63031;
|
|
}
|
|
|
|
.status-i_gang {
|
|
background-color: #a29bfe;
|
|
color: #2d3436;
|
|
}
|
|
|
|
.status-afsluttet {
|
|
background-color: #55efc4;
|
|
color: #00b894;
|
|
}
|
|
|
|
.status-on_hold {
|
|
background-color: #fab1a0;
|
|
color: #e17055;
|
|
}
|
|
|
|
.tag {
|
|
display: inline-block;
|
|
background-color: var(--primary-color);
|
|
color: white;
|
|
padding: 0.3rem 0.6rem;
|
|
border-radius: 4px;
|
|
font-size: 0.8rem;
|
|
margin-right: 0.5rem;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
body.dark-mode .tag {
|
|
background-color: var(--secondary-color);
|
|
}
|
|
|
|
.dark-mode-toggle {
|
|
background: none;
|
|
border: none;
|
|
color: white;
|
|
font-size: 1.2rem;
|
|
cursor: pointer;
|
|
padding: 0.5rem;
|
|
}
|
|
|
|
.empty-state {
|
|
text-align: center;
|
|
padding: 3rem 1rem;
|
|
color: #999;
|
|
}
|
|
|
|
body.dark-mode .empty-state {
|
|
color: #666;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Navigation -->
|
|
<nav class="navbar navbar-expand-lg navbar-dark">
|
|
<div class="container">
|
|
<a class="navbar-brand" href="/">🛠️ BMC Hub</a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav ms-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" href="/sag">Sager</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="dark-mode-toggle" onclick="toggleDarkMode()">🌙</button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Main Content -->
|
|
<div class="content-wrapper">
|
|
<div class="container">
|
|
<!-- Page Header -->
|
|
<div class="page-header">
|
|
<h1>📋 Sager</h1>
|
|
<a href="/sag/new" class="btn-new">+ Ny sag</a>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="filter-section">
|
|
<div class="row g-3">
|
|
<div class="col-md-4">
|
|
<label>Status</label>
|
|
<form method="get" style="display: flex; gap: 0.5rem;">
|
|
<select name="status" onchange="this.form.submit()" style="flex: 1;">
|
|
<option value="">Alle statuser</option>
|
|
{% for s in statuses %}
|
|
<option value="{{ s }}" {% if s == current_status %}selected{% endif %}>{{ s }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</form>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label>Tag</label>
|
|
<form method="get" style="display: flex; gap: 0.5rem;">
|
|
<select name="tag" onchange="this.form.submit()" style="flex: 1;">
|
|
<option value="">Alle tags</option>
|
|
{% for t in all_tags %}
|
|
<option value="{{ t }}" {% if t == current_tag %}selected{% endif %}>{{ t }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</form>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label>Søg</label>
|
|
<input type="text" placeholder="Søg efter sager..." class="form-control" id="searchInput">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cases List -->
|
|
<div id="casesList">
|
|
{% if sager %}
|
|
{% for sag in sager %}
|
|
<a href="/sag/{{ sag.id }}" class="sag-card">
|
|
<div class="sag-title">{{ sag.titel }}</div>
|
|
{% if sag.beskrivelse %}
|
|
<div style="color: #666; font-size: 0.9rem; margin-bottom: 0.5rem;">{{ sag.beskrivelse[:100] }}{% if sag.beskrivelse|length > 100 %}...{% endif %}</div>
|
|
{% endif %}
|
|
<div class="sag-meta">
|
|
<span class="status-badge status-{{ sag.status }}">{{ sag.status }}</span>
|
|
<span>{{ sag.type }}</span>
|
|
<span style="color: #999;">{{ sag.created_at.strftime('%Y-%m-%d') if sag.created_at else '' }}</span>
|
|
</div>
|
|
</a>
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="empty-state">
|
|
<p>Ingen sager fundet</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
function toggleDarkMode() {
|
|
document.body.classList.toggle('dark-mode');
|
|
localStorage.setItem('darkMode', document.body.classList.contains('dark-mode'));
|
|
}
|
|
|
|
// Load dark mode preference
|
|
if (localStorage.getItem('darkMode') === 'true') {
|
|
document.body.classList.add('dark-mode');
|
|
}
|
|
|
|
// Search functionality
|
|
document.getElementById('searchInput').addEventListener('keyup', function(e) {
|
|
const search = e.target.value.toLowerCase();
|
|
document.querySelectorAll('.sag-card').forEach(card => {
|
|
const text = card.textContent.toLowerCase();
|
|
card.style.display = text.includes(search) ? 'block' : 'none';
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|