Spaces:
Running
Running
| <html lang="my"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Coins ဝယ်ယူပါ — Recap Studio</title> | |
| <style> | |
| *{box-sizing:border-box;margin:0;padding:0} | |
| body{font-family:'Segoe UI',sans-serif;background:#0f0f1a;color:#e0e0ff;min-height:100vh;padding:20px} | |
| .container{max-width:520px;margin:0 auto} | |
| h1{text-align:center;font-size:1.5rem;margin-bottom:6px;color:#a78bfa} | |
| .subtitle{text-align:center;color:#888;font-size:.85rem;margin-bottom:24px} | |
| .back-btn{display:inline-flex;align-items:center;gap:6px;color:#a78bfa;text-decoration:none;font-size:.85rem;margin-bottom:18px} | |
| .back-btn:hover{color:#c4b5fd} | |
| /* Packages */ | |
| .packages{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:24px} | |
| .pkg{border:2px solid #2a2a4a;border-radius:12px;padding:16px;cursor:pointer;transition:.2s;background:#16162a;text-align:center;position:relative} | |
| .pkg:hover{border-color:#7c3aed;transform:translateY(-2px)} | |
| .pkg.selected{border-color:#a78bfa;background:#1e1440} | |
| .pkg.popular::before{content:'🔥 Popular';position:absolute;top:-10px;left:50%;transform:translateX(-50%);background:#7c3aed;color:#fff;font-size:.7rem;padding:2px 10px;border-radius:20px;white-space:nowrap} | |
| .pkg-coins{font-size:1.6rem;font-weight:700;color:#a78bfa} | |
| .pkg-unit{font-size:.8rem;color:#888;margin-bottom:4px} | |
| .pkg-price{font-size:.95rem;color:#fbbf24;font-weight:600} | |
| /* KBZ Pay info */ | |
| .kbz-card{background:#1a1a2e;border:1px solid #2a2a4a;border-radius:12px;padding:18px;margin-bottom:20px} | |
| .kbz-title{font-size:.85rem;color:#888;margin-bottom:10px} | |
| .kbz-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px} | |
| .kbz-label{font-size:.8rem;color:#888} | |
| .kbz-val{font-size:1rem;font-weight:700;color:#e0e0ff;letter-spacing:.5px} | |
| .copy-btn{background:#2a2a4a;border:none;color:#a78bfa;font-size:.75rem;padding:4px 10px;border-radius:6px;cursor:pointer;transition:.2s} | |
| .copy-btn:hover{background:#3a3a6a} | |
| .selected-pkg-info{text-align:center;font-size:.9rem;color:#fbbf24;margin-bottom:12px;min-height:22px} | |
| /* Slip upload */ | |
| .slip-section{margin-bottom:20px} | |
| .slip-label{font-size:.85rem;color:#888;margin-bottom:8px;display:block} | |
| .slip-drop{border:2px dashed #3a3a6a;border-radius:12px;padding:30px;text-align:center;cursor:pointer;transition:.2s;position:relative;overflow:hidden} | |
| .slip-drop:hover,.slip-drop.drag{border-color:#a78bfa;background:#1a1440} | |
| .slip-drop input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;height:100%} | |
| .slip-preview{width:100%;max-height:200px;object-fit:contain;border-radius:8px;display:none;margin-top:10px} | |
| .slip-icon{font-size:2rem;margin-bottom:8px} | |
| .slip-text{font-size:.85rem;color:#888} | |
| /* Submit */ | |
| .submit-btn{width:100%;padding:14px;border:none;border-radius:12px;background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;font-size:1rem;font-weight:700;cursor:pointer;transition:.2s} | |
| .submit-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 20px rgba(124,58,237,.5)} | |
| .submit-btn:disabled{opacity:.5;cursor:not-allowed} | |
| /* Toast */ | |
| .toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:#1e1440;border:1px solid #7c3aed;color:#e0e0ff;padding:12px 24px;border-radius:12px;font-size:.9rem;opacity:0;transition:.3s;pointer-events:none;z-index:999;white-space:nowrap} | |
| .toast.show{opacity:1} | |
| .toast.error{border-color:#ef4444;background:#2a0a0a} | |
| .toast.success{border-color:#22c55e;background:#0a2a0a} | |
| .history-link{display:block;text-align:center;color:#a78bfa;font-size:.85rem;margin-top:16px;text-decoration:none} | |
| .history-link:hover{text-decoration:underline} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <a href="/app" class="back-btn">← App သို့ပြန်သွားရန်</a> | |
| <h1>🪙 Coins ဝယ်ယူပါ</h1> | |
| <p class="subtitle">KBZ Pay ဖြင့် ငွေပေးချေပြီး Slip တင်ပေးပါ</p> | |
| <!-- Packages --> | |
| <div class="packages" id="packages"></div> | |
| <div class="selected-pkg-info" id="selectedInfo">Package တစ်ခု ရွေးချယ်ပါ</div> | |
| <!-- KBZ Pay Info --> | |
| <div class="kbz-card"> | |
| <div class="kbz-title">💳 KBZ Pay ငွေလွှဲရမည့် အချက်အလက်</div> | |
| <div class="kbz-row"> | |
| <span class="kbz-label">Name</span> | |
| <div style="display:flex;align-items:center;gap:8px"> | |
| <span class="kbz-val" id="kbzName">—</span> | |
| <button class="copy-btn" onclick="copyText('kbzName')">Copy</button> | |
| </div> | |
| </div> | |
| <div class="kbz-row"> | |
| <span class="kbz-label">Phone</span> | |
| <div style="display:flex;align-items:center;gap:8px"> | |
| <span class="kbz-val" id="kbzNum">—</span> | |
| <button class="copy-btn" onclick="copyText('kbzNum')">Copy</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Slip Upload --> | |
| <div class="slip-section"> | |
| <span class="slip-label">📸 ငွေလွှဲ Slip ပုံ တင်ပေးပါ</span> | |
| <div class="slip-drop" id="slipDrop"> | |
| <input type="file" accept="image/*" id="slipInput" onchange="handleSlip(this)"> | |
| <div class="slip-icon">📎</div> | |
| <div class="slip-text">Slip ပုံကို ထိုနေရာတွင် ထည့်ပါ သို့မဟုတ် နှိပ်ပါ</div> | |
| <img id="slipPreview" class="slip-preview" alt="Slip Preview"> | |
| </div> | |
| </div> | |
| <button class="submit-btn" id="submitBtn" onclick="submitPayment()" disabled> | |
| 💰 Payment တင်ပေးပါ | |
| </button> | |
| <a href="/payment-history" class="history-link">📋 ငွေပေးချေမှု မှတ်တမ်း ကြည့်ရန်</a> | |
| </div> | |
| <div class="toast" id="toast"></div> | |
| <script> | |
| let username = ''; | |
| let selectedPkg = null; | |
| let slipBase64 = null; | |
| const packages = []; | |
| async function init() { | |
| // Read from same sessionStorage key used by index.html | |
| try { | |
| const saved = sessionStorage.getItem('recap_user'); | |
| if (!saved) { window.location.href = '/login'; return; } | |
| const sess = JSON.parse(saved); | |
| username = sess.u || ''; | |
| } catch(e) { window.location.href = '/login'; return; } | |
| if (!username) { window.location.href = '/login'; return; } | |
| const r = await fetch('/api/payment/packages').then(r => r.json()); | |
| r.packages.forEach((p, i) => packages.push(p)); | |
| document.getElementById('kbzName').textContent = r.kbz_name; | |
| document.getElementById('kbzNum').textContent = r.kbz_number; | |
| renderPackages(); | |
| } | |
| function renderPackages() { | |
| const el = document.getElementById('packages'); | |
| el.innerHTML = packages.map((p, i) => ` | |
| <div class="pkg ${i===1?'popular':''}" id="pkg${i}" onclick="selectPkg(${i})"> | |
| <div class="pkg-coins">${p.coins}</div> | |
| <div class="pkg-unit">Coins</div> | |
| <div class="pkg-price">${p.price}</div> | |
| </div> | |
| `).join(''); | |
| } | |
| function selectPkg(i) { | |
| document.querySelectorAll('.pkg').forEach(el => el.classList.remove('selected')); | |
| document.getElementById('pkg'+i).classList.add('selected'); | |
| selectedPkg = packages[i]; | |
| document.getElementById('selectedInfo').textContent = | |
| `✅ ${selectedPkg.coins} Coins — ${selectedPkg.price} ရွေးချယ်ထားသည်`; | |
| checkReady(); | |
| } | |
| function handleSlip(input) { | |
| const file = input.files[0]; | |
| if (!file) return; | |
| if (file.size > 5 * 1024 * 1024) { showToast('❌ ပုံဆိုဒ် 5MB ထက် မကြီးပါနှင့်', 'error'); return; } | |
| const reader = new FileReader(); | |
| reader.onload = e => { | |
| slipBase64 = e.target.result; | |
| const img = document.getElementById('slipPreview'); | |
| img.src = slipBase64; | |
| img.style.display = 'block'; | |
| document.querySelector('.slip-icon').style.display = 'none'; | |
| document.querySelector('.slip-text').style.display = 'none'; | |
| checkReady(); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| function checkReady() { | |
| document.getElementById('submitBtn').disabled = !(selectedPkg && slipBase64); | |
| } | |
| async function submitPayment() { | |
| if (!selectedPkg || !slipBase64) return; | |
| const btn = document.getElementById('submitBtn'); | |
| btn.disabled = true; | |
| btn.textContent = '⏳ တင်နေသည်…'; | |
| try { | |
| const r = await fetch('/api/payment/submit', { | |
| method: 'POST', | |
| headers: {'Content-Type':'application/json'}, | |
| body: JSON.stringify({ | |
| username, coins: selectedPkg.coins, | |
| price: selectedPkg.price, slip_image: slipBase64 | |
| }) | |
| }).then(r => r.json()); | |
| if (r.ok) { | |
| showToast(r.msg, 'success'); | |
| setTimeout(() => window.location.href = '/payment-history', 2000); | |
| } else { | |
| showToast(r.msg, 'error'); | |
| btn.disabled = false; | |
| btn.textContent = '💰 Payment တင်ပေးပါ'; | |
| } | |
| } catch(e) { | |
| showToast('❌ Error: ' + e.message, 'error'); | |
| btn.disabled = false; | |
| btn.textContent = '💰 Payment တင်ပေးပါ'; | |
| } | |
| } | |
| function copyText(id) { | |
| const t = document.getElementById(id).textContent; | |
| navigator.clipboard.writeText(t).then(() => showToast('✅ Copied!', 'success')); | |
| } | |
| function showToast(msg, type='') { | |
| const t = document.getElementById('toast'); | |
| t.textContent = msg; | |
| t.className = 'toast show ' + type; | |
| setTimeout(() => t.className = 'toast', 3000); | |
| } | |
| // Drag over | |
| const drop = document.getElementById('slipDrop'); | |
| drop.addEventListener('dragover', e => { e.preventDefault(); drop.classList.add('drag'); }); | |
| drop.addEventListener('dragleave', () => drop.classList.remove('drag')); | |
| drop.addEventListener('drop', e => { | |
| e.preventDefault(); drop.classList.remove('drag'); | |
| const f = e.dataTransfer.files[0]; | |
| if (f) { document.getElementById('slipInput').files = e.dataTransfer.files; handleSlip({files:[f]}); } | |
| }); | |
| init(); | |
| </script> | |
| </body> | |
| </html> | |