402 lines
22 KiB
PHP
402 lines
22 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/lang.php';
|
|
require_once __DIR__ . '/includes/header.php';
|
|
?>
|
|
<main class="container py-5">
|
|
<div class="text-center mb-5">
|
|
<h1 class="display-4 fw-bold mb-3"><?= __('mining') ?></h1>
|
|
<p class="lead text-white-50 mx-auto" style="max-width: 700px;">
|
|
<?= __('mining_desc') ?>
|
|
</p>
|
|
</div>
|
|
|
|
<div class="row g-4 mb-5">
|
|
<?php
|
|
$pools = [
|
|
['symbol' => 'BTC', 'name' => __('bitcoin') . __('mining_pool'), 'apy' => '12.5%', 'min' => '0.01 ' . __('BTC'), 'term' => '30 ' . __('day'), 'hot' => true],
|
|
['symbol' => 'ETH', 'name' => __('ethereum') . __('mining_pool'), 'apy' => '8.2%', 'min' => '0.1 ' . __('ETH'), 'term' => __('flexible'), 'hot' => false],
|
|
['symbol' => 'USDT', 'name' => __('tether') . __('mining_pool'), 'apy' => '15.0%', 'min' => '100 ' . __('USDT'), 'term' => '90 ' . __('day'), 'hot' => true],
|
|
['symbol' => 'BNB', 'name' => __('binance_coin') . __('mining_pool'), 'apy' => '22.0%', 'min' => '1 ' . __('BNB'), 'term' => '180 ' . __('day'), 'hot' => false],
|
|
['symbol' => 'SOL', 'name' => __('solana') . __('mining_pool'), 'apy' => '14.2%', 'min' => '5 ' . __('SOL'), 'term' => '60 ' . __('day'), 'hot' => false],
|
|
['symbol' => 'AVAX', 'name' => __('avalanche') . __('mining_pool'), 'apy' => '18.5%', 'min' => '10 ' . __('AVAX'), 'term' => '120 ' . __('day'), 'hot' => false],
|
|
];
|
|
|
|
foreach ($pools as $pool): ?>
|
|
<div class="col-6 col-md-4">
|
|
<div class="card h-100 bg-dark border-secondary shadow-hover transition-all position-relative overflow-hidden" style="border-radius: 20px;">
|
|
<?php if ($pool['hot']): ?>
|
|
<div class="position-absolute top-0 end-0 bg-primary text-white px-2 py-0 small fw-bold" style="border-bottom-left-radius: 12px; font-size: 10px;"><?= __('hot') ?></div>
|
|
<?php endif; ?>
|
|
<div class="card-body p-3 p-md-4">
|
|
<div class="d-flex align-items-center mb-3 mb-md-4">
|
|
<div class="bg-black p-1 p-md-2 rounded-circle me-2 me-md-3 shadow-sm">
|
|
<img src="<?php echo getCoinIcon($pool['symbol']); ?>" width="24" height="24" class="coin-icon-mobile" alt="<?= $pool['symbol'] ?>" onerror="handleIconError(this, '<?= $pool['symbol'] ?>')">
|
|
</div>
|
|
<h6 class="m-0 fw-bold pool-name-mobile"><?= $pool['name'] ?></h6>
|
|
</div>
|
|
|
|
<div class="bg-black rounded-3 p-2 p-md-3 mb-3 mb-md-4">
|
|
<div class="d-flex justify-content-between mb-1 mb-md-2">
|
|
<span class="text-white-50" style="font-size: 10px;"><?= __('est_apy') ?></span>
|
|
<span class="text-success fw-bold" style="font-size: 12px;"><?= $pool['apy'] ?></span>
|
|
</div>
|
|
<div class="d-flex justify-content-between mb-1 mb-md-2">
|
|
<span class="text-white-50" style="font-size: 10px;"><?= __('min_deposit') ?></span>
|
|
<span class="text-white" style="font-size: 10px;"><?= $pool['min'] ?></span>
|
|
</div>
|
|
<div class="d-flex justify-content-between">
|
|
<span class="text-white-50" style="font-size: 10px;"><?= __('lock_period') ?></span>
|
|
<span class="text-primary fw-medium" style="font-size: 10px;"><?= $pool['term'] ?></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-none d-md-flex gap-2 mb-4 small text-white-50">
|
|
<i class="bi bi-shield-check text-success"></i> <?= __('principal_protected') ?>
|
|
<i class="bi bi-lightning-fill text-warning ms-2"></i> <?= __('daily_payouts') ?>
|
|
</div>
|
|
|
|
<button class="btn btn-primary w-100 py-2 py-md-3 fw-bold rounded-pill" style="font-size: 12px;" onclick="openMiningModal('<?= $pool['symbol'] ?>', '<?= $pool['name'] ?>', '<?= $pool['apy'] ?>', '<?= $pool['term'] ?>', '<?= (float)$pool['min'] ?>')"><?= __('start_mining') ?></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<!-- Mining Modal -->
|
|
<div class="modal fade" id="miningModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content bg-surface border-secondary text-white rounded-4 shadow-lg">
|
|
<div class="modal-header border-secondary">
|
|
<h5 class="modal-title fw-bold" id="miningModalTitle"><?= __('confirm_order') ?></h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="d-flex align-items-center mb-4">
|
|
<div class="bg-black p-2 rounded-circle me-3 shadow-sm" id="miningModalIcon">
|
|
<!-- Icon will be injected here -->
|
|
</div>
|
|
<div>
|
|
<h6 class="m-0 fw-bold" id="miningModalPoolName"></h6>
|
|
<div class="text-white-50 small" id="miningModalSymbol"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-black rounded-3 p-3 mb-4">
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span class="text-white-50 small"><?= __('est_apy') ?></span>
|
|
<span class="text-success fw-bold" id="miningModalApy"></span>
|
|
</div>
|
|
<div class="d-flex justify-content-between">
|
|
<span class="text-white-50 small"><?= __('lock_period') ?></span>
|
|
<span class="text-primary fw-medium" id="miningModalTerm"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="form-label text-white-50 small"><?= __('purchase_amount') ?></label>
|
|
<div class="input-group">
|
|
<input type="number" id="miningAmount" class="form-control bg-black border-secondary text-white p-3" placeholder="<?= __('enter_amount') ?>">
|
|
<span class="input-group-text bg-black border-secondary text-white" id="miningModalUnit">USDT</span>
|
|
</div>
|
|
<div class="d-flex justify-content-between mt-2">
|
|
<span class="text-white-50 small" style="font-size: 11px;"><?= __('min_deposit') ?>: <span id="miningModalMin"></span></span>
|
|
<span class="text-white-50 small" style="font-size: 11px; cursor: pointer;" onclick="setMaxMining()"><?= __('available_balance') ?>: <span id="miningModalAvailable">0.00</span></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-primary bg-opacity-10 p-3 rounded-3 small text-white-50 mb-4">
|
|
<i class="bi bi-info-circle me-2 text-primary"></i> <?= __('final_price_settlement') ?>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 p-3">
|
|
<button type="button" class="btn btn-primary w-100 py-3 fw-bold rounded-pill" onclick="submitMining()"><?= __('confirm') ?></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let currentPool = null;
|
|
|
|
function openMiningModal(symbol, name, apy, term, min) {
|
|
currentPool = { symbol, name, apy, term, min };
|
|
document.getElementById('miningModalPoolName').innerText = name;
|
|
document.getElementById('miningModalSymbol').innerText = symbol;
|
|
document.getElementById('miningModalApy').innerText = apy;
|
|
document.getElementById('miningModalTerm').innerText = term;
|
|
document.getElementById('miningModalMin').innerText = min + ' ' + symbol;
|
|
document.getElementById('miningModalUnit').innerText = symbol;
|
|
document.getElementById('miningModalIcon').innerHTML = `<img src="${getCoinIconJs(symbol)}" width="32" height="32" onerror="handleIconError(this, '${symbol}')">`;
|
|
|
|
// Get balance
|
|
fetchBalance(symbol);
|
|
|
|
const modal = new bootstrap.Modal(document.getElementById('miningModal'));
|
|
modal.show();
|
|
}
|
|
|
|
async function fetchBalance(symbol) {
|
|
try {
|
|
const resp = await fetch(`/api/balance.php?symbol=${symbol}`);
|
|
const data = await resp.json();
|
|
if (data.success) {
|
|
document.getElementById('miningModalAvailable').innerText = data.available;
|
|
}
|
|
} catch (e) {
|
|
console.error('Balance fetch failed', e);
|
|
}
|
|
}
|
|
|
|
function setMaxMining() {
|
|
document.getElementById('miningAmount').value = document.getElementById('miningModalAvailable').innerText;
|
|
}
|
|
|
|
async function submitMining() {
|
|
const amount = document.getElementById('miningAmount').value;
|
|
if (!amount || parseFloat(amount) < currentPool.min) {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '<?= __('failed') ?>',
|
|
text: '<?= __('amount_limit_error') ?>'.replace('%min%', currentPool.min).replace('%max%', '∞')
|
|
});
|
|
return;
|
|
}
|
|
|
|
const available = parseFloat(document.getElementById('miningModalAvailable').innerText);
|
|
if (parseFloat(amount) > available) {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '<?= __('failed') ?>',
|
|
text: '<?= __('insufficient_balance') ?>'
|
|
});
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
title: '<?= __('confirm_order') ?>?',
|
|
text: `${currentPool.name} - ${amount} ${currentPool.symbol}`,
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonText: '<?= __('confirm') ?>',
|
|
cancelButtonText: '<?= __('back') ?>',
|
|
background: '#1e2329',
|
|
color: '#fff'
|
|
}).then(async (result) => {
|
|
if (result.isConfirmed) {
|
|
try {
|
|
const response = await fetch('/api/mining.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
symbol: currentPool.symbol,
|
|
pool_name: currentPool.name,
|
|
amount: amount,
|
|
apy: currentPool.apy,
|
|
period: currentPool.term
|
|
})
|
|
});
|
|
const data = await response.json();
|
|
if (data.success) {
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: '<?= __('success') ?>',
|
|
text: '<?= __('request_sent') ?>'
|
|
}).then(() => {
|
|
bootstrap.Modal.getInstance(document.getElementById('miningModal')).hide();
|
|
location.reload();
|
|
});
|
|
} else {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '<?= __('failed') ?>',
|
|
text: data.error || '<?= __('request_failed') ?>'
|
|
});
|
|
}
|
|
} catch (e) {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: '<?= __('failed') ?>',
|
|
text: '<?= __('request_failed') ?>'
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Calculator logic
|
|
function calculateMiningProfit() {
|
|
const amount = parseFloat(document.getElementById('mining-calc-amount').value);
|
|
const select = document.getElementById('mining-calc-pool');
|
|
const apy = parseFloat(select.value);
|
|
const symbol = select.options[select.selectedIndex].getAttribute('data-symbol');
|
|
|
|
if (!amount || isNaN(amount)) {
|
|
document.getElementById('calc-daily-profit').innerText = '--';
|
|
document.getElementById('calc-monthly-profit').innerText = '--';
|
|
document.getElementById('calc-daily-symbol').innerText = '';
|
|
document.getElementById('calc-monthly-symbol').innerText = '';
|
|
return;
|
|
}
|
|
|
|
const daily = (amount * apy) / 365;
|
|
const monthly = (amount * apy) / 12;
|
|
|
|
document.getElementById('calc-daily-profit').innerText = daily.toFixed(6);
|
|
document.getElementById('calc-monthly-profit').innerText = monthly.toFixed(4);
|
|
document.getElementById('calc-daily-symbol').innerText = symbol;
|
|
document.getElementById('calc-monthly-symbol').innerText = symbol;
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
@media (max-width: 768px) {
|
|
.display-4 { font-size: 1.8rem !important; }
|
|
.pool-name-mobile { font-size: 0.85rem !important; }
|
|
.coin-icon-mobile { width: 24px; height: 24px; }
|
|
.row.g-4 { --bs-gutter-x: 0.5rem; --bs-gutter-y: 0.5rem; }
|
|
.py-5 { padding-top: 2rem !important; padding-bottom: 2rem !important; }
|
|
}
|
|
</style>
|
|
</div>
|
|
|
|
<div class="row g-4 align-items-center py-5">
|
|
<div class="col-md-6">
|
|
<h2 class="fw-bold mb-4"><?= __('why_mining') ?></h2>
|
|
<div class="d-flex gap-4 mb-4">
|
|
<div class="bg-primary bg-opacity-10 p-3 rounded-4">
|
|
<i class="bi bi-cpu fs-2 text-primary"></i>
|
|
</div>
|
|
<div>
|
|
<h5 class="fw-bold"><?= __('adv_hardware') ?></h5>
|
|
<p class="text-white-50"><?= __('adv_hardware_desc') ?></p>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex gap-4 mb-4">
|
|
<div class="bg-success bg-opacity-10 p-3 rounded-4">
|
|
<i class="bi bi-wallet2 fs-2 text-success"></i>
|
|
</div>
|
|
<div>
|
|
<h5 class="fw-bold"><?= __('auto_compound') ?></h5>
|
|
<p class="text-white-50"><?= __('auto_compound_desc') ?></p>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex gap-4">
|
|
<div class="bg-info bg-opacity-10 p-3 rounded-4">
|
|
<i class="bi bi-bar-chart-line fs-2 text-info"></i>
|
|
</div>
|
|
<div>
|
|
<h5 class="fw-bold"><?= __('real_time_monitor') ?></h5>
|
|
<p class="text-white-50"><?= __('real_time_monitor_desc') ?></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="bg-surface p-5 rounded-5 border border-secondary text-center shadow">
|
|
<h3 class="fw-bold mb-3"><?= __('calc_profit') ?></h3>
|
|
<p class="text-white-50 mb-4"><?= __('calc_desc') ?></p>
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-md-7">
|
|
<div class="input-group">
|
|
<span class="input-group-text bg-black border-secondary text-white-50"><i class="bi bi-wallet2"></i></span>
|
|
<input type="number" id="mining-calc-amount" class="form-control bg-black border-secondary text-white p-3" placeholder="<?= __('amount_to_invest') ?>" oninput="calculateMiningProfit()">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-5">
|
|
<select id="mining-calc-pool" class="form-select bg-black border-secondary text-white p-3 h-100" onchange="calculateMiningProfit()">
|
|
<?php foreach ($pools as $index => $pool): ?>
|
|
<option value="<?= (float)$pool['apy'] / 100 ?>" data-symbol="<?= $pool['symbol'] ?>"><?= $pool['symbol'] ?> (<?= $pool['apy'] ?>)</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="bg-black p-4 rounded-4 mb-4 border border-secondary border-opacity-25 shadow-inner">
|
|
<div class="row">
|
|
<div class="col-6 border-end border-secondary border-opacity-50">
|
|
<div class="text-white-50 small mb-2"><?= __('daily_profit') ?></div>
|
|
<div class="text-success fw-bold fs-4" id="calc-daily-profit">--</div>
|
|
<div class="text-white-50 mt-1" id="calc-daily-symbol" style="font-size: 0.7rem;"></div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="text-white-50 small mb-2"><?= __('monthly_profit') ?></div>
|
|
<div class="text-success fw-bold fs-4" id="calc-monthly-profit">--</div>
|
|
<div class="text-white-50 mt-1" id="calc-monthly-symbol" style="font-size: 0.7rem;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-sm" onclick="calculateMiningProfit()"><?= __('try_calc') ?></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- My Mining Orders -->
|
|
<?php if ($user): ?>
|
|
<div class="py-5">
|
|
<h2 class="fw-bold mb-4"><?= __('my_mining_orders') ?></h2>
|
|
<div class="card bg-surface border-secondary rounded-4 overflow-hidden shadow">
|
|
<div class="table-responsive">
|
|
<table class="table table-dark table-hover mb-0 align-middle">
|
|
<thead class="bg-black bg-opacity-50 text-white-50 small border-secondary">
|
|
<tr>
|
|
<th class="ps-4 py-3 border-secondary"><?= __('coin') ?></th>
|
|
<th class="py-3 border-secondary"><?= __('pool_name') ?></th>
|
|
<th class="py-3 border-secondary"><?= __('amount') ?></th>
|
|
<th class="py-3 border-secondary"><?= __('est_apy') ?></th>
|
|
<th class="py-3 border-secondary"><?= __('status') ?></th>
|
|
<th class="text-end pe-4 py-3 border-secondary"><?= __('time') ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="border-0">
|
|
<?php
|
|
$stmt = db()->prepare("SELECT * FROM staking_records WHERE user_id = ? ORDER BY created_at DESC");
|
|
$stmt->execute([$user['id']]);
|
|
$myOrders = $stmt->fetchAll();
|
|
|
|
if (empty($myOrders)): ?>
|
|
<tr>
|
|
<td colspan="6" class="text-center py-5 text-white-50">
|
|
<i class="bi bi-inbox fs-2 d-block mb-2"></i>
|
|
<?= __('no_records_found') ?>
|
|
</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($myOrders as $order): ?>
|
|
<tr class="border-secondary small">
|
|
<td class="ps-4 py-3">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<img src="<?= getCoinIcon($order['symbol']) ?>" width="20" height="20" onerror="handleIconError(this, '<?= $order['symbol'] ?>')">
|
|
<span class="fw-bold"><?= $order['symbol'] ?></span>
|
|
</div>
|
|
</td>
|
|
<td class="py-3"><?= $order['plan_name'] ?></td>
|
|
<td class="py-3"><span class="text-white fw-bold"><?= number_format($order['amount'], 4) ?></span></td>
|
|
<td class="py-3 text-success fw-bold"><?= number_format($order['daily_profit'] * 365, 1) ?>%</td>
|
|
<td class="py-3">
|
|
<span class="badge bg-success bg-opacity-10 text-success border border-success border-opacity-25 px-2 py-1"><?= __($order['status']) ?></span>
|
|
</td>
|
|
<td class="text-end pe-4 py-3 text-white-50" style="font-size: 0.75rem;"><?= date('Y-m-d H:i', strtotime($order['created_at'])) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</main>
|
|
|
|
<style>
|
|
.shadow-hover:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 1rem 3rem rgba(0,0,0,0.5) !important;
|
|
}
|
|
.transition-all {
|
|
transition: all 0.3s ease;
|
|
}
|
|
.bg-surface {
|
|
background-color: var(--surface);
|
|
}
|
|
</style>
|
|
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|