<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quy Trình Admin Nạp Tiền Full</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
:root {
--primary: #5c67f2;
--primary-hover: #4851c2;
--success: #10b981;
--error: #ef4444;
--warning: #f59e0b;
--text-main: #1f2937;
--text-sub: #6b7280;
--border: #e5e7eb;
--bg-modal: #ffffff;
}
body {
font-family: 'Segoe UI', sans-serif;
background-color: #aaadc4;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
/* MODAL CHÍNH */
.modal {
background: var(--bg-modal);
width: 700px;
max-width: 95%;
border-radius: 16px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
display: flex;
flex-direction: column;
overflow: hidden;
transition: height 0.3s ease;
}
/* HEADER */
.modal-header {
padding: 20px 30px;
border-bottom: 1px solid var(--border);
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
}
.step-info { display: flex; align-items: center; gap: 12px; }
.step-badge {
background: #e0e7ff; color: var(--primary);
padding: 4px 12px; border-radius: 99px; font-size: 12px; font-weight: 700;
}
.modal-title { font-size: 18px; font-weight: 600; color: var(--text-main); }
/* BODY CONTENT */
.modal-body {
padding: 30px;
min-height: 350px; /* Giữ chiều cao ổn định */
position: relative;
}
.step-content { display: none; animation: fadeIn 0.4s ease; }
.step-content.active { display: block; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
/* FORM ELEMENTS */
label { display: block; margin-bottom: 8px; font-weight: 500; font-size: 14px; color: var(--text-main); }
select, input {
width: 100%; padding: 12px; border: 1px solid var(--border);
border-radius: 8px; font-size: 14px; box-sizing: border-box; outline: none;
transition: border-color 0.2s;
}
select:focus, input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(92, 103, 242, 0.15); }
/* STEP 1: WALLET CARDS */
.wallet-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 20px; }
.card-select {
border: 1px solid var(--border); padding: 15px; border-radius: 10px;
cursor: pointer; display: flex; align-items: center; gap: 12px;
transition: all 0.2s;
}
.card-select:hover { border-color: var(--primary); background: #f9fafb; }
.card-select.selected { border-color: var(--primary); background: #eff6ff; box-shadow: 0 4px 6px -1px rgba(92, 103, 242, 0.1); }
.icon-box {
width: 40px; height: 40px; border-radius: 50%; display: flex;
align-items: center; justify-content: center; color: white; font-size: 18px;
}
/* STEP 3: RESULT BOXES */
.result-box {
margin-top: 20px; padding: 15px; border-radius: 8px;
display: none; border-left: 4px solid transparent;
}
.res-success { background: #ecfdf5; border-color: var(--success); }
.res-fail { background: #fef2f2; border-color: var(--error); }
.res-used { background: #fffbeb; border-color: var(--warning); }
.res-title { font-weight: bold; font-size: 14px; margin-bottom: 5px; display: flex; align-items: center; gap: 8px; }
.res-desc { font-size: 13px; color: var(--text-sub); margin: 0; line-height: 1.5; }
/* FOOTER */
.modal-footer {
padding: 20px 30px; border-top: 1px solid var(--border);
display: flex; justify-content: flex-end; gap: 12px;
background: #fff;
}
.btn { padding: 10px 24px; border-radius: 8px; border: none; font-weight: 600; cursor: pointer; transition: 0.2s; font-size: 14px; }
.btn-back { background: white; border: 1px solid var(--border); color: var(--text-sub); }
.btn-back:hover { background: #f3f4f6; }
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover { background: var(--primary-hover); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* LOADING */
.loading-overlay {
display: none; text-align: center; padding: 20px;
}
/* DEV TOOLS (Test Button) */
.dev-tools {
margin-top: 25px; padding: 10px; background: #111827; border-radius: 8px;
}
.dev-header { font-size: 11px; text-transform: uppercase; color: #9ca3af; margin-bottom: 8px; letter-spacing: 1px; }
.btn-test { font-size: 11px; padding: 5px 10px; border-radius: 4px; border: none; cursor: pointer; color: white; margin-right: 5px; font-weight: bold;}
</style>
</head>
<body>
<div class="modal">
<div class="modal-header">
<div class="step-info">
<span class="step-badge" id="step-badge">Bước 1/3</span>
<span class="modal-title" id="step-title">Thông tin nạp</span>
</div>
<i class="fas fa-times" style="color: #9ca3af; cursor: pointer;"></i>
</div>
<div class="modal-body">
<div id="step-1" class="step-content active">
<div style="margin-bottom: 20px;">
<label>Doanh nghiệp</label>
<select id="enterprise" onchange="validateStep1()">
<option value="">-- Chọn doanh nghiệp --</option>
<option value="1">Công ty Công Nghệ ABC</option>
<option value="2">Global Dropshipping LLC</option>
</select>
</div>
<label>Chọn Ví nhận tiền</label>
<div class="wallet-grid">
<div class="card-select selected" onclick="selectWallet(this, 'USD')" id="wallet-usd">
<div class="icon-box" style="background: #10b981;"><i class="fas fa-dollar-sign"></i></div>
<div>
<div style="font-weight: 600;">Ví USD</div>
<div style="font-size: 12px; color: var(--text-sub);">Balance: $1,200</div>
</div>
</div>
<div class="card-select" onclick="selectWallet(this, 'VND')" id="wallet-vnd">
<div class="icon-box" style="background: #3b82f6;"><i class="fas fa-university"></i></div>
<div>
<div style="font-weight: 600;">Ví VND</div>
<div style="font-size: 12px; color: var(--text-sub);">Balance: 0 đ</div>
</div>
</div>
</div>
<label>Số tiền muốn nạp</label>
<input type="number" id="amount" placeholder="Nhập số tiền..." oninput="validateStep1()">
</div>
<div id="step-2" class="step-content">
<p style="color: var(--text-sub); margin-bottom: 15px;">Bạn đang nạp <b id="display-amount">...</b> vào ví <b id="display-wallet">...</b></p>
<div class="wallet-grid">
<div class="card-select" onclick="selectMethod(this, 'usdt')">
<div class="icon-box" style="background: #2563eb;"><i class="fab fa-bitcoin"></i></div>
<div>
<div style="font-weight: 600;">USDT (Tron)</div>
<div style="font-size: 12px; color: var(--text-sub);">Tự động check Blockchain</div>
</div>
</div>
<div class="card-select" onclick="selectMethod(this, 'pingpong')">
<div class="icon-box" style="background: #db2777;"><i class="fas fa-envelope-open-text"></i></div>
<div>
<div style="font-weight: 600;">PingPong</div>
<div style="font-size: 12px; color: var(--text-sub);">Tự động quét Email</div>
</div>
</div>
</div>
</div>
<div id="step-3" class="step-content">
<div style="background: #f8fafc; padding: 15px; border-radius: 8px; border: 1px dashed var(--border); margin-bottom: 20px;">
<label id="lbl-input-code">Mã giao dịch (TxID/Hash)</label>
<div style="display: flex; gap: 8px;">
<input type="text" id="tx-input" placeholder="Nhập mã..." oninput="resetCheckState()">
<button class="btn-primary" style="padding: 0 20px; border-radius: 8px; border:none; cursor: pointer;" onclick="checkTransaction()">
<i class="fas fa-search"></i> Check
</button>
</div>
</div>
<div id="loading" class="loading-overlay">
<i class="fas fa-circle-notch fa-spin fa-2x" style="color: var(--primary);"></i>
<div style="margin-top: 10px; font-size: 13px; color: var(--text-sub);">Đang kết nối API để kiểm tra...</div>
</div>
<div id="res-success" class="result-box res-success">
<div class="res-title" style="color: #047857;"><i class="fas fa-check-circle"></i> Hợp lệ: Sẵn sàng nạp</div>
<div class="res-desc">
Mã giao dịch chính xác. Số tiền <b>$1,000</b>. Chưa từng sử dụng.<br>
Bạn có thể xác nhận nạp ngay bây giờ.
</div>
</div>
<div id="res-fail" class="result-box res-fail">
<div class="res-title" style="color: #b91c1c;"><i class="fas fa-times-circle"></i> Không tìm thấy giao dịch</div>
<div class="res-desc">
Hệ thống không tìm thấy mã này trên Blockchain/Email. Vui lòng kiểm tra lại ký tự hoặc thử lại sau vài phút.
</div>
</div>
<div id="res-used" class="result-box res-used">
<div class="res-title" style="color: #b45309;"><i class="fas fa-exclamation-triangle"></i> Cảnh báo: Mã đã sử dụng</div>
<div class="res-desc">
Mã này đã được nạp thành công vào lúc <b>14:30 12/10/2025</b> bởi <b>Admin_Huy</b>. Không thể nạp lại.
</div>
</div>
<div class="dev-tools">
<div class="dev-header">Test Nhanh (Click để điền code mẫu)</div>
<button class="btn-test" style="background: var(--success);" onclick="autoFill('VALID_CODE_123')">1. Case OK</button>
<button class="btn-test" style="background: var(--error);" onclick="autoFill('FAIL_CODE_XYZ')">2. Case Lỗi</button>
<button class="btn-test" style="background: var(--warning);" onclick="autoFill('USED_CODE_999')">3. Case Trùng</button>
</div>
</div>
<div id="step-4" class="step-content" style="text-align: center; padding-top: 40px;">
<div style="width: 80px; height: 80px; background: #d1fae5; color: #10b981; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 40px; margin: 0 auto 20px auto;">
<i class="fas fa-check"></i>
</div>
<h2 style="color: var(--text-main); margin: 0;">Nạp tiền thành công!</h2>
<p style="color: var(--text-sub);">Số dư ví đã được cập nhật.</p>
</div>
</div>
<div class="modal-footer" id="modal-footer">
<button class="btn btn-back" id="btn-back" onclick="prevStep()" disabled>Quay lại</button>
<button class="btn btn-primary" id="btn-next" onclick="nextStep()" disabled>Tiếp theo</button>
</div>
</div>
<script>
// STATE
let currentStep = 1;
let formData = {
enterprise: '',
wallet: 'USD',
amount: '',
method: '',
txCode: ''
};
// MOCK DATA (Giả lập Database)
const MOCK_DB = {
'USED_CODE_999': { status: 'USED' },
'VALID_CODE_123': { status: 'NEW', amount: 1000 },
'FAIL_CODE_XYZ': { status: 'NOT_FOUND' }
};
// --- LOGIC BƯỚC 1 ---
function selectWallet(el, type) {
document.querySelectorAll('#step-1 .card-select').forEach(c => c.classList.remove('selected'));
el.classList.add('selected');
formData.wallet = type;
// Cập nhật hiển thị ngay lập tức
validateStep1();
}
function validateStep1() {
formData.enterprise = document.getElementById('enterprise').value;
formData.amount = document.getElementById('amount').value;
// CẬP NHẬT MỚI: Không disable nút nữa, chỉ kiểm tra ngầm
// Logic cũ gây lỗi đã được loại bỏ ở đây
}
// --- LOGIC BƯỚC 2 ---
function selectMethod(el, method) {
document.querySelectorAll('#step-2 .card-select').forEach(c => c.classList.remove('selected'));
el.classList.add('selected');
formData.method = method;
}
// --- LOGIC BƯỚC 3 (CHECK CORE) ---
function resetCheckState() {
document.querySelectorAll('.result-box').forEach(b => b.style.display = 'none');
document.getElementById('btn-next').disabled = true;
document.getElementById('btn-next').innerText = "Tiếp theo";
}
function autoFill(code) {
document.getElementById('tx-input').value = code;
resetCheckState();
checkTransaction();
}
async function checkTransaction() {
const code = document.getElementById('tx-input').value.trim();
if(!code) return;
resetCheckState();
document.getElementById('loading').style.display = 'block';
await new Promise(r => setTimeout(r, 800)); // Giảm thời gian chờ xuống 0.8s cho nhanh
document.getElementById('loading').style.display = 'none';
if (code.includes('FAIL') || (!MOCK_DB[code] && !code.includes('VALID') && !code.includes('USED'))) {
document.getElementById('res-fail').style.display = 'block';
return;
}
if (code.includes('USED')) {
document.getElementById('res-used').style.display = 'block';
return;
}
document.getElementById('res-success').style.display = 'block';
const btnNext = document.getElementById('btn-next');
btnNext.disabled = false;
btnNext.innerHTML = '<i class="fas fa-check"></i> Xác nhận & Nạp';
btnNext.setAttribute('onclick', 'finishProcess()');
}
// --- NAVIGATION (SỬA LỖI CHÍNH Ở ĐÂY) ---
function nextStep() {
// KIỂM TRA DỮ LIỆU TRƯỚC KHI NEXT
if (currentStep === 1) {
const ent = document.getElementById('enterprise').value;
const amt = document.getElementById('amount').value;
// Nếu thiếu dữ liệu -> Báo lỗi ngay lập tức thay vì im lặng
if (ent === "" || amt <= 0 || amt === "") {
alert("Vui lòng chọn Doanh nghiệp và nhập Số tiền hợp lệ!");
return; // Dừng lại, không cho qua
}
// Gán dữ liệu hiển thị
document.getElementById('display-amount').innerText = formData.wallet === 'USD' ? `$${amt}` : `${amt} VND`;
document.getElementById('display-wallet').innerText = formData.wallet;
}
if (currentStep === 2) {
if (!formData.method) {
alert("Vui lòng chọn Phương thức thanh toán (USDT hoặc PingPong)!");
return;
}
}
// CHUYỂN BƯỚC
document.getElementById(`step-${currentStep}`).classList.remove('active');
currentStep++;
document.getElementById(`step-${currentStep}`).classList.add('active');
// Update UI Header/Footer
document.getElementById('step-badge').innerText = `Bước ${currentStep}/3`;
document.getElementById('btn-back').disabled = false;
// Xử lý nút Next ở các bước
const btnNext = document.getElementById('btn-next');
if(currentStep === 2) {
document.getElementById('step-title').innerText = "Phương thức";
// Ở bước 2, ta vẫn cho bấm next để nó check xem đã chọn chưa (như logic if ở trên)
}
if(currentStep === 3) {
document.getElementById('step-title').innerText = "Xác thực Giao dịch";
const methodLabel = formData.method === 'usdt' ? 'Mạng Tron (Hash)' : 'Mã PingPong (TxID)';
document.getElementById('lbl-input-code').innerText = `Nhập ${methodLabel}`;
// Riêng bước 3 thì PHẢI disable nút Next chờ check xong
btnNext.disabled = true;
}
}
function prevStep() {
if(currentStep === 1) return;
document.getElementById(`step-${currentStep}`).classList.remove('active');
currentStep--;
document.getElementById(`step-${currentStep}`).classList.add('active');
document.getElementById('step-badge').innerText = `Bước ${currentStep}/3`;
const btnNext = document.getElementById('btn-next');
btnNext.disabled = false; // Luôn mở khóa khi quay lại
btnNext.innerText = "Tiếp theo";
btnNext.setAttribute('onclick', 'nextStep()');
if(currentStep === 1) {
document.getElementById('step-title').innerText = "Thông tin nạp";
document.getElementById('btn-back').disabled = true;
}
if(currentStep === 2) {
document.getElementById('step-title').innerText = "Phương thức";
resetCheckState();
}
}
function finishProcess() {
document.getElementById('step-3').classList.remove('active');
document.getElementById('step-4').classList.add('active');
document.getElementById('modal-footer').style.display = 'none';
document.getElementById('step-badge').innerText = "Hoàn tất";
document.getElementById('step-title').innerText = "Kết quả";
}
// Kích hoạt ngay khi load trang để nút bấm được luôn (Bỏ trạng thái disabled mặc định của HTML cũ)
window.onload = function() {
document.getElementById('btn-next').disabled = false;
}
</script>
</body>
</html>
Số dòng: 434