xsDx
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user