Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
{% 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 %}
|
||||
Reference in New Issue
Block a user