📘 Bürostatus-System (DNB)
DNB steht für „Der Nächste Bitte!“ und ist ein leichtgewichtiges PHP/MySQL-System zur Statusanzeige von Büros mit Login und öffentlicher Übersicht.
🔧 Ziel des Projekts
Ziel ist es, für jedes Büro einen eigenen Login zu ermöglichen, über den Mitarbeiter ihren aktuellen Status festlegen können:
- frei → Büro ist verfügbar
- besetzt → Kunde im Gespräch
- abwesend → nicht besetzt (Pause, außer Haus etc.)
Diese Informationen werden in einer zentralen Datenbank gespeichert und über eine öffentliche Anzeige im Wartebereich dargestellt.
📁 Ordnerstruktur
/var/www/html/dnb/
│
├── config.php # DB-Zugangsdaten
├── login.php # Login für Büros
├── index.php # Status ändern (nach Login)
├── wartebereich.php # Öffentliche Übersicht (Tabelle)
├── wartebereich_display.php# Display-optimierte Übersicht
├── logout.php # Abmeldung
└── style.css # Grunddesign
🧩 Datenbankstruktur
CREATE DATABASE buero_status CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE buero_status;
CREATE TABLE bueros (
user VARCHAR(20) PRIMARY KEY,
pass VARCHAR(255) NOT NULL,
raumnr VARCHAR(10) NOT NULL,
tuer VARCHAR(30) NOT NULL,
status ENUM('frei','besetzt','abwesend') DEFAULT 'frei'
);
INSERT INTO bueros (user, pass, raumnr, tuer) VALUES
('Buero1','passwort1','0.12','1. Tür links'),
('Buero2','passwort2','3.45','2. Tür links'),
('Buero3','passwort3','6.78','2. Tür rechts'),
('Buero4','passwort4','9.01','1. Tür rechts');
👤 MySQL-Benutzer
Büro-User:
CREATE USER 'Buero1'@'localhost' IDENTIFIED BY 'passwort1';
CREATE USER 'Buero2'@'localhost' IDENTIFIED BY 'passwort2';
CREATE USER 'Buero3'@'localhost' IDENTIFIED BY 'passwort3';
CREATE USER 'Buero4'@'localhost' IDENTIFIED BY 'passwort4';
Viewer (für öffentliche Anzeige und Web-Zugriffe):
CREATE USER 'viewer'@'localhost' IDENTIFIED BY 'viewerpass';
GRANT SELECT, UPDATE ON buero_status.bueros TO 'viewer'@'localhost';
FLUSH PRIVILEGES;
⚙️ config.php
<?php
$db_host = 'localhost';
$db_name = 'buero_status';
$db_viewer_user = 'viewer';
$db_viewer_pass = 'viewerpass';
?>
login.php
<?php
session_start();
include 'config.php';
$error = '';
$mysqli = new mysqli($db_host, $db_viewer_user, $db_viewer_pass, $db_name);
if ($mysqli->connect_error) die("DB-Fehler: ".$mysqli->connect_error);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$user = $_POST['user'] ?? '';
$pass = $_POST['pass'] ?? '';
$stmt = $mysqli->prepare("SELECT raumnr, tuer, status, pass FROM bueros WHERE user=?");
$stmt->bind_param('s', $user);
$stmt->execute();
$stmt->bind_result($raumnr, $tuer, $status, $db_pass);
if ($stmt->fetch()) {
if ($pass === $db_pass) {
$_SESSION['user'] = $user;
$_SESSION['raumnr'] = $raumnr;
$_SESSION['tuer'] = $tuer;
$_SESSION['status'] = $status;
$stmt->close();
$mysqli->close();
header('Location: index.php');
exit;
} else {
$error = 'Ungültiges Passwort';
}
} else {
$error = 'Ungültiger Benutzer';
}
$stmt->close();
}
$mysqli->close();
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Büro Login</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Büro Login</h1>
<?php if ($error): ?>
<p style="color:red; text-align:center;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>
<form method="post">
<label>
Benutzer:
<select name="user" required>
<option value="">-- Bitte auswählen --</option>
<option value="Buero1">Büro 1</option>
<option value="Buero2">Büro 2</option>
<option value="Buero3">Büro 3</option>
<option value="Buero4">Büro 4</option>
</select>
</label>
<br><br>
<label>
Passwort:
<input type="password" name="pass" required>
</label>
<br><br>
<button type="submit">Login</button>
</form>
</body>
</html>
index.php
<?php
session_start();
include 'config.php';
if (!isset($_SESSION['user'])) {
header('Location: login.php');
exit;
}
$mysqli = new mysqli($db_host, $db_viewer_user, $db_viewer_pass, $db_name);
if ($mysqli->connect_error) die("DB-Fehler: ".$mysqli->connect_error);
// Statusänderung
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['status'])) {
$status = $_POST['status'];
$stmt = $mysqli->prepare("UPDATE bueros SET status=? WHERE user=?");
$stmt->bind_param('ss', $status, $_SESSION['user']);
$stmt->execute();
$_SESSION['status'] = $status;
$stmt->close();
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Status ändern</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Raum <?=htmlspecialchars($_SESSION['raumnr'])?> (<?=htmlspecialchars($_SESSION['tuer'])?>)</h1>
<p style="text-align:center;">Aktueller Status: <strong><?=htmlspecialchars($_SESSION['status'])?></strong></p>
<form method="post">
<select name="status">
<option value="frei" <?= $_SESSION['status']=='frei'?'selected':'' ?>>frei</option>
<option value="besetzt" <?= $_SESSION['status']=='besetzt'?'selected':'' ?>>besetzt</option>
<option value="abwesend" <?= $_SESSION['status']=='abwesend'?'selected':'' ?>>abwesend</option>
</select>
<button type="submit">Status ändern</button>
</form>
<p style="text-align:center;"><a href="logout.php">Logout</a> | <a href="wartebereich.php">Wartebereich ansehen</a></p>
</body>
</html>
wartebereich.php
<?php
include 'config.php';
$mysqli = new mysqli($db_host, $db_viewer_user, $db_viewer_pass, $db_name);
if ($mysqli->connect_error) die("DB-Fehler: ".$mysqli->connect_error);
$result = $mysqli->query("SELECT raumnr, tuer, status FROM bueros ORDER BY raumnr ASC");
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Wartebereich</title>
<meta http-equiv="refresh" content="5">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Wartebereich Übersicht</h1>
<table>
<tr>
<th>Raum</th>
<th>Tür</th>
<th>Status</th>
</tr>
<?php while ($row = $result->fetch_assoc()): ?>
<tr class="status-<?=htmlspecialchars($row['status'])?>">
<td><?=htmlspecialchars($row['raumnr'])?></td>
<td><?=htmlspecialchars($row['tuer'])?></td>
<td><?=htmlspecialchars($row['status'])?></td>
</tr>
<?php endwhile; ?>
</table>
</body>
</html>
<?php $mysqli->close(); ?>
wartebereich_display.php
<?php
include 'config.php';
$mysqli = new mysqli($db_host, $db_viewer_user, $db_viewer_pass, $db_name);
if ($mysqli->connect_error) die("DB-Fehler: ".$mysqli->connect_error);
$result = $mysqli->query("SELECT raumnr, tuer, status FROM bueros ORDER BY raumnr ASC");
$bueros = $result->fetch_all(MYSQLI_ASSOC);
$mysqli->close();
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Wartebereich (Anzeige)</title>
<meta http-equiv="refresh" content="10"> <!-- automatischer Reload -->
<style>
body {
font-family: Arial, sans-serif;
background-color: #111;
color: white;
margin: 0;
padding: 40px;
}
h1 {
text-align: center;
font-size: 2.5em;
margin-bottom: 40px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.card {
border-radius: 15px;
padding: 30px;
text-align: center;
font-size: 1.5em;
font-weight: bold;
box-shadow: 0 0 10px rgba(0,0,0,0.4);
}
.status-frei {
background-color: #1f8b1f;
}
.status-besetzt {
background-color: #b32424;
}
.status-abwesend {
background-color: #b3a52f;
}
.raumnr {
font-size: 2em;
display: block;
}
.tuer {
font-size: 1.2em;
margin: 10px 0;
opacity: 0.85;
}
</style>
</head>
<body>
<h1>Wartebereich</h1>
<div class="grid">
<?php foreach ($bueros as $b): ?>
<div class="card status-<?=htmlspecialchars($b['status'])?>">
<span class="raumnr"><?=htmlspecialchars($b['raumnr'])?></span>
<span class="tuer"><?=htmlspecialchars($b['tuer'])?></span>
<span class="status"><?=htmlspecialchars($b['status'])?></span>
</div>
<?php endforeach; ?>
</div>
</body>
</html>
logout.php
<?php
session_start();
session_destroy();
header('Location: login.php');
exit;
style.css
body {
font-family: Arial, sans-serif;
background: #f4f4f4;
color: #333;
margin: 0;
padding: 20px;
}
h1, h2 {
text-align: center;
}
table {
border-collapse: collapse;
width: 80%;
margin: 20px auto;
}
table th, table td {
border: 1px solid #ccc;
padding: 10px;
text-align: center;
}
table th {
background: #666;
color: white;
}
.status-frei {
background-color: #a0e6a0;
}
.status-besetzt {
background-color: #e6a0a0;
}
.status-abwesend {
background-color: #e6e6a0;
}
form {
text-align: center;
margin-top: 20px;
}
button {
padding: 5px 15px;
font-size: 1em;
}
💻 Ablauf
- Login:
Mitarbeiter loggt sich mitBuero1
bisBuero4
und Passwort ein (login.php
). - Status ändern:
Nach dem Login erscheint die Seiteindex.php
– dort kann der Status per Dropdown geändert werden. - Wartebereich (Tabelle):
wartebereich.php
zeigt eine einfache Übersicht aller Räume. - Wartebereich (Display):
wartebereich_display.php
ist die visuell optimierte Version mit farbigen Boxen für große Bildschirme. - Logout:
Beendet die Sitzung und leitet zurück zum Login.
🧾 Erweiterungs- und Verbesserungsmöglichkeiten
- Automatische Zeitprotokollierung jeder Statusänderung
- Statistikseite mit Anzahl der Termine pro Tag / Büro
- API-Endpunkt für Integration in externe Systeme
- Live-Aktualisierung über AJAX statt Seitenreload
- Responsive Ansicht für Mobilgeräte
- (Azure-)AD-Anbindung