feat: Implement floors, locations, and racks management

- Added list, edit, and save functionalities for floors, locations, and racks.
- Enhanced UI with search and filter options for better usability.
- Implemented SVG upload for floor plans in the floors module.
- Added validation for required fields in the save processes.
- Improved navigation in the header to reflect new modules.
- Styled forms and tables for a consistent look and feel across modules.
This commit is contained in:
2026-02-11 14:34:07 +01:00
parent 2f341bff9f
commit 0d3c6e1ae7
26 changed files with 3753 additions and 1045 deletions

View File

@@ -1,3 +1,144 @@
<?php
/**
* modules/dashboard/list.php
* Dashboard / Startseite - Übersicht über alle Komponenten
*/
echo '<p>Dashboard</p>';
// =========================
// Statistiken aus DB laden
// =========================
$stats = [
'devices' => $sql->single("SELECT COUNT(*) as cnt FROM devices", "", [])['cnt'] ?? 0,
'device_types' => $sql->single("SELECT COUNT(*) as cnt FROM device_types", "", [])['cnt'] ?? 0,
'racks' => $sql->single("SELECT COUNT(*) as cnt FROM racks", "", [])['cnt'] ?? 0,
'floors' => $sql->single("SELECT COUNT(*) as cnt FROM floors", "", [])['cnt'] ?? 0,
'locations' => $sql->single("SELECT COUNT(*) as cnt FROM locations", "", [])['cnt'] ?? 0,
];
// Recent devices
$recentDevices = $sql->get(
"SELECT d.id, d.name, dt.name as type_name, r.name as rack_name, f.name as floor_name
FROM devices d
LEFT JOIN device_types dt ON d.device_type_id = dt.id
LEFT JOIN racks r ON d.rack_id = r.id
LEFT JOIN floors f ON r.floor_id = f.id
ORDER BY d.id DESC LIMIT 5",
"", []
);
?>
<!-- Dashboard / Übersicht -->
<div class="dashboard">
<h1>Dashboard</h1>
<!-- Statistik-Karten -->
<div class="stats-grid">
<div class="stat-card">
<h3><?php echo $stats['locations']; ?></h3>
<p>Standorte</p>
<a href="?module=floors&action=list">Verwalten →</a>
</div>
<div class="stat-card">
<h3><?php echo $stats['device_types']; ?></h3>
<p>Gerätetypen</p>
<a href="?module=device_types&action=list">Verwalten →</a>
</div>
<div class="stat-card">
<h3><?php echo $stats['devices']; ?></h3>
<p>Geräte</p>
<a href="?module=devices&action=list">Verwalten →</a>
</div>
<div class="stat-card">
<h3><?php echo $stats['racks']; ?></h3>
<p>Racks</p>
<a href="?module=racks&action=list">Verwalten →</a>
</div>
</div>
<!-- Zuletzt hinzugefügte Geräte -->
<h2>Zuletzt hinzugefügt</h2>
<?php if (!empty($recentDevices)): ?>
<table class="recent-devices">
<thead>
<tr>
<th>Name</th>
<th>Typ</th>
<th>Rack</th>
<th>Stockwerk</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($recentDevices as $device): ?>
<tr>
<td><?php echo htmlspecialchars($device['name']); ?></td>
<td><?php echo htmlspecialchars($device['type_name'] ?? '-'); ?></td>
<td><?php echo htmlspecialchars($device['rack_name'] ?? '-'); ?></td>
<td><?php echo htmlspecialchars($device['floor_name'] ?? '-'); ?></td>
<td><a href="?module=devices&action=edit&id=<?php echo $device['id']; ?>">Bearbeiten</a></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p><em>Noch keine Geräte vorhanden. <a href="?module=device_types&action=list">Starten Sie mit Gerätetypen</a>.</em></p>
<?php endif; ?>
</div>
<style>
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.stat-card {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
text-align: center;
background: #f9f9f9;
}
.stat-card h3 {
font-size: 2.5em;
margin: 0;
color: #333;
}
.stat-card p {
margin: 10px 0;
color: #666;
}
.stat-card a {
display: inline-block;
margin-top: 10px;
padding: 8px 12px;
background: #007bff;
color: white;
text-decoration: none;
border-radius: 4px;
}
.recent-devices {
width: 100%;
border-collapse: collapse;
}
.recent-devices th, .recent-devices td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.recent-devices th {
background: #f0f0f0;
}
</style>