Initial commit: aplicatie de cantarire si etichetare
Aplicatie Flask + SQLite pentru productie alimentara: cantarirea componentelor unui produs finit si tiparirea etichetei prin QZ Tray. - produse finite (retete) formate din componente cantarite - designer vizual de etichete (mm/px, zona sigura, campuri variabile, cod QR cu continut din mai multe bucati) - legare produs finit -> sablon de eticheta - navigare pe doua taburi: Cantarire / Setari - administrare: componente, produse finite, sabloane, campuri, istoric - backup, resetare baza de date, checklist de pregatire, /healthz - CLI de administrare si serviciu systemd pentru productie - vendor/syncpulse-scale-bridge (GPL-3.0-or-later) pentru citirea cantarului
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<!doctype html>
|
||||
<html lang="ro">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Etichetă {{ payload.fields.recipe_code }} · {{ payload.fields.total_weight }} {{ payload.fields.unit }}</title>
|
||||
<style>
|
||||
@page { size: {{ payload.template.width_mm }}mm {{ payload.template.height_mm }}mm; margin: 0; }
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; background: #e9edf1; }
|
||||
.preview-bar {
|
||||
position: sticky; top: 0; z-index: 2;
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
padding: 10px 16px; background: #0f172a; color: #fff;
|
||||
font: 14px/1.4 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
||||
}
|
||||
.preview-bar button {
|
||||
margin-left: auto; padding: 8px 16px; border: 0; border-radius: 6px;
|
||||
background: #14b8a6; color: #04201d; font-weight: 700; cursor: pointer;
|
||||
}
|
||||
.preview-stage { padding: 24px; display: flex; justify-content: center; }
|
||||
.label-sheet {
|
||||
width: {{ payload.template.width_mm }}mm;
|
||||
height: {{ payload.template.height_mm }}mm;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 6px 24px rgba(15, 23, 42, .18);
|
||||
}
|
||||
{{ payload.css|safe }}
|
||||
@media print {
|
||||
html, body { background: #fff; }
|
||||
.preview-bar, .preview-stage { padding: 0; }
|
||||
.preview-bar { display: none !important; }
|
||||
.label-sheet { box-shadow: none; margin: 0; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{% if preview %}
|
||||
<div class="preview-bar">
|
||||
<strong>Previzualizare șablon</strong>
|
||||
<span>{{ payload.template.name }} · {{ payload.template.width_mm|weight }} × {{ payload.template.height_mm|weight }} mm</span>
|
||||
<button type="button" onclick="window.print()">Tipărește previzualizarea</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="preview-stage">
|
||||
<div class="label-sheet" id="label-sheet">
|
||||
{{ payload.html|safe }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script id="label-payload" type="application/json">{{ payload|tojson }}</script>
|
||||
<script src="{{ url_for('static', filename='js/vendor/qz-tray.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/qz-print.js') }}"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var payload = JSON.parse(document.getElementById('label-payload').textContent);
|
||||
var auto = {{ 'true' if auto else 'false' }};
|
||||
var preview = {{ 'true' if preview else 'false' }};
|
||||
|
||||
function acknowledge() {
|
||||
if (preview) return;
|
||||
try {
|
||||
fetch(payload.ack_url, { method: 'POST', headers: { 'Accept': 'application/json' } });
|
||||
} catch (e) { /* tipărirea a reușit; confirmarea este auxiliară */ }
|
||||
}
|
||||
|
||||
function doPrint() {
|
||||
if (window.CantarirePrint && typeof window.CantarirePrint.print === 'function') {
|
||||
Promise.resolve(window.CantarirePrint.print(payload)).then(function (result) {
|
||||
if (result && result.method === 'qz') acknowledge();
|
||||
}, function (err) {
|
||||
console.error('Tipărirea QZ Tray a eșuat:', err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
window.print();
|
||||
acknowledge();
|
||||
}
|
||||
|
||||
window.addEventListener('load', function () {
|
||||
if (!auto) return;
|
||||
setTimeout(doPrint, 120);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user