user-console.html 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <!DOCTYPE html>
  2. <html lang="vi">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Console — DoTouch.AI</title>
  7. <link rel="stylesheet" href="../web-v1.1.0/style.css">
  8. <style>
  9. /* ── 控制台布局 ── */
  10. .console { display:flex; min-height:100vh; }
  11. .sidebar { width:236px; flex-shrink:0; background:var(--card); border-right:1px solid var(--border); padding:20px 14px; position:sticky; top:84px; height:calc(100vh - 84px); display:flex; flex-direction:column; }
  12. .sidebar .logo { padding:0 10px 18px; border-bottom:1px solid var(--border); }
  13. .sidebar .logo svg { height:34px; }
  14. .side-nav { margin-top:14px; flex:1; }
  15. .side-nav a { display:flex; align-items:center; gap:10px; padding:11px 12px; border-radius:10px; color:var(--muted); font-size:14px; margin-bottom:4px; cursor:pointer; }
  16. .side-nav a:hover { color:var(--text); background:rgba(124,92,255,.08); }
  17. .side-nav a.active { color:var(--text); background:rgba(124,92,255,.15); font-weight:600; }
  18. .side-nav a .ico { width:20px; text-align:center; }
  19. .side-user { border-top:1px solid var(--border); padding:14px 12px 6px; }
  20. .side-user .email { font-size:12.5px; color:var(--muted); word-break:break-all; }
  21. .side-user .bal { font-size:16px; font-weight:800; margin-top:4px; }
  22. .main { flex:1; min-width:0; padding:26px 32px 60px; }
  23. .main-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:24px; flex-wrap:wrap; gap:12px; }
  24. .main-head h1 { font-size:22px; font-weight:800; }
  25. .main-head .sub { color:var(--muted); font-size:13px; margin-top:3px; }
  26. .tab-panel { display:none; }
  27. .tab-panel.active { display:block; }
  28. .stat-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:16px; }
  29. .stat-card { background:var(--card); border:1px solid var(--border); border-radius:14px; padding:20px; }
  30. .stat-card .lbl { font-size:12px; color:var(--muted); }
  31. .stat-card .val { font-size:26px; font-weight:800; margin-top:6px; }
  32. .stat-card .val.green { color:var(--green-l); }
  33. .stat-card .val.purple { color:var(--purple-l); }
  34. .stat-card .sub2 { font-size:11.5px; color:var(--muted); margin-top:4px; }
  35. .bar-chart { display:flex; align-items:flex-end; gap:10px; height:130px; padding:14px 6px 0; }
  36. .bar-col { flex:1; display:flex; flex-direction:column; align-items:center; gap:6px; }
  37. .bar { width:70%; max-width:34px; border-radius:6px 6px 2px 2px; background:linear-gradient(180deg,var(--purple),rgba(124,92,255,.25)); min-height:6px; }
  38. .bar.today { background:linear-gradient(180deg,var(--green),rgba(0,229,160,.3)); }
  39. .bar-lbl { font-size:10.5px; color:var(--muted); }
  40. .sec-title { font-size:15px; font-weight:700; margin:26px 0 12px; display:flex; justify-content:space-between; align-items:center; }
  41. .sec-title a { font-size:12.5px; color:var(--purple-l); }
  42. .topup-grid { display:flex; gap:10px; flex-wrap:wrap; }
  43. .topup-amt { border:1px solid var(--border); background:var(--card2); border-radius:12px; padding:14px 22px; cursor:pointer; text-align:center; min-width:110px; transition:border-color .15s; }
  44. .topup-amt:hover, .topup-amt.selected { border-color:var(--purple); background:rgba(124,92,255,.1); }
  45. .topup-amt b { display:block; font-size:17px; }
  46. .topup-amt span { font-size:11px; color:var(--muted); }
  47. .pay-btns { display:flex; gap:10px; flex-wrap:wrap; margin-top:16px; }
  48. .pay-btn { border:1px solid var(--border); background:var(--card); color:var(--text); padding:10px 18px; border-radius:10px; cursor:pointer; font-family:inherit; font-size:13.5px; font-weight:600; }
  49. .pay-btn:hover { border-color:var(--purple); }
  50. .key-form { background:var(--card); border:1px solid var(--border); border-radius:14px; padding:22px; margin-bottom:20px; }
  51. .key-form .row { display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end; }
  52. .key-form .field { flex:1; min-width:180px; }
  53. .status-badge { font-size:11px; padding:2px 10px; border-radius:999px; }
  54. .status-badge.active { color:var(--green-l); background:rgba(0,229,160,.1); border:1px solid rgba(0,229,160,.3); }
  55. .status-badge.revoked { color:var(--muted); background:rgba(154,163,192,.1); border:1px solid rgba(154,163,192,.3); }
  56. .status-badge.expired { color:var(--gold); background:rgba(255,194,77,.1); border:1px solid rgba(255,194,77,.3); }
  57. .op-btn { font-size:12px; padding:4px 10px; border-radius:7px; border:1px solid var(--border); background:var(--card2); color:var(--muted); cursor:pointer; margin-right:6px; }
  58. .op-btn:hover { color:var(--text); border-color:var(--purple); }
  59. .op-btn.danger:hover { border-color:#FF6B6B; color:#FF8A8A; }
  60. /* ── 限额 ── */
  61. .quota-bar { background:var(--card2); border-radius:999px; height:6px; width:100px; overflow:hidden; }
  62. .quota-fill { height:100%; border-radius:999px; background:var(--green); }
  63. .quota-fill.warn { background:var(--gold); }
  64. .quota-fill.over { background:#FF6B6B; }
  65. .quota-meta { font-size:10.5px; color:var(--muted); margin-top:3px; }
  66. .quota-banner { display:none; align-items:center; gap:10px; background:rgba(255,194,77,.1); border:1px solid rgba(255,194,77,.4); color:var(--gold); border-radius:12px; padding:12px 18px; font-size:13px; margin-bottom:18px; }
  67. .quota-banner.over { background:rgba(255,107,107,.1); border-color:rgba(255,107,107,.4); color:#FF8A8A; }
  68. .quota-banner.show { display:flex; }
  69. .q-form { display:grid; grid-template-columns:1fr 1fr; gap:10px 14px; }
  70. .q-form .field input { width:100%; }
  71. .q-form .full { grid-column:1/-1; }
  72. .q-sec { font-size:12px; color:var(--purple-l); font-weight:700; grid-column:1/-1; margin-top:6px; }
  73. @media (max-width:860px){ .console{flex-direction:column;} .sidebar{width:100%;height:auto;position:static;flex-direction:row;flex-wrap:wrap;align-items:center;} .side-nav{display:flex;flex-wrap:wrap;} .main{padding:20px;} }
  74. </style>
  75. </head>
  76. <body>
  77. <div class="dev-note" id="demoLoginBanner" style="bottom:56px;"></div>
  78. <div class="dev-note">v1.0.1 · 控制台(语言切换完整 · 官网头部导航:首页|模型|定价|操作文档|控制台 · 始终可见)</div>
  79. <!-- ══════════ 官网头部导航(始终可见) ══════════ -->
  80. <header>
  81. <div class="wrap nav">
  82. <a class="nav-logo" href="../web-v1.1.0/index.html">
  83. <svg viewBox="0 0 460 120" xmlns="http://www.w3.org/2000/svg">
  84. <defs><linearGradient id="hg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#9B7BFF"/><stop offset="1" stop-color="#5C3DF0"/></linearGradient></defs>
  85. <g transform="translate(0,6) scale(0.92)"><circle cx="50" cy="50" r="33" stroke="rgba(124,92,255,.3)" stroke-width="1.5" stroke-dasharray="2 7" fill="none"/><g stroke="#00E5A0" stroke-width="1.8" opacity=".55"><line x1="50" y1="50" x2="76" y2="26"/><line x1="50" y1="50" x2="26" y2="76"/><line x1="50" y1="50" x2="78" y2="75"/></g><circle cx="50" cy="50" r="12" stroke="rgba(124,92,255,.4)" fill="none"/><circle cx="50" cy="50" r="7.5" fill="url(#hg)"/><circle cx="76" cy="26" r="4" fill="#00E5A0"/><circle cx="26" cy="76" r="4" fill="#00E5A0"/><circle cx="78" cy="75" r="4" fill="#00E5A0"/></g>
  86. <text x="128" y="78" font-size="50" font-weight="700" fill="#E8ECF8" font-family="inherit">DoTouch</text><text x="348" y="78" font-size="50" font-weight="700" fill="url(#hg)" font-family="inherit">.AI</text>
  87. </svg>
  88. </a>
  89. <nav class="nav-links">
  90. <a href="../web-v1.1.0/index.html" data-i18n="nav_home">Trang chủ</a>
  91. <a href="../web-v1.1.0/models.html" data-i18n="nav_models">Models</a>
  92. <a href="../web-v1.1.0/pricing.html" data-i18n="nav_pricing">Pricing</a>
  93. <a href="../web-v1.1.0/docs.html" data-i18n="nav_docs_ops">Hướng dẫn</a>
  94. <a href="user-console.html" class="active" data-i18n="nav_console">Console</a>
  95. </nav>
  96. <div class="nav-right">
  97. <div class="lang-switch">
  98. <button class="lang-btn active" data-lang="vi">VI</button><button class="lang-btn" data-lang="en">EN</button><button class="lang-btn" data-lang="zh-CN">简</button><button class="lang-btn" data-lang="zh-TW">繁</button>
  99. </div>
  100. <a class="btn btn-sm" href="#" data-open-auth="login" data-i18n="nav_login">Đăng nhập</a>
  101. <a class="btn btn-primary btn-sm" href="#" data-open-auth="register" data-i18n="nav_signup">Bắt đầu</a>
  102. </div>
  103. </div>
  104. </header>
  105. <div class="console">
  106. <!-- ══ 侧边栏 ══ -->
  107. <aside class="sidebar">
  108. <div class="logo">
  109. <svg viewBox="0 0 460 120" xmlns="http://www.w3.org/2000/svg">
  110. <defs><linearGradient id="sg" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#9B7BFF"/><stop offset="1" stop-color="#5C3DF0"/></linearGradient></defs>
  111. <g transform="translate(0,6) scale(0.92)"><circle cx="50" cy="50" r="33" stroke="rgba(124,92,255,.3)" stroke-width="1.5" stroke-dasharray="2 7" fill="none"/><g stroke="#00E5A0" stroke-width="1.8" opacity=".55"><line x1="50" y1="50" x2="76" y2="26"/><line x1="50" y1="50" x2="26" y2="76"/><line x1="50" y1="50" x2="78" y2="75"/></g><circle cx="50" cy="50" r="7.5" fill="url(#sg)"/><circle cx="76" cy="26" r="4" fill="#00E5A0"/><circle cx="26" cy="76" r="4" fill="#00E5A0"/><circle cx="78" cy="75" r="4" fill="#00E5A0"/></g>
  112. <text x="128" y="78" font-size="50" font-weight="700" fill="#E8ECF8" font-family="inherit">DoTouch</text><text x="348" y="78" font-size="50" font-weight="700" fill="url(#sg)" font-family="inherit">.AI</text>
  113. </svg>
  114. </div>
  115. <nav class="side-nav">
  116. <a class="active" data-tab="overview"><span class="ico">📊</span><span data-i18n="c_overview">Tổng quan</span></a>
  117. <a data-tab="keys"><span class="ico">🔑</span><span data-i18n="c_keys">API Keys</span></a>
  118. <a data-tab="wallet"><span class="ico">💳</span><span data-i18n="c_wallet">Nạp tiền</span></a>
  119. <a data-tab="usage"><span class="ico">📈</span><span data-i18n="c_usage">Sử dụng</span></a>
  120. </nav>
  121. <div class="side-user">
  122. <div class="lang-switch" style="margin-bottom:10px;">
  123. <button class="lang-btn active" data-lang="vi">VI</button><button class="lang-btn" data-lang="en">EN</button><button class="lang-btn" data-lang="zh-CN">简</button><button class="lang-btn" data-lang="zh-TW">繁</button>
  124. </div>
  125. <div class="email">nguyen.anh@example.com</div>
  126. <div class="bal"><span class="price-usd" data-usd="23.50">$23.50</span></div>
  127. </div>
  128. </aside>
  129. <!-- ══ 主区 ══ -->
  130. <main class="main">
  131. <div class="quota-banner" id="quotaBanner"><span>⚠️</span><span data-i18n="q_banner_80">Đã đạt 80% giới hạn hằng ngày, vui lòng kiểm tra.</span></div>
  132. <div class="main-head">
  133. <div>
  134. <h1 data-i18n="c_total">Tổng quan</h1>
  135. <div class="sub" data-i18n="c_welcome">Chào mừng trở lại, Nguyen Anh 👋</div>
  136. </div>
  137. <a class="btn btn-primary btn-sm" href="#" data-i18n="c_create_key">+ Tạo API Key</a>
  138. </div>
  139. <!-- ══ Tab 1: Tổng quan ══ -->
  140. <div class="tab-panel active" id="tab-overview">
  141. <div class="stat-grid">
  142. <div class="stat-card"><div class="lbl" data-i18n="c_balance">Số dư</div><div class="val green"><span class="price-usd" data-usd="23.50">$23.50</span></div><div class="sub2">≈ <span class="price-usd" data-usd="23.50">$23.50</span></div></div>
  143. <div class="stat-card"><div class="lbl" data-i18n="c_today_req">Yêu cầu hôm nay</div><div class="val purple">1,284 <span data-i18n="c_req_unit">req</span></div><div class="sub2" data-i18n="c_sub_today">so với hôm qua</div></div>
  144. <div class="stat-card"><div class="lbl" data-i18n="c_today_tokens">Token hôm nay</div><div class="val">4.2M</div><div class="sub2" data-i18n="c_inout">in 3.1M · out 1.1M</div></div>
  145. <div class="stat-card"><div class="lbl" data-i18n="c_active_keys">API Key đang hoạt động</div><div class="val">3</div><div class="sub2" data-i18n="c_key_meta">1 đã thu hồi · 1 sắp hết hạn</div></div>
  146. </div>
  147. <div class="card" style="margin-top:18px;">
  148. <div class="sec-title" style="margin:0 0 12px;"><span data-i18n="q_limits">Giới hạn</span><span style="font-size:12px;color:var(--muted);" data-i18n="q_daily">Hằng ngày</span></div>
  149. <div style="display:flex;flex-direction:column;gap:12px;">
  150. <div><div style="display:flex;justify-content:space-between;font-size:12px;color:var(--muted);margin-bottom:4px;"><span data-i18n="q_req">Yêu cầu</span><span>6,420 / 10,000</span></div><div class="quota-bar" style="width:100%;"><div class="quota-fill warn" style="width:64%"></div></div></div>
  151. <div><div style="display:flex;justify-content:space-between;font-size:12px;color:var(--muted);margin-bottom:4px;"><span data-i18n="q_tokens">Token</span><span>82.4M / 100M</span></div><div class="quota-bar" style="width:100%;"><div class="quota-fill" style="width:82%"></div></div></div>
  152. <div><div style="display:flex;justify-content:space-between;font-size:12px;color:var(--muted);margin-bottom:4px;"><span data-i18n="q_cost">Chi phí</span><span><span class="price-usd" data-usd="3.85">$3.85</span> / <span class="price-usd" data-usd="5">$5.00</span></span></div><div class="quota-bar" style="width:100%;"><div class="quota-fill" style="width:77%"></div></div></div>
  153. </div>
  154. </div>
  155. <div class="sec-title"><span data-i18n="c_usage_7d">Sử dụng 7 ngày qua</span><a href="#" data-i18n="c_see_all">Xem chi tiết →</a></div>
  156. <div class="card">
  157. <div class="bar-chart">
  158. <div class="bar-col"><div class="bar" style="height:34%"></div><span class="bar-lbl">T2</span></div>
  159. <div class="bar-col"><div class="bar" style="height:52%"></div><span class="bar-lbl">T3</span></div>
  160. <div class="bar-col"><div class="bar" style="height:41%"></div><span class="bar-lbl">T4</span></div>
  161. <div class="bar-col"><div class="bar" style="height:65%"></div><span class="bar-lbl">T5</span></div>
  162. <div class="bar-col"><div class="bar" style="height:48%"></div><span class="bar-lbl">T6</span></div>
  163. <div class="bar-col"><div class="bar" style="height:78%"></div><span class="bar-lbl">T7</span></div>
  164. <div class="bar-col"><div class="bar today" style="height:58%"></div><span class="bar-lbl">CN</span></div>
  165. </div>
  166. </div>
  167. <div class="sec-title"><span data-i18n="c_recent_tx">Giao dịch gần đây</span><a href="#" data-i18n="c_see_all">Xem chi tiết →</a></div>
  168. <div class="table-wrap">
  169. <table class="data">
  170. <thead><tr><th data-i18n="c_t_time">Thời gian</th><th data-i18n="c_t_type">Loại</th><th data-i18n="c_t_amount">Số tiền</th><th data-i18n="c_t_ref">Tham chiếu</th></tr></thead>
  171. <tbody>
  172. <tr><td style="color:var(--muted);">2026-08-08 01:42</td><td><span class="tag tag-green" data-i18n="c_tx_usage">usage</span></td><td class="price">-<span class="price-usd" data-usd="0.0032">$0.0032</span></td><td class="price">glm-5.2</td></tr>
  173. <tr><td style="color:var(--muted);">2026-08-08 01:15</td><td><span class="tag tag-green" data-i18n="c_tx_usage">usage</span></td><td class="price">-<span class="price-usd" data-usd="0.0011">$0.0011</span></td><td class="price">deepseek-v4-flash</td></tr>
  174. <tr><td style="color:var(--muted);">2026-08-07 22:30</td><td><span class="tag tag-purple" data-i18n="c_tx_deposit">deposit</span></td><td class="price">+<span class="price-usd" data-usd="20">$20.00</span></td><td class="price">Stripe · 4242</td></tr>
  175. <tr><td style="color:var(--muted);">2026-08-07 18:02</td><td><span class="tag tag-green" data-i18n="c_tx_usage">usage</span></td><td class="price">-<span class="price-usd" data-usd="0.0084">$0.0084</span></td><td class="price">qwen3-max</td></tr>
  176. </tbody>
  177. </table>
  178. </div>
  179. </div>
  180. <!-- ══ Tab 2: API Keys ══ -->
  181. <div class="tab-panel" id="tab-keys">
  182. <div class="key-form">
  183. <div class="row">
  184. <div class="field"><label data-i18n="c_key_name">Tên Key</label><input type="text" placeholder="production-key"></div>
  185. <div class="field"><label data-i18n="c_key_expire">Hết hạn (tùy chọn)</label><input type="date"></div>
  186. <button class="btn btn-primary" style="margin-bottom:0;" data-i18n="c_key_create_btn">+ Tạo Key</button>
  187. </div>
  188. <p class="auth-note" style="color:var(--gold);margin-top:10px;" data-i18n="c_key_once">⚠️ Key sẽ chỉ được hiển thị một lần sau khi tạo. Hãy lưu ngay.</p>
  189. </div>
  190. <div class="table-wrap">
  191. <table class="data">
  192. <thead><tr><th data-i18n="c_t_name">Tên</th><th data-i18n="c_t_key">Key</th><th data-i18n="c_t_status">Trạng thái</th><th data-i18n="c_t_last">Sử dụng gần nhất</th><th data-i18n="c_t_created">Tạo lúc</th><th data-i18n="q_limits">Giới hạn</th><th data-i18n="c_t_action">Thao tác</th></tr></thead>
  193. <tbody>
  194. <tr><td><b>production</b></td><td class="price">dt_8e7535c9••••</td><td><span class="status-badge active" data-i18n="c_st_active">active</span></td><td style="color:var(--muted);">2 phút</td><td style="color:var(--muted);">2026-07-20</td><td><div class="quota-bar"><div class="quota-fill warn" style="width:64%"></div></div><div class="quota-meta">6,420/10,000 · 82%</div></td><td><button class="op-btn" data-i18n="c_rotate">Đổi key</button><button class="op-btn" data-i18n="q_edit">Cấu hình giới hạn</button><button class="op-btn danger" data-i18n="c_revoke">Thu hồi</button></td></tr>
  195. <tr><td><b>staging</b></td><td class="price">dt_cb906568••••</td><td><span class="status-badge active" data-i18n="c_st_active">active</span></td><td style="color:var(--muted);">1 giờ</td><td style="color:var(--muted);">2026-07-28</td><td><div class="quota-bar"><div class="quota-fill" style="width:23%"></div></div><div class="quota-meta">2,310/10,000</div></td><td><button class="op-btn" data-i18n="c_rotate">Đổi key</button><button class="op-btn" data-i18n="q_edit">Cấu hình giới hạn</button><button class="op-btn danger" data-i18n="c_revoke">Thu hồi</button></td></tr>
  196. <tr><td><b>local-dev</b></td><td class="price">dt_5f2a11e3••••</td><td><span class="status-badge expired" data-i18n="c_st_expired">expired</span></td><td style="color:var(--muted);">2026-08-01</td><td style="color:var(--muted);">2026-06-15</td><td><div class="quota-bar"><div class="quota-fill over" style="width:100%"></div></div><div class="quota-meta" style="color:#FF6B6B;">10,000/10,000</div></td><td><button class="op-btn" data-i18n="c_rotate">Đổi key</button><button class="op-btn" data-i18n="q_edit">Cấu hình giới hạn</button><button class="op-btn danger" data-i18n="c_delete">Xóa</button></td></tr>
  197. <tr><td><b>old-integration</b></td><td class="price">dt_7b4d90a2••••</td><td><span class="status-badge revoked" data-i18n="c_st_revoked">revoked</span></td><td style="color:var(--muted);">2026-07-05</td><td style="color:var(--muted);">2026-05-01</td><td><button class="op-btn" data-i18n="c_reactivate">Kích hoạt lại</button></td></tr>
  198. </tbody>
  199. </table>
  200. </div>
  201. <div class="notice" style="margin-top:14px;" data-i18n="c_security">🔒 Bảo mật: Key được lưu dạng băm SHA-256. Đổi key = thu hồi + tạo mới (POST /v1/keys/:id/rotate).</div>
  202. </div>
  203. <!-- ══ Tab 3: Nạp tiền ══ -->
  204. <div class="tab-panel" id="tab-wallet">
  205. <div class="stat-grid" style="margin-bottom:20px;">
  206. <div class="stat-card"><div class="lbl" data-i18n="c_avail">Số dư khả dụng</div><div class="val green"><span class="price-usd" data-usd="23.50">$23.50</span></div><div class="sub2">≈ <span class="price-usd" data-usd="23.50">$23.50</span></div></div>
  207. <div class="stat-card"><div class="lbl" data-i18n="c_month_topup">Đã nạp (tháng này)</div><div class="val">$40.00</div><div class="sub2" data-i18n="c_topup_sub">2 giao dịch</div></div>
  208. </div>
  209. <div class="card">
  210. <div class="sec-title" style="margin-top:0;" data-i18n="c_select_amount">Chọn số tiền nạp</div>
  211. <div class="topup-grid">
  212. <div class="topup-amt selected"><b class="price-usd" data-usd="5">$5.00</b><span>≈ <span class="price-usd" data-usd="5">$5.00</span></span></div>
  213. <div class="topup-amt"><b class="price-usd" data-usd="10">$10.00</b><span>≈ <span class="price-usd" data-usd="10">$10.00</span></span></div>
  214. <div class="topup-amt"><b class="price-usd" data-usd="20">$20.00</b><span>≈ <span class="price-usd" data-usd="20">$20.00</span></span></div>
  215. <div class="topup-amt"><b class="price-usd" data-usd="50">$50.00</b><span>≈ <span class="price-usd" data-usd="50">$50.00</span></span></div>
  216. </div>
  217. <div class="sec-title" data-i18n="c_pay_method">Phương thức thanh toán</div>
  218. <div class="pay-btns">
  219. <button class="pay-btn">🟢 MoMo</button>
  220. <button class="pay-btn">🔵 ZaloPay</button>
  221. <button class="pay-btn">⚡ Stripe</button>
  222. <button class="pay-btn">🅿️ PayPal</button>
  223. <button class="pay-btn">🅰️ Alipay</button>
  224. <button class="pay-btn">💳 <span data-i18n="pay_card">Thẻ ngân hàng</span></button>
  225. </div>
  226. <button class="btn btn-primary" style="margin-top:20px;width:100%;justify-content:center;" data-i18n="c_topup_now">Nạp ngay</button>
  227. <p class="auth-note" style="margin-top:10px;" data-i18n="rate_note">Tỷ giá tham khảo: 1 USD ≈ 25.400₫ (cập nhật tự động khi nạp tiền)</p>
  228. </div>
  229. <div class="sec-title" data-i18n="c_deposit_history">Lịch sử nạp</div>
  230. <div class="table-wrap">
  231. <table class="data">
  232. <thead><tr><th data-i18n="c_t_time">Thời gian</th><th data-i18n="c_pay_method">Phương thức</th><th data-i18n="c_t_amount">Số tiền</th><th data-i18n="c_t_status">Trạng thái</th></tr></thead>
  233. <tbody>
  234. <tr><td style="color:var(--muted);">2026-08-07 22:30</td><td>Stripe · 4242</td><td class="price">+<span class="price-usd" data-usd="20">$20.00</span></td><td><span class="status-badge active" data-i18n="c_st_success">success</span></td></tr>
  235. <tr><td style="color:var(--muted);">2026-07-28 09:12</td><td>MoMo</td><td class="price">+<span class="price-usd" data-usd="20">$20.00</span></td><td><span class="status-badge active" data-i18n="c_st_success">success</span></td></tr>
  236. </tbody>
  237. </table>
  238. </div>
  239. </div>
  240. <!-- ══ Tab 4: Sử dụng ══ -->
  241. <div class="tab-panel" id="tab-usage">
  242. <div class="stat-grid">
  243. <div class="stat-card"><div class="lbl" data-i18n="c_today_req">Yêu cầu hôm nay</div><div class="val purple">1,284 <span data-i18n="c_req_unit">req</span></div><div class="sub2"><span data-i18n="c_tokens">Token</span>: 4.2M</div></div>
  244. <div class="stat-card"><div class="lbl" data-i18n="c_7days">7 ngày</div><div class="val">7,940 <span data-i18n="c_req_unit">req</span></div><div class="sub2">31.5M tokens</div></div>
  245. <div class="stat-card"><div class="lbl" data-i18n="c_30days">30 ngày</div><div class="val green">32,118 <span data-i18n="c_req_unit">req</span></div><div class="sub2">128M tokens</div></div>
  246. </div>
  247. <div class="sec-title" data-i18n="c_by_model">Theo mô hình (7 ngày)</div>
  248. <div class="table-wrap">
  249. <table class="data">
  250. <thead><tr><th data-i18n="pt_model">Mô hình</th><th data-i18n="c_requests">Yêu cầu</th><th>Token in</th><th>Token out</th><th data-i18n="c_cost">Chi phí</th></tr></thead>
  251. <tbody>
  252. <tr><td><b>deepseek-v4-flash</b></td><td>3,412</td><td class="price">12.8M</td><td class="price">4.1M</td><td class="price"><span class="price-usd" data-usd="2.91">$2.91</span></td></tr>
  253. <tr><td><b>glm-5.2</b></td><td>1,855</td><td class="price">6.3M</td><td class="price">2.2M</td><td class="price"><span class="price-usd" data-usd="4.86">$4.86</span></td></tr>
  254. <tr><td><b>qwen3-max</b></td><td>1,204</td><td class="price">5.1M</td><td class="price">1.8M</td><td class="price"><span class="price-usd" data-usd="5.94">$5.94</span></td></tr>
  255. <tr><td><b>deepseek-v4-pro</b></td><td>1,469</td><td class="price">7.2M</td><td class="price">2.6M</td><td class="price"><span class="price-usd" data-usd="4.03">$4.03</span></td></tr>
  256. </tbody>
  257. </table>
  258. </div>
  259. <div class="notice" style="margin-top:14px;" data-i18n="c_usage_note">📊 Chi tiết từng request có sẵn tại GET /v1/usage (phân trang).</div>
  260. </div>
  261. </main>
  262. </div>
  263. <!-- 限额编辑弹窗 -->
  264. <div class="modal-mask" id="quotaModal">
  265. <div class="modal" style="width:520px;">
  266. <button class="modal-close" onclick="document.getElementById('quotaModal').classList.remove('open')">✕</button>
  267. <h3 data-i18n="q_edit">Cấu hình giới hạn</h3>
  268. <div class="q-form">
  269. <div class="q-sec" data-i18n="q_daily">Hằng ngày</div>
  270. <div class="field"><label data-i18n="q_req">Yêu cầu</label><input type="number" value="10000" placeholder="0 = không giới hạn"></div>
  271. <div class="field"><label data-i18n="q_tokens">Token</label><input type="number" value="100000000"></div>
  272. <div class="field"><label data-i18n="q_cost">Chi phí (USD)</label><input type="number" value="5"></div>
  273. <div class="q-sec" data-i18n="q_total">Tổng</div>
  274. <div class="field"><label data-i18n="q_req">Yêu cầu</label><input type="number" placeholder="0 = không giới hạn"></div>
  275. <div class="field"><label data-i18n="q_tokens">Token</label><input type="number" placeholder="0 = không giới hạn"></div>
  276. <div class="field"><label data-i18n="q_cost">Chi phí (USD)</label><input type="number" placeholder="0 = không giới hạn"></div>
  277. <div class="field full"><label data-i18n="q_alert_pct">Cảnh báo tại (%)</label><input type="number" value="80"></div>
  278. </div>
  279. <button class="btn btn-primary btn-block" onclick="document.getElementById('quotaModal').classList.remove('open')" data-i18n="q_save">Lưu</button>
  280. </div>
  281. </div>
  282. <!-- 认证弹窗 -->
  283. <div class="modal-mask" id="authModal">
  284. <div class="modal">
  285. <button class="modal-close" aria-label="Close">✕</button>
  286. <div id="viewLogin">
  287. <h3 data-i18n="auth_login_title">Đăng nhập</h3>
  288. <div class="auth-error" data-i18n="auth_err_email">Email không hợp lệ</div>
  289. <div class="field"><label data-i18n="auth_email">Email</label><input type="email" placeholder="you@example.com"></div>
  290. <div class="field"><label data-i18n="auth_password">Mật khẩu</label><input type="password"></div>
  291. <button class="btn btn-primary btn-block" data-i18n="auth_login_btn">Đăng nhập</button>
  292. <div class="auth-links"><a data-auth-view="reset" data-i18n="auth_forgot">Quên mật khẩu?</a><a data-auth-view="register" data-i18n="auth_to_register">Tạo tài khoản</a></div>
  293. </div>
  294. <div id="viewRegister" hidden>
  295. <h3 data-i18n="auth_register_title">Tạo tài khoản</h3>
  296. <div class="auth-error" data-i18n="auth_err_pwd">Mật khẩu không khớp</div>
  297. <div class="field"><label data-i18n="auth_email">Email</label><input type="email" placeholder="you@example.com"></div>
  298. <div class="field"><label data-i18n="auth_password">Mật khẩu</label><input type="password"></div>
  299. <div class="field"><label data-i18n="auth_confirm">Xác nhận mật khẩu</label><input type="password"></div>
  300. <div class="field">
  301. <label data-i18n="auth_code_label">Mã xác minh</label>
  302. <div class="code-row">
  303. <input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1">
  304. <button class="btn btn-sm code-send" data-send-code data-i18n="auth_code_send">Gửi mã</button>
  305. </div>
  306. <p class="auth-note" data-code-note data-i18n="auth_code_note">Mã gồm 8 ký tự chữ hoa & số, hiệu lực 15 phút</p>
  307. </div>
  308. <button class="btn btn-primary btn-block" data-i18n="auth_register_btn">Đăng ký</button>
  309. <div class="auth-links"><a data-auth-view="login" data-i18n="auth_to_login">Đã có tài khoản? Đăng nhập</a></div>
  310. </div>
  311. <div id="viewReset" hidden>
  312. <h3 data-i18n="auth_reset_title">Đặt lại mật khẩu</h3>
  313. <div class="auth-error" data-i18n="auth_err_pwd">Mật khẩu không khớp</div>
  314. <div class="field"><label data-i18n="auth_email">Email</label><input type="email" placeholder="you@example.com"></div>
  315. <div class="field">
  316. <label data-i18n="auth_code_label">Mã xác minh</label>
  317. <div class="code-row">
  318. <input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1"><input class="code-cell" maxlength="1">
  319. <button class="btn btn-sm code-send" data-send-code data-i18n="auth_code_send">Gửi mã</button>
  320. </div>
  321. <p class="auth-note" data-code-note data-i18n="auth_code_note">Mã gồm 8 ký tự chữ hoa & số, hiệu lực 15 phút</p>
  322. </div>
  323. <div class="field"><label data-i18n="auth_new_pwd">Mật khẩu mới</label><input type="password"></div>
  324. <div class="field"><label data-i18n="auth_confirm_new">Xác nhận mật khẩu mới</label><input type="password"></div>
  325. <button class="btn btn-primary btn-block" data-i18n="auth_reset_btn">Đặt lại mật khẩu</button>
  326. <div class="auth-links"><a data-auth-view="login" data-i18n="auth_back_login">Quay lại đăng nhập</a></div>
  327. </div>
  328. </div>
  329. </div>
  330. <script src="../web-v1.1.0/i18n.js"></script>
  331. <script>
  332. document.querySelectorAll('.side-nav a').forEach(a => a.addEventListener('click', () => {
  333. document.querySelectorAll('.side-nav a').forEach(x => x.classList.remove('active'));
  334. document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
  335. a.classList.add('active');
  336. document.getElementById('tab-' + a.dataset.tab).classList.add('active');
  337. document.querySelector('.main-head h1').textContent = a.querySelector('[data-i18n]').textContent;
  338. }));
  339. document.querySelectorAll('[data-i18n="q_edit"]').forEach(b => b.addEventListener('click', () => document.getElementById('quotaModal').classList.add('open')));
  340. document.querySelectorAll('.topup-amt').forEach(el => el.addEventListener('click', () => {
  341. document.querySelectorAll('[data-i18n="q_edit"]').forEach(b => b.addEventListener('click', () => document.getElementById('quotaModal').classList.add('open')));
  342. document.querySelectorAll('.topup-amt').forEach(x => x.classList.remove('selected'));
  343. el.classList.add('selected');
  344. }));
  345. </script>
  346. </body>
  347. </html>