dphcko-frontend/src/lib/calculator/Calculator.svelte
2023-09-08 01:13:54 +02:00

158 lines
3.2 KiB
Svelte

<script lang="ts">
import type CalculatorValues from '$lib/calculator/type/CalculatorValues';
import {
refreshBasePrice,
refreshFinalPrice,
refreshVatAmount
} from '$lib/calculator/functions/RefreshFunctions';
let calcValues: CalculatorValues = {
basePrice: 0.0,
vatRate: 0.0,
vatAmount: 0.0,
finalPrice: 0.0
};
let calcValuesCache: CalculatorValues = {
...calcValues
};
function refreshCache(calcValues: CalculatorValues) {
calcValuesCache = {
...calcValues
};
}
function refreshPrices(calcValues: CalculatorValues) {
if (!validateCalculatorValues(calcValues)) {
// Calculator values are invalid, we don't want to refresh the prices.
return false;
}
if (
calcValues.basePrice !== calcValuesCache.basePrice ||
calcValues.vatRate !== calcValuesCache.vatRate
) {
refreshFinalPrice(calcValues);
} else if (calcValues.finalPrice !== calcValuesCache.finalPrice) {
refreshBasePrice(calcValues);
}
refreshVatAmount(calcValues);
refreshCache(calcValues);
}
function validateCalculatorValues(calcValues: CalculatorValues) {
let property: keyof typeof calcValues;
for (property in calcValues) {
if (calcValues[property] === null) {
return false;
}
}
return true;
}
function handleFocus(event: Event) {
const element = event.target;
if (element instanceof HTMLInputElement) {
if (element.value === '0') {
element.value = '';
}
}
}
function handleBlur(event: Event) {
const element = event.target;
if (element instanceof HTMLInputElement) {
if (element.value === '') {
element.value = '0';
}
}
}
$: refreshPrices(calcValues);
const invalidNumberErrorText = 'Zadejte platné číslo.';
</script>
<form>
<label for="vatRate">Sazba DPH (%)</label>
<input
id="vatRate"
type="number"
min="0"
max="100"
bind:value={calcValues.vatRate}
class:invalid={calcValues.vatRate === null}
on:focus={handleFocus}
on:blur={handleBlur}
/>
{#if calcValues.vatRate === null}
<p class="invalid">{invalidNumberErrorText}</p>
{/if}
<label for="basePrice">Cena bez DPH (Kč)</label>
<input
id="basePrice"
type="number"
min="0"
bind:value={calcValues.basePrice}
class:invalid={calcValues.basePrice === null}
on:focus={handleFocus}
on:blur={handleBlur}
/>
{#if calcValues.basePrice === null}
<p class="invalid">{invalidNumberErrorText}</p>
{/if}
<label for="finalPrice">Cena s DPH (Kč)</label>
<input
id="finalPrice"
type="number"
min="0"
bind:value={calcValues.finalPrice}
class:invalid={calcValues.finalPrice === null}
on:focus={handleFocus}
on:blur={handleBlur}
/>
{#if calcValues.finalPrice === null}
<p class="invalid">{invalidNumberErrorText}</p>
{/if}
</form>
<div class="vatAmount">
Výše DPH: {calcValues.vatAmount}
</div>
<style>
p.invalid {
color: var(--invalid-color);
}
input {
width: 100%;
margin: 0.25em 0 0.625em;
border: 2px solid gray;
border-radius: 3px;
}
input:last-child {
margin-bottom: 1.25em;
}
input.invalid {
border: 4px solid var(--invalid-color);
}
input[type='number'] {
-moz-appearance: textfield;
appearance: textfield;
}
input[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
}
</style>