Runtime Engine generisch

This commit is contained in:
2026-05-29 21:39:21 +02:00
parent 9dff578c15
commit 04a29ae8cd
3 changed files with 13 additions and 89 deletions

View File

@@ -59,8 +59,6 @@
{{ $description := printf {{ $description := printf
"Konvertieren Sie %s in %s. Einfache und schnelle Umrechnung mit Einheitsumrechner." "Konvertieren Sie %s in %s. Einfache und schnelle Umrechnung mit Einheitsumrechner."
$fromName $toName }} $fromName $toName }}
{{ $fromCurrency := $fromCode }}
{{ $toCurrency := $toCode }}
{{ $fromRate := 1 }} {{ $fromRate := 1 }}
{{ if ne $fromCode "eur" }} {{ if ne $fromCode "eur" }}
{{ $fromRate = index $pbRates $fromCode }} {{ $fromRate = index $pbRates $fromCode }}
@@ -79,8 +77,6 @@
"slug" $slug "slug" $slug
"description" $description "description" $description
"engine" "runtime" "engine" "runtime"
"currency_from" $fromCurrency
"currency_to" $toCurrency
"rate" $rate "rate" $rate
"rates_updated" $latestUpdate "rates_updated" $latestUpdate
}} }}

View File

@@ -13,8 +13,11 @@
"{ toIntermediate: v => %s, fromIntermediate: v => %s }" "{ toIntermediate: v => %s, fromIntermediate: v => %s }"
$toExpr $fromExpr }} $toExpr $fromExpr }}
{{ else if eq .Params.engine "runtime" }} {{ else if eq .Params.engine "runtime" }}
{{ $config = dict "fromCurrency" .Params.from {{ $fromCode := .Params.from }}
"toCurrency" .Params.to | jsonify }} {{ $toCode := .Params.to }}
{{ $config = printf
"{ init: async function () { const pbUrl = document.querySelector('meta[name=\\'pocketbase-url\\']')?.content || 'https://www.alphabreed.com'; try { const response = await fetch(`${pbUrl}/api/collections/currencies/records`); if (!response.ok) { this.ratesError = 'Wechselkurse konnten nicht geladen werden.'; return; } const data = await response.json(); for (const item of data.items || []) { this.rates[item.id] = item.rate; } } catch (e) { this.ratesError = 'Wechselkurse konnten nicht geladen werden.'; } }, convert: function (value) { const fromRate = '%s' === 'eur' ? 1 : this.rates['%s']; const toRate = '%s' === 'eur' ? 1 : this.rates['%s']; if (!fromRate || !toRate) { return null; } return value.times(new Decimal(toRate)).dividedBy(new Decimal(fromRate)); } }"
$fromCode $fromCode $toCode $toCode }}
{{ end }} {{ end }}
{{ $availableUnits := partial "available-units.html" {{ $availableUnits := partial "available-units.html"
(dict "category" .Params.category "units" $catData.units) }} (dict "category" .Params.category "units" $catData.units) }}

View File

@@ -36,92 +36,12 @@ function navActions() {
* @returns {object} Alpine component data * @returns {object} Alpine component data
*/ */
function createConverter(engine, config) { function createConverter(engine, config) {
if (engine === 'runtime') {
return {
inputValue: '1',
result: '',
rates: {},
ratesError: '',
async init() {
await this.loadRates();
const params = new URLSearchParams(
window.location.search);
const valueParam = params.get('v');
if (valueParam) {
this.inputValue = valueParam.replace(/,/g, '.');
}
this.$watch('inputValue', val => {
if (val && val.indexOf(',') !== -1) {
this.inputValue = val.replace(/,/g, '.');
}
});
this.calculate();
},
async loadRates() {
const pbUrl = document.querySelector(
'meta[name="pocketbase-url"]')?.content
|| 'https://www.alphabreed.com';
try {
const response = await fetch(
`${pbUrl}/api/collections/currencies/records`);
if (!response.ok) {
this.ratesError =
'Wechselkurse konnten nicht geladen werden.';
return;
}
const data = await response.json();
for (const item of data.items || []) {
this.rates[item.id] = item.rate;
}
} catch (e) {
this.ratesError =
'Wechselkurse konnten nicht geladen werden.';
}
},
calculate() {
try {
this.result = '';
if (Object.keys(this.rates).length === 0) {
return;
}
const normalized = parseNumber(
this.inputValue);
if (!normalized || isNaN(normalized)) {
return;
}
const fromCode = config.fromCurrency || '';
const toCode = config.toCurrency || '';
const fromRate = fromCode === 'eur'
? 1 : this.rates[fromCode];
const toRate = toCode === 'eur'
? 1 : this.rates[toCode];
if (!fromRate || !toRate) {
return;
}
const value = new Decimal(normalized);
const rate = new Decimal(toRate)
.dividedBy(new Decimal(fromRate));
const rawResult = value.times(rate);
this.result = prettyNumber(rawResult);
const normalizedInputValue = this.inputValue
.replace(/,/g, '.');
if (normalizedInputValue
&& normalizedInputValue !== '0') {
history.replaceState(
null, '', '?v=' + normalizedInputValue);
}
} catch (e) {
this.result = '';
}
}
};
}
return { return {
inputValue: '1', inputValue: '1',
result: '', result: '',
rates: {},
ratesError: '', ratesError: '',
init() { async init() {
const params = new URLSearchParams( const params = new URLSearchParams(
window.location.search); window.location.search);
const valueParam = params.get('v'); const valueParam = params.get('v');
@@ -133,6 +53,9 @@ function createConverter(engine, config) {
this.inputValue = val.replace(/,/g, '.'); this.inputValue = val.replace(/,/g, '.');
} }
}); });
if (typeof config.init === 'function') {
await config.init.call(this);
}
this.calculate(); this.calculate();
}, },
calculate() { calculate() {
@@ -144,7 +67,9 @@ function createConverter(engine, config) {
} }
const value = new Decimal(normalized); const value = new Decimal(normalized);
let rawResult; let rawResult;
if (engine === 'linear') { if (typeof config.convert === 'function') {
rawResult = config.convert.call(this, value);
} else if (engine === 'linear') {
const fromFactor = new Decimal( const fromFactor = new Decimal(
config.fromFactor); config.fromFactor);
const toFactor = new Decimal( const toFactor = new Decimal(