Files
WYGIWYH/app/templates/mini_tools/unit_price_calculator.html
2025-11-09 15:31:50 -03:00

186 lines
8.1 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n %}
{% block title %}{% translate 'Unit Price Calculator' %}{% endblock %}
{% block content %}
<div class="container px-md-3 py-3 column-gap-5">
<div class="text-3xl font-bold font-mono w-full mb-3">
<div>{% translate 'Unit Price Calculator' %}</div>
</div>
<div class="card bg-base-100 shadow mb-3 hidden" id="card-placeholder">
<div class="card-header bg-base-200 p-4 flex flex-row justify-between rounded-box">
<h5 class="title grow"></h5>
<button class="btn btn-error btn-sm"
role="button"
data-tippy-content="{% translate "Delete" %}"
_="on click remove the closest .card to me then trigger update on #items then trigger tooltips on body">
<i class="fa-solid fa-trash fa-fw"></i>
</button>
</div>
<div class="card-body">
<div class="grid lg:grid-cols-3 gap-3">
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Item price' %}</legend>
<input type="number" inputmode="decimal" class="input input-bordered w-full item-price" id="price">
</fieldset>
</div>
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Item amount' %}</legend>
<input type="number" inputmode="decimal" class="input input-bordered w-full item-amount" id="amount">
</fieldset>
</div>
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Unit price' %}</legend>
<div class="unit-price text-xl" data-amount="0">0</div>
</fieldset>
</div>
</div>
</div>
</div>
<div id="items" _="on input or update
for card in <.card />
set price to card.querySelector('.item-price').value
set amount to card.querySelector('.item-amount').value
// Calculate and format unit price
if amount > 0 set unitPrice to (price / amount) else set unitPrice to 0 end
set formattedUnitPrice to unitPrice.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40})
set card.querySelector('.unit-price').innerHTML to formattedUnitPrice
call card.querySelector('.unit-price').setAttribute('data-amount', unitPrice)
end
then
// Remove existing highlight classes from all unit prices
for unitPriceEl in <*.unit-price/>
remove .bg-error\/20 from the closest .card to unitPriceEl
remove .bg-success\/20 from the closest .card to unitPriceEl
end
// Get all unit prices and find min/max
set unitPrices to <.card:not(#card-placeholder) .unit-price/>
set unitPricesAmounts to <.card:not(#card-placeholder) .unit-price/> @data-amount
js(unitPricesAmounts)
unitPricesAmounts = unitPricesAmounts.filter(element => element !== '0')
return Math.min(...unitPricesAmounts)
end
set minAmount to it
js(unitPricesAmounts)
unitPricesAmounts = unitPricesAmounts.filter(element => element !== '0')
return Math.max(...unitPricesAmounts)
end
set maxAmount to it
if maxAmount and minAmount
for unitPriceEl in unitPrices
set amount to parseFloat(unitPriceEl.getAttribute('data-amount'))
if amount == minAmount
add .bg-success\/20 to the closest .card to unitPriceEl
add .bg-opacity-20 to the closest .card to unitPriceEl
continue
end
if amount == maxAmount
add .bg-error\/20 to the closest .card to unitPriceEl
add .bg-opacity-20 to the closest .card to unitPriceEl
end
end
end
end">
<div class="card bg-base-100 shadow mb-3">
<div class="card-header bg-base-200 p-4 flex flex-row justify-between rounded-box">
<h5>{% trans "Item" %} A</h5>
</div>
<div class="card-body">
<div class="grid lg:grid-cols-3 gap-3">
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Item price' %}</legend>
<input type="number" inputmode="decimal" class="input input-bordered w-full item-price" id="price">
</fieldset>
</div>
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Item amount' %}</legend>
<input type="number" inputmode="decimal" class="input input-bordered w-full item-amount" id="amount">
</fieldset>
</div>
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Unit price' %}</legend>
<div class="unit-price text-xl" data-amount="0">0</div>
</fieldset>
</div>
</div>
</div>
</div>
<div class="card bg-base-100 shadow mb-3">
<div class="card-header bg-base-200 p-4 flex flex-row justify-between rounded-box">
<h5>{% trans "Item" %} B</h5>
</div>
<div class="card-body">
<div class="grid lg:grid-cols-3 gap-3">
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Item price' %}</legend>
<input type="number" inputmode="decimal" class="input input-bordered w-full item-price" id="price">
</fieldset>
</div>
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Item amount' %}</legend>
<input type="number" inputmode="decimal" class="input input-bordered w-full item-amount" id="amount">
</fieldset>
</div>
<div>
<fieldset class="fieldset">
<legend class="fieldset-legend">{% trans 'Unit price' %}</legend>
<div class="unit-price text-xl" data-amount="0">0</div>
</fieldset>
</div>
</div>
</div>
</div>
</div>
<div class="grid lg:grid-cols-[2fr_1fr] gap-3 mt-6">
<div>
<button class="btn btn-primary w-full"
_="on click
get #card-placeholder
set newCard to it.cloneNode(true)
remove @id from newCard
remove .hidden from newCard then
set itemCount to <#items .card />'s length
if itemCount < 26
set letter to String.fromCharCode(65 + itemCount)
else
set letter to String.fromCharCode(65 + Math.floor((itemCount - 26) / 26)) + String.fromCharCode(65 + ((itemCount - 26) mod 26))
end
set newCard.querySelector('.title').innerHTML to `{% trans "Item" %} ${letter}`
put newCard as HTML at the end of #items
trigger tooltips on body
end">
{% trans 'Add' %}
</button>
</div>
<div>
<button class="btn btn-error w-full"
_="on click
for el in <.item-price, .item-amount />
set card to the closest .card to el
set el's value to ''
end
trigger update on #items
end">
{% trans 'Clear' %}
</button>
</div>
</div>
</div>
{% endblock %}