xsDx
All checks were successful
Deploy / deploy-staging (push) Successful in 33s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-08-14 02:29:09 +02:00
parent 8bcd445759
commit 6c9f3d3a77
4 changed files with 79 additions and 13 deletions

View File

@@ -204,6 +204,24 @@
return amount / runtimeDays;
}
function toKhPerSecond(value, unit) {
const numericValue = Number(value);
const normalizedUnit = String(unit || '').trim();
if (!Number.isFinite(numericValue) || numericValue <= 0 || !normalizedUnit) {
return 0;
}
if (normalizedUnit === 'MH/s') {
return numericValue * 1000;
}
if (normalizedUnit === 'kH/s') {
return numericValue;
}
return 0;
}
function recentMeasurementWindow(rows, windowDays) {
if (!Array.isArray(rows) || rows.length === 0) {
return [];
@@ -1066,6 +1084,7 @@
speed_min: '',
speed_unit: 'auto',
price_max: '',
max_doge: '',
runtime_months: '',
});
const [costPlanForm, setCostPlanForm] = useState({
@@ -1199,6 +1218,7 @@
.slice(0, 6);
const hasCryptoOfferBasis = Number(offerPreviewForm.crypto_base_price_amount) > 0;
const hasFiatOfferBasis = Number(offerPreviewForm.fiat_base_price_amount) > 0;
const maxDogeFilter = minerOfferFilters.max_doge === '' ? null : Number(minerOfferFilters.max_doge);
const filteredMinerOffers = evaluatedMinerOffers.filter((offer) => {
const paymentType = String(offer.payment_type || '').toLowerCase();
const speedMin = minerOfferFilters.speed_min === '' ? null : Number(minerOfferFilters.speed_min);
@@ -1211,6 +1231,11 @@
offer.base_price_currency || offer.effective_price_currency,
reportCurrency
);
const comparableDogePrice = convertCurrencyValue(
offer.effective_price_amount ?? offer.base_price_amount,
offer.effective_price_currency || offer.base_price_currency,
'DOGE'
);
const runtime = Number(offer.runtime_months);
const comparableHashrate = speedUnit === 'kh'
? offerHashrate * 1000
@@ -1220,7 +1245,19 @@
return false;
}
if (selectedOfferType === 'crypto' && !isOfferAvailableForWallet(offer, latestWalletSnapshot)) {
if (
selectedOfferType === 'crypto' &&
Number.isFinite(maxDogeFilter) &&
(!Number.isFinite(comparableDogePrice) || comparableDogePrice > maxDogeFilter)
) {
return false;
}
if (
selectedOfferType === 'crypto' &&
!Number.isFinite(maxDogeFilter) &&
!isOfferAvailableForWallet(offer, latestWalletSnapshot)
) {
return false;
}
@@ -1242,7 +1279,7 @@
return true;
});
const scenarioMinerOffers = filteredMinerOffers.filter((offer) => isOfferAvailableForWallet(offer, latestWalletSnapshot));
const scenarioMinerOffers = filteredMinerOffers;
const speedUnits = ['kH/s', 'MH/s'];
const fiatCurrencies = currencies.filter((currency) => !currency.is_crypto);
const cryptoCurrencies = currencies.filter((currency) => !!currency.is_crypto);
@@ -1311,6 +1348,8 @@
const dailyReportAmount = Number.isFinite(dailyAmount) && dailyCurrency
? (dailyCurrency === reportCurrency ? dailyAmount : convertCurrencyValue(dailyAmount, dailyCurrency, reportCurrency))
: null;
const totalHashrateKh = toKhPerSecond(miner.mining_speed_value, miner.mining_speed_unit) + toKhPerSecond(miner.bonus_speed_value, miner.bonus_speed_unit);
const costPerKh = totalHashrateKh > 0 ? (Number(miner.total_cost_amount) / totalHashrateKh) : null;
return {
id: `purchase-${miner.id}`,
source: 'miete',
@@ -1323,6 +1362,8 @@
daily_cost_amount: dailyAmount,
daily_cost_currency: dailyCurrency,
daily_cost_report_amount: Number.isFinite(dailyReportAmount) ? dailyReportAmount : null,
total_hashrate_kh: totalHashrateKh > 0 ? totalHashrateKh : null,
cost_per_kh_amount: Number.isFinite(costPerKh) && costPerKh > 0 ? costPerKh : null,
base_amount: baseAmount,
base_currency: baseCurrency,
miner_id: miner.id,
@@ -1346,6 +1387,8 @@
const dailyReportAmount = Number.isFinite(dailyAmount) && dailyCurrency
? (dailyCurrency === reportCurrency ? dailyAmount : convertCurrencyValue(dailyAmount, dailyCurrency, reportCurrency))
: null;
const totalHashrateKh = toKhPerSecond(plan.mining_speed_value, plan.mining_speed_unit) + toKhPerSecond(plan.bonus_speed_value, plan.bonus_speed_unit);
const costPerKh = totalHashrateKh > 0 ? (Number(plan.total_cost_amount) / totalHashrateKh) : null;
return {
id: `plan-${plan.id}`,
source: 'manual',
@@ -1358,6 +1401,8 @@
daily_cost_amount: dailyAmount,
daily_cost_currency: dailyCurrency,
daily_cost_report_amount: Number.isFinite(dailyReportAmount) ? dailyReportAmount : null,
total_hashrate_kh: totalHashrateKh > 0 ? totalHashrateKh : null,
cost_per_kh_amount: Number.isFinite(costPerKh) && costPerKh > 0 ? costPerKh : null,
base_amount: plan.base_price_amount,
base_currency: currentSettings.report_currency || 'EUR',
payment_type: plan.payment_type,
@@ -3485,7 +3530,7 @@
const renderMinerTable = (rows, emptyText) => (
h('div', { className: 'mc-table-shell' }, [
h('table', { key: 'table', className: 'mc-table' }, [
h('thead', { key: 'head' }, h('tr', null, ['Label', 'Start', 'Laufzeit', 'Auto', 'Kosten', 'Waehrung', 'Aktiv', 'Aktion'].map((label) => h('th', { key: label }, label)))),
h('thead', { key: 'head' }, h('tr', null, ['Label', 'Start', 'Laufzeit', 'Auto', 'Kosten Server', 'Kosten/kH/s', 'Waehrung', 'Aktiv', 'Aktion'].map((label) => h('th', { key: label }, label)))),
h('tbody', { key: 'body' },
rows.length
? rows.map((row) => h('tr', { key: row.id }, [
@@ -3500,7 +3545,7 @@
row.end_at ? h('div', { key: 'end', className: 'mc-kicker' }, `Ende ${fmtDate(row.end_at)}`) : null,
]),
h('td', { key: 'renew' }, row.payment_type === 'crypto' ? 'nein' : (row.auto_renew ? 'ja' : 'nein')),
h('td', { key: 'cost' }, [
h('td', { key: 'cost-total' }, [
h('div', { key: 'effective' }, fmtNumber(row.effective_amount, 6)),
row.daily_cost_amount !== null && row.daily_cost_amount !== undefined && row.daily_cost_currency
? h('div', { key: 'daily', className: 'mc-kicker' }, [
@@ -3514,6 +3559,14 @@
? h('div', { key: 'base', className: 'mc-kicker' }, `Basis ${fmtNumber(row.base_amount, 6)} ${row.base_currency}`)
: null,
]),
h('td', { key: 'cost-kh' }, row.cost_per_kh_amount !== null && row.cost_per_kh_amount !== undefined
? [
h('div', { key: 'amount' }, fmtNumber(row.cost_per_kh_amount, 6)),
row.total_hashrate_kh !== null && row.total_hashrate_kh !== undefined
? h('div', { key: 'hash', className: 'mc-kicker' }, `bei ${fmtNumber(row.total_hashrate_kh, 4)} kH/s`)
: null,
]
: 'n/a'),
h('td', { key: 'currency' }, [
h('div', { key: 'currency-main' }, row.effective_currency),
row.payment_type ? h('div', { key: 'currency-mode', className: 'mc-kicker' }, row.payment_type === 'crypto' ? 'Zahlung Krypto' : 'Zahlung FIAT') : null,
@@ -3530,7 +3583,7 @@
: '—'
),
]))
: [h('tr', { key: 'empty' }, h('td', { colSpan: 8 }, emptyText))]
: [h('tr', { key: 'empty' }, h('td', { colSpan: 9 }, emptyText))]
),
]),
])
@@ -3618,6 +3671,9 @@
{ value: 'auto', label: 'MH/s' },
{ value: 'kh', label: 'kH/s' },
], (value) => setMinerOfferFilters({ ...minerOfferFilters, speed_unit: value || 'auto' })),
selectedOfferType === 'crypto'
? inputField('Max. DOGE', 'number', minerOfferFilters.max_doge, (value) => setMinerOfferFilters({ ...minerOfferFilters, max_doge: value }), '0.0001')
: null,
inputField(`Max. Basispreis (${reportCurrency})`, 'number', minerOfferFilters.price_max, (value) => setMinerOfferFilters({ ...minerOfferFilters, price_max: value }), '0.0001'),
selectField('Laufzeit', minerOfferFilters.runtime_months, [{ value: '', label: 'Alle Laufzeiten' }].concat(Array.from(new Set(evaluatedMinerOffers.map((offer) => String(offer.runtime_months || '')).filter(Boolean))).sort((a, b) => Number(a) - Number(b)).map((value) => ({
value,