Hope: O Primeiro Impacto
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HEINEKEN ON TRADE - GESTÃO CENTRALIZADA</title>
<!-- Google Fonts & FontAwesome Icons -->
<link href="https://googleapis.com" rel="stylesheet">
<link rel="stylesheet" href="https://cloudflare.com">
<style>
:root {
--heineken-green: #00824A;
--heineken-bright-green: #00F27E;
--heineken-red: #D61A22;
--bg-deep: #050a08;
--card-bg: rgba(255, 255, 255, 0.03);
--text-main: #f4f4f4;
--text-dim: #a0a0a0;
--glass-blur: blur(20px);
--glass-border: rgba(255, 255, 255, 0.08);
}
* { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Inter', sans-serif; }
body {
background-color: var(--bg-deep);
background-image: radial-gradient(circle at 50% 0%, #0c1a12 0%, #050a08 100%);
color: var(--text-main); padding-top: 85px; min-height: 100vh;
}
header {
position: fixed; top: 0; left: 0; width: 100%; height: 70px;
background: rgba(0, 10, 5, 0.7); backdrop-filter: var(--glass-blur);
display: flex; justify-content: space-between; align-items: center;
padding: 0 20px; border-bottom: 1px solid var(--glass-border); z-index: 9999;
}
.header-title { display: flex; align-items: center; gap: 10px; }
header h1 { font-size: 1.2rem; font-weight: 800; letter-spacing: 1px; }
.heineken-star { color: var(--heineken-red); font-size: 1.4rem; }
main { padding: 15px; max-width: 1200px; margin: 0 auto; }
.welcome-box, .section-card {
background: var(--card-bg); border: 1px solid var(--glass-border);
border-radius: 16px; padding: 24px; margin-bottom: 20px;
}
.welcome-box { border-top: 2px solid var(--heineken-bright-green); }
.welcome-box h2 { color: var(--heineken-bright-green); font-size: 1.2rem; margin-bottom: 4px; }
.welcome-box p { font-size: 0.85rem; color: var(--text-dim); }
.section-card h2 {
font-size: 1.1rem; color: var(--heineken-bright-green);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
padding-bottom: 12px; margin-bottom: 20px; display: flex; align-items: center; gap: 8px;
}
/* LAYOUT DUAS COLUNAS */
.dashboard-layout { display: grid; grid-template-columns: 1fr 2fr; gap: 20px; }
@media (max-width: 992px) { .dashboard-layout { grid-template-columns: 1fr; } }
/* FORMULÁRIO ESTILO DARK PREMIUM */
.form-group { margin-bottom: 15px; }
.form-group label { display: block; font-size: 0.85rem; margin-bottom: 6px; color: #d0d0d0; font-weight: 600; }
.form-input {
width: 100%; padding: 12px; border-radius: 8px;
background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.1);
color: #fff; font-size: 0.95rem; outline: none; transition: 0.3s;
}
.form-input:focus { border-color: var(--heineken-bright-green); background: rgba(0,0,0,0.5); }
/* TABELA */
.table-responsive { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; text-align: left; font-size: 0.9rem; }
th, td { padding: 12px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }
th { color: var(--heineken-bright-green); font-weight: 600; text-transform: uppercase; font-size: 0.8rem; }
.estado-ok { color: var(--heineken-bright-green); font-weight: 600; }
.estado-pendente { color: var(--heineken-red); font-weight: 600; }
/* BOTÕES */
.btn {
padding: 12px 20px; border: none; border-radius: 8px; width: 100%;
font-size: 0.9rem; font-weight: 600; cursor: pointer; text-transform: uppercase;
transition: all 0.3s ease; display: flex; justify-content: center; align-items: center; gap: 8px;
}
.btn-success { background-color: var(--heineken-green); color: white; }
.btn-success:hover { background-color: #00a35c; transform: translateY(-2px); }
.actions-cell { display: flex; gap: 8px; }
.btn-mini {
padding: 6px 10px; border: none; border-radius: 4px; font-size: 0.75rem;
font-weight: 600; cursor: pointer; background: rgba(255,255,255,0.1); color: #fff;
transition: 0.2s; display: inline-flex; align-items: center; gap: 4px;
}
.btn-edit:hover { background: var(--heineken-bright-green); color: #000; }
.btn-delete:hover { background: var(--heineken-red); color: #fff; }
/* MODAL */
.modal {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.8); backdrop-filter: blur(5px);
display: flex; justify-content: center; align-items: center; z-index: 10000;
opacity: 0; pointer-events: none; transition: opacity 0.3s ease;
}
.modal.active { opacity: 1; pointer-events: auto; }
.modal-content {
background: #0c1a12; border: 1px solid var(--heineken-bright-green);
padding: 25px; border-radius: 12px; width: 90%; max-width: 400px;
}
.modal-content h3 { font-size: 1.1rem; margin-bottom: 15px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; }
.modal-btn { padding: 8px 16px; border-radius: 6px; font-size: 0.85rem; font-weight: 600; cursor: pointer; border: none; }
.btn-save { background: var(--heineken-bright-green); color: #000; }
.btn-cancel { background: rgba(255,255,255,0.1); color: #fff; }
</style>
</head>
<body>
<header>
<div class="header-title">
<i class="fa-solid fa-star heineken-star"></i>
<h1>HEINEKEN ON TRADE</h1>
</div>
</header>
<main>
<div class="welcome-box">
<div>
<h2>Painel de Gestão Centralizada</h2>
<p>Registe novos postos de venda ou corrija localizações pendentes com gravação local automática.</p>
</div>
</div>
<div class="dashboard-layout">
<!-- COLUNA ESQUERDA: NOVO REGISTO -->
<section class="section-card">
<h2><i class="fa-solid fa-plus"></i> Novo PDV</h2>
<form id="form-novo-pdv" onsubmit="adicionarPDV(event)">
<div class="form-group">
<label for="pdv-nome">Nome do PDV</label>
<input type="text" id="pdv-nome" class="form-input" placeholder="Ex: Bar Central" required>
</div>
<div class="form-group">
<label for="pdv-local">Localização</label>
<input type="text" id="pdv-local" class="form-input" placeholder="Ex: Lisboa (ou ?? se pendente)">
</div>
<button type="submit" class="btn btn-success">
<i class="fa-solid fa-floppy-disk"></i> Registar PDV
</button>
</form>
</section>
<!-- COLUNA DIREITA: HISTÓRICO -->
<section class="section-card">
<h2><i class="fa-solid fa-list-check"></i> Histórico de Registos</h2>
<div class="table-responsive">
<table>
<thead>
<tr>
<th>PDV</th>
<th>Localização</th>
<th>Estado</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="historico-tbody"></tbody>
</table>
</div>
</section>
</div>
</main>
<!-- MODAL DE EDIÇÃO -->
<div class="modal" id="editModal">
<div class="modal-content">
<h3 id="modalTitle">Atualizar Local</h3>
<input type="text" id="newLocalInput" class="form-input" style="margin-bottom: 15px;" placeholder="Introduza o local correto">
<div class="modal-actions">
<button class="modal-btn btn-cancel" onclick="fecharModal()">Cancelar</button>
<button class="modal-btn btn-save" onclick="salvarAtualizacao()">Guardar</button>
</div>
</div>
</div>
<script>
// Dados iniciais de simulação
const dadosIniciais = [
{ id: 1, pdv: "Quiosque Praia", local: "Setúbal" },
{ id: 2, pdv: "Taberna Central", local: "??" },
{ id: 3, pdv: "Café do Bairro", local: "" },
{ id: 4, pdv: "Restaurante Mar", local: "Lisboa" }
];
let historicoExemplo = JSON.parse(localStorage.getItem('historico_pdv')) || dadosIniciais;
let idEmEdicao = null;
const tbody = document.getElementById('historico-tbody');
// RENDERIZAR TABELA COM INSERÇÃO EFICIENTE
function renderizarTabela() {
tbody.innerHTML = "";
historicoExemplo.forEach(item => {
const ehValido = item.local && item.local.trim() !== "" && !item.local.includes("?");
const classeEstado = ehValido ? "estado-ok" : "estado-pendente";
const textoEstado = ehValido ? "Ativo" : "Local ??";
const linhaHtml = `
<tr>
<td>${item.pdv}</td>
<td>${item.local || "Não informado"}</td>
<td class="${classeEstado}">${textoEstado}</td>