Start Komplette Webseiten Restaurant Tische Live

Restaurant Tische Live

Mit unserem Tischzuweisungs System organisierst du Gäste in deinem Restaurant effizient und modern. Unser System bietet:

  • Gäste-Eintragung per QR-Code: Gäste scannen den Code, tragen sich selbst ein, einfach und kontaktlos.
  • Live Updates für Service & Küche: Jede Anmeldung wird sofort auf den Dashboards der Kellner und in der Küche angezeigt.
  • Tischzuweisung & Statusverwaltung: Service-Mitarbeiter können Tische zuweisen und den Status der Gäste aktualisieren.
  • Admin-Bereich mit PIN-Schutz: Kontrolliere alle Vorgänge zentral und sicher.
  • Statistiken & Monitoring: Behalte den Überblick über aktuelle Gäste und Auslastung.

Setup in einer Datei: Mit nur einem Klick werden alle benötigten Dateien und Ordner automatisch erstellt, inkl. WebSocket-Live-Update, QR-Code-Integration und modernen Dashboards.

Perfekt für Restaurants, Cafés oder Bars, die ihre Gästeverwaltung digital, live und ohne komplizierte Installation umsetzen wollen.

<?php
/**
Ein Dreamcodes.NET Codeschnipsel
 */

// -----------------------------
// Basisverzeichnisse
// -----------------------------
$baseDir = __DIR__;
$folders = [
    "$baseDir/public",
    "$baseDir/public/css",
    "$baseDir/public/js",
    "$baseDir/api",
    "$baseDir/data"
];
foreach ($folders as $f) if(!is_dir($f)) mkdir($f,0777,true);

// -----------------------------
// CSS
// -----------------------------
$cssFile = "$baseDir/public/css/style.css";
if(!file_exists($cssFile)){
    file_put_contents($cssFile, <<<CSS
body { font-family:Arial,sans-serif; margin:0; padding:0; background:#f2f2f2; }
header { background:#333;color:#fff;padding:15px;font-size:24px; }
main { padding:20px; }
.card { background:#fff;padding:20px;margin-bottom:20px;border-radius:8px;box-shadow:0 4px 8px rgba(0,0,0,.1);}
button { padding:10px 14px;border:none;border-radius:6px;background:#007bff;color:white;cursor:pointer;}
table{width:100%;border-collapse:collapse;}
td,th{padding:10px;border-bottom:1px solid #ddd;}
#qrcode{margin-top:20px;}
CSS
);
}

// -----------------------------
// JS
// -----------------------------
$jsFile = "$baseDir/public/js/app.js";
if(!file_exists($jsFile)){
    file_put_contents($jsFile, <<<JS
let ws;
function connectWS(role){
    ws = new WebSocket('ws://localhost:8080');
    ws.onopen = ()=>ws.send(JSON.stringify({type:'join',role}));
    ws.onmessage = e=>{
        const msg = JSON.parse(e.data);
        if(msg.type==='newEntry') updateUI(msg.entry);
        if(msg.type==='updateEntry') updateUI(msg.entry);
    };
}

function ajax(action,data,callback){
    data.action=action;
    fetch('/api/api.php',{method:'POST',body:new URLSearchParams(data)})
        .then(r=>r.json()).then(callback);
}
JS
);
}

// -----------------------------
// API
// -----------------------------
$apiFile = "$baseDir/api/api.php";
if(!file_exists($apiFile)){
    file_put_contents($apiFile, <<<PHP
<?php
session_start();
header('Content-Type: application/json');

\$dataFile = __DIR__.'/../data/db.json';
if(!file_exists(\$dataFile)) file_put_contents(\$dataFile,'[]');
\$db = json_decode(file_get_contents(\$dataFile),true);

\$action = \$_GET['action']??'';

function save(\$db,\$file){ file_put_contents(\$file,json_encode(\$db,JSON_PRETTY_PRINT)); }

switch(\$action){
    case 'login':
        \$pin = \$_POST['pin']??'';
        if(\$pin==='1234'){ \$_SESSION['admin']=true; echo json_encode(['ok'=>true]); }
        else echo json_encode(['ok'=>false]);
        exit;

    case 'add':
        \$entry=[
            'id'=>uniqid(),
            'name'=>htmlspecialchars(\$_POST['name']??''),
            'guests'=>intval(\$_POST['guests']??0),
            'table'=>null,
            'status'=>'waiting',
            'time'=>date('H:i')
        ];
        \$db[]=\$entry;
        save(\$db,\$dataFile);
        file_put_contents(__DIR__.'/../data/ws_push.json',json_encode(['type'=>'newEntry','entry'=>\$entry]));
        echo json_encode(['ok'=>true,'entry'=>\$entry]);
        exit;

    case 'update':
        foreach(\$db as &\$e){
            if(\$e['id']===\$_POST['id']){
                if(isset(\$_POST['table'])) \$e['table']=$_POST['table'];
                if(isset(\$_POST['status'])) \$e['status']=$_POST['status'];
            }
        }
        save(\$db,\$dataFile);
        file_put_contents(__DIR__.'/../data/ws_push.json',json_encode(['type'=>'updateEntry','entry'=>$_POST]));
        echo json_encode(['ok'=>true]);
        exit;

    case 'list':
        echo json_encode(\$db); exit;
}
echo json_encode(['ok'=>false,'msg'=>'no action']);
PHP
);
}

// -----------------------------
// Gäste-Seite mit QR-Code
// -----------------------------
$guestFile = "$baseDir/public/guest.html";
$qrUrl = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/public/guest.html';
if(!file_exists($guestFile)){
    file_put_contents($guestFile, <<<HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/style.css">
<script src="js/app.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
</head>
<body>
<header>Gäste Anmeldung</header>
<main>
<div class="card">
<input id="name" placeholder="Name">
<input id="guests" type="number" placeholder="Anzahl Gäste">
<button onclick="addGuest()">Eintragen</button>
<div id="qrcode"></div>
</div>
<script>
connectWS('guest');
function addGuest(){
    let n=name.value, g=guests.value;
    ajax('add',{name:n,guests:g},function(res){
        if(res.ok){ alert('Danke, '+res.entry.name+'!'); name.value=''; guests.value=''; }
    });
}

// QR-Code erzeugen
new QRCode(document.getElementById("qrcode"), {
    text: "$qrUrl",
    width: 160,
    height: 160
});
</script>
</main>
</body>
</html>
HTML
);
}

// -----------------------------
// Service-Seite
// -----------------------------
$serviceFile = "$baseDir/public/service.html";
if(!file_exists($serviceFile)){
    file_put_contents($serviceFile, <<<HTML
<!DOCTYPE html>
<html>
<head><link rel="stylesheet" href="css/style.css"><script src="js/app.js"></script></head>
<body>
<header>Service Dashboard</header>
<main>
<table><thead><tr><th>Name</th><th>Gäste</th><th>Tisch</th><th>Status</th><th></th></tr></thead>
<tbody id="rows"></tbody></table>
</main>
<script>
connectWS('service');

function updateUI(e){
    let tbody=document.getElementById('rows');
    let row=document.getElementById(e.id);
    if(!row){
        tbody.innerHTML+=\`<tr id="\${e.id}"><td>\${e.name}</td><td>\${e.guests}</td>
        <td><input value="\${e.table??''}" onchange="update('\${e.id}','table',this.value)"></td>
        <td>\${e.status}</td>
        <td><button onclick="update('\${e.id}','status','seated')">✔</button></td></tr>\`;
    } else {
        row.cells[2].firstChild.value = e.table??'';
        row.cells[3].textContent = e.status;
    }
}

function update(id,field,val){
    let data={id}; data[field]=val;
    ajax('update',data,function(){ ws.send(JSON.stringify({type:'updateEntry',entry:data})); });
}

// Initial fetch
ajax('list',{},function(list){ list.forEach(updateUI); });
</script>
</body>
</html>
HTML
);
}

// -----------------------------
// Küchenansicht
// -----------------------------
$kitchenFile = "$baseDir/public/kitchen.html";
if(!file_exists($kitchenFile)){
    file_put_contents($kitchenFile, <<<HTML
<!DOCTYPE html>
<html>
<head><link rel="stylesheet" href="css/style.css"><script src="js/app.js"></script></head>
<body>
<header>Küchen Monitor</header>
<main>
<ul id="queue"></ul>
</main>
<script>
connectWS('kitchen');

function updateUI(e){
    let ul=document.getElementById('queue');
    let li=document.getElementById('li_'+e.id);
    if(!li && e.status==='waiting'){
        ul.innerHTML+='<li id="li_'+e.id+'">'+e.name+' ('+e.guests+')</li>';
    } else if(li && e.status!=='waiting'){
        li.remove();
    }
}

// Initial fetch
ajax('list',{},function(list){ list.forEach(updateUI); });
</script>
</body>
</html>
HTML
);
}

// -----------------------------
// Admin-Login
// -----------------------------
$adminFile = "$baseDir/public/admin.html";
if(!file_exists($adminFile)){
    file_put_contents($adminFile, <<<HTML
<!DOCTYPE html>
<html>
<head><link rel="stylesheet" href="css/style.css"><script src="js/app.js"></script></head>
<body>
<header>Admin Login</header>
<main>
<div class="card">
<input id="pin" placeholder="PIN">
<button onclick="login()">Login</button>
</div>
<script>
function login(){
    ajax('login',{pin:pin.value},function(res){
        if(res.ok) location='service.html';
        else alert('Falscher PIN');
    });
}
</script>
</main>
</body>
</html>
HTML
);
}

// -----------------------------
// Setup abgeschlossen
// -----------------------------
echo "<h1>Setup abgeschlossen!</h1>";
echo "<ul>
<li><a href='public/guest.html'>Gäste</a></li>
<li><a href='public/service.html'>Service/Kellner</a></li>
<li><a href='public/kitchen.html'>Küche</a></li>
<li><a href='public/admin.html'>Admin</a></li>
</ul>";
echo "<p>Datenbank: data/db.json</p>";
echo "<p>Bitte starten Sie zusätzlich den WebSocket-Server auf ws://localhost:8080</p>";

Schritte nach Setup:

  1. Datei Php Dateieinmal im Browser aufrufen → alles wird erstellt.
  2. WebSocket-Server starten (PHP Ratchet):
<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
require __DIR__.'/vendor/autoload.php';

class GuestFlowWS implements MessageComponentInterface {
    protected $clients;
    public function __construct(){ $this->clients = new \SplObjectStorage; }
    public function onOpen(ConnectionInterface $conn){ $this->clients->attach($conn); }
    public function onMessage(ConnectionInterface $from, $msg){
        foreach($this->clients as $client){ if($from!==$client) $client->send($msg); }
    }
    public function onClose(ConnectionInterface $conn){ $this->clients->detach($conn); }
    public function onError(ConnectionInterface $conn, \Exception $e){ $conn->close(); }
}

$app = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(new Ratchet\WebSocket\WsServer(new GuestFlowWS())),
    new React\Socket\SocketServer('0.0.0.0:8080')
);
$app->run();

Die mobile Version verlassen