Webbserver - Love Blomberg

Show sourcecode

The following files exists in this folder. Click to view.

public_html/crumbs/admin/orders/

api.php
orders.php
sendmail.php
statusdisplay.php

statusdisplay.php

177 lines UTF-8 Unix (LF)
<?php
// SÄKERHET: Kräv admin-inloggning för att se statusdisplayen (förhindrar obehörig åtkomst)
session_start();
if (!isset(
$_SESSION['is_admin']) || $_SESSION['is_admin'] != 1) {
  
http_response_code(403);
  die(
"Åtkomst nekad. Endast admin kan se denna sida.");
}
?>
<!DOCTYPE html>
<html lang="sv">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Orderstatus - Crumbs</title>
  <link rel="stylesheet" href="../../style/stylesheet.css">
  <style>
    body { overflow: hidden; }

    .display-wrapper {
      display: flex;
      flex-direction: column;
      height: 100vh;
      padding: 28px;
      gap: 20px;
    }

    .legend {
      display: flex;
      justify-content: center;
      gap: 32px;
      flex-shrink: 0;
    }

    .legend-item {
      display: flex;
      align-items: center;
      gap: 10px;
      font-size: 20px;
      font-weight: 700;
      color: var(--text);
    }

    .legend-dot {
      width: 24px;
      height: 24px;
      border-radius: 50%;
    }

    .legend-dot.pending { background: var(--warning); }
    .legend-dot.preparing { background: var(--primary); }
    .legend-dot.done { background: var(--success); }

    .orders-grid {
      flex: 1;
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
      gap: 16px;
      align-content: start;
      overflow-y: auto;
    }

    .order-tile {
      display: flex;
      align-items: center;
      justify-content: center;
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 24px;
      aspect-ratio: 1;
      transition: transform var(--transition), opacity var(--transition);
    }

    .order-tile .order-number {
      font-size: 56px;
      font-weight: 900;
      color: #fff;
      text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
      line-height: 1;
    }

    .order-tile {
      height: 5rem;
    }

    .order-tile.pending {
      background: var(--warning);
      border-color: var(--warning);
    }

    .order-tile.preparing {
      background: var(--primary);
      border-color: var(--primary);
    }

    .order-tile.done {
      background: var(--success);
      border-color: var(--success);
    }

    .empty-message {
      grid-column: 1 / -1;
      text-align: center;
      color: var(--muted);
      font-size: 24px;
      font-weight: 700;
      padding: 80px 0;
    }

    @keyframes pulse-done {
      0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4); }
      50% { box-shadow: 0 0 0 12px rgba(34, 197, 94, 0); }
    }

    .order-tile.done {
      animation: pulse-done 2s ease-in-out infinite;
    }
  </style>
</head>
<body>
  <div class="display-wrapper">
    <div class="legend">
      <div class="legend-item">
        <div class="legend-dot pending"></div>
        Väntar
      </div>
      <div class="legend-item">
        <div class="legend-dot preparing"></div>
        Tillagas
      </div>
      <div class="legend-item">
        <div class="legend-dot done"></div>
        Klar att hämtas
      </div>
    </div>

    <div class="orders-grid" id="orders-grid">
      <div class="empty-message">Laddar beställningar...</div>
    </div>
  </div>

  <script>
    function renderOrders(orders) {
      const grid = document.getElementById('orders-grid');
      const active = orders.filter(o => o.status !== 'delivered');

      if (active.length === 0) {
        grid.innerHTML = '<div class="empty-message">Inga aktiva beställningar</div>';
        return;
      }

      // Sort: done first (ready for pickup), then preparing, then pending
      const statusOrder = { done: 0, preparing: 1, pending: 2 };
      active.sort((a, b) => statusOrder[a.status] - statusOrder[b.status]);

      const html = active.map(order => `
        <div class="order-tile ${order.status}">
          <span class="order-number">#${String(order.order_id).padStart(4, '0')}</span>
        </div>
      `).join('');

      grid.innerHTML = html;
    }

    function fetchOrders() {
      fetch('api.php')
        .then(res => res.json())
        .then(orders => renderOrders(orders))
        .catch(err => console.error('Kunde inte hämta beställningar:', err));
    }

    fetchOrders();
    setInterval(fetchOrders, 5000);
  </script>
</body>
</html>