mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-21 08:11:36 +02:00
183 lines
8.2 KiB
HTML
183 lines
8.2 KiB
HTML
{% extends "layouts/base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% translate 'Unit Price Calculator' %}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
|
<div>{% translate 'Unit Price Calculator' %}</div>
|
|
</div>
|
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:mb-3 tw:hidden" id="card-placeholder">
|
|
<div class="tw:card-header tw:bg-base-200 tw:p-4 tw:flex tw:flex-row tw:justify-between">
|
|
<h5 class="title tw:flex-grow"></h5>
|
|
<button class="tw:btn tw:btn-secondary tw:btn-sm tw:text-error"
|
|
role="button"
|
|
data-bs-toggle="tooltip"
|
|
data-bs-title="{% translate "Delete" %}"
|
|
_="on click remove the closest .tw\:card to me then trigger update on #items then call bootstrap.Tooltip.getOrCreateInstance(me).dispose()">
|
|
<i class="fa-solid fa-trash fa-fw"></i>
|
|
</button>
|
|
</div>
|
|
<div class="tw:card-body">
|
|
<div class="tw:grid tw:lg:grid-cols-3 tw:gap-3">
|
|
<div>
|
|
<div>
|
|
<label for="price" class="tw:label">{% trans 'Item price' %}</label>
|
|
<input type="number" inputmode="decimal" class="tw:input tw:input-bordered tw:w-full item-price" id="price">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div>
|
|
<label for="amount" class="tw:label">{% trans 'Item amount' %}</label>
|
|
<input type="number" inputmode="decimal" class="tw:input tw:input-bordered tw:w-full item-amount" id="amount">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="tw:label">{% trans 'Unit price' %}</label>
|
|
<div class="unit-price tw:text-xl" data-amount="0">0</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="items" _="on input or update
|
|
for card in <tw\\: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 .tw\:bg-error from the closest .tw\\:card to unitPriceEl
|
|
remove .tw\:bg-error from unitPriceEl's classList
|
|
remove .tw\:bg-success from the closest .tw\\:card to unitPriceEl
|
|
remove .tw\:bg-success from unitPriceEl's classList
|
|
end
|
|
|
|
// Get all unit prices and find min/max
|
|
set unitPrices to <.tw\:card\:not(#card-placeholder) .unit-price/>
|
|
set unitPricesAmounts to <.tw\: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 .tw\:bg-success to the closest .tw\:card to unitPriceEl
|
|
add .tw\:bg-opacity-20 to the closest .tw\:card to unitPriceEl
|
|
continue
|
|
end
|
|
if amount == maxAmount
|
|
add .tw\:bg-error to the closest .tw\:card to unitPriceEl
|
|
add .tw\:bg-opacity-20 to the closest .tw\:card to unitPriceEl
|
|
end
|
|
end
|
|
end
|
|
end">
|
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:mb-3">
|
|
<div class="tw:card-header tw:bg-base-200 tw:p-4">
|
|
<h5>{% trans "Item" %} A</h5>
|
|
</div>
|
|
<div class="tw:card-body">
|
|
<div class="tw:grid tw:lg:grid-cols-3 tw:gap-3">
|
|
<div>
|
|
<div>
|
|
<label for="price" class="tw:label">{% trans 'Item price' %}</label>
|
|
<input type="number" inputmode="decimal" class="tw:input tw:input-bordered tw:w-full item-price" id="price">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div>
|
|
<label for="amount" class="tw:label">{% trans 'Item amount' %}</label>
|
|
<input type="number" inputmode="decimal" class="tw:input tw:input-bordered tw:w-full item-amount" id="amount">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="tw:label">{% trans 'Unit price' %}</label>
|
|
<div class="unit-price tw:text-xl" data-amount="0">0</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:mb-3">
|
|
<div class="tw:card-header tw:bg-base-200 tw:p-4">
|
|
<h5>{% trans "Item" %} B</h5>
|
|
</div>
|
|
<div class="tw:card-body">
|
|
<div class="tw:grid tw:lg:grid-cols-3 tw:gap-3">
|
|
<div>
|
|
<div>
|
|
<label for="price" class="tw:label">{% trans 'Item price' %}</label>
|
|
<input type="number" inputmode="decimal" class="tw:input tw:input-bordered tw:w-full item-price" id="price">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div>
|
|
<label for="amount" class="tw:label">{% trans 'Item amount' %}</label>
|
|
<input type="number" inputmode="decimal" class="tw:input tw:input-bordered tw:w-full item-amount" id="amount">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="tw:label">{% trans 'Unit price' %}</label>
|
|
<div class="unit-price tw:text-xl" data-amount="0">0</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tw:grid tw:lg:grid-cols-[2fr_1fr] tw:gap-3 tw:mt-3">
|
|
<div>
|
|
<button class="tw:btn tw:btn-outline tw:btn-primary tw:w-full"
|
|
_="on click
|
|
get #card-placeholder
|
|
set newCard to it.cloneNode(true)
|
|
remove @id from newCard
|
|
remove .tw\:hidden from newCard then
|
|
set itemCount to <#items [class='tw: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="tw:btn tw:btn-outline tw:btn-error tw:w-full"
|
|
_="on click
|
|
for el in <.item-price, .item-amount />
|
|
set card to the closest .tw:\card to el
|
|
set el's value to ''
|
|
end
|
|
trigger update on #items
|
|
end">
|
|
{% trans 'Clear' %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|