Initialisierung Start
This commit is contained in:
283
Zeiterfassung/templates/dashboard.html
Normal file
283
Zeiterfassung/templates/dashboard.html
Normal file
@@ -0,0 +1,283 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" class="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Futuristisches Zeiterfassungs-Dashboard</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#3B82F6',
|
||||
secondary: '#1E40AF',
|
||||
dark: '#111827',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.glassmorphism {
|
||||
background: rgba(30, 64, 175, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-900 text-white min-h-screen">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<header class="mb-8">
|
||||
<h1 class="text-4xl font-bold text-center text-blue-500">Futuristisches Zeiterfassungs-Dashboard</h1>
|
||||
</div>
|
||||
|
||||
<!-- Zeiterfassungsformular -->
|
||||
<div class="glassmorphism p-6 mb-8">
|
||||
<h2 class="text-2xl font-semibold mb-4">Neue Zeiterfassung</h2>
|
||||
<form action="{{ url_for('eintragen') }}" method="POST" id="zeiterfassungForm" class="space-y-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<label for="mitarbeiter" class="block text-sm font-medium mb-1">Mitarbeiter</label>
|
||||
<select id="mitarbeiter" name="mitarbeiter_name" required class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3">
|
||||
<option value="" disabled selected>Wähle einen Mitarbeiter</option>
|
||||
{% for mitarbeiter in mitarbeiter_list %}
|
||||
<option value="{{ mitarbeiter }}">{{ mitarbeiter }}</option>
|
||||
{% endfor %}
|
||||
<option value="new">Neuer Mitarbeiter hinzufügen</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="projekttyp" class="block text-sm font-medium mb-1">Projekttyp</label>
|
||||
<select id="projekttyp" name="projekttyp" required class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3">
|
||||
<option value="Arbeitszeit" selected>Arbeitszeit</option>
|
||||
<option value="Urlaubstag">Urlaubstag</option>
|
||||
<option value="Krankheitstag">Krankheitstag</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="arbeitszeit-feld">
|
||||
<label for="projekt" class="block text-sm font-medium mb-1">Projekt</label>
|
||||
<select id="projekt" name="projekt" class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3">
|
||||
<option value="" disabled selected>Wähle ein Projekt</option>
|
||||
{% for projekt in projekt_list %}
|
||||
<option value="{{ projekt }}">{{ projekt }}</option>
|
||||
{% endfor %}
|
||||
<option value="new">Neues Projekt hinzufügen</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="arbeitszeit-feld">
|
||||
<label for="arbeitszeit" class="block text-sm font-medium mb-1">Arbeitszeit (in Stunden)</label>
|
||||
<input type="number" step="0.1" id="arbeitszeit" name="arbeitszeit" class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3">
|
||||
</div>
|
||||
<div class="arbeitszeit-feld">
|
||||
<label for="strasse" class="block text-sm font-medium mb-1">Straße</label>
|
||||
<input type="text" id="strasse" name="strasse" class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3">
|
||||
</div>
|
||||
<div class="urlaub-krank-feld hidden">
|
||||
<label for="tage" class="block text-sm font-medium mb-1">Anzahl der Tage</label>
|
||||
<input type="number" id="tage" name="tage" min="1" class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="beschreibung" class="block text-sm font-medium mb-1">Beschreibung der Tätigkeit</label>
|
||||
<textarea id="beschreibung" name="beschreibung" rows="3" class="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Eintragen</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Dashboard -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-8">
|
||||
<!-- Gesamtarbeitszeit -->
|
||||
<div class="glassmorphism p-6">
|
||||
<h3 class="text-xl font-semibold mb-4">Gesamtarbeitszeit</h3>
|
||||
<canvas id="gesamtarbeitszeitChart"></canvas>
|
||||
</div>
|
||||
<!-- Projektzeitverteilung -->
|
||||
<div class="glassmorphism p-6">
|
||||
<h3 class="text-xl font-semibold mb-4">Projektzeitverteilung</h3>
|
||||
<canvas id="projektzeitverteilungChart"></canvas>
|
||||
</div>
|
||||
<!-- Mitarbeiterproduktivität -->
|
||||
<div class="glassmorphism p-6">
|
||||
<h3 class="text-xl font-semibold mb-4">Mitarbeiterproduktivität</h3>
|
||||
<canvas id="mitarbeiterproduktivitaetChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Übersichtstabelle der Zeiterfassungen -->
|
||||
<div class="glassmorphism p-6 mb-8">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h2 class="text-2xl font-semibold">Übersicht der Zeiterfassungen</h2>
|
||||
<button id="toggleTable" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
|
||||
<span class="chevron-up">▲</span>
|
||||
<span class="chevron-down hidden">▼</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="tableContent">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full table-auto">
|
||||
<thead>
|
||||
<tr class="bg-blue-900">
|
||||
<th class="px-4 py-2">Mitarbeiter</th>
|
||||
<th class="px-4 py-2">Projekttyp</th>
|
||||
<th class="px-4 py-2">Projekt</th>
|
||||
<th class="px-4 py-2">Datum</th>
|
||||
<th class="px-4 py-2">Arbeitszeit (h)</th>
|
||||
<th class="px-4 py-2">Straße</th>
|
||||
<th class="px-4 py-2">Beschreibung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for eintrag in zeiterfassung_list %}
|
||||
<tr class="border-b border-gray-700">
|
||||
<td class="px-4 py-2">{{ eintrag.mitarbeiter_name }}</td>
|
||||
<td class="px-4 py-2">{{ eintrag.projekttyp }}</td>
|
||||
<td class="px-4 py-2">{{ eintrag.projekt }}</td>
|
||||
<td class="px-4 py-2">{{ eintrag.datum }}</td>
|
||||
<td class="px-4 py-2">{{ eintrag.arbeitszeit }}</td>
|
||||
<td class="px-4 py-2">{{ eintrag.strasse }}</td>
|
||||
<td class="px-4 py-2">{{ eintrag.beschreibung }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter und Aktionen -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
|
||||
<form action="{{ url_for('wochenbericht_send') }}" method="POST">
|
||||
<button type="submit" class="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
|
||||
Wochenbericht per E-Mail senden
|
||||
</button>
|
||||
</form>
|
||||
<a href="{{ url_for('wochenbericht') }}" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-center">
|
||||
Wochenbericht herunterladen
|
||||
</a>
|
||||
<div class="flex">
|
||||
<input type="text" id="filterInput" placeholder="Nach Mitarbeiter oder Projekt filtern" class="flex-grow bg-gray-700 border border-gray-600 rounded-l-md py-2 px-3">
|
||||
<button id="filterButton" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r-md">Filtern</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Toggle table visibility
|
||||
const toggleTable = document.getElementById('toggleTable');
|
||||
const tableContent = document.getElementById('tableContent');
|
||||
const chevronUp = document.querySelector('.chevron-up');
|
||||
const chevronDown = document.querySelector('.chevron-down');
|
||||
|
||||
toggleTable.addEventListener('click', () => {
|
||||
tableContent.classList.toggle('hidden');
|
||||
chevronUp.classList.toggle('hidden');
|
||||
chevronDown.classList.toggle('hidden');
|
||||
});
|
||||
|
||||
// Filter table
|
||||
const filterInput = document.getElementById('filterInput');
|
||||
const filterButton = document.getElementById('filterButton');
|
||||
const tableRows = document.querySelectorAll('tbody tr');
|
||||
|
||||
function filterTable() {
|
||||
const filterValue = filterInput.value.toLowerCase();
|
||||
tableRows.forEach(row => {
|
||||
const text = row.textContent.toLowerCase();
|
||||
row.style.display = text.includes(filterValue) ? '' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
filterButton.addEventListener('click', filterTable);
|
||||
filterInput.addEventListener('keyup', (event) => {
|
||||
if (event.key === 'Enter') {
|
||||
filterTable();
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle fields based on project type
|
||||
const projekttypSelect = document.getElementById('projekttyp');
|
||||
const arbeitszeitFelder = document.querySelectorAll('.arbeitszeit-feld');
|
||||
const urlaubKrankFeld = document.querySelector('.urlaub-krank-feld');
|
||||
|
||||
projekttypSelect.addEventListener('change', () => {
|
||||
const isArbeitszeit = projekttypSelect.value === 'Arbeitszeit';
|
||||
arbeitszeitFelder.forEach(feld => {
|
||||
feld.style.display = isArbeitszeit ? 'block' : 'none';
|
||||
});
|
||||
urlaubKrankFeld.style.display = isArbeitszeit ? 'none' : 'block';
|
||||
});
|
||||
|
||||
// Chart.js visualizations
|
||||
// Gesamtarbeitszeit Chart
|
||||
const gesamtarbeitszeitCtx = document.getElementById('gesamtarbeitszeitChart').getContext('2d');
|
||||
new Chart(gesamtarbeitszeitCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
|
||||
datasets: [{
|
||||
label: 'Gesamtarbeitszeit',
|
||||
data: [8, 7.5, 9, 8.5, 7, 4, 0],
|
||||
borderColor: 'rgb(59, 130, 246)',
|
||||
tension: 0.1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Projektzeitverteilung Chart
|
||||
const projektzeitverteilungCtx = document.getElementById('projektzeitverteilungChart').getContext('2d');
|
||||
new Chart(projektzeitverteilungCtx, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['Projekt A', 'Projekt B', 'Projekt C', 'Projekt D'],
|
||||
datasets: [{
|
||||
data: [12, 19, 3, 5],
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.8)',
|
||||
'rgba(54, 162, 235, 0.8)',
|
||||
'rgba(255, 206, 86, 0.8)',
|
||||
'rgba(75, 192, 192, 0.8)'
|
||||
]
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true
|
||||
}
|
||||
});
|
||||
|
||||
// Mitarbeiterproduktivität Chart
|
||||
const mitarbeiterproduktivitaetCtx = document.getElementById('mitarbeiterproduktivitaetChart').getContext('2d');
|
||||
new Chart(mitarbeiterproduktivitaetCtx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['Max', 'Anna', 'Tom', 'Lisa'],
|
||||
datasets: [{
|
||||
label: 'Produktivität (Stunden/Tag)',
|
||||
data: [7.5, 8.2, 6.8, 7.9],
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.8)'
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user