以完好
This commit is contained in:
parent
f48e424e36
commit
55c32caea5
21
api/balance.php
Normal file
21
api/balance.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once __DIR__ . '/../includes/lang.php';
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$symbol = $_GET['symbol'] ?? 'USDT';
|
||||
$symbol = strtoupper($symbol);
|
||||
|
||||
$stmt = db()->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = ?");
|
||||
$stmt->execute([$_SESSION['user_id'], $symbol]);
|
||||
$balance = $stmt->fetch();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'available' => $balance ? (float)$balance['available'] : 0.00
|
||||
]);
|
||||
68
api/mining.php
Normal file
68
api/mining.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once __DIR__ . '/../includes/lang.php';
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(['success' => false, 'error' => __('unauthorized')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (!$input || empty($input['symbol']) || empty($input['amount'])) {
|
||||
echo json_encode(['success' => false, 'error' => __('fill_all_fields')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$userId = $_SESSION['user_id'];
|
||||
$symbol = strtoupper($input['symbol']);
|
||||
$poolName = $input['pool_name'];
|
||||
$amount = (float)$input['amount'];
|
||||
$apy = (float)str_replace('%', '', $input['apy']);
|
||||
$periodStr = $input['period'];
|
||||
$dailyProfit = $apy / 365;
|
||||
|
||||
// Check balance
|
||||
$stmt = db()->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = ?");
|
||||
$stmt->execute([$userId, $symbol]);
|
||||
$balance = $stmt->fetch();
|
||||
|
||||
if (!$balance || $balance['available'] < $amount) {
|
||||
echo json_encode(['success' => false, 'error' => __('insufficient_balance')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
$db->beginTransaction();
|
||||
|
||||
// Deduct balance
|
||||
$stmt = $db->prepare("UPDATE user_balances SET available = available - ?, frozen = frozen + ? WHERE user_id = ? AND symbol = ?");
|
||||
$stmt->execute([$amount, $amount, $userId, $symbol]);
|
||||
|
||||
// Create staking record
|
||||
$period = 0;
|
||||
if (preg_match('/(\d+)/', $periodStr, $matches)) {
|
||||
$period = (int)$matches[1];
|
||||
} else {
|
||||
$period = 0; // flexible
|
||||
}
|
||||
|
||||
$startDate = date('Y-m-d');
|
||||
$endDate = date('Y-m-d', strtotime("+$period days"));
|
||||
if ($period == 0) $endDate = '2099-12-31';
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO staking_records (user_id, plan_name, amount, symbol, daily_profit, period, status, start_date, end_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$userId, $poolName, $amount, $symbol, $dailyProfit, $period, 'running', $startDate, $endDate]);
|
||||
|
||||
// Add transaction record
|
||||
$stmt = $db->prepare("INSERT INTO transactions (user_id, symbol, type, amount, status) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$userId, $symbol, 'mining', $amount, 'completed']);
|
||||
|
||||
$db->commit();
|
||||
echo json_encode(['success' => true]);
|
||||
} catch (Exception $e) {
|
||||
$db->rollBack();
|
||||
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||
}
|
||||
428
app.php
428
app.php
@ -28,87 +28,100 @@ if (isset($_GET['action']) && $_GET['action'] === 'download') {
|
||||
?>
|
||||
<main class="app-page-wrapper">
|
||||
<!-- Hero Section -->
|
||||
<section class="app-hero py-5">
|
||||
<div class="container py-lg-5">
|
||||
<section class="app-hero py-5 position-relative overflow-hidden">
|
||||
<!-- Background decorative elements -->
|
||||
<div class="position-absolute top-0 start-0 w-100 h-100 bg-gradient-dark z-0"></div>
|
||||
<div class="blob blob-1"></div>
|
||||
<div class="blob blob-2"></div>
|
||||
|
||||
<div class="container py-lg-5 position-relative z-1">
|
||||
<div class="row align-items-center g-5">
|
||||
<div class="col-lg-6 text-center text-lg-start animate__animated animate__fadeInLeft">
|
||||
<h1 class="display-4 fw-bold text-white mb-4 line-height-1-2">
|
||||
<?= __('support_anywhere') ?>
|
||||
<h1 class="display-3 fw-bold text-white mb-4 line-height-1-2">
|
||||
<span class="text-gradient-primary-light"><?= __('support_anywhere') ?></span>
|
||||
</h1>
|
||||
<p class="lead text-white-50 mb-5 fs-5">
|
||||
<p class="lead text-white mb-5 fs-5 opacity-75">
|
||||
<?= __('app_mockup_desc') ?>
|
||||
</p>
|
||||
|
||||
<div class="download-section mb-5">
|
||||
<div class="row g-3 justify-content-center justify-content-lg-start">
|
||||
<div class="col-12 mb-2 d-lg-none">
|
||||
<a href="?action=download" class="download-btn-modern smart-download w-100">
|
||||
<i class="bi bi-download"></i>
|
||||
<a href="?action=download" class="download-btn-modern smart-download w-100 shadow-primary">
|
||||
<i class="bi bi-download text-white"></i>
|
||||
<div class="text">
|
||||
<span><?= __('get_started') ?></span>
|
||||
<div class="store"><?= __('app_download') ?></div>
|
||||
<span class="text-white-50"><?= __('get_started') ?></span>
|
||||
<div class="store text-white"><?= __('app_download') ?></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6 col-md-4">
|
||||
<a href="<?= getSetting('ios_download_url', '#') ?>" class="download-btn-modern ios">
|
||||
<i class="bi bi-apple"></i>
|
||||
<i class="bi bi-apple text-white"></i>
|
||||
<div class="text">
|
||||
<span><?= __('download_on') ?></span>
|
||||
<div class="store"><?= __('app_store') ?></div>
|
||||
<span class="text-white-50"><?= __('download_on') ?></span>
|
||||
<div class="store text-white"><?= __('app_store') ?></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6 col-md-4">
|
||||
<a href="<?= getSetting('android_download_url', '#') ?>" class="download-btn-modern android">
|
||||
<i class="bi bi-google-play"></i>
|
||||
<i class="bi bi-google-play text-info"></i>
|
||||
<div class="text">
|
||||
<span><?= __('get_it_on') ?></span>
|
||||
<div class="store"><?= __('google_play') ?></div>
|
||||
<span class="text-white-50"><?= __('get_it_on') ?></span>
|
||||
<div class="store text-white"><?= __('google_play') ?></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<a href="<?= getSetting('apk_download_url', '#') ?>" class="download-btn-modern apk">
|
||||
<i class="bi bi-android2"></i>
|
||||
<i class="bi bi-android2 text-success"></i>
|
||||
<div class="text">
|
||||
<span><?= __('download_on') ?></span>
|
||||
<div class="store"><?= __('android_apk') ?></div>
|
||||
<span class="text-white-50"><?= __('download_on') ?></span>
|
||||
<div class="store text-white"><?= __('android_apk') ?></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="qr-container d-inline-flex align-items-center p-3 rounded-4 bg-white bg-opacity-5 border border-secondary shadow-lg">
|
||||
<div class="qr-code p-2 bg-white rounded-3">
|
||||
<div class="qr-container-modern d-inline-flex align-items-center p-1 rounded-5 bg-glass border border-white border-opacity-10 shadow-lg animate__animated animate__zoomIn">
|
||||
<div class="qr-code-wrapper p-3 bg-white rounded-5 shadow-inner">
|
||||
<?php
|
||||
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
|
||||
$download_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . '/app.php?action=download';
|
||||
?>
|
||||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=120x120&data=<?= urlencode($download_url) ?>" alt="QR" width="120" height="120">
|
||||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=<?= urlencode($download_url) ?>" alt="QR" class="qr-img">
|
||||
</div>
|
||||
<div class="ms-4 text-start">
|
||||
<h5 class="text-white fw-bold mb-1"><?= __('scan_download') ?></h5>
|
||||
<p class="text-white-50 small mb-0"><?= __('scan_qr_to_download') ?></p>
|
||||
<div class="px-4 py-2 text-start">
|
||||
<h5 class="text-white fw-bold mb-1 fs-6"><?= __('scan_download') ?></h5>
|
||||
<p class="text-white-50 x-small mb-0"><?= __('scan_qr_to_download') ?></p>
|
||||
<div class="mt-2 d-flex gap-1">
|
||||
<div class="dot bg-primary"></div>
|
||||
<div class="dot bg-success"></div>
|
||||
<div class="dot bg-info"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 text-center position-relative animate__animated animate__fadeInRight">
|
||||
<div class="mockup-container">
|
||||
<div class="mockup-container-modern">
|
||||
<!-- CSS Based Mockup for better performance and reliability -->
|
||||
<div class="iphone-mockup">
|
||||
<div class="screen">
|
||||
<div class="iphone-mockup-modern">
|
||||
<div class="screen-modern">
|
||||
<iframe src="/binary.php?symbol=BTC" frameborder="0" style="width: 100%; height: 100%; border: none;"></iframe>
|
||||
</div>
|
||||
<div class="home-bar"></div>
|
||||
<div class="notch"></div>
|
||||
<div class="home-bar-modern"></div>
|
||||
<div class="notch-modern"></div>
|
||||
</div>
|
||||
<!-- Floating elements for depth -->
|
||||
<div class="floating-icon icon-1"><i class="bi bi-currency-bitcoin text-warning"></i></div>
|
||||
<div class="floating-icon icon-2"><i class="bi bi-shield-lock-fill text-primary"></i></div>
|
||||
<div class="floating-icon icon-3"><i class="bi bi-lightning-fill text-info"></i></div>
|
||||
<div class="floating-element element-1"><div class="glass-card"><i class="bi bi-currency-bitcoin text-warning"></i><span>BTC/USDT</span></div></div>
|
||||
<div class="floating-element element-2"><div class="glass-card"><i class="bi bi-shield-check text-success"></i><span>Secure</span></div></div>
|
||||
<div class="floating-element element-3"><div class="glass-card"><i class="bi bi-lightning-charge-fill text-info"></i><span>Fast</span></div></div>
|
||||
|
||||
<!-- Background Glow -->
|
||||
<div class="mockup-glow"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -116,32 +129,32 @@ if (isset($_GET['action']) && $_GET['action'] === 'download') {
|
||||
</section>
|
||||
|
||||
<!-- Installation Guide -->
|
||||
<section class="py-5 bg-black bg-opacity-20">
|
||||
<div class="container">
|
||||
<section class="py-5 position-relative overflow-hidden" style="background: #080a0c;">
|
||||
<div class="container position-relative z-1">
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="text-white fw-bold"><?= __('kyc_steps') ?></h2>
|
||||
<p class="text-white-50"><?= __('recharge_steps') ?></p>
|
||||
<h2 class="text-white fw-bold display-6 mb-3"><?= __('kyc_steps') ?></h2>
|
||||
<p class="text-white-50 lead mx-auto" style="max-width: 600px;"><?= __('recharge_steps') ?></p>
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-4">
|
||||
<div class="guide-card p-4 rounded-4 bg-surface border border-secondary h-100">
|
||||
<div class="step-num mb-3">01</div>
|
||||
<div class="guide-card-modern p-4 rounded-5 bg-glass-dark border border-white border-opacity-5 h-100">
|
||||
<div class="step-badge mb-4">01</div>
|
||||
<h4 class="text-white mb-3"><?= __('scan_download') ?></h4>
|
||||
<p class="text-white-50 small mb-0"><?= __('app_guide_step1') ?></p>
|
||||
<p class="text-white-50 mb-0"><?= __('app_guide_step1') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="guide-card p-4 rounded-4 bg-surface border border-secondary h-100">
|
||||
<div class="step-num mb-3">02</div>
|
||||
<div class="guide-card-modern p-4 rounded-5 bg-glass-dark border border-white border-opacity-5 h-100">
|
||||
<div class="step-badge mb-4">02</div>
|
||||
<h4 class="text-white mb-3"><?= __('app_install_auth') ?></h4>
|
||||
<p class="text-white-50 small mb-0"><?= __('app_guide_step2') ?></p>
|
||||
<p class="text-white-50 mb-0"><?= __('app_guide_step2') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="guide-card p-4 rounded-4 bg-surface border border-secondary h-100">
|
||||
<div class="step-num mb-3">03</div>
|
||||
<div class="guide-card-modern p-4 rounded-5 bg-glass-dark border border-white border-opacity-5 h-100">
|
||||
<div class="step-badge mb-4">03</div>
|
||||
<h4 class="text-white mb-3"><?= __('app_experience_now') ?></h4>
|
||||
<p class="text-white-50 small mb-0"><?= __('app_guide_step3') ?></p>
|
||||
<p class="text-white-50 mb-0"><?= __('app_guide_step3') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -149,39 +162,40 @@ if (isset($_GET['action']) && $_GET['action'] === 'download') {
|
||||
</section>
|
||||
|
||||
<!-- Features -->
|
||||
<section class="py-5 bg-black bg-opacity-30 border-top border-secondary">
|
||||
<section class="py-5 bg-gradient-dark-reverse border-top border-white border-opacity-5">
|
||||
<div class="container">
|
||||
<div class="row g-4">
|
||||
<div class="col-md-4">
|
||||
<div class="feature-item p-4 text-center">
|
||||
<div class="icon-circle bg-primary bg-opacity-10 text-primary mb-3 mx-auto">
|
||||
<div class="feature-item-modern p-4 text-center">
|
||||
<div class="icon-box bg-gradient-primary text-white mb-4 shadow-primary">
|
||||
<i class="bi bi-graph-up-arrow fs-2"></i>
|
||||
</div>
|
||||
<h4 class="text-white fw-bold"><?= __('real_time_alerts') ?></h4>
|
||||
<h4 class="text-white fw-bold mb-3"><?= __('real_time_alerts') ?></h4>
|
||||
<p class="text-white-50"><?= __('full_trading_features') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="feature-item p-4 text-center">
|
||||
<div class="icon-circle bg-success bg-opacity-10 text-success mb-3 mx-auto">
|
||||
<div class="feature-item-modern p-4 text-center">
|
||||
<div class="icon-box bg-gradient-success text-white mb-4 shadow-success">
|
||||
<i class="bi bi-safe2 fs-2"></i>
|
||||
</div>
|
||||
<h4 class="text-white fw-bold"><?= __('two_fa_security') ?></h4>
|
||||
<h4 class="text-white fw-bold mb-3"><?= __('two_fa_security') ?></h4>
|
||||
<p class="text-white-50"><?= __('inst_security_desc') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="feature-item p-4 text-center">
|
||||
<div class="icon-circle bg-info bg-opacity-10 text-info mb-3 mx-auto">
|
||||
<div class="feature-item-modern p-4 text-center">
|
||||
<div class="icon-box bg-gradient-info text-white mb-4 shadow-info">
|
||||
<i class="bi bi-chat-dots fs-2"></i>
|
||||
</div>
|
||||
<h4 class="text-white fw-bold"><?= __('live_chat_247') ?></h4>
|
||||
<h4 class="text-white fw-bold mb-3"><?= __('live_chat_247') ?></h4>
|
||||
<p class="text-white-50"><?= __('support_247') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<script>
|
||||
@ -199,169 +213,251 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.guide-card {
|
||||
transition: all 0.3s ease;
|
||||
:root {
|
||||
--primary: #0062ff;
|
||||
--primary-light: #4c9aff;
|
||||
--success: #02c076;
|
||||
--info: #00d2ff;
|
||||
--warning: #f0b90b;
|
||||
--surface: #1e2329;
|
||||
--glass: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
.guide-card:hover {
|
||||
|
||||
.app-page-wrapper {
|
||||
background: #080a0c;
|
||||
overflow-x: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bg-gradient-dark {
|
||||
background: radial-gradient(circle at 0% 0%, rgba(0, 98, 255, 0.1) 0%, transparent 50%),
|
||||
radial-gradient(circle at 100% 100%, rgba(2, 192, 118, 0.05) 0%, transparent 50%);
|
||||
}
|
||||
|
||||
.bg-gradient-dark-reverse {
|
||||
background: radial-gradient(circle at 100% 0%, rgba(0, 210, 255, 0.05) 0%, transparent 50%),
|
||||
radial-gradient(circle at 0% 100%, rgba(0, 98, 255, 0.05) 0%, transparent 50%);
|
||||
}
|
||||
|
||||
.text-gradient-primary-light {
|
||||
background: linear-gradient(135deg, #fff 0%, var(--primary-light) 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.bg-glass {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.bg-glass-dark {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* Blobs for background decoration */
|
||||
.blob {
|
||||
position: absolute;
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background: var(--primary);
|
||||
filter: blur(150px);
|
||||
opacity: 0.1;
|
||||
border-radius: 50%;
|
||||
z-index: 0;
|
||||
}
|
||||
.blob-1 { top: -100px; right: -100px; }
|
||||
.blob-2 { bottom: -100px; left: -100px; background: var(--success); }
|
||||
|
||||
/* Buttons */
|
||||
.download-btn-modern {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 14px 18px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 16px;
|
||||
text-decoration: none !important;
|
||||
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
height: 100%;
|
||||
}
|
||||
.download-btn-modern:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-color: var(--primary);
|
||||
transform: translateY(-5px);
|
||||
border-color: var(--primary) !important;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.step-num {
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
color: var(--primary);
|
||||
opacity: 0.5;
|
||||
font-family: 'Inter', sans-serif;
|
||||
.download-btn-modern i {
|
||||
font-size: 28px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.download-btn-modern .text .store {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.download-btn-modern .text span {
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
display: block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.smart-download {
|
||||
background: var(--primary) !important;
|
||||
border-color: var(--primary) !important;
|
||||
}
|
||||
.smart-download i {
|
||||
color: #fff !important;
|
||||
}
|
||||
.smart-download .text .store {
|
||||
color: #fff !important;
|
||||
}
|
||||
.smart-download .text span {
|
||||
color: rgba(255,255,255,0.8) !important;
|
||||
}
|
||||
|
||||
.highlight-pulse {
|
||||
border-color: var(--primary) !important;
|
||||
box-shadow: 0 0 15px rgba(0, 98, 255, 0.4);
|
||||
animation: pulse-border 2s infinite;
|
||||
/* QR Code */
|
||||
.qr-container-modern {
|
||||
margin-top: 20px;
|
||||
}
|
||||
@keyframes pulse-border {
|
||||
0% { box-shadow: 0 0 0 0 rgba(0, 98, 255, 0.4); }
|
||||
70% { box-shadow: 0 0 0 10px rgba(0, 98, 255, 0); }
|
||||
100% { box-shadow: 0 0 0 0 rgba(0, 98, 255, 0); }
|
||||
}
|
||||
.app-page-wrapper {
|
||||
background: #0b0e11;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.download-btn-modern {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 15px;
|
||||
background: #1e2329;
|
||||
border: 1px solid #2b3139;
|
||||
.qr-img {
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
height: 100%;
|
||||
}
|
||||
.download-btn-modern:hover {
|
||||
background: #2b3139;
|
||||
border-color: var(--primary);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
.download-btn-modern i {
|
||||
font-size: 24px;
|
||||
margin-right: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
.download-btn-modern .text {
|
||||
text-align: left;
|
||||
}
|
||||
.download-btn-modern .text span {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: #848e9c;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.download-btn-modern .text .store {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
.dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.x-small { font-size: 11px; }
|
||||
|
||||
/* Mockup CSS */
|
||||
.mockup-container {
|
||||
/* Mockup */
|
||||
.mockup-container-modern {
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
padding: 40px;
|
||||
display: inline-block;
|
||||
}
|
||||
.iphone-mockup {
|
||||
width: 300px;
|
||||
height: 600px;
|
||||
background: #2b3139;
|
||||
border-radius: 40px;
|
||||
border: 12px solid #1e2329;
|
||||
.iphone-mockup-modern {
|
||||
width: 280px;
|
||||
height: 580px;
|
||||
background: #111;
|
||||
border-radius: 45px;
|
||||
border: 10px solid #222;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
box-shadow: 0 50px 100px rgba(0,0,0,0.5);
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
box-shadow: 0 50px 100px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.iphone-mockup .screen {
|
||||
.screen-modern {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #0b0e11;
|
||||
border-radius: 28px;
|
||||
border-radius: 35px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
.iphone-mockup .notch {
|
||||
.notch-modern {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 150px;
|
||||
width: 130px;
|
||||
height: 25px;
|
||||
background: #1e2329;
|
||||
border-bottom-left-radius: 20px;
|
||||
border-bottom-right-radius: 20px;
|
||||
background: #222;
|
||||
border-bottom-left-radius: 18px;
|
||||
border-bottom-right-radius: 18px;
|
||||
z-index: 10;
|
||||
}
|
||||
.iphone-mockup .home-bar {
|
||||
.home-bar-modern {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 100px;
|
||||
width: 90px;
|
||||
height: 4px;
|
||||
background: rgba(255,255,255,0.2);
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 2px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.floating-icon {
|
||||
.mockup-glow {
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: #1e2329;
|
||||
border: 1px solid #2b3139;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 120%;
|
||||
height: 110%;
|
||||
background: radial-gradient(circle, rgba(0, 98, 255, 0.15) 0%, transparent 70%);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.floating-element {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
animation: float 5s ease-in-out infinite;
|
||||
}
|
||||
.glass-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding: 10px 15px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.glass-card i { font-size: 20px; }
|
||||
.glass-card span { font-size: 12px; font-weight: 600; color: #fff; }
|
||||
|
||||
.element-1 { top: 15%; right: -20px; animation-delay: 0s; }
|
||||
.element-2 { bottom: 25%; left: -30px; animation-delay: 1.5s; }
|
||||
.element-3 { top: 45%; left: -50px; animation-delay: 0.7s; }
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0) rotate(0); }
|
||||
50% { transform: translateY(-15px) rotate(2deg); }
|
||||
}
|
||||
|
||||
/* Guide Cards */
|
||||
.guide-card-modern {
|
||||
transition: all 0.4s ease;
|
||||
}
|
||||
.guide-card-modern:hover {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-color: var(--primary-light) !important;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
.step-badge {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: linear-gradient(135deg, var(--primary), var(--info));
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
animation: float 4s ease-in-out infinite;
|
||||
z-index: 5;
|
||||
}
|
||||
.icon-1 { top: 10%; right: 10%; animation-delay: 0s; }
|
||||
.icon-2 { bottom: 20%; left: 10%; animation-delay: 1s; }
|
||||
.icon-3 { top: 40%; left: -5%; animation-delay: 2s; }
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-20px); }
|
||||
font-weight: 900;
|
||||
font-size: 20px;
|
||||
box-shadow: 0 10px 20px rgba(0, 98, 255, 0.3);
|
||||
}
|
||||
|
||||
.icon-circle {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 50%;
|
||||
/* Feature Items */
|
||||
.icon-box {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 22px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.bg-gradient-primary { background: linear-gradient(135deg, var(--primary), var(--primary-light)); }
|
||||
.bg-gradient-success { background: linear-gradient(135deg, var(--success), #3ae39f); }
|
||||
.bg-gradient-info { background: linear-gradient(135deg, var(--info), #5de4ff); }
|
||||
|
||||
.shadow-primary { box-shadow: 0 15px 30px rgba(0, 98, 255, 0.25); }
|
||||
.shadow-success { box-shadow: 0 15px 30px rgba(2, 192, 118, 0.25); }
|
||||
.shadow-info { box-shadow: 0 15px 30px rgba(0, 210, 255, 0.25); }
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.iphone-mockup {
|
||||
width: 260px;
|
||||
height: 520px;
|
||||
.iphone-mockup-modern {
|
||||
width: 240px;
|
||||
height: 500px;
|
||||
}
|
||||
.display-3 { font-size: 2.5rem; }
|
||||
.element-1, .element-2, .element-3 { display: none; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
BIN
assets/pasted-20260219-073456-0e79a370.png
Normal file
BIN
assets/pasted-20260219-073456-0e79a370.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/pasted-20260219-080909-f22812cc.png
Normal file
BIN
assets/pasted-20260219-080909-f22812cc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
BIN
assets/pasted-20260219-081544-37a22a14.png
Normal file
BIN
assets/pasted-20260219-081544-37a22a14.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
BIN
assets/pasted-20260219-082349-d2b06418.png
Normal file
BIN
assets/pasted-20260219-082349-d2b06418.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/pasted-20260219-082954-46ef5781.png
Normal file
BIN
assets/pasted-20260219-082954-46ef5781.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
24
db/migrations/20260219_create_mining_orders.php
Normal file
24
db/migrations/20260219_create_mining_orders.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
// db/migrations/20260219_create_mining_orders.php
|
||||
require_once __DIR__ . '/../config.php';
|
||||
|
||||
try {
|
||||
$db = db();
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS mining_orders (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
symbol VARCHAR(10) NOT NULL,
|
||||
pool_name VARCHAR(100) NOT NULL,
|
||||
amount DECIMAL(20, 8) NOT NULL,
|
||||
apy DECIMAL(10, 4) NOT NULL,
|
||||
period VARCHAR(20) NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'running',
|
||||
start_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
end_time DATETIME,
|
||||
last_payout DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
total_profit DECIMAL(20, 8) DEFAULT 0
|
||||
)");
|
||||
echo "Table mining_orders created successfully.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Error creating table: " . $e->getMessage() . "\n";
|
||||
}
|
||||
@ -336,10 +336,34 @@ if (isset($_SESSION['user_id'])) {
|
||||
'ATOM': '1481/small/cosmos.png',
|
||||
'IMX': '17233/small/immutable-x.png',
|
||||
'KAS': '26851/small/kaspa.png',
|
||||
'DAI': '992/small/dai.png',
|
||||
'STX': '2069/small/stacks.png',
|
||||
'RNDR': '11634/small/render-token.png',
|
||||
'INJ': '12882/small/injective_protocol.png',
|
||||
'TIA': '31967/small/tia.png',
|
||||
'SUI': '26375/small/sui-ocean-64.png',
|
||||
'SEI': '31322/small/sei.png',
|
||||
};
|
||||
function getCoinIconJs(symbol) {
|
||||
const id = window.coinIcons[symbol.toUpperCase()] || '1/small/bitcoin.png';
|
||||
return "https://assets.coingecko.com/coins/images/" + id;
|
||||
symbol = symbol.toUpperCase();
|
||||
const id = window.coinIcons[symbol];
|
||||
if (id) {
|
||||
return "https://coin-images.coingecko.com/coins/images/" + id;
|
||||
}
|
||||
// Fallback to Binance CDN
|
||||
return "https://bin.bnbstatic.com/static/images/home/market/coin-icon/" + symbol + ".png";
|
||||
}
|
||||
function handleIconError(img, symbol) {
|
||||
if (!img.triedOKX) {
|
||||
img.triedOKX = true;
|
||||
img.src = "https://static.okx.com/cdn/oksupport/asset/currency/icon/" + symbol.toLowerCase() + ".png";
|
||||
} else if (!img.triedCrypto) {
|
||||
img.triedCrypto = true;
|
||||
img.src = "https://assets.coincap.io/assets/icons/" + symbol.toLowerCase() + "@2x.png";
|
||||
} else {
|
||||
img.src = 'https://coin-images.coingecko.com/coins/images/1/small/bitcoin.png';
|
||||
img.onerror = null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@ -377,6 +377,7 @@ $translations = [
|
||||
'limit' => '限价',
|
||||
'amount' => '数量',
|
||||
'operation' => '操作',
|
||||
'action' => '操作',
|
||||
'frozen' => '冻结',
|
||||
'converted_to' => '折合',
|
||||
'asset_records' => '资产记录',
|
||||
@ -386,6 +387,9 @@ $translations = [
|
||||
'time' => '时间',
|
||||
'hot' => '热门',
|
||||
'executing' => '进行中',
|
||||
'running' => '运行中',
|
||||
'pool_name' => '矿池名称',
|
||||
'my_mining_orders' => '我的矿池订单',
|
||||
'won' => '盈利',
|
||||
'loss' => '亏损',
|
||||
'total' => '总计',
|
||||
@ -886,6 +890,7 @@ $translations = [
|
||||
'limit' => 'Limit',
|
||||
'amount' => 'Amount',
|
||||
'operation' => 'Operation',
|
||||
'action' => 'Action',
|
||||
'frozen' => 'Frozen',
|
||||
'converted_to' => 'Converted',
|
||||
'asset_records' => 'Asset Records',
|
||||
@ -895,6 +900,9 @@ $translations = [
|
||||
'time' => 'Time',
|
||||
'hot' => 'Hot',
|
||||
'executing' => 'Executing',
|
||||
'running' => 'Running',
|
||||
'pool_name' => 'Pool Name',
|
||||
'my_mining_orders' => 'My Mining Orders',
|
||||
'won' => 'Won',
|
||||
'loss' => 'Loss',
|
||||
'total' => 'Total',
|
||||
@ -1020,6 +1028,7 @@ function __($key) {
|
||||
}
|
||||
|
||||
function getCoinIcon($symbol) {
|
||||
$symbol = strtoupper($symbol);
|
||||
$icon_ids = [
|
||||
'BTC' => '1/small/bitcoin.png',
|
||||
'ETH' => '279/small/ethereum.png',
|
||||
@ -1048,7 +1057,20 @@ function getCoinIcon($symbol) {
|
||||
'ATOM' => '1481/small/cosmos.png',
|
||||
'IMX' => '17233/small/immutable-x.png',
|
||||
'KAS' => '26851/small/kaspa.png',
|
||||
'DAI' => '992/small/dai.png',
|
||||
'STX' => '2069/small/stacks.png',
|
||||
'RNDR' => '11634/small/render-token.png',
|
||||
'INJ' => '12882/small/injective_protocol.png',
|
||||
'TIA' => '31967/small/tia.png',
|
||||
'SUI' => '26375/small/sui-ocean-64.png',
|
||||
'SEI' => '31322/small/sei.png',
|
||||
];
|
||||
$id = $icon_ids[strtoupper($symbol)] ?? '1/small/bitcoin.png';
|
||||
return "https://assets.coingecko.com/coins/images/" . $id;
|
||||
|
||||
if (isset($icon_ids[$symbol])) {
|
||||
return "https://coin-images.coingecko.com/coins/images/" . $icon_ids[$symbol];
|
||||
}
|
||||
|
||||
// Fallback order: Binance -> OKX
|
||||
// Binance is very reliable for symbols
|
||||
return "https://bin.bnbstatic.com/static/images/home/market/coin-icon/" . $symbol . ".png";
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ function renderTerminal($activeTab = 'spot') {
|
||||
<div class="coin-row" data-symbol="<?= $coin['symbol'] ?>" onclick="location.href='?symbol=<?= $coin['symbol'] ?>'">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-light p-1 rounded-circle me-2" style="width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">
|
||||
<img src="<?php echo getCoinIcon($coin['symbol']); ?>" onerror="this.src='/assets/images/coin-placeholder.png'" alt="<?= $coin['symbol'] ?>" style="width: 18px; height: 18px; margin: 0;">
|
||||
<img src="<?php echo getCoinIcon($coin['symbol']); ?>" alt="<?= $coin['symbol'] ?>" onerror="handleIconError(this, '<?= $coin['symbol'] ?>')" style="width: 18px; height: 18px; margin: 0;">
|
||||
</div>
|
||||
<div>
|
||||
<div class="symbol fw-bold text-white" style="font-size: 13px;"><?= $lang === 'zh' ? __($coin['symbol']) : $coin['symbol'] ?></div>
|
||||
@ -105,19 +105,19 @@ function renderTerminal($activeTab = 'spot') {
|
||||
<div class="d-flex gap-4 header-stats d-none d-md-flex">
|
||||
|
||||
<div class="header-stat">
|
||||
<label class="d-block small text-muted"><?= __('change_24h') ?></label>
|
||||
<label class="d-block small text-white"><?= __('change_24h') ?></label>
|
||||
<span class="text-success fw-bold">--</span>
|
||||
</div>
|
||||
<div class="header-stat">
|
||||
<label class="d-block small text-muted"><?= __('high') ?></label>
|
||||
<label class="d-block small text-white"><?= __('high') ?></label>
|
||||
<span class="text-white fw-bold">--</span>
|
||||
</div>
|
||||
<div class="header-stat">
|
||||
<label class="d-block small text-muted"><?= __('low') ?></label>
|
||||
<label class="d-block small text-white"><?= __('low') ?></label>
|
||||
<span class="text-white fw-bold">--</span>
|
||||
</div>
|
||||
<div class="header-stat">
|
||||
<label class="d-block small text-muted"><?= __('vol_24h') ?></label>
|
||||
<label class="d-block small text-white"><?= __('vol_24h') ?></label>
|
||||
<span class="text-white fw-bold">--</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -155,7 +155,7 @@ function renderTerminal($activeTab = 'spot') {
|
||||
tvWidget = new TradingView.widget(
|
||||
{
|
||||
"autosize": true,
|
||||
"symbol": "BINANCE:<?= $currentSymbol ?>USDT",
|
||||
"symbol": "<?= $currentSymbol === 'USDT' ? 'BINANCE:USDTDAI' : ($currentSymbol . 'USDT') ?>",
|
||||
"interval": "1",
|
||||
"timezone": "Etc/UTC",
|
||||
"theme": "dark",
|
||||
@ -859,7 +859,7 @@ function renderTerminal($activeTab = 'spot') {
|
||||
row.innerHTML = `
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-light p-1 rounded-circle me-2" style="width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">
|
||||
<img src="${getCoinIconJs(symbol)}" onerror="this.src='/assets/images/coin-placeholder.png'" alt="${symbol}" style="width: 18px; height: 18px; margin: 0;">
|
||||
<img src="${getCoinIconJs(symbol)}" onerror="handleIconError(this, '${symbol}')" alt="${symbol}" style="width: 18px; height: 18px; margin: 0;">
|
||||
</div>
|
||||
<div>
|
||||
<div class="symbol fw-bold text-white">${symbol}</div>
|
||||
|
||||
68
index.php
68
index.php
@ -187,7 +187,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src="<?php echo getCoinIcon($coin['symbol']); ?>" width="32" height="32" class="me-2 rounded-circle bg-light p-1" alt="<?php echo $coin['symbol']; ?>" onerror="this.src='https://assets.coingecko.com/coins/images/1/small/bitcoin.png'">
|
||||
<img src="<?php echo getCoinIcon($coin['symbol']); ?>" width="32" height="32" class="me-2 rounded-circle bg-light p-1" alt="<?php echo $coin['symbol']; ?>" onerror="handleIconError(this, '<?php echo $coin['symbol']; ?>')">
|
||||
<span class="fw-bold fs-5"><?php echo $lang === 'zh' ? __($coin['symbol']) : $coin['symbol']; ?></span>
|
||||
<small class="text-muted ms-2 d-none d-md-inline">/USDT</small>
|
||||
</div>
|
||||
@ -348,32 +348,50 @@ function updateUI(symbol, price, change) {
|
||||
badge.className = `change-badge badge ${change >= 0 ? 'bg-success' : 'bg-danger'}`;
|
||||
}
|
||||
|
||||
// Sparklines
|
||||
document.querySelectorAll('.sparkline-canvas').forEach(canvas => {
|
||||
const ctx = canvas.getContext('2d');
|
||||
const isUp = Math.random() > 0.4;
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: new Array(10).fill(''),
|
||||
datasets: [{
|
||||
data: new Array(10).fill(0).map(() => Math.random() * 100),
|
||||
borderColor: isUp ? '#26a69a' : '#ef5350',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
fill: true,
|
||||
backgroundColor: isUp ? 'rgba(38, 166, 154, 0.1)' : 'rgba(239, 83, 80, 0.1)',
|
||||
tension: 0.4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: { legend: { display: false } },
|
||||
scales: { x: { display: false }, y: { display: false } },
|
||||
maintainAspectRatio: false
|
||||
// Sparklines with real data
|
||||
async function initSparklines() {
|
||||
const symbols = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT', 'XRPUSDT', 'ADAUSDT', 'DOGEUSDT', 'DOTUSDT', 'MATICUSDT', 'LINKUSDT', 'SHIBUSDT'];
|
||||
|
||||
for (const symbol of symbols) {
|
||||
try {
|
||||
const response = await fetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=1h&limit=20`);
|
||||
const data = await response.json();
|
||||
const prices = data.map(d => parseFloat(d[4]));
|
||||
const s = symbol.replace('USDT', '');
|
||||
const canvas = document.getElementById(`spark-${s}`);
|
||||
if (!canvas) continue;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
const isUp = prices[prices.length - 1] >= prices[0];
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: new Array(prices.length).fill(''),
|
||||
datasets: [{
|
||||
data: prices,
|
||||
borderColor: isUp ? '#0ecb81' : '#f6465d',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
fill: true,
|
||||
backgroundColor: isUp ? 'rgba(14, 203, 129, 0.1)' : 'rgba(246, 70, 93, 0.1)',
|
||||
tension: 0.4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: { legend: { display: false }, tooltip: { enabled: false } },
|
||||
scales: { x: { display: false }, y: { display: false } },
|
||||
maintainAspectRatio: false,
|
||||
responsive: true
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch sparkline for ${symbol}:`, err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
initSparklines();
|
||||
initPriceUpdate();
|
||||
</script>
|
||||
|
||||
|
||||
98
market.php
98
market.php
@ -12,8 +12,8 @@ require_once __DIR__ . '/includes/header.php';
|
||||
<th class="ps-4 py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('coin') ?></th>
|
||||
<th class="py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('last_price') ?></th>
|
||||
<th class="py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('change_24h') ?></th>
|
||||
<th class="py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('vol_24h') ?></th>
|
||||
<th class="text-end pe-4 py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('market') ?></th>
|
||||
<th class="py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('market') ?></th>
|
||||
<th class="text-end pe-4 py-4 border-0 fw-bold text-uppercase" style="letter-spacing: 1px; color: #ffffff !important;"><?= __('action') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="border-0">
|
||||
@ -44,7 +44,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
<td class="ps-4 py-3 border-0">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-white p-1 rounded-circle me-3 shadow-sm" style="width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;">
|
||||
<img src="<?php echo getCoinIcon($coin['symbol']); ?>" width="26" height="26" alt="<?= $coin['symbol'] ?>" onerror="this.src='https://assets.coingecko.com/coins/images/1/small/bitcoin.png'">
|
||||
<img src="<?php echo getCoinIcon($coin['symbol']); ?>" width="26" height="26" alt="<?= $coin['symbol'] ?>" onerror="handleIconError(this, '<?= $coin['symbol'] ?>')">
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold text-white fs-5"><?php echo $lang === 'zh' ? __($coin['symbol']) : $coin['symbol']; ?></div>
|
||||
@ -52,11 +52,13 @@ require_once __DIR__ . '/includes/header.php';
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="fw-bold text-white border-0 fs-5">$<?php echo $coin['price']; ?></td>
|
||||
<td class="border-0 fw-bold fs-5 <?php echo strpos($coin['change'], '+') !== false ? 'text-success' : 'text-danger'; ?>">
|
||||
<td class="fw-bold text-white border-0 fs-5 price-val" data-symbol="<?php echo $coin['symbol']; ?>">$<?php echo $coin['price']; ?></td>
|
||||
<td class="border-0 fw-bold fs-5 change-val <?php echo strpos($coin['change'], '+') !== false ? 'text-success' : 'text-danger'; ?>" data-symbol="<?php echo $coin['symbol']; ?>">
|
||||
<?php echo $coin['change']; ?>
|
||||
</td>
|
||||
<td class="text-light-50 border-0 fw-medium" style="color: #eaecef !important; opacity: 0.8;"><?php echo $coin['vol']; ?></td>
|
||||
<td class="border-0" style="width: 150px; height: 60px;">
|
||||
<canvas id="spark-<?= $coin['symbol'] ?>" style="max-width: 120px; height: 40px;"></canvas>
|
||||
</td>
|
||||
<td class="text-end pe-4 border-0">
|
||||
<a href="trade.php?symbol=<?php echo $coin['symbol']; ?>" class="btn btn-primary btn-md px-4 rounded-pill fw-bold"><?= __('trade') ?></a>
|
||||
</td>
|
||||
@ -70,23 +72,101 @@ require_once __DIR__ . '/includes/header.php';
|
||||
<?php foreach ($full_coins as $coin): ?>
|
||||
<div class="p-3 mb-2 rounded-4 bg-black bg-opacity-20 border border-secondary border-opacity-50 d-flex align-items-center justify-content-between" onclick="location.href='trade.php?symbol=<?= $coin['symbol'] ?>'">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<img src="<?= getCoinIcon($coin['symbol']) ?>" width="32" height="32" class="rounded-circle bg-white p-1">
|
||||
<img src="<?= getCoinIcon($coin['symbol']) ?>" width="32" height="32" class="rounded-circle bg-white p-1" alt="<?= $coin['symbol'] ?>" onerror="handleIconError(this, '<?= $coin['symbol'] ?>')">
|
||||
<div>
|
||||
<div class="fw-bold text-white"><?= $lang === 'zh' ? __($coin['symbol']) : $coin['symbol'] ?></div>
|
||||
<div class="text-white-50 x-small"><?= $coin['vol'] ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="fw-bold text-white">$<?= $coin['price'] ?></div>
|
||||
<div class="fw-bold text-white price-val" data-symbol="<?= $coin['symbol'] ?>">$<?= $coin['price'] ?></div>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<div class="fw-bold <?= strpos($coin['change'], '+') !== false ? 'text-success' : 'text-danger' ?>"><?= $coin['change'] ?></div>
|
||||
<div class="fw-bold change-val <?= strpos($coin['change'], '+') !== false ? 'text-success' : 'text-danger' ?>" data-symbol="<?= $coin['symbol'] ?>"><?= $coin['change'] ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
async function updatePrices() {
|
||||
const symbols = [<?php echo "'" . implode("','", array_map(function($c){return $c['symbol'];}, $full_coins)) . "'"; ?>];
|
||||
for (const s of symbols) {
|
||||
try {
|
||||
const symbol = s === 'USDT' ? 'USDTDAI' : s + 'USDT';
|
||||
const response = await fetch(`https://api.binance.com/api/v3/ticker/24hr?symbol=${symbol}`);
|
||||
const data = await response.json();
|
||||
|
||||
const price = parseFloat(data.lastPrice);
|
||||
const change = parseFloat(data.priceChangePercent);
|
||||
|
||||
const priceCells = document.querySelectorAll(`.price-val[data-symbol="${s}"]`);
|
||||
const changeCells = document.querySelectorAll(`.change-val[data-symbol="${s}"]`);
|
||||
|
||||
const formattedPrice = price < 1 ? price.toFixed(4) : (price < 10 ? price.toFixed(3) : price.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}));
|
||||
const formattedChange = (change >= 0 ? '+' : '') + change.toFixed(2) + '%';
|
||||
|
||||
priceCells.forEach(cell => {
|
||||
cell.textContent = '$' + formattedPrice;
|
||||
});
|
||||
|
||||
changeCells.forEach(cell => {
|
||||
cell.textContent = formattedChange;
|
||||
cell.className = `border-0 fw-bold fs-5 change-val ${change >= 0 ? 'text-success' : 'text-danger'}`;
|
||||
// Special handling for mobile view class
|
||||
if (cell.parentElement.classList.contains('text-end')) {
|
||||
cell.className = `fw-bold change-val ${change >= 0 ? 'text-success' : 'text-danger'}`;
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch price for ${s}:`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function initSparklines() {
|
||||
updatePrices(); // Initial price update
|
||||
setInterval(updatePrices, 10000); // Update every 10 seconds
|
||||
|
||||
const symbols = [<?php echo "'" . implode("','", array_map(function($c){return $c['symbol'];}, $full_coins)) . "'"; ?>];
|
||||
for (const s of symbols) {
|
||||
try {
|
||||
const symbol = s === 'USDT' ? 'USDTDAI' : s + 'USDT';
|
||||
const response = await fetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=1h&limit=20`);
|
||||
const data = await response.json();
|
||||
const prices = data.map(d => parseFloat(d[4]));
|
||||
const canvas = document.getElementById(`spark-${s}`);
|
||||
if (!canvas) continue;
|
||||
const ctx = canvas.getContext('2d');
|
||||
const isUp = prices[prices.length - 1] >= prices[0];
|
||||
new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: new Array(prices.length).fill(''),
|
||||
datasets: [{
|
||||
data: prices,
|
||||
borderColor: isUp ? '#0ecb81' : '#f6465d',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0,
|
||||
fill: true,
|
||||
backgroundColor: isUp ? 'rgba(14, 203, 129, 0.1)' : 'rgba(246, 70, 93, 0.1)',
|
||||
tension: 0.4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
plugins: { legend: { display: false }, tooltip: { enabled: false } },
|
||||
scales: { x: { display: false }, y: { display: false } },
|
||||
maintainAspectRatio: false,
|
||||
responsive: true
|
||||
}
|
||||
});
|
||||
} catch (err) {}
|
||||
}
|
||||
}
|
||||
initSparklines();
|
||||
</script>
|
||||
<style>
|
||||
.x-small { font-size: 11px; }
|
||||
</style>
|
||||
|
||||
297
mining.php
297
mining.php
@ -5,7 +5,7 @@ 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-muted mx-auto" style="max-width: 700px;">
|
||||
<p class="lead text-white-50 mx-auto" style="max-width: 700px;">
|
||||
<?= __('mining_desc') ?>
|
||||
</p>
|
||||
</div>
|
||||
@ -30,38 +30,224 @@ require_once __DIR__ . '/includes/header.php';
|
||||
<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">
|
||||
<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-muted" style="font-size: 10px;"><?= __('est_apy') ?></span>
|
||||
<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-muted" style="font-size: 10px;"><?= __('min_deposit') ?></span>
|
||||
<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-muted" style="font-size: 10px;"><?= __('lock_period') ?></span>
|
||||
<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-muted">
|
||||
<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;"><?= __('start_mining') ?></button>
|
||||
<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; }
|
||||
@ -82,7 +268,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="fw-bold"><?= __('adv_hardware') ?></h5>
|
||||
<p class="text-muted"><?= __('adv_hardware_desc') ?></p>
|
||||
<p class="text-white-50"><?= __('adv_hardware_desc') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-4 mb-4">
|
||||
@ -91,7 +277,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="fw-bold"><?= __('auto_compound') ?></h5>
|
||||
<p class="text-muted"><?= __('auto_compound_desc') ?></p>
|
||||
<p class="text-white-50"><?= __('auto_compound_desc') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-4">
|
||||
@ -100,34 +286,103 @@ require_once __DIR__ . '/includes/header.php';
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="fw-bold"><?= __('real_time_monitor') ?></h5>
|
||||
<p class="text-muted"><?= __('real_time_monitor_desc') ?></p>
|
||||
<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-muted mb-4"><?= __('calc_desc') ?></p>
|
||||
<div class="input-group mb-4">
|
||||
<span class="input-group-text bg-black border-secondary text-white"><?= __('USDT') ?></span>
|
||||
<input type="number" id="mining-calc-amount" class="form-control bg-black border-secondary text-white p-3" placeholder="<?= __('amount_to_invest') ?>">
|
||||
<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">
|
||||
<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">
|
||||
<div class="text-muted small mb-1"><?= __('daily_profit') ?></div>
|
||||
<div class="text-success fw-bold fs-4">--</div>
|
||||
<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-muted small mb-1"><?= __('monthly_profit') ?></div>
|
||||
<div class="text-success fw-bold fs-4">--</div>
|
||||
<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-outline-primary w-100 py-3 rounded-pill fw-bold"><?= __('try_calc') ?></button>
|
||||
<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>
|
||||
|
||||
@ -212,7 +212,7 @@ $kycStatusColor = [
|
||||
<tr class="border-secondary">
|
||||
<td class="ps-4 py-3" style="width: 25%;">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<img src="<?= getCoinIcon($b['symbol']) ?>" width="24" height="24" class="rounded-circle">
|
||||
<img src="<?= getCoinIcon($b['symbol']) ?>" width="24" height="24" class="rounded-circle" alt="<?= $b['symbol'] ?>" onerror="handleIconError(this, '<?= $b['symbol'] ?>')">
|
||||
<span class="fw-bold text-white small"><?= $lang === 'zh' ? __($b['symbol']) : $b['symbol'] ?></span>
|
||||
</div>
|
||||
</td>
|
||||
@ -239,7 +239,7 @@ $kycStatusColor = [
|
||||
<?php foreach ($balances as $b): if($b['available'] == 0 && $b['frozen'] == 0 && !in_array($b['symbol'], ['BTC', 'ETH', 'USDT'])) continue; ?>
|
||||
<div class="d-flex align-items-center justify-content-between p-3 mb-2 rounded-4 bg-black bg-opacity-20 border border-secondary border-opacity-50">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<img src="<?= getCoinIcon($b['symbol']) ?>" width="32" height="32" class="rounded-circle">
|
||||
<img src="<?= getCoinIcon($b['symbol']) ?>" width="32" height="32" class="rounded-circle" alt="<?= $b['symbol'] ?>" onerror="handleIconError(this, '<?= $b['symbol'] ?>')">
|
||||
<div>
|
||||
<div class="fw-bold text-white"><?= $lang === 'zh' ? __($b['symbol']) : $b['symbol'] ?></div>
|
||||
<div class="text-white-50 x-small"><?= __('available_balance') ?>: <?= number_format($b['available'], 4) ?></div>
|
||||
|
||||
@ -119,7 +119,7 @@ $bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('coin') ?></label>
|
||||
<div class="d-flex align-items-center gap-3 p-3 bg-dark border border-secondary rounded-4">
|
||||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT">
|
||||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT" onerror="handleIconError(this, 'USDT')">
|
||||
<div>
|
||||
<div class="fw-bold text-white"><?= $lang === 'zh' ? __('USDT') : 'USDT' ?></div>
|
||||
<div class="text-white-50 small"><?= __('tether') ?></div>
|
||||
|
||||
8
swap.php
8
swap.php
@ -28,7 +28,7 @@ if ($user) {
|
||||
<input type="number" id="from-amount" class="form-control bg-transparent border-0 text-white p-0 shadow-none w-50 fw-bold" placeholder="0.00" style="color: #fff !important; font-size: clamp(24px, 5vw, 32px) !important;">
|
||||
<div class="ms-auto dropdown">
|
||||
<div class="d-flex align-items-center bg-dark p-2 rounded-pill px-2 px-md-3 border border-secondary cursor-pointer shadow-sm dropdown-toggle" data-bs-toggle="dropdown">
|
||||
<img src="<?php echo getCoinIcon('USDT'); ?>" width="24" height="24" class="me-2 rounded-circle" id="from-coin-img">
|
||||
<img src="<?php echo getCoinIcon('USDT'); ?>" width="24" height="24" class="me-2 rounded-circle" id="from-coin-img" alt="USDT" onerror="handleIconError(this, 'USDT')">
|
||||
<span class="fw-bold text-white small" id="from-coin-symbol" data-symbol="USDT"><?= __('USDT') ?></span>
|
||||
</div>
|
||||
<ul class="dropdown-menu dropdown-menu-dark bg-dark border-secondary rounded-4 shadow-lg p-2" style="max-height: 300px; overflow-y: auto;">
|
||||
@ -36,7 +36,7 @@ if ($user) {
|
||||
$swap_coins = ['BTC', 'ETH', 'USDT', 'BNB', 'SOL', 'XRP', 'ADA', 'DOGE', 'DOT', 'MATIC', 'LINK', 'SHIB'];
|
||||
foreach($swap_coins as $sc): ?>
|
||||
<li><a class="dropdown-item rounded-3 py-2 d-flex align-items-center gap-2" href="#" onclick="selectCoin('from', '<?= $sc ?>', '<?= __($sc) ?>', '<?= getCoinIcon($sc) ?>')">
|
||||
<img src="<?= getCoinIcon($sc) ?>" width="20" height="20"> <?= __($sc) ?>
|
||||
<img src="<?= getCoinIcon($sc) ?>" width="20" height="20" alt="<?= $sc ?>" onerror="handleIconError(this, '<?= $sc ?>')"> <?= __($sc) ?>
|
||||
</a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@ -61,13 +61,13 @@ if ($user) {
|
||||
<input type="number" id="to-amount" class="form-control bg-transparent border-0 text-white p-0 shadow-none w-50 fw-bold" placeholder="0.00" readonly style="color: #fff !important; opacity: 1; font-size: clamp(24px, 5vw, 32px) !important;">
|
||||
<div class="ms-auto dropdown">
|
||||
<div class="d-flex align-items-center bg-dark p-2 rounded-pill px-2 px-md-3 border border-secondary cursor-pointer shadow-sm dropdown-toggle" data-bs-toggle="dropdown">
|
||||
<img src="<?php echo getCoinIcon('BTC'); ?>" width="24" height="24" class="me-2 rounded-circle" id="to-coin-img">
|
||||
<img src="<?php echo getCoinIcon('BTC'); ?>" width="24" height="24" class="me-2 rounded-circle" id="to-coin-img" alt="BTC" onerror="handleIconError(this, 'BTC')">
|
||||
<span class="fw-bold text-white small" id="to-coin-symbol" data-symbol="BTC"><?= __('BTC') ?></span>
|
||||
</div>
|
||||
<ul class="dropdown-menu dropdown-menu-dark bg-dark border-secondary rounded-4 shadow-lg p-2" style="max-height: 300px; overflow-y: auto;">
|
||||
<?php foreach($swap_coins as $sc): ?>
|
||||
<li><a class="dropdown-item rounded-3 py-2 d-flex align-items-center gap-2" href="#" onclick="selectCoin('to', '<?= $sc ?>', '<?= __($sc) ?>', '<?= getCoinIcon($sc) ?>')">
|
||||
<img src="<?= getCoinIcon($sc) ?>" width="20" height="20"> <?= __($sc) ?>
|
||||
<img src="<?= getCoinIcon($sc) ?>" width="20" height="20" alt="<?= $sc ?>" onerror="handleIconError(this, '<?= $sc ?>')"> <?= __($sc) ?>
|
||||
</a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
@ -52,7 +52,7 @@ $available = $bal['available'] ?? 0;
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('coin') ?></label>
|
||||
<div class="d-flex align-items-center gap-3 p-3 bg-dark border border-secondary rounded-4">
|
||||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT">
|
||||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT" onerror="handleIconError(this, 'USDT')">
|
||||
<div>
|
||||
<div class="fw-bold text-white"><?= $lang === 'zh' ? __('USDT') : 'USDT' ?></div>
|
||||
<div class="text-white-50 small"><?= __('tether') ?></div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user