| <!DOCTYPE html> |
| <html lang="my"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Payment ααΎααΊαααΊαΈ β 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:600px;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} |
| |
| .card{background:#16162a;border:1px solid #2a2a4a;border-radius:12px;padding:16px;margin-bottom:12px} |
| .card-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px} |
| .card-coins{font-size:1.3rem;font-weight:700;color:#a78bfa} |
| .badge{font-size:.75rem;padding:3px 10px;border-radius:20px;font-weight:600} |
| .badge.pending{background:#3a2a00;color:#fbbf24;border:1px solid #854d0e} |
| .badge.approved{background:#052e16;color:#22c55e;border:1px solid #166534} |
| .badge.rejected{background:#2a0a0a;color:#ef4444;border:1px solid #7f1d1d} |
| .card-price{font-size:.9rem;color:#fbbf24;margin-bottom:4px} |
| .card-meta{font-size:.78rem;color:#666;display:flex;gap:12px;flex-wrap:wrap} |
| .card-note{margin-top:8px;font-size:.8rem;color:#888;font-style:italic} |
| .empty{text-align:center;padding:60px 0;color:#555;font-size:.9rem} |
| .buy-btn{display:block;margin:20px auto 0;padding:12px 32px;background:linear-gradient(135deg,#7c3aed,#a855f7);border:none;border-radius:12px;color:#fff;font-size:.95rem;font-weight:700;cursor:pointer;text-decoration:none;text-align:center} |
| .refresh-btn{display:block;text-align:center;color:#a78bfa;font-size:.8rem;margin-bottom:16px;cursor:pointer;background:none;border:none} |
| .refresh-btn:hover{text-decoration:underline} |
| .loading{text-align:center;padding:40px;color:#666} |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <a href="/app" class="back-btn">β App ααα―α·ααΌααΊαα½α¬αΈαααΊ</a> |
| <h1>π Payment ααΎααΊαααΊαΈ</h1> |
| <p class="subtitle">ααα―ααΊααα―ααΊ αα½α±αα±αΈαα»α±ααΎα― ααΎααΊαααΊαΈαα»α¬αΈ</p> |
|
|
| <button class="refresh-btn" onclick="loadHistory()">π Refresh</button> |
| <div id="list"><div class="loading">β³ Loadingβ¦</div></div> |
| <a href="/payment" class="buy-btn">πͺ Coins αααΊαααΊαααΊ</a> |
| </div> |
|
|
| <script> |
| let username = ''; |
| try { |
| const saved = sessionStorage.getItem('recap_user'); |
| if (saved) username = JSON.parse(saved).u || ''; |
| } catch(e) {} |
| const STATUS_LABEL = { pending: 'β³ Pending', approved: 'β
Approved', rejected: 'β Rejected' }; |
| |
| async function loadHistory() { |
| if (!username) { window.location.href = '/login'; return; } |
| const el = document.getElementById('list'); |
| el.innerHTML = '<div class="loading">β³ Loadingβ¦</div>'; |
| try { |
| const r = await fetch(`/api/payment/history?username=${encodeURIComponent(username)}`).then(r => r.json()); |
| if (!r.ok) { el.innerHTML = `<div class="empty">β ${r.msg}</div>`; return; } |
| if (!r.payments.length) { |
| el.innerHTML = '<div class="empty">π Payment ααΎααΊαααΊαΈ αααΎααα±αΈαα«</div>'; |
| return; |
| } |
| el.innerHTML = r.payments.map(p => ` |
| <div class="card"> |
| <div class="card-top"> |
| <div> |
| <div class="card-coins">πͺ ${p.coins} Coins</div> |
| <div class="card-price">${p.price}</div> |
| </div> |
| <span class="badge ${p.status}">${STATUS_LABEL[p.status] || p.status}</span> |
| </div> |
| <div class="card-meta"> |
| <span>π ${p.id}</span> |
| <span>π
${p.created_at.slice(0,16).replace('T',' ')}</span> |
| ${p.updated_at !== p.created_at ? `<span>π ${p.updated_at.slice(0,16).replace('T',' ')}</span>` : ''} |
| </div> |
| ${p.admin_note ? `<div class="card-note">π ${p.admin_note}</div>` : ''} |
| </div> |
| `).join(''); |
| } catch(e) { |
| el.innerHTML = `<div class="empty">β Error: ${e.message}</div>`; |
| } |
| } |
| |
| loadHistory(); |
| </script> |
| </body> |
| </html> |
|
|