Files
nexus/modules/fx-rates/pages/currencies.php
Lars Gebhardt-Kusche b9f248aae0
All checks were successful
Deploy / deploy-staging (push) Successful in 6s
Deploy / deploy-production (push) Has been skipped
asdasd
2026-05-02 02:56:00 +02:00

214 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require_once dirname(__DIR__) . '/bootstrap.php';
$assets = app()->assets();
if ($assets) {
$assets->addStyle('/module/fx-rates/asset?file=fx-rates.css');
$assets->addScript('/module/fx-rates/asset?file=fx-rates-currencies.js', 'footer', true);
}
$settings = module_fn('fx-rates', 'settings');
$service = module_fn('fx-rates', 'service');
$notice = trim((string) ($_GET['notice'] ?? ''));
$error = trim((string) ($_GET['error'] ?? ''));
if (strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET')) === 'POST') {
try {
$action = trim((string) ($_POST['fx_action'] ?? ''));
if ($action === 'save_selection') {
$payload = [
'display_base_currency' => (string) ($_POST['display_base_currency'] ?? ''),
'preferred_currencies' => $_POST['preferred_currencies'] ?? [],
];
$saved = module_fn('fx-rates', 'save_runtime_settings', $payload);
$params = ['notice' => 'Waehrungs-Auswahl gespeichert.'];
if (is_array($saved) && !empty($saved['display_base_currency'])) {
$params['base'] = (string) $saved['display_base_currency'];
}
redirect('/module/fx-rates/currencies?' . http_build_query($params));
}
if ($action === 'sync_catalog') {
$result = module_fn('fx-rates', 'run_setup_action', 'sync_currency_catalog');
redirect('/module/fx-rates/currencies?' . http_build_query([
'notice' => sprintf('Waehrungskatalog synchronisiert. %d Waehrungen verarbeitet.', (int) ($result['synced_count'] ?? 0)),
]));
}
if ($action === 'refresh_rates') {
$result = $service->refreshLatestRates(null, (string) ($settings['default_base_currency'] ?? ''), 'manual');
redirect('/module/fx-rates/currencies?' . http_build_query([
'notice' => sprintf('Alle Wechselkurse aktualisiert. %d Werte gespeichert.', (int) ($result['updated_count'] ?? 0)),
]));
}
} catch (\Throwable $exception) {
redirect('/module/fx-rates/currencies?' . http_build_query([
'error' => $exception->getMessage() !== '' ? $exception->getMessage() : 'Aktion konnte nicht ausgefuehrt werden.',
]));
}
}
$catalog = is_array($settings['currency_catalog'] ?? null) ? $settings['currency_catalog'] : [];
$preferredCurrencies = is_array($settings['preferred_currencies'] ?? null) ? $settings['preferred_currencies'] : [];
$displayBaseCurrency = strtoupper(trim((string) ($settings['display_base_currency'] ?? $settings['default_base_currency'] ?? 'EUR')));
$latest = $service->latestStatus();
$recentFetches = $service->recentFetches(15);
$currencies = [];
foreach ($catalog as $item) {
if (!is_array($item)) {
continue;
}
$code = strtoupper(trim((string) ($item['code'] ?? '')));
$name = trim((string) ($item['name'] ?? ''));
if ($code === '' || $name === '') {
continue;
}
$currencies[] = [
'code' => $code,
'name' => $name,
];
}
$cryptoCodes = array_fill_keys([
'ADA', 'ARB', 'BNB', 'BTC', 'DAI', 'DOGE', 'DOT', 'ETH', 'LINK', 'LTC',
'SOL', 'USDC', 'USDT', 'XAG', 'XAU', 'XRP',
], true);
$fiatCount = 0;
$cryptoCount = 0;
foreach ($currencies as $currency) {
if (isset($cryptoCodes[$currency['code']])) {
$cryptoCount++;
} else {
$fiatCount++;
}
}
$currencyPageData = json_encode([
'currencies' => $currencies,
'preferred_currencies' => array_values(array_unique(array_map(static fn (mixed $code): string => strtoupper(trim((string) $code)), $preferredCurrencies))),
'display_base_currency' => $displayBaseCurrency,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$tabs = [
['label' => 'Ueberblick', 'href' => '/module/fx-rates'],
['label' => 'Waehrungen', 'href' => '/module/fx-rates/currencies', 'active' => true],
];
?>
<?= module_shell_header('fx-rates', [
'title' => 'Waehrungskurse',
'tabs' => $tabs,
'actions' => [
['label' => 'Setup', 'href' => '/modules/setup/fx-rates', 'variant' => 'secondary', 'size' => 'sm'],
],
]) ?>
<div id="fx-rates-currencies" data-page='<?= e(is_string($currencyPageData) ? $currencyPageData : '{}') ?>'>
<div class="fx-stack">
<div class="fx-card">
<?php if ($notice !== ''): ?>
<div class="fx-message is-success"><?= e($notice) ?></div>
<?php elseif ($error !== ''): ?>
<div class="fx-message is-error"><?= e($error) ?></div>
<?php endif; ?>
<h2>Waehrungs-Update</h2>
<p>Auswahl wird in den FX-Rates-Einstellungen gespeichert und steht damit auf Handy und Desktop gleich zur Verfuegung.</p>
<div class="fx-action-row">
<form method="post">
<input type="hidden" name="fx_action" value="save_selection">
<input type="hidden" name="display_base_currency" value="<?= e($displayBaseCurrency) ?>" data-fx-display-base-hidden>
<div data-fx-hidden-preferred></div>
<button type="submit" class="fx-button fx-button--ghost">Auswahl speichern</button>
</form>
<form method="post">
<input type="hidden" name="fx_action" value="refresh_rates">
<button type="submit" class="fx-button fx-button--accent">Alle Wechselkurse aktualisieren</button>
</form>
<form method="post">
<input type="hidden" name="fx_action" value="sync_catalog">
<button type="submit" class="fx-button fx-button--ghost">Waehrungskatalog sync</button>
</form>
</div>
<div class="fx-mini-grid">
<div class="fx-mini-card">
<div class="fx-mini-label">Fiat</div>
<div><?= e((string) $fiatCount) ?> Waehrungen</div>
</div>
<div class="fx-mini-card">
<div class="fx-mini-label">Krypto</div>
<div><?= e((string) $cryptoCount) ?> Waehrungen</div>
</div>
</div>
<div class="fx-field-label">Bevorzugte Waehrungen fuer Anzeige</div>
<div class="fx-currency-selection-row">
<div class="fx-token-list fx-token-list--inline" data-fx-token-list></div>
<div class="fx-currency-search">
<input type="text" class="fx-input" value="" placeholder="Waehrung hinzufuegen: EUR, USD, DOGE oder Euro" autocomplete="off" data-fx-search-input>
</div>
</div>
<div class="fx-suggestion-list" data-fx-suggestions></div>
<div class="fx-field fx-currency-search">
<label class="fx-field-label" for="fx-display-base-select">Darstellung auf Basis von</label>
<select id="fx-display-base-select" class="fx-select" data-fx-display-base-select></select>
</div>
</div>
<div class="fx-card">
<div class="fx-card-head">
<div>
<h2>Letzte 15 Kurs-Uploads</h2>
<p>Zeigt die zuletzt gespeicherten Wechselkurse aus der Datenbank.</p>
</div>
<div class="fx-card-meta">
<div><strong>Anzeige-Basis:</strong> <?= e($displayBaseCurrency) ?></div>
<div><strong>Letzter Abruf:</strong> <?= e((string) ($latest['fetched_at_display'] ?? $latest['fetched_at'] ?? 'noch keiner')) ?></div>
</div>
</div>
<div class="fx-table-wrap">
<table class="fx-table">
<thead>
<tr>
<th>Zeit</th>
<th>Stichtag</th>
<th>Fetch-Basis</th>
<?php foreach ($preferredCurrencies as $currency): ?>
<th><?= e((string) $currency) ?></th>
<?php endforeach; ?>
<th>Provider</th>
</tr>
</thead>
<tbody>
<?php if ($recentFetches === []): ?>
<tr><td colspan="<?= 4 + count($preferredCurrencies) ?>">Noch keine Abrufe vorhanden.</td></tr>
<?php else: ?>
<?php foreach ($recentFetches as $fetch): ?>
<?php
$snapshot = $service->snapshotByFetchId((int) ($fetch['id'] ?? 0), $displayBaseCurrency, $preferredCurrencies);
$rates = is_array($snapshot['rates'] ?? null) ? $snapshot['rates'] : [];
?>
<tr>
<td><?= e((string) ($fetch['fetched_at_display'] ?? $fetch['fetched_at'] ?? '')) ?></td>
<td><?= e((string) ($fetch['rate_date'] ?? '')) ?></td>
<td><?= e((string) ($fetch['base_currency'] ?? '')) ?></td>
<?php foreach ($preferredCurrencies as $currency): ?>
<?php $value = $rates[(string) $currency] ?? null; ?>
<td><?= is_numeric($value) ? e(number_format((float) $value, 8, ',', '')) : '' ?></td>
<?php endforeach; ?>
<td><?= e((string) ($fetch['provider'] ?? '')) ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?= module_shell_footer() ?>