diff --git a/modules/mining-checker/assets/js/app.js b/modules/mining-checker/assets/js/app.js index 0b8553d..2f3444f 100644 --- a/modules/mining-checker/assets/js/app.js +++ b/modules/mining-checker/assets/js/app.js @@ -2220,6 +2220,16 @@ value: latest ? fmtNumber(latest.doge_per_day_interval, 4) : 'n/a', sub: payload?.summary?.current_hashrate_mh ? `Hashrate ${fmtNumber(payload.summary.current_hashrate_mh, 4)} MH/s` : (latest ? `Trend ${latest.trend_label}` : ''), }), + h(StatCard, { + key: 'perday-since-payout', + label: `${currentCoinCurrency} pro Tag seit letzter Auszahlung`, + value: latest && latest.doge_per_day_since_last_payout !== null && latest.doge_per_day_since_last_payout !== undefined + ? fmtNumber(latest.doge_per_day_since_last_payout, 4) + : 'n/a', + sub: latest && latest.last_payout_at + ? `Seit ${fmtDate(latest.last_payout_at)} · ${fmtNumber(latest.coins_since_last_payout, 6)} ${currentCoinCurrency}` + : 'Noch keine Auszahlung vor dem letzten Upload', + }), h(StatCard, { key: 'value', label: 'Aktueller Gegenwert', @@ -2290,7 +2300,7 @@ panel('Mining-History', 'Die letzten 10 Mining-Uploads inkl. Performance-Werten und OCR-Metadaten.', h('div', { className: 'mc-table-shell' }, [ h('table', { key: 'table', className: 'mc-table' }, [ h('thead', { key: 'thead' }, h('tr', null, [ - 'Zeit', 'Coins', 'Kurs', 'Quelle', perDayLabel, 'Trend', 'Notiz', 'Aktion' + 'Zeit', 'Coins', 'Kurs', 'Quelle', perDayLabel, 'Seit Auszahlung/Tag', 'Trend', 'Notiz', 'Aktion' ].map((label) => h('th', { key: label }, label)))), h('tbody', { key: 'tbody' }, measurements.slice(-10).reverse().map((row) => h('tr', { key: row.id }, [ @@ -2299,6 +2309,9 @@ h('td', { key: 'price' }, row.price_per_coin ? `${fmtNumber(row.price_per_coin, 6)} ${row.price_currency}` : 'n/a'), h('td', { key: 'source' }, row.source), h('td', { key: 'rate' }, fmtNumber(row.doge_per_day_interval, 4)), + h('td', { key: 'rate-payout' }, row.doge_per_day_since_last_payout !== null && row.doge_per_day_since_last_payout !== undefined + ? `${fmtNumber(row.doge_per_day_since_last_payout, 4)}${row.last_payout_at ? ` seit ${fmtDate(row.last_payout_at)}` : ''}` + : 'n/a'), h('td', { key: 'trend' }, row.trend_label), h('td', { key: 'note' }, row.note || row.ocr_flags.join(', ') || '—'), h('td', { key: 'action' }, h('button', { diff --git a/modules/mining-checker/src/Domain/AnalyticsService.php b/modules/mining-checker/src/Domain/AnalyticsService.php index 8fa2f0b..7329252 100644 --- a/modules/mining-checker/src/Domain/AnalyticsService.php +++ b/modules/mining-checker/src/Domain/AnalyticsService.php @@ -47,6 +47,7 @@ final class AnalyticsService $result = []; $payoutIndex = 0; $payoutsByAsset = []; + $latestPayoutByAsset = []; $latestPriceByCurrency = []; $lastIndex = count($measurements) - 1; @@ -61,7 +62,13 @@ final class AnalyticsService } $payoutAsset = strtoupper(trim((string) ($payouts[$payoutIndex]['payout_currency'] ?? $coinCurrency))); - $payoutsByAsset[$payoutAsset] = ($payoutsByAsset[$payoutAsset] ?? 0.0) + (float) ($payouts[$payoutIndex]['coins_amount'] ?? 0); + $payoutAmount = (float) ($payouts[$payoutIndex]['coins_amount'] ?? 0); + $payoutsByAsset[$payoutAsset] = ($payoutsByAsset[$payoutAsset] ?? 0.0) + $payoutAmount; + $latestPayoutByAsset[$payoutAsset] = [ + 'payout_at' => (string) ($payouts[$payoutIndex]['payout_at'] ?? ''), + 'payout_ts' => $payoutTs, + 'coins_amount' => $payoutAmount, + ]; $payoutIndex++; } @@ -80,6 +87,11 @@ final class AnalyticsService $perDayInterval = null; $perHourPerMhInterval = null; $perDayPerMhInterval = null; + $hoursSinceLastPayout = null; + $coinsSinceLastPayout = null; + $perHourSinceLastPayout = null; + $perDaySinceLastPayout = null; + $lastPayoutAt = null; if (is_array($previous) && $previousMeasuredTs !== null) { $intervalStartTs = $previousMeasuredTs; @@ -98,6 +110,18 @@ final class AnalyticsService } } + if (isset($latestPayoutByAsset[$coinCurrency]) && is_array($latestPayoutByAsset[$coinCurrency])) { + $lastPayout = $latestPayoutByAsset[$coinCurrency]; + $lastPayoutTs = (int) ($lastPayout['payout_ts'] ?? 0); + if ($lastPayoutTs > 0 && $measuredTs > $lastPayoutTs) { + $hoursSinceLastPayout = ($measuredTs - $lastPayoutTs) / 3600; + $coinsSinceLastPayout = $visibleCoinsTotal; + $perHourSinceLastPayout = $hoursSinceLastPayout > 0 ? $coinsSinceLastPayout / $hoursSinceLastPayout : null; + $perDaySinceLastPayout = $perHourSinceLastPayout !== null ? $perHourSinceLastPayout * 24 : null; + $lastPayoutAt = (string) ($lastPayout['payout_at'] ?? ''); + } + } + $trendLabel = 'stabil'; if ($perHourInterval !== null && $previousIntervalRate !== null) { $delta = $perHourInterval - $previousIntervalRate; @@ -188,6 +212,11 @@ final class AnalyticsService 'doge_per_day_interval' => $this->roundOrNull($perDayInterval, 6), 'doge_per_hour_per_mh_interval' => $this->roundOrNull($perHourPerMhInterval, 8), 'doge_per_day_per_mh_interval' => $this->roundOrNull($perDayPerMhInterval, 8), + 'last_payout_at' => $lastPayoutAt, + 'hours_since_last_payout' => $this->roundOrNull($hoursSinceLastPayout, 4), + 'coins_since_last_payout' => $this->roundOrNull($coinsSinceLastPayout, 6), + 'doge_per_hour_since_last_payout' => $this->roundOrNull($perHourSinceLastPayout, 6), + 'doge_per_day_since_last_payout' => $this->roundOrNull($perDaySinceLastPayout, 6), 'trend_label' => $trendLabel, 'effective_price_per_coin' => $this->roundOrNull($price, 8), 'effective_price_currency' => $priceCurrency, diff --git a/partials/landingpages/index.php b/partials/landingpages/index.php index afc8d3e..f551bd8 100644 --- a/partials/landingpages/index.php +++ b/partials/landingpages/index.php @@ -21,6 +21,23 @@ $widgetTemplatesById = []; foreach ($widgetTemplates as $template) { $widgetTemplatesById[(int) ($template['id'] ?? 0)] = $template; } +$priorityModuleEntries = []; +if ($authUser !== null) { + $accessibleModules = $auth->filterModules(array_values(modules()->all())); + $accessibleModulesByName = []; + foreach ($accessibleModules as $module) { + $name = trim((string) ($module['name'] ?? '')); + if ($name !== '' && !empty($module['enabled'])) { + $accessibleModulesByName[$name] = $module; + } + } + + foreach (['mining-checker', 'boersenchecker'] as $moduleName) { + if (isset($accessibleModulesByName[$moduleName])) { + $priorityModuleEntries[] = $accessibleModulesByName[$moduleName]; + } + } +} $GLOBALS['layout_header_base_title'] = 'Nexus'; $GLOBALS['layout_header_title'] = 'Nexus'; @@ -49,6 +66,19 @@ $renderBookmarks = static function (array $config): array { }; ?>
+ +
+

Schnellzugriff

+

Wichtige Module für deinen direkten Einstieg.

+ +
+

Kein Home-Dashboard verfügbar