Files
NaMesa_site/mockups/03_mesas.html

555 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ReservaMesa — Mapa de Mesas Mockup</title>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg-primary: #0F0E0C;
--bg-secondary: #1A1814;
--bg-tertiary: #252219;
--bg-hover: #2E2A22;
--brand: #D4891A;
--brand-light: #E8A832;
--brand-muted: #3D2E0F;
--status-confirmed: #10B981;
--status-pending: #F59E0B;
--status-seated: #3B82F6;
--status-cancelled: #EF4444;
--text-primary: #F5F0E8;
--text-secondary: #A09880;
--text-muted: #6B6355;
--border: #2A261E;
--border-strong: #3D3828;
--font-display: 'Playfair Display', serif;
--font-body: 'DM Sans', sans-serif;
--font-mono: 'DM Mono', monospace;
}
body { font-family: var(--font-body); background: var(--bg-primary); color: var(--text-primary); display: flex; height: 100vh; overflow: hidden; font-size: 14px; }
.sidebar { width: 220px; flex-shrink: 0; background: var(--bg-secondary); border-right: 1px solid var(--border); display: flex; flex-direction: column; }
.sidebar-logo { padding: 20px 20px 16px; border-bottom: 1px solid var(--border); }
.logo-mark { font-family: var(--font-display); font-size: 18px; font-weight: 700; color: var(--brand-light); }
.logo-sub { font-size: 10px; color: var(--text-muted); letter-spacing: 1.5px; text-transform: uppercase; }
.sidebar-restaurant { padding: 12px 16px; margin: 10px; background: var(--bg-tertiary); border-radius: 8px; border: 1px solid var(--border); }
.restaurant-name { font-weight: 600; font-size: 12px; }
.restaurant-status { font-size: 10px; color: var(--status-confirmed); display: flex; align-items: center; gap: 4px; margin-top: 2px; }
.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.nav-section { padding: 6px 10px 0; flex: 1; }
.nav-label { font-size: 9px; color: var(--text-muted); letter-spacing: 1.5px; text-transform: uppercase; padding: 8px 8px 4px; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 7px; color: var(--text-secondary); cursor: pointer; font-size: 13px; font-weight: 500; margin-bottom: 1px; }
.nav-item.active { background: var(--brand-muted); color: var(--brand-light); }
.nav-icon { width: 16px; height: 16px; }
.nav-badge { margin-left: auto; background: var(--brand); color: #000; font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 10px; }
.sidebar-footer { padding: 12px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 10px; }
.avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--brand-muted); border: 2px solid var(--brand); display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: var(--brand-light); }
.footer-name { font-size: 12px; font-weight: 600; }
.footer-role { font-size: 10px; color: var(--text-muted); }
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.topbar { height: 56px; background: var(--bg-secondary); border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 24px; gap: 16px; flex-shrink: 0; }
.topbar-title { font-family: var(--font-display); font-size: 18px; font-weight: 600; flex: 1; }
.topbar-date { font-size: 12px; color: var(--text-muted); font-family: var(--font-mono); }
.btn { display: flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 7px; font-size: 12px; font-weight: 600; cursor: pointer; border: none; font-family: var(--font-body); }
.btn-primary { background: var(--brand); color: #000; }
.btn-ghost { background: transparent; color: var(--text-secondary); border: 1px solid var(--border-strong); }
/* CONTENT */
.content { flex: 1; display: flex; overflow: hidden; }
/* FLOOR PLAN AREA */
.floorplan-area { flex: 1; padding: 20px; overflow: auto; position: relative; }
.zone-label {
font-size: 10px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 1.5px;
font-weight: 600;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.zone-label::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.floor-section {
margin-bottom: 24px;
}
.tables-layout {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
/* TABLE SHAPES */
.table-item {
position: relative;
cursor: pointer;
transition: transform 0.15s;
}
.table-item:hover { transform: scale(1.04); }
.table-rect {
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2px solid transparent;
position: relative;
}
.table-rect.free {
background: rgba(16,185,129,0.08);
border-color: rgba(16,185,129,0.4);
}
.table-rect.reserved {
background: rgba(245,158,11,0.08);
border-color: rgba(245,158,11,0.4);
}
.table-rect.occupied {
background: rgba(59,130,246,0.08);
border-color: rgba(59,130,246,0.4);
}
.table-rect.selected {
box-shadow: 0 0 0 3px var(--brand);
border-color: var(--brand);
background: var(--brand-muted);
}
.table-num {
font-family: var(--font-display);
font-size: 18px;
font-weight: 700;
}
.table-rect.free .table-num { color: var(--status-confirmed); }
.table-rect.reserved .table-num { color: var(--status-pending); }
.table-rect.occupied .table-num { color: var(--status-seated); }
.table-rect.selected .table-num { color: var(--brand-light); }
.table-pax {
font-size: 10px;
margin-top: 2px;
opacity: 0.7;
}
.table-rect.free .table-pax { color: var(--status-confirmed); }
.table-rect.reserved .table-pax { color: var(--status-pending); }
.table-rect.occupied .table-pax { color: var(--status-seated); }
/* Chairs decoration */
.chair {
position: absolute;
width: 10px;
height: 10px;
border-radius: 3px;
background: currentColor;
opacity: 0.25;
}
/* LEGEND */
.legend {
display: flex;
gap: 16px;
align-items: center;
padding: 12px 20px;
border-bottom: 1px solid var(--border);
background: var(--bg-secondary);
}
.legend-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 11px;
color: var(--text-secondary);
}
.legend-dot { width: 10px; height: 10px; border-radius: 3px; }
.legend-dot.free { background: rgba(16,185,129,0.3); border: 1.5px solid var(--status-confirmed); }
.legend-dot.reserved { background: rgba(245,158,11,0.3); border: 1.5px solid var(--status-pending); }
.legend-dot.occupied { background: rgba(59,130,246,0.3); border: 1.5px solid var(--status-seated); }
/* DETAIL PANEL */
.detail-panel {
width: 280px;
background: var(--bg-secondary);
border-left: 1px solid var(--border);
display: flex;
flex-direction: column;
overflow: hidden;
}
.detail-header {
padding: 16px 18px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 10px;
}
.detail-title {
font-family: var(--font-display);
font-size: 16px;
font-weight: 600;
flex: 1;
}
.mesa-status-indicator {
padding: 4px 10px;
border-radius: 20px;
font-size: 11px;
font-weight: 600;
}
.mesa-status-indicator.reserved { background: rgba(245,158,11,0.15); color: var(--status-pending); }
.detail-body { padding: 16px 18px; flex: 1; display: flex; flex-direction: column; gap: 14px; }
.detail-row {
display: flex;
flex-direction: column;
gap: 3px;
}
.detail-label { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.8px; }
.detail-value { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.detail-value.mono { font-family: var(--font-mono); color: var(--brand-light); }
.detail-divider { height: 1px; background: var(--border); margin: 4px 0; }
.client-card {
background: var(--bg-tertiary);
border: 1px solid var(--border);
border-radius: 8px;
padding: 12px;
}
.client-card-name { font-size: 14px; font-weight: 700; }
.client-card-phone { font-size: 12px; color: var(--text-muted); font-family: var(--font-mono); margin-top: 2px; }
.client-card-note { font-size: 11px; color: var(--brand); margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.detail-actions { padding: 14px 18px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 6px; }
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }
.mockup-label { position: fixed; bottom: 12px; right: 16px; font-size: 10px; color: var(--text-muted); font-family: var(--font-mono); letter-spacing: 1px; opacity: 0.5; }
svg { display: block; }
</style>
</head>
<body>
<aside class="sidebar">
<div class="sidebar-logo">
<div class="logo-mark">ReservaMesa</div>
<div class="logo-sub">Dashboard</div>
</div>
<div style="padding: 10px;">
<div class="sidebar-restaurant">
<div class="restaurant-name">Restaurante Solar</div>
<div class="restaurant-status"><span class="dot"></span> Aberto agora</div>
</div>
</div>
<nav class="nav-section">
<div class="nav-label">Principal</div>
<div class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
Dashboard
</div>
<div class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"/><path d="m9 16 2 2 4-4"/></svg>
Reservas
<span class="nav-badge">12</span>
</div>
<div class="nav-item active">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/></svg>
Mesas
</div>
<div class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
Calendário
</div>
<div class="nav-label" style="margin-top:8px">Análise</div>
<div class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>
Analytics
</div>
<div class="nav-label" style="margin-top:8px">Gestão</div>
<div class="nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93a10 10 0 0 0-14.14 0"/></svg>
Configurações
</div>
</nav>
<div class="sidebar-footer">
<div class="avatar">JS</div>
<div style="flex:1"><div class="footer-name">João Silva</div><div class="footer-role">Gestor</div></div>
</div>
</aside>
<main class="main">
<div class="topbar">
<div class="topbar-title">Mapa de Mesas</div>
<div class="topbar-date">Quarta, 6 Mai 2026 · 19:00</div>
<div style="display:flex;gap:8px">
<button class="btn btn-ghost">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
Editar Layout
</button>
<button class="btn btn-primary">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
Adicionar Mesa
</button>
</div>
</div>
<!-- LEGEND -->
<div class="legend">
<span style="font-size:11px;color:var(--text-muted);font-weight:600;margin-right:4px">Estado das Mesas:</span>
<div class="legend-item"><div class="legend-dot free"></div>Livre (5)</div>
<div class="legend-item"><div class="legend-dot reserved"></div>Reservada (6)</div>
<div class="legend-item"><div class="legend-dot occupied"></div>Ocupada (5)</div>
<div style="margin-left:auto;font-size:11px;color:var(--text-muted)">Clique numa mesa para ver detalhes</div>
</div>
<div class="content">
<!-- FLOOR PLAN -->
<div class="floorplan-area">
<!-- Interior Zone -->
<div class="floor-section">
<div class="zone-label">Interior</div>
<div class="tables-layout">
<!-- Table 1 - Occupied (2p) -->
<div class="table-item">
<div class="table-rect occupied" style="width:72px;height:72px">
<div class="table-num">1</div>
<div class="table-pax">2 pax</div>
</div>
</div>
<!-- Table 2 - Free (4p) -->
<div class="table-item">
<div class="table-rect free" style="width:88px;height:72px">
<div class="table-num">2</div>
<div class="table-pax">4 pax</div>
</div>
</div>
<!-- Table 3 - Reserved (selected) -->
<div class="table-item">
<div class="table-rect selected" style="width:72px;height:72px">
<div class="table-num" style="color:var(--brand-light)">3</div>
<div class="table-pax" style="color:var(--brand)">2 pax</div>
</div>
</div>
<!-- Table 4 - Occupied (6p) - long table -->
<div class="table-item">
<div class="table-rect occupied" style="width:140px;height:72px">
<div class="table-num">4</div>
<div class="table-pax">6 pax</div>
</div>
</div>
<!-- Table 5 - Free (4p) -->
<div class="table-item">
<div class="table-rect free" style="width:88px;height:72px">
<div class="table-num">5</div>
<div class="table-pax">4 pax</div>
</div>
</div>
<!-- Table 6 - Reserved (3p) -->
<div class="table-item">
<div class="table-rect reserved" style="width:80px;height:72px">
<div class="table-num">6</div>
<div class="table-pax">3 pax</div>
</div>
</div>
<!-- Table 7 - Occupied (2p) -->
<div class="table-item">
<div class="table-rect occupied" style="width:72px;height:72px">
<div class="table-num">7</div>
<div class="table-pax">2 pax</div>
</div>
</div>
<!-- Table 8 - Free (4p) -->
<div class="table-item">
<div class="table-rect free" style="width:88px;height:72px">
<div class="table-num">8</div>
<div class="table-pax">4 pax</div>
</div>
</div>
</div>
</div>
<!-- Exterior Zone -->
<div class="floor-section">
<div class="zone-label">Exterior / Esplanada</div>
<div class="tables-layout">
<!-- Table 9 - Reserved (6p) -->
<div class="table-item">
<div class="table-rect reserved" style="width:120px;height:72px">
<div class="table-num">9</div>
<div class="table-pax">6 pax</div>
</div>
</div>
<!-- Table 10 - Occupied (4p) -->
<div class="table-item">
<div class="table-rect occupied" style="width:88px;height:72px">
<div class="table-num">10</div>
<div class="table-pax">4 pax</div>
</div>
</div>
<!-- Table 11 - Reserved (2p) -->
<div class="table-item">
<div class="table-rect reserved" style="width:72px;height:72px">
<div class="table-num">11</div>
<div class="table-pax">2 pax</div>
</div>
</div>
<!-- Table 12 - Occupied (8p) - banquet -->
<div class="table-item">
<div class="table-rect occupied" style="width:180px;height:80px">
<div class="table-num">12</div>
<div class="table-pax">8 pax · Grupo Empresa XY</div>
</div>
</div>
</div>
</div>
<!-- VIP Zone -->
<div class="floor-section">
<div class="zone-label">VIP / Privado</div>
<div class="tables-layout">
<!-- Table 13 - Free (4p) -->
<div class="table-item">
<div class="table-rect free" style="width:88px;height:72px; border-style: dashed;">
<div class="table-num">13</div>
<div class="table-pax">4 pax</div>
</div>
</div>
<!-- Table 14 - Reserved (4p) -->
<div class="table-item">
<div class="table-rect reserved" style="width:88px;height:72px; border-style: dashed;">
<div class="table-num">14</div>
<div class="table-pax">4 pax</div>
</div>
</div>
<!-- Table 15 - Free (2p) -->
<div class="table-item">
<div class="table-rect free" style="width:72px;height:72px; border-style: dashed;">
<div class="table-num">15</div>
<div class="table-pax">2 pax</div>
</div>
</div>
<!-- Table 16 - Occupied (6p) -->
<div class="table-item">
<div class="table-rect occupied" style="width:120px;height:72px; border-style: dashed;">
<div class="table-num">16</div>
<div class="table-pax">6 pax</div>
</div>
</div>
</div>
</div>
</div>
<!-- DETAIL PANEL - shown when table selected -->
<div class="detail-panel">
<div class="detail-header">
<div class="detail-title">Mesa 3</div>
<div class="mesa-status-indicator reserved">Reservada</div>
</div>
<div class="detail-body">
<div class="detail-row">
<div class="detail-label">Zona</div>
<div class="detail-value">Interior</div>
</div>
<div class="detail-row">
<div class="detail-label">Capacidade</div>
<div class="detail-value">2 pessoas</div>
</div>
<div class="detail-divider"></div>
<div class="detail-label" style="margin-bottom: 6px;">Reserva Atual</div>
<div class="detail-row">
<div class="detail-label">Hora</div>
<div class="detail-value mono">21:30</div>
</div>
<div class="client-card">
<div class="client-card-name">Sofia Lopes</div>
<div class="client-card-phone">+351 925 147 369</div>
<div class="client-card-note">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:inline;margin-right:4px"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
Jantar especial — aniversário
</div>
</div>
<div class="detail-row">
<div class="detail-label">Grupo</div>
<div class="detail-value">2 pessoas</div>
</div>
</div>
<div class="detail-actions">
<button class="btn btn-primary" style="width:100%;justify-content:center;font-size:12px;padding:9px">
Confirmar Reserva
</button>
<button class="btn btn-ghost" style="width:100%;justify-content:center;font-size:12px;padding:9px">
Ver Detalhe Completo
</button>
<button class="btn" style="width:100%;justify-content:center;font-size:12px;padding:9px;color:var(--status-cancelled);border:1px solid rgba(239,68,68,0.3);">
Cancelar Reserva
</button>
</div>
</div>
</div>
</main>
<div class="mockup-label">MOCKUP v1.0 — RESERVAMESA MESAS</div>
</body>
</html>