dcdsf
This commit is contained in:
@@ -923,6 +923,7 @@
|
|||||||
note: '',
|
note: '',
|
||||||
});
|
});
|
||||||
const [payoutModalOpen, setPayoutModalOpen] = useState(false);
|
const [payoutModalOpen, setPayoutModalOpen] = useState(false);
|
||||||
|
const [walletTransferRows, setWalletTransferRows] = useState([]);
|
||||||
const [walletWithdrawalForm, setWalletWithdrawalForm] = useState({
|
const [walletWithdrawalForm, setWalletWithdrawalForm] = useState({
|
||||||
withdrawal_at: '',
|
withdrawal_at: '',
|
||||||
coins_amount: '',
|
coins_amount: '',
|
||||||
@@ -930,6 +931,7 @@
|
|||||||
note: '',
|
note: '',
|
||||||
});
|
});
|
||||||
const [walletWithdrawalModalOpen, setWalletWithdrawalModalOpen] = useState(false);
|
const [walletWithdrawalModalOpen, setWalletWithdrawalModalOpen] = useState(false);
|
||||||
|
const [walletWithdrawalRows, setWalletWithdrawalRows] = useState([]);
|
||||||
const [minerOfferForm, setMinerOfferForm] = useState({
|
const [minerOfferForm, setMinerOfferForm] = useState({
|
||||||
label: '',
|
label: '',
|
||||||
runtime_months: '',
|
runtime_months: '',
|
||||||
@@ -989,8 +991,8 @@
|
|||||||
{ code: 'USDC', name: 'USD Coin' },
|
{ code: 'USDC', name: 'USD Coin' },
|
||||||
];
|
];
|
||||||
const currentCostPlans = Array.isArray(currentSettings.cost_plans) ? currentSettings.cost_plans : [];
|
const currentCostPlans = Array.isArray(currentSettings.cost_plans) ? currentSettings.cost_plans : [];
|
||||||
const currentPayouts = Array.isArray(currentSettings.payouts) ? currentSettings.payouts : [];
|
const currentPayouts = walletTransferRows.length ? walletTransferRows : (Array.isArray(currentSettings.payouts) ? currentSettings.payouts : []);
|
||||||
const currentWalletWithdrawals = Array.isArray(currentSettings.wallet_withdrawals) ? currentSettings.wallet_withdrawals : [];
|
const currentWalletWithdrawals = walletWithdrawalRows.length ? walletWithdrawalRows : (Array.isArray(currentSettings.wallet_withdrawals) ? currentSettings.wallet_withdrawals : []);
|
||||||
const currentWalletSnapshots = Array.isArray(payload?.wallet_snapshots) ? payload.wallet_snapshots : [];
|
const currentWalletSnapshots = Array.isArray(payload?.wallet_snapshots) ? payload.wallet_snapshots : [];
|
||||||
const currentMinerOffers = Array.isArray(currentSettings.miner_offers) ? currentSettings.miner_offers : [];
|
const currentMinerOffers = Array.isArray(currentSettings.miner_offers) ? currentSettings.miner_offers : [];
|
||||||
const currentPurchasedMiners = Array.isArray(currentSettings.purchased_miners) ? currentSettings.purchased_miners : [];
|
const currentPurchasedMiners = Array.isArray(currentSettings.purchased_miners) ? currentSettings.purchased_miners : [];
|
||||||
@@ -1013,7 +1015,7 @@
|
|||||||
const selectableCurrencies = preferredSelectableCurrencies.length ? preferredSelectableCurrencies : currencies;
|
const selectableCurrencies = preferredSelectableCurrencies.length ? preferredSelectableCurrencies : currencies;
|
||||||
const evaluatedMinerOffers = Array.isArray(payload?.summary?.miner_offers) ? payload.summary.miner_offers : [];
|
const evaluatedMinerOffers = Array.isArray(payload?.summary?.miner_offers) ? payload.summary.miner_offers : [];
|
||||||
const availableMinerOffers = evaluatedMinerOffers.filter((offer) => isOfferAvailableForWallet(offer, currentMiningCurrency, currentWalletMiningBalance));
|
const availableMinerOffers = evaluatedMinerOffers.filter((offer) => isOfferAvailableForWallet(offer, currentMiningCurrency, currentWalletMiningBalance));
|
||||||
const filteredMinerOffers = availableMinerOffers.filter((offer) => {
|
const filteredMinerOffers = evaluatedMinerOffers.filter((offer) => {
|
||||||
const speedMin = minerOfferFilters.speed_min === '' ? null : Number(minerOfferFilters.speed_min);
|
const speedMin = minerOfferFilters.speed_min === '' ? null : Number(minerOfferFilters.speed_min);
|
||||||
const speedUnit = String(minerOfferFilters.speed_unit || 'auto');
|
const speedUnit = String(minerOfferFilters.speed_unit || 'auto');
|
||||||
const priceMax = minerOfferFilters.price_max === '' ? null : Number(minerOfferFilters.price_max);
|
const priceMax = minerOfferFilters.price_max === '' ? null : Number(minerOfferFilters.price_max);
|
||||||
@@ -1445,6 +1447,14 @@
|
|||||||
loadFxHistory(projectKey);
|
loadFxHistory(projectKey);
|
||||||
}, [activeTab, projectKey]);
|
}, [activeTab, projectKey]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeTab !== 'wallet') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadWalletTransfers(projectKey);
|
||||||
|
loadWalletWithdrawals(projectKey);
|
||||||
|
}, [activeTab, projectKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
syncMiningCheckerTabButtons(activeTab);
|
syncMiningCheckerTabButtons(activeTab);
|
||||||
|
|
||||||
@@ -1918,6 +1928,7 @@
|
|||||||
timeoutMs: 8000,
|
timeoutMs: 8000,
|
||||||
});
|
});
|
||||||
applySavedPayout(savedPayout);
|
applySavedPayout(savedPayout);
|
||||||
|
setWalletTransferRows((previous) => previous.filter((row) => String(row.id) !== String(savedPayout.id)).concat(savedPayout).sort((left, right) => String(left?.payout_at || '').localeCompare(String(right?.payout_at || ''))));
|
||||||
invalidateProjectBootstrapCache(projectKey);
|
invalidateProjectBootstrapCache(projectKey);
|
||||||
setMessage('Wallet-Transfer gespeichert.');
|
setMessage('Wallet-Transfer gespeichert.');
|
||||||
setPayoutForm({ payout_at: '', coins_amount: '', payout_currency: currentSettings.crypto_currency || 'DOGE', note: '' });
|
setPayoutForm({ payout_at: '', coins_amount: '', payout_currency: currentSettings.crypto_currency || 'DOGE', note: '' });
|
||||||
@@ -1946,6 +1957,7 @@
|
|||||||
await request(`${apiBase}/projects/${encodeURIComponent(projectKey)}/payouts/${encodeURIComponent(transfer.id)}`, {
|
await request(`${apiBase}/projects/${encodeURIComponent(projectKey)}/payouts/${encodeURIComponent(transfer.id)}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
|
setWalletTransferRows((previous) => previous.filter((row) => String(row.id) !== String(transfer.id)));
|
||||||
invalidateProjectBootstrapCache(projectKey);
|
invalidateProjectBootstrapCache(projectKey);
|
||||||
await reloadBootstrapAfterMutation('Wallet-Transfer geloescht.');
|
await reloadBootstrapAfterMutation('Wallet-Transfer geloescht.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -1955,6 +1967,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadWalletTransfers(key) {
|
||||||
|
try {
|
||||||
|
const result = await request(`${apiBase}/projects/${encodeURIComponent(key)}/payouts`, { timeoutMs: 6000 });
|
||||||
|
setWalletTransferRows(Array.isArray(result) ? result : []);
|
||||||
|
} catch (_err) {
|
||||||
|
setWalletTransferRows([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function submitWalletWithdrawal(event) {
|
async function submitWalletWithdrawal(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
@@ -1968,6 +1989,7 @@
|
|||||||
timeoutMs: 8000,
|
timeoutMs: 8000,
|
||||||
});
|
});
|
||||||
invalidateProjectBootstrapCache(projectKey);
|
invalidateProjectBootstrapCache(projectKey);
|
||||||
|
await loadWalletWithdrawals(projectKey);
|
||||||
setMessage('Wallet-Auszahlung gespeichert.');
|
setMessage('Wallet-Auszahlung gespeichert.');
|
||||||
setWalletWithdrawalForm({
|
setWalletWithdrawalForm({
|
||||||
withdrawal_at: '',
|
withdrawal_at: '',
|
||||||
@@ -1984,6 +2006,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadWalletWithdrawals(key) {
|
||||||
|
try {
|
||||||
|
const result = await request(`${apiBase}/projects/${encodeURIComponent(key)}/wallet-withdrawals`, { timeoutMs: 6000 });
|
||||||
|
setWalletWithdrawalRows(Array.isArray(result) ? result : []);
|
||||||
|
} catch (_err) {
|
||||||
|
setWalletWithdrawalRows([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function deleteWalletWithdrawal(withdrawal) {
|
async function deleteWalletWithdrawal(withdrawal) {
|
||||||
if (!withdrawal || !withdrawal.id) {
|
if (!withdrawal || !withdrawal.id) {
|
||||||
return;
|
return;
|
||||||
@@ -2001,6 +2032,7 @@
|
|||||||
await request(`${apiBase}/projects/${encodeURIComponent(projectKey)}/wallet-withdrawals/${encodeURIComponent(withdrawal.id)}`, {
|
await request(`${apiBase}/projects/${encodeURIComponent(projectKey)}/wallet-withdrawals/${encodeURIComponent(withdrawal.id)}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
|
setWalletWithdrawalRows((previous) => previous.filter((row) => String(row.id) !== String(withdrawal.id)));
|
||||||
invalidateProjectBootstrapCache(projectKey);
|
invalidateProjectBootstrapCache(projectKey);
|
||||||
await reloadBootstrapAfterMutation('Wallet-Auszahlung geloescht.');
|
await reloadBootstrapAfterMutation('Wallet-Auszahlung geloescht.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -2936,7 +2968,7 @@
|
|||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
panel('Miner-Angebote', currentWalletMiningBalance !== null
|
panel('Miner-Angebote', currentWalletMiningBalance !== null
|
||||||
? `Hier werden nur Basis-Miner gepflegt. Krypto-Angebote werden gegen deinen aktuellen Wallet-Bestand (${fmtNumber(currentWalletMiningBalance, 8)} ${currentMiningCurrency}) gefiltert.`
|
? `Hier werden nur Basis-Miner gepflegt. Die Verfuegbarkeit von Krypto-Angeboten wird gegen deinen aktuellen NC-Wallet-Bestand (${fmtNumber(currentWalletMiningBalance, 8)} ${currentMiningCurrency}) bewertet.`
|
||||||
: 'Hier werden nur Basis-Miner gepflegt. Alle vorgegebenen Geschwindigkeiten und Preise werden daraus automatisch abgeleitet.',
|
: 'Hier werden nur Basis-Miner gepflegt. Alle vorgegebenen Geschwindigkeiten und Preise werden daraus automatisch abgeleitet.',
|
||||||
[
|
[
|
||||||
h('div', { key: 'actions', className: 'mc-inline-row' }, [
|
h('div', { key: 'actions', className: 'mc-inline-row' }, [
|
||||||
@@ -2954,7 +2986,7 @@
|
|||||||
{ value: 'kh', label: 'kH/s' },
|
{ value: 'kh', label: 'kH/s' },
|
||||||
], (value) => setMinerOfferFilters({ ...minerOfferFilters, speed_unit: value || 'auto' })),
|
], (value) => setMinerOfferFilters({ ...minerOfferFilters, speed_unit: value || 'auto' })),
|
||||||
inputField(`Max. Basispreis (${reportCurrency})`, 'number', minerOfferFilters.price_max, (value) => setMinerOfferFilters({ ...minerOfferFilters, price_max: value }), '0.0001'),
|
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(availableMinerOffers.map((offer) => String(offer.runtime_months || '')).filter(Boolean))).sort((a, b) => Number(a) - Number(b)).map((value) => ({
|
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,
|
value,
|
||||||
label: `${value} Monate`,
|
label: `${value} Monate`,
|
||||||
}))), (value) => setMinerOfferFilters({ ...minerOfferFilters, runtime_months: value })),
|
}))), (value) => setMinerOfferFilters({ ...minerOfferFilters, runtime_months: value })),
|
||||||
@@ -2987,6 +3019,7 @@
|
|||||||
? h('div', { key: 'rec-ref', className: 'mc-kicker' }, `Basis ${fmtNumber(offer.base_price_amount, 6)} ${offer.base_price_currency}`)
|
? h('div', { key: 'rec-ref', className: 'mc-kicker' }, `Basis ${fmtNumber(offer.base_price_amount, 6)} ${offer.base_price_currency}`)
|
||||||
: null,
|
: null,
|
||||||
offer.payment_type ? h('div', { key: 'paytype', className: 'mc-kicker' }, offer.payment_type === 'crypto' ? `Zahlung in Krypto (${currentSettings.crypto_currency || 'DOGE'})` : `Zahlung in FIAT (${offer.base_price_currency || 'EUR'})`) : null,
|
offer.payment_type ? h('div', { key: 'paytype', className: 'mc-kicker' }, offer.payment_type === 'crypto' ? `Zahlung in Krypto (${currentSettings.crypto_currency || 'DOGE'})` : `Zahlung in FIAT (${offer.base_price_currency || 'EUR'})`) : null,
|
||||||
|
h('div', { key: 'availability', className: 'mc-kicker' }, isOfferAvailableForWallet(offer, currentMiningCurrency, currentWalletMiningBalance) ? 'Im NC Wallet verfuegbar' : 'Nicht genug NC Wallet Bestand'),
|
||||||
h('div', { key: 'renew', className: 'mc-kicker' }, offer.auto_renew ? 'Automatische Verlängerung' : 'Laeuft aus'),
|
h('div', { key: 'renew', className: 'mc-kicker' }, offer.auto_renew ? 'Automatische Verlängerung' : 'Laeuft aus'),
|
||||||
]),
|
]),
|
||||||
h('td', { key: 'action' }, [
|
h('td', { key: 'action' }, [
|
||||||
@@ -3034,6 +3067,7 @@
|
|||||||
});
|
});
|
||||||
setPurchaseMinerModalOpen(true);
|
setPurchaseMinerModalOpen(true);
|
||||||
},
|
},
|
||||||
|
disabled: !isOfferAvailableForWallet(offer, currentMiningCurrency, currentWalletMiningBalance),
|
||||||
}, 'Mieten'),
|
}, 'Mieten'),
|
||||||
]),
|
]),
|
||||||
]))
|
]))
|
||||||
|
|||||||
@@ -395,7 +395,18 @@ final class MiningRepository
|
|||||||
'SELECT * FROM ' . $this->table('payouts') . ' WHERE project_key = :project_key AND owner_sub = :owner_sub ORDER BY payout_at ASC, id ASC'
|
'SELECT * FROM ' . $this->table('payouts') . ' WHERE project_key = :project_key AND owner_sub = :owner_sub ORDER BY payout_at ASC, id ASC'
|
||||||
);
|
);
|
||||||
$stmt->execute(['project_key' => $projectKey, 'owner_sub' => $this->ownerSub]);
|
$stmt->execute(['project_key' => $projectKey, 'owner_sub' => $this->ownerSub]);
|
||||||
return $this->normalizeRows($stmt->fetchAll() ?: []);
|
$rows = $this->normalizeRows($stmt->fetchAll() ?: []);
|
||||||
|
if ($rows !== []) {
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy fallback: older payout rows may exist without a user scope assignment.
|
||||||
|
$legacyStmt = $this->pdo->prepare(
|
||||||
|
'SELECT * FROM ' . $this->table('payouts') . ' WHERE project_key = :project_key ORDER BY payout_at ASC, id ASC'
|
||||||
|
);
|
||||||
|
$legacyStmt->execute(['project_key' => $projectKey]);
|
||||||
|
|
||||||
|
return $this->normalizeRows($legacyStmt->fetchAll() ?: []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function savePayout(string $projectKey, array $payload): array
|
public function savePayout(string $projectKey, array $payload): array
|
||||||
|
|||||||
Reference in New Issue
Block a user