Files
foodlinkk-command-center/cockpit/templates/products.html
T
Aissa 5d60d33db1 Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering,
reclamefolder filters, Proxmox monitoring en documentatie.
2026-06-09 00:41:27 +00:00

42 lines
2.5 KiB
HTML

{% extends "base.html" %}
{% block content %}
<div x-data="productsCrud()">
<header class="page-header"><h1>Products</h1><p class="subtitle page-tip">SKU catalog with margin calculator.</p></header>
<button class="btn btn-primary" @click="show=true; id=null">Add product</button>
<section class="panel"><h2>Margin calculator</h2>
<div class="form-grid"><input type="number" class="form-input" x-model="margin.cost" placeholder="Cost" />
<input type="number" class="form-input" x-model="margin.sell" placeholder="Sell" />
<button class="btn btn-secondary" @click="calcMargin()">Calculate</button></div>
<p x-show="margin.result">Margin: <strong x-text="margin.result"></strong>%</p></section>
<table class="data-table"><thead><tr><th>Name</th><th>Status</th><th>Margin %</th><th></th></tr></thead>
<tbody>{% for p in products %}<tr class="clickable-row" @click="edit({{ p.id }}, '{{ p.name|e }}', '{{ p.status|e }}', {{ p.margin_pct or 0 }})">
<td>{{ p.name }}</td><td>{{ p.status }}</td><td>{{ p.margin_pct }}</td>
<td><button class="btn btn-sm btn-reject" @click.stop="remove({{ p.id }})">Delete</button></td></tr>{% endfor %}</tbody></table>
<div class="modal" :class="{ open: show }" @click.self="show=false"><div class="modal-card">
<input class="form-input" x-model="form.name" /><input class="form-input" x-model="form.status" /><input type="number" class="form-input" x-model="form.margin_pct" />
<button class="btn btn-primary" @click="save()">Save</button></div></div>
</div>
{% endblock %}
{% block scripts %}
<script>
function productsCrud() {
return {
show: false, id: null, form: { name: '', status: 'concept', margin_pct: 0, client_id: null },
margin: { cost: 0, sell: 0, result: null },
edit(id, name, status, margin_pct) { this.id=id; this.form={name,status,margin_pct,client_id:null}; this.show=true; },
async calcMargin() {
const r = await Cockpit.api('/products/margin-calc', { method: 'POST', body: JSON.stringify({ cost: +this.margin.cost, sell: +this.margin.sell }) });
this.margin.result = r.margin_pct;
},
async save() {
const body = { ...this.form, margin_pct: parseFloat(this.form.margin_pct) };
if (this.id) await Cockpit.api('/products/' + this.id, { method: 'PUT', body: JSON.stringify(body) });
else await Cockpit.api('/products', { method: 'POST', body: JSON.stringify(body) });
location.reload();
},
async remove(id) { if (!Cockpit.confirmDelete()) return; await Cockpit.api('/products/' + id, { method: 'DELETE' }); location.reload(); }
};
}
</script>
{% endblock %}