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

This commit is contained in:
2026-08-14 00:53:01 +02:00
parent 743c743c2c
commit 9f6368583d

View File

@@ -1731,42 +1731,31 @@
const overviewCharts = useMemo(() => {
const overviewWindowDays = Number(payload?.bootstrap_meta?.overview_window_days || 15);
const overviewRows = recentMeasurementWindow(measurements, overviewWindowDays);
const chartCoinCurrency = String(currentSettings.crypto_currency || 'DOGE').toUpperCase();
const comparisonRows = overviewRows.filter((row) => {
const miningRate = Number(row.doge_per_hour_per_mh_interval);
const price = Number(row.effective_price_per_coin ?? row.price_per_coin);
return Number.isFinite(miningRate) && miningRate > 0 && Number.isFinite(price) && price > 0;
const performanceByDay = new Map();
overviewRows.forEach((row) => {
const rate = Number(row.doge_per_day_interval);
const dayKey = String(row.measured_date || '').trim() || String(row.measured_at || '').slice(0, 10);
if (!dayKey || !Number.isFinite(rate) || rate < 0) {
return;
}
const existing = performanceByDay.get(dayKey) || { sum: 0, count: 0, label: fmtDate(dayKey) };
existing.sum += rate;
existing.count += 1;
performanceByDay.set(dayKey, existing);
});
const baseComparison = comparisonRows[0] || null;
const baseMining = baseComparison ? Number(baseComparison.doge_per_hour_per_mh_interval) : null;
const basePrice = baseComparison ? Number(baseComparison.effective_price_per_coin ?? baseComparison.price_per_coin) : null;
return {
mining: overviewRows.map((row) => ({ x: fmtDate(row.measured_at), y: row.coins_total })),
performance: overviewRows.filter((row) => row.doge_per_day_interval !== null)
.map((row) => ({ x: fmtDate(row.measured_at), y: row.doge_per_day_interval })),
performance: Array.from(performanceByDay.entries())
.sort((left, right) => String(left[0]).localeCompare(String(right[0])))
.map(([, entry]) => ({
x: entry.label,
y: entry.count > 0 ? (entry.sum / entry.count) : null,
}))
.filter((point) => Number.isFinite(Number(point.y))),
pricing: overviewRows.filter((row) => row.price_per_coin !== null)
.map((row) => ({ x: fmtDate(row.measured_at), y: row.price_per_coin })),
miningVsPrice: baseMining && basePrice ? [
{
key: 'mining-rate',
label: `${chartCoinCurrency}/h je MH/s Index`,
color: '#2dd4bf',
data: comparisonRows.map((row) => ({
x: fmtDate(row.measured_at),
y: (Number(row.doge_per_hour_per_mh_interval) / baseMining) * 100,
})),
},
{
key: 'doge-price',
label: `${chartCoinCurrency}-Kurs Index`,
color: '#f59e0b',
data: comparisonRows.map((row) => ({
x: fmtDate(row.measured_at),
y: (Number(row.effective_price_per_coin ?? row.price_per_coin) / basePrice) * 100,
})),
},
] : [],
};
}, [currentSettings.crypto_currency, measurements, payload?.bootstrap_meta?.overview_window_days]);
@@ -2756,6 +2745,9 @@
const totalEarnedOverall = latest && latest.growth_since_baseline !== null && latest.growth_since_baseline !== undefined
? Number(latest.growth_since_baseline)
: null;
const totalEarnedOverallFiat = latest && totalEarnedOverall !== null
? convertMeasurementMoney(latest, totalEarnedOverall, reportCurrency)
: null;
const totalSpentOverallCurrentAsset = latest
? convertMeasurementMoney(
latest,
@@ -2763,6 +2755,30 @@
currentCoinCurrency
)
: null;
const totalSpentOverallFiat = latest && totalSpentOverallCurrentAsset !== null
? convertMeasurementMoney(latest, totalSpentOverallCurrentAsset, reportCurrency)
: null;
const spentByType = activeMinerRows.reduce((summary, row) => {
const amount = Number(row?.effective_amount);
const currency = String(row?.effective_currency || '').toUpperCase();
if (!Number.isFinite(amount) || amount <= 0 || !currency) {
return summary;
}
if (row.payment_type === 'crypto') {
const converted = convertCurrencyValue(amount, currency, currentCoinCurrency);
if (Number.isFinite(converted)) {
summary.crypto += converted;
}
return summary;
}
const converted = convertCurrencyValue(amount, currency, reportCurrency);
if (Number.isFinite(converted)) {
summary.fiat += converted;
}
return summary;
}, { crypto: 0, fiat: 0 });
const breakEvenReached = breakEvenRemainingAmount !== null && breakEvenRemainingAmount <= 0;
const breakEvenEta = latest && latest.break_even_eta_at ? fmtDate(latest.break_even_eta_at) : null;
const walletBalanceCurrentAsset = payload?.summary?.payouts?.wallet_balance_current_asset;
@@ -2805,15 +2821,20 @@
key: 'earned-overall',
label: `Bisher verdient gesamt ${currentCoinCurrency}`,
value: totalEarnedOverall !== null ? fmtNumber(totalEarnedOverall, 6) : 'n/a',
sub: currentSettings?.baseline_measured_at
? `Seit Baseline ${fmtDate(currentSettings.baseline_measured_at)}`
: 'Benötigt Baseline',
sub: [
totalEarnedOverallFiat !== null ? `${fmtMoney(totalEarnedOverallFiat, reportCurrency)}` : null,
currentSettings?.baseline_measured_at ? `Seit Baseline ${fmtDate(currentSettings.baseline_measured_at)}` : 'Benötigt Baseline',
].filter(Boolean).join(' · '),
}),
h(StatCard, {
key: 'spent-overall',
label: `Bisher ausgegeben gesamt ${currentCoinCurrency}`,
value: totalSpentOverallCurrentAsset !== null ? fmtNumber(totalSpentOverallCurrentAsset, 6) : 'n/a',
sub: 'FIAT und Krypto auf die aktuelle Mining-Währung reduziert',
sub: [
totalSpentOverallFiat !== null ? `${fmtMoney(totalSpentOverallFiat, reportCurrency)}` : null,
`Krypto ${fmtNumber(spentByType.crypto, 6)} ${currentCoinCurrency}`,
`FIAT ${fmtMoney(spentByType.fiat, reportCurrency)}`,
].filter(Boolean).join(' · '),
}),
h(StatCard, {
key: 'perday',
@@ -2865,13 +2886,8 @@
}),
]),
h('div', { key: 'charts', className: 'mc-overview-grid' }, [
panel('Mining-Verlauf', 'Coins total der letzten 15 Tage.', h(SimpleChart, { type: 'line', data: overviewCharts.mining })),
panel('Performance-Verlauf', `${perDayLabel}-Raten der letzten 15 Tage.`, h(SimpleChart, { type: 'area', data: overviewCharts.performance })),
panel('Performance-Verlauf', `${perDayLabel}-Raten der letzten 15 Tage als Tagesdurchschnitt ohne negative Ausreißer.`, h(SimpleChart, { type: 'area', data: overviewCharts.performance })),
panel('Kurs-Verlauf', 'Preiswerte der letzten 15 Tage.', h(SimpleChart, { type: 'line', data: overviewCharts.pricing })),
panel('Mining vs. Kurs', `Index-Vergleich der letzten 15 Tage. Mining wird auf ${currentCoinCurrency} pro Stunde je MH/s normalisiert, beide Reihen starten bei 100.`, h(SimpleChart, {
type: 'line',
series: overviewCharts.miningVsPrice,
})),
]),
panel('Zielmonitor', `Rest-${currentCoinCurrency} und Resttage werden gegen den letzten verfuegbaren Kurs je Zielwaehrung berechnet.`,
h('div', { className: 'mc-target-grid' },