DNB


📘 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

  1. Login:
    Mitarbeiter loggt sich mit Buero1 bis Buero4 und Passwort ein (login.php).
  2. Status ändern:
    Nach dem Login erscheint die Seite index.php – dort kann der Status per Dropdown geändert werden.
  3. Wartebereich (Tabelle):
    wartebereich.php zeigt eine einfache Übersicht aller Räume.
  4. Wartebereich (Display):
    wartebereich_display.php ist die visuell optimierte Version mit farbigen Boxen für große Bildschirme.
  5. 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