update: new berichte
This commit is contained in:
1 parent
865320a75c
commit
0559317875
2 files changed
+335
No files matched your search
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
$mode = $_GET['mode'] ?? 'fk';
|
||||
|
||||
if ($mode === 'normal') {
|
||||
$data = Databaseshow("Firmenberichte");
|
||||
} else {
|
||||
$data = DatabaseShowWithFK(
|
||||
"Berufsschulberichte",
|
||||
$Berufsschulberichte,
|
||||
);
|
||||
}
|
||||
|
||||
$data = array_reverse($data);
|
||||
|
||||
$displayData = (is_array($data) && isset($data['rows'])) ? $data['rows'] : $data;
|
||||
$count = is_array($displayData) ? count($displayData) : 0;
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="../style.css">
|
||||
<style>
|
||||
.debug-table-container {
|
||||
background: #252525;
|
||||
border-radius: 8px;
|
||||
padding: 0;
|
||||
margin-top: 20px;
|
||||
overflow-x: auto;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
color: #ccc;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #333;
|
||||
text-align: left;
|
||||
padding: 15px 12px;
|
||||
border-bottom: 2px solid #3498db;
|
||||
color: #3498db;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
letter-spacing: 1px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 12px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: rgba(52, 152, 219, 0.1);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Highlight für DATUM Spalte */
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
background: #252525;
|
||||
z-index: 5;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
th:first-child {
|
||||
z-index: 11;
|
||||
background: #333;
|
||||
}
|
||||
|
||||
.debug-raw {
|
||||
background: #1a1a1a;
|
||||
color: #00ff00;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
font-family: 'Fira Code', monospace;
|
||||
font-size: 12px;
|
||||
overflow: auto;
|
||||
border-left: 4px solid #3498db;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.badge-count {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
padding: 3px 10px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.empty-note {
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="<?= ($_SESSION['dark_mode'] ?? true) ? 'dark-mode' : '' ?>">
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<h2 style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span>📊 Berichtte-Vorschau:</span>
|
||||
|
||||
<div>
|
||||
<a href="?service=<?= $selectedService ?>&mode=fk">
|
||||
<button <?= $mode === 'fk' ? 'style="background:#3498db;color:white;"' : '' ?>>
|
||||
Berufsschulberichte
|
||||
</button>
|
||||
</a>
|
||||
|
||||
<a href="?service=<?= $selectedService ?>&mode=normal">
|
||||
<button <?= $mode === 'normal' ? 'style="background:#3498db;color:white;"' : '' ?>>
|
||||
Arbeitsberichte
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<?php if ($count > 0 && is_array($displayData[0])): ?>
|
||||
<div class="debug-table-container">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach (array_keys($displayData[0]) as $column): ?>
|
||||
<th><?= htmlspecialchars($column) ?></th>
|
||||
<?php endforeach; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($displayData as $row): ?>
|
||||
<tr>
|
||||
<?php foreach ($row as $key => $cell): ?>
|
||||
<td><?= htmlspecialchars($cell ?? '-') ?></td>
|
||||
<?php endforeach; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="debug-table-container">
|
||||
<div class="empty-note">
|
||||
Keine tabellarischen Daten gefunden.<br>
|
||||
<small>Struktur: <?= is_array($data) ? 'Array ('.count($data).' Keys)' : gettype($data) ?></small>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
$conn = db_connect();
|
||||
$view = $_GET['view'] ?? 'show';
|
||||
$selectedService = $_GET['service'];
|
||||
|
||||
// --- LOGIK: Überstunden-Eintrag (Abbau) speichern ---
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_overtime'])) {
|
||||
$datum = $_POST['ot_date'];
|
||||
$minuten = intval($_POST['ot_minutes']);
|
||||
$grund = $conn->real_escape_string($_POST['ot_reason']);
|
||||
$insert_sql = "INSERT INTO Ueberstunden (DATUM, MINUTEN, GRUND) VALUES ('$datum', $minuten, '$grund')";
|
||||
$conn->query($insert_sql);
|
||||
}
|
||||
|
||||
// --- Daten laden ---
|
||||
$daten = [];
|
||||
$sql = "SELECT `DATUM`, `PROZESS_1`, `PROZESS_2`, `PROZESS_3`, `PROZESS_4`, `BEGINN`, `ENDE_REAL`, `OVERTIME` FROM Firmenberichte ORDER BY `DATUM` DESC";
|
||||
if ($erg = $conn->query($sql)) {
|
||||
while ($datensatz = $erg->fetch_object()) { $daten[] = $datensatz; }
|
||||
$erg->free();
|
||||
}
|
||||
|
||||
// --- Gesamtsumme berechnen ---
|
||||
$minuten_berichte = 0;
|
||||
$res1 = $conn->query("SELECT SUM(OVERTIME) AS summe FROM Firmenberichte");
|
||||
if ($row = $res1->fetch_object()) { $minuten_berichte = intval($row->summe); }
|
||||
|
||||
$minuten_extra = 0;
|
||||
$res2 = $conn->query("SELECT SUM(MINUTEN) AS summe FROM Ueberstunden");
|
||||
if ($row = $res2->fetch_object()) { $minuten_extra = intval($row->summe); }
|
||||
|
||||
$gesamt_minuten = $minuten_berichte - $minuten_extra;
|
||||
?>
|
||||
|
||||
<div class="arbeitsberichte-wrapper">
|
||||
<div style="display: flex; gap: 10px; margin-bottom: 25px;">
|
||||
<a href="?service=<?= $selectedService ?>&view=rechner" style="text-decoration:none;">
|
||||
<button class="nav-btn <?= $view == 'rechner' ? 'active' : '' ?>" style="padding: 10px 20px; cursor: pointer; border: none; border-radius: 4px; font-weight: bold;
|
||||
background: <?= $view == 'rechner' ? '#007bff' : 'rgba(150,150,150,0.2)' ?>;
|
||||
color: <?= $view == 'rechner' ? '#fff' : '#fff' ?>;">
|
||||
Live-Timer
|
||||
</button>
|
||||
</a>
|
||||
<a href="?service=<?= $selectedService ?>&view=show" style="text-decoration:none;">
|
||||
<button class="nav-btn <?= $view == 'show' ? 'active' : '' ?>" style="padding: 10px 20px; cursor: pointer; border: none; border-radius: 4px; font-weight: bold;
|
||||
background: <?= $view == 'show' ? '#007bff' : 'rgba(150,150,150,0.2)' ?>;
|
||||
color: <?= $view == 'show' ? '#fff' : '#fff' ?>;">
|
||||
Übersicht
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ($view === 'rechner'): ?>
|
||||
<div class="overtime-container" style="color: inherit;">
|
||||
<h2 style="color: inherit;">Überstunden Rechner</h2>
|
||||
<label for="startTime">Arbeitsstartzeit:</label>
|
||||
<input type="time" id="startTime" step="60"
|
||||
style="background: rgba(150,150,150,0.1); color: inherit; border: 1px solid #555;">
|
||||
<button id="startBtn">Timer starten</button>
|
||||
|
||||
<div id="resultBox" class="overtime-result">
|
||||
<p style="margin:0; font-size: 0.9rem;">Überstunden / Restzeit:</p>
|
||||
<div id="result">0:00</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div
|
||||
style="background: rgba(150,150,150,0.05); padding: 25px; border-radius: 10px; margin-bottom: 25px; border: 1px solid rgba(150,150,150,0.2); border-left: 6px solid #007bff;">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<span style="color: #888; font-size: 0.8rem; font-weight: bold; text-transform: uppercase;">Aktueller
|
||||
Stand</span>
|
||||
<h2 style="margin: 5px 0 0 0; font-size: 2rem; color: <?= $gesamt_minuten >= 0 ? '#28a745' : '#dc3545' ?>;">
|
||||
<?= intdiv($gesamt_minuten, 60) ?>h <?= abs($gesamt_minuten % 60) ?>min
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<form method="POST" style="display: flex; gap: 15px; flex-wrap: wrap; align-items: flex-end;">
|
||||
<input type="hidden" name="add_overtime" value="1">
|
||||
<div style="display: flex; flex-direction: column; gap: 5px;">
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Datum</label>
|
||||
<input type="date" name="ot_date" value="<?= date('Y-m-d') ?>" required
|
||||
style="padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 5px;">
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Minuten Abbau</label>
|
||||
<input type="number" name="ot_minutes" placeholder="480" required
|
||||
style="width: 100px; padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 5px; flex-grow: 1;">
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Grund</label>
|
||||
<input type="text" name="ot_reason" placeholder="z.B. Abbau" required
|
||||
style="padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
|
||||
</div>
|
||||
<button type="submit"
|
||||
style="background: #007bff; color: white; border: none; padding: 10px 20px; border-radius: 4px; font-weight: bold; cursor: pointer;">
|
||||
Eintrag speichern
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- <table style="width: 100%; border-collapse: collapse; color: inherit;">
|
||||
<thead>
|
||||
<tr style="background: rgba(0,123,255,0.15); text-align: left;">
|
||||
<th style="padding: 12px; border-bottom: 2px solid #007bff;">Datum</th>
|
||||
<th style="padding: 12px; border-bottom: 2px solid #007bff;">Prozesse</th>
|
||||
<th style="padding: 12px; border-bottom: 2px solid #007bff;">Zeitraum</th>
|
||||
<th style="padding: 12px; border-bottom: 2px solid #007bff;">Overtime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($daten as $b): ?>
|
||||
<tr style="border-bottom: 1px solid rgba(150,150,150,0.2); vertical-align: top;">
|
||||
<td style="padding: 12px; white-space: nowrap;"><?= htmlspecialchars($b->DATUM) ?></td>
|
||||
<td style="padding: 12px;">
|
||||
<div style="display: flex; flex-direction: column; gap: 3px; font-size: 0.85rem; opacity: 0.8;">
|
||||
<?php for($i=1; $i<=4; $i++): $p = "PROZESS_$i"; ?>
|
||||
<?php if(!empty($b->$p)): ?> <span>• <?= htmlspecialchars($b->$p) ?></span> <?php endif; ?>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td style="padding: 12px; font-size: 0.9rem; white-space: nowrap;"><?= $b->BEGINN ?> -
|
||||
<?= $b->ENDE_REAL ?></td>
|
||||
<td style="padding: 12px; font-weight: bold; color: <?= $b->OVERTIME >= 0 ? '#28a745' : '#dc3545' ?>;">
|
||||
<?= $b->OVERTIME ?> min
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table> -->
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Live-Rechner Logik
|
||||
if (document.getElementById('startBtn')) {
|
||||
document.getElementById('startBtn').addEventListener('click', function() {
|
||||
const startTimeInput = document.getElementById('startTime').value;
|
||||
if (!startTimeInput) return;
|
||||
const [hours, minutes] = startTimeInput.split(':').map(Number);
|
||||
let startDate = new Date();
|
||||
startDate.setHours(hours, minutes, 0);
|
||||
const targetWorkMs = 8.5 * 60 * 60 * 1000;
|
||||
const resultEl = document.getElementById('result');
|
||||
const resultBox = document.getElementById('resultBox');
|
||||
|
||||
setInterval(() => {
|
||||
const diffMs = (new Date() - startDate) - targetWorkMs;
|
||||
const negative = diffMs < 0;
|
||||
const absMs = Math.abs(diffMs);
|
||||
const h = Math.floor(absMs / 3600000);
|
||||
const m = Math.floor((absMs % 3600000) / 60000);
|
||||
resultEl.innerText = (negative ? '-' : '+') + h + ":" + (m < 10 ? '0' : '') + m;
|
||||
if (negative) {
|
||||
resultBox.classList.add('negative');
|
||||
} else {
|
||||
resultBox.classList.remove('negative');
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
Reference in new issue
Block a user