feat(server): /imprimir — página A4 com QR + instruções pronta pra impressão

This commit is contained in:
PontualTech / Karlão 2026-04-28 05:36:59 -03:00
parent c89f71885c
commit fe78a4afa9

View file

@ -267,6 +267,71 @@ app.get('/.well-known/assetlinks.json', (req, res) => {
const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.3.0/Shivao-v1.3.0.apk'; const LATEST_APK_URL = 'https://git.pontualtech.work/karlao/shivao-projeto/releases/download/v1.3.0/Shivao-v1.3.0.apk';
app.get('/apk', (req, res) => res.redirect(302, LATEST_APK_URL)); app.get('/apk', (req, res) => res.redirect(302, LATEST_APK_URL));
// Página A4 imprimível com QR Code + instruções (cola no barco/marina)
app.get('/imprimir', (req, res) => {
const url = `https://${req.headers.host || 'shivao.pontualtech.work'}/apk`;
const qrApi = `https://api.qrserver.com/v1/create-qr-code/?size=480x480&data=${encodeURIComponent(url)}&color=0e2a3d&bgcolor=ffffff&qzone=2&format=png`;
res.type('html').send(`<!DOCTYPE html><html lang="pt-BR"><head><meta charset="UTF-8"><title>Imprimir · QR Code Shivao</title><style>
@page{size:A4;margin:0}
*{box-sizing:border-box;-webkit-print-color-adjust:exact;print-color-adjust:exact}
body{margin:0;padding:0;background:#efe5cd;font-family:Georgia,serif;color:#0e2a3d}
.page{width:210mm;min-height:297mm;padding:25mm 20mm;margin:0 auto;background:linear-gradient(180deg,#fbf5e2 0%,#efe5cd 100%);position:relative;overflow:hidden}
.page::before{content:'';position:absolute;top:0;left:0;right:0;height:8mm;background:linear-gradient(90deg,#0e2a3d,#a07832,#0e2a3d)}
.page::after{content:'';position:absolute;bottom:0;left:0;right:0;height:8mm;background:linear-gradient(90deg,#0e2a3d,#a07832,#0e2a3d)}
.head{text-align:center;margin-bottom:8mm}
.brand{display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:6mm}
.compass{width:42px;height:42px;border:2.5px solid #a07832;border-radius:50%;position:relative;flex-shrink:0}
.compass::before,.compass::after{content:'';position:absolute;background:#a07832}
.compass::before{top:50%;left:-3px;right:-3px;height:2px;transform:translateY(-50%)}
.compass::after{top:-3px;bottom:-3px;left:50%;width:2px;transform:translateX(-50%)}
h1{font-style:italic;font-size:34pt;color:#a07832;margin:0;letter-spacing:-0.5px}
.subtitle{font-style:italic;font-size:13pt;color:#5d7186;margin-top:1mm}
.tagline{font-family:'Courier New',monospace;font-size:9pt;letter-spacing:3px;text-transform:uppercase;color:#7d6943;margin-top:2mm}
.qr-section{background:#fff;padding:10mm;border-radius:6mm;box-shadow:0 4px 16px rgba(14,42,61,.12);margin:8mm auto;width:fit-content;text-align:center;border:1px solid rgba(184,156,108,.3)}
.qr-section img{display:block;margin:0 auto;width:140mm;height:140mm;max-width:100%}
.qr-label{font-family:'Courier New',monospace;font-size:11pt;color:#0e2a3d;margin-top:5mm;letter-spacing:1px}
.steps{margin:8mm 0;display:grid;grid-template-columns:repeat(2,1fr);gap:5mm}
.step{background:rgba(255,255,255,.55);padding:5mm 6mm;border-radius:4mm;border-left:3px solid #a07832}
.step-num{font-family:'Courier New',monospace;font-size:9pt;color:#a07832;letter-spacing:2px;font-weight:600}
.step-text{font-size:11pt;line-height:1.5;margin-top:2mm;color:#0e2a3d}
.step-text strong{color:#0e2a3d}
.url-box{background:#0e2a3d;color:#efe5cd;padding:5mm 8mm;text-align:center;border-radius:4mm;margin-top:4mm}
.url-box .label{font-family:'Courier New',monospace;font-size:8pt;letter-spacing:3px;text-transform:uppercase;opacity:.7;margin-bottom:2mm}
.url-box .url{font-family:'Courier New',monospace;font-size:14pt;letter-spacing:1px;color:#c89f54;font-weight:600}
.foot{position:absolute;bottom:14mm;left:20mm;right:20mm;text-align:center;font-size:8pt;color:#5d7186;font-style:italic;line-height:1.6}
.foot a{color:#a07832;text-decoration:none}
.print-btn{position:fixed;bottom:20px;right:20px;background:#a07832;color:#fff;padding:14px 24px;border-radius:8px;border:none;font-family:Georgia,serif;font-size:14pt;cursor:pointer;box-shadow:0 4px 16px rgba(0,0,0,.2);z-index:1000}
@media print{.print-btn{display:none}}
</style></head><body>
<div class="page">
<div class="head">
<div class="brand"><div class="compass"></div><h1>Shivao</h1></div>
<div class="subtitle">Diário de Bordo · Aplicativo Náutico</div>
<div class="tagline">GPS · Vigia de Fundeio · Meteorologia</div>
</div>
<div class="qr-section">
<img src="${qrApi}" alt="QR Code">
<div class="qr-label">aponte a câmera do celular Android aqui </div>
</div>
<div class="steps">
<div class="step"><div class="step-num">PASSO 1</div><div class="step-text">Abra a <strong>câmera</strong> do seu Android e aponte pro QR Code acima</div></div>
<div class="step"><div class="step-num">PASSO 2</div><div class="step-text">Toque na notificação que aparece pra abrir o link no <strong>Chrome</strong></div></div>
<div class="step"><div class="step-num">PASSO 3</div><div class="step-text">O Chrome baixa o <strong>APK</strong> (3,4 MB). Toque no download <strong>Instalar</strong></div></div>
<div class="step"><div class="step-num">PASSO 4</div><div class="step-text">Aceite "fontes desconhecidas" se pedir. <strong>Pronto</strong> abra o ícone Shivao</div></div>
</div>
<div class="url-box">
<div class="label">Não tem leitor de QR? Digite no Chrome:</div>
<div class="url">shivao.pontualtech.work/apk</div>
</div>
<div class="foot">
Shivao · PontualTech · CNPJ 32.772.178/0001-47<br>
<a href="https://shivao.pontualtech.work/politica">shivao.pontualtech.work/politica</a> · <a href="https://shivao.pontualtech.work/termos">/termos</a>
</div>
</div>
<button class="print-btn" onclick="window.print()">🖨 Imprimir / Salvar PDF</button>
</body></html>`);
});
// QR Code da URL /apk pra facilitar instalação no celular // QR Code da URL /apk pra facilitar instalação no celular
app.get('/qr', (req, res) => { app.get('/qr', (req, res) => {
const url = `https://${req.headers.host || 'shivao.pontualtech.work'}/apk`; const url = `https://${req.headers.host || 'shivao.pontualtech.work'}/apk`;