移动端一期.html 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6. <title>权益专区</title>
  7. <script src="https://cdn.tailwindcss.com"></script>
  8. <style>
  9. .no-scrollbar::-webkit-scrollbar { display: none; }
  10. .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
  11. .tab-indicator { transition: all 0.3s ease; }
  12. .view-transition { transition: transform 0.35s cubic-bezier(0.4, 0.0, 0.2, 1); }
  13. </style>
  14. </head>
  15. <body class="bg-gray-100 flex justify-center h-screen overflow-hidden font-sans">
  16. <!-- 侧边全局控制面板 -->
  17. <div class="fixed top-[20%] right-0 z-50 flex items-start max-w-sm">
  18. <button onclick="toggleSimPanel()" class="bg-black/60 text-white text-[11px] py-1.5 px-2 rounded-l-md shadow-md flex items-center gap-1 backdrop-blur-sm">
  19. <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
  20. 状态
  21. </button>
  22. <div id="sim-panel" class="absolute top-8 right-2 bg-white/95 backdrop-blur-md border border-gray-200 p-2 rounded-lg shadow-xl w-[140px] text-[11px] transition-all origin-top-right scale-0 opacity-0 pointer-events-none">
  23. <div class="font-bold mb-1.5 text-gray-800 border-b pb-1 text-center">切换等级</div>
  24. <div class="flex flex-col gap-1.5">
  25. <button onclick="setUserLevel('prospect')" id="btn-state-prospect" class="px-2 py-1.5 rounded bg-gray-100 text-gray-700 transition">潜客</button>
  26. <button onclick="setUserLevel('credit_only')" id="btn-state-credit_only" class="px-2 py-1.5 rounded bg-gray-100 text-gray-700 transition">仅持有信用卡客户</button>
  27. <button onclick="setUserLevel('advance')" id="btn-state-advance" class="px-2 py-1.5 rounded bg-gray-100 text-gray-700 transition">运筹理财</button>
  28. <button onclick="setUserLevel('premier')" id="btn-state-premier" class="px-2 py-1.5 rounded bg-gray-100 text-gray-700 transition">卓越理财</button>
  29. <button onclick="setUserLevel('elite')" id="btn-state-elite" class="px-2 py-1.5 rounded bg-gray-100 text-gray-700 transition">卓越理财·尊尚</button>
  30. <button onclick="setUserLevel('global')" id="btn-state-global" class="px-2 py-1.5 rounded bg-gray-100 text-gray-700 transition">环球私人银行</button>
  31. </div>
  32. </div>
  33. </div>
  34. <!-- 移动端模拟容器 -->
  35. <div class="w-full max-w-[400px] h-full bg-white flex flex-col relative shadow-2xl overflow-hidden">
  36. <!-- 顶部状态栏 -->
  37. <div class="h-11 w-full flex justify-between items-center px-5 text-black bg-white z-30 relative shrink-0">
  38. <span class="text-[15px] font-medium">9:41</span>
  39. <div class="flex gap-1.5 items-center">
  40. <svg width="18" height="12" viewBox="0 0 18 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 12V9H3.5V12H1.5ZM6 12V6.5H8V12H6ZM10.5 12V3.5H12.5V12H10.5ZM15 12V0H17V12H15Z" fill="black"/></svg>
  41. <svg width="16" height="12" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 12C9.10457 12 10 11.1046 10 10C10 8.89543 9.10457 8 8 8C6.89543 8 6 8.89543 6 10C6 11.1046 6.89543 12 8 12Z" fill="black"/><path d="M2.34315 5.65685C5.46734 2.53266 10.5327 2.53266 13.6569 5.65685" stroke="black" stroke-width="1.5" stroke-linecap="round"/><path d="M5.17157 8.48528C6.73367 6.92318 9.26633 6.92318 10.8284 8.48528" stroke="black" stroke-width="1.5" stroke-linecap="round"/></svg>
  42. <svg width="25" height="12" viewBox="0 0 25 12" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="0.5" y="0.5" width="21" height="11" rx="2.5" stroke="black"/><rect x="2" y="2" width="18" height="8" rx="1" fill="black"/><path d="M23 4V8" stroke="black" stroke-width="1.5" stroke-linecap="round"/></svg>
  43. </div>
  44. </div>
  45. <!-- 视图 A: 权益介绍页 (Home View) -->
  46. <div id="home-view" class="flex flex-col h-[calc(100%-44px)] w-full absolute top-[44px] left-0 bg-white view-transition translate-x-0 z-10">
  47. <header class="h-11 flex items-center justify-between px-4 bg-white z-20 shrink-0">
  48. <button class="text-gray-800 p-1"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg></button>
  49. <h1 class="text-[17px] font-medium text-gray-900 absolute left-1/2 -translate-x-1/2">权益介绍页</h1>
  50. <div class="w-8"></div>
  51. </header>
  52. <div class="flex-1 overflow-y-auto no-scrollbar pb-8 relative">
  53. <div id="no-tier-banner" onclick="showZone()" class="px-4 py-3 bg-[#fdfaf8] border-b border-gray-100 flex items-center justify-between cursor-pointer active:bg-gray-50 transition">
  54. <div class="flex items-center gap-3">
  55. <div class="w-10 h-10 rounded-full bg-gray-100 flex items-center justify-center border border-gray-200">
  56. <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="14" x="3" y="8" rx="2"/><path d="M12 5a3 3 0 1 0-3 3"/><path d="M15 8a3 3 0 1 0-3-3"/><path d="M12 8v10"/><path d="M3 12h18"/></svg>
  57. </div>
  58. <div>
  59. <div class="text-[15px] text-gray-900">权益首页</div>
  60. <div class="text-[12px] text-gray-500">一键查看您的所有权益</div>
  61. </div>
  62. </div>
  63. <button class="text-[13px] text-gray-500 flex items-center pointer-events-none">
  64. 立即查看 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
  65. </button>
  66. </div>
  67. <div class="flex justify-between px-2 pt-2 border-b border-gray-200 relative">
  68. <button onclick="switchTab('premier')" class="flex-1 py-3 text-[14px] font-medium relative text-gray-900" id="tab-btn-premier">卓越理财</button>
  69. <button onclick="switchTab('elite')" class="flex-1 py-3 text-[14px] font-medium relative text-gray-500" id="tab-btn-elite">卓越理财·尊尚</button>
  70. <button onclick="switchTab('global')" class="flex-1 py-3 text-[14px] font-medium relative text-gray-500" id="tab-btn-global">环球私人银行</button>
  71. <div id="tab-indicator" class="absolute bottom-0 h-[2px] bg-[#d70014] tab-indicator" style="width: 33.33%; left: 0%;"></div>
  72. </div>
  73. <div id="content-area" class="px-5 pt-5 pb-10"></div>
  74. </div>
  75. </div>
  76. <!-- 视图 B: 权益首页/专区 (Zone View) -->
  77. <div id="zone-view" class="flex flex-col h-[calc(100%-44px)] w-full absolute top-[44px] left-0 bg-[#f4f5f8] view-transition translate-x-full z-20">
  78. <header class="h-11 flex items-center justify-between px-4 bg-white z-20 shrink-0 border-b border-gray-100">
  79. <button onclick="hideZone()" class="text-gray-800 p-1"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg></button>
  80. <h1 class="text-[17px] font-medium text-gray-900 absolute left-1/2 -translate-x-1/2">权益首页</h1>
  81. <div class="w-8"></div>
  82. </header>
  83. <div class="flex-1 overflow-y-auto no-scrollbar pb-8 relative" id="zone-content-area"></div>
  84. </div>
  85. <!-- 积分规则弹窗 -->
  86. <div id="rule-modal-backdrop" class="absolute inset-0 bg-black/50 z-[60] opacity-0 pointer-events-none transition-opacity duration-300" onclick="closeRuleModal()"></div>
  87. <div id="rule-modal" class="absolute bottom-0 left-0 w-full bg-white z-[70] rounded-t-2xl transform translate-y-full transition-transform duration-300 flex flex-col" style="height: 85%;">
  88. <div class="flex justify-between items-center px-5 py-4 border-b border-gray-100 shrink-0">
  89. <h2 class="text-[17px] font-medium text-gray-900">积分规则</h2>
  90. <button onclick="closeRuleModal()" class="text-gray-500 p-1 hover:bg-gray-100 rounded-full transition">
  91. <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
  92. </button>
  93. </div>
  94. <div class="flex-1 overflow-y-auto px-5 py-5 no-scrollbar">
  95. <h3 class="text-[14px] font-medium text-gray-800 mb-4">汇丰银行(中国)有限公司积分使用规则</h3>
  96. <div class="text-[13px] text-gray-600 leading-[1.8] space-y-4 text-justify">
  97. <p>本积分使用规则(“本规则”)为汇丰银行(中国)有限公司(“本行”)的客户(“客户”)使用本行信用卡及借记卡积分(即“汇友荟”汇丰客户关系积分)(简称“汇友荟积分”)兑换本行提供的礼品、里程或刷卡金等项目(具体以本行积分换礼平台正式公布的有效兑换项目为准,以下称“兑换项目”)等需要遵守的使用规则。</p>
  98. <p class="font-medium text-gray-800 pt-2">一、 兑换及使用渠道</p>
  99. <p>1. 除本规则以下相关兑换项目项下有特别说明外,客户可使用信用卡积分及“汇友荟”汇丰客户关系积分在积分换礼平台兑换相关项目,具体兑换渠道如下:<br>
  100. (1) 登录“汇丰中国客户服务”微信服务号,点击“我的汇丰”—“我的积分”—“积分商城”页面兑换;或<br>
  101. (2) 登录汇丰银行App,在“我的”点击“我的积分”—“积分商城”页面兑换礼品;<br>
  102. (3) 人工服务申请兑换:拨打本行24小时客服热线95366或4008695366(该渠道仅限本行信用卡主卡持卡人兑换部分项目申请时使用)兑换。</p>
  103. <p>2. 积分一旦兑换成功,不可撤销、更改或退还。若因系统或网络原因导致兑换失败,积分将自动退回账户。</p>
  104. <p class="font-medium text-gray-800 pt-2">二、 积分有效期</p>
  105. <p>信用卡积分有效期与信用卡有效期一致。如客户在信用卡有效期届满前未消耗完毕,积分将于信用卡到期次月清零。“汇友荟”积分有效期详见对应活动的具体规则。请客户关注积分到期日并及时兑换。</p>
  106. <p class="pt-10 pb-10 text-center text-gray-300">-- 到底了 --</p>
  107. </div>
  108. </div>
  109. </div>
  110. <!-- 余额计算规则弹窗 -->
  111. <div id="balance-rule-modal-backdrop" class="absolute inset-0 bg-black/50 z-[60] opacity-0 pointer-events-none transition-opacity duration-300" onclick="closeBalanceRuleModal()"></div>
  112. <div id="balance-rule-modal" class="absolute bottom-0 left-0 w-full bg-white z-[70] rounded-t-2xl transform translate-y-full transition-transform duration-300 flex flex-col min-h-[220px]">
  113. <div class="flex justify-between items-center px-5 py-4 shrink-0 border-b border-gray-50">
  114. <h2 class="text-[18px] font-medium text-gray-900">提示</h2>
  115. <button onclick="closeBalanceRuleModal()" class="text-gray-500 p-1 hover:bg-gray-100 rounded-full transition">
  116. <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
  117. </button>
  118. </div>
  119. <div class="flex-1 px-5 pb-8 pt-4">
  120. <div class="text-[15px] text-gray-700 leading-[1.6]">
  121. 月内日均余额 = 当月内每日账户余额之和 / 当月天数。
  122. </div>
  123. </div>
  124. </div>
  125. <!-- 底部 Home Indicator (iOS风格) -->
  126. <div class="h-8 w-full flex justify-center items-center z-[80] absolute bottom-0 pointer-events-none">
  127. <div class="w-32 h-1 bg-gray-900 rounded-full"></div>
  128. </div>
  129. </div>
  130. <script>
  131. // --- 核心 SVG 图标库 ---
  132. const icons = {
  133. cap: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 10v6M2 10l10-5 10 5-10 5z"/><path d="M6 12v5c3 3 9 3 12 0v-5"/></svg>`,
  134. heart: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/></svg>`,
  135. bulb: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.9 1.2 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>`,
  136. gift: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="8" width="18" height="14" rx="2"/><path d="M12 5a3 3 0 1 0-3 3"/><path d="M15 8a3 3 0 1 0-3-3"/><path d="M12 8v14"/><path d="M3 12h18"/></svg>`,
  137. diamond: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3h12l4 6-10 13L2 9Z"/></svg>`,
  138. medbox: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="8" width="16" height="12" rx="2"/><path d="M8 8V6a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M12 11v4M10 13h4"/></svg>`,
  139. car: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 12 10s-6.7.6-8.5 1.1C2.7 11.3 2 12.1 2 13v3c0 .6.4 1 1 1h2"/><rect width="16" height="8" x="4" y="10" rx="2"/><path d="M7 14h.01"/><path d="M17 14h.01"/><path d="m10 10-1.5-4h7l-1.5 4"/></svg>`,
  140. plane: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.2-1.1.7l-1.2 3.6 7.7 4.4-4.2 4.2-3.1-.8c-.4-.1-.8.1-1 .5l-.8 2.3 5.4 1.8 1.8 5.4 2.3-.8c.4-.2.6-.6.5-1l-.8-3.1 4.2-4.2 4.4 7.7 3.6-1.2c.5-.2.8-.6.7-1.1Z"/></svg>`,
  141. globe: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/><path d="M2 12h20"/></svg>`,
  142. coffee: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ba6534" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17 8h1a4 4 0 1 1 0 8h-1"/><path d="M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z"/><line x1="6" x2="6" y1="2" y2="4"/><line x1="10" x2="10" y1="2" y2="4"/><line x1="14" x2="14" y1="2" y2="4"/></svg>`,
  143. planeRed: `<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#d70014" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.2-1.1.7l-1.2 3.6 7.7 4.4-4.2 4.2-3.1-.8c-.4-.1-.8.1-1 .5l-.8 2.3 5.4 1.8 1.8 5.4 2.3-.8c.4-.2.6-.6.5-1l-.8-3.1 4.2-4.2 4.4 7.7 3.6-1.2c.5-.2.8-.6.7-1.1Z"/></svg>`,
  144. help: `<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="1.5" class="ml-1 inline-block"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>`,
  145. copy: `<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="1.5" class="ml-1 inline-block cursor-pointer"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`,
  146. doc: `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="mr-1 inline-block"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>`,
  147. clipboard: `<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>`
  148. };
  149. // --- 权益主页数据 (Home Page Data) ---
  150. const tabData = {
  151. premier: {
  152. id: 'premier', title: '卓越理财', subtitle: '为您和您的家人提供尊崇专属礼遇和权益',
  153. imageSrc: 'https://images.unsplash.com/photo-1518893494013-481c1d8ed3fd?q=80&w=800&auto=format&fit=crop',
  154. imageStyle: 'filter: sepia(0.4) hue-rotate(330deg);',
  155. features: [
  156. { title: '国际教育', desc: '享专属国际化学校优惠及背景提升项目' },
  157. { title: '酒店礼遇', desc: '高端酒店及商场会籍匹配' },
  158. { title: '环球礼遇', desc: '汇丰中国信用卡持卡人,尊享机场贵宾厅及礼宾车等礼遇' },
  159. { title: '优选健康荟', desc: '享香港私立医院体检专属折扣' }
  160. ]
  161. },
  162. elite: {
  163. id: 'elite', title: '卓越理财·尊尚', subtitle: '开启尊尚体验,享受环球出行、高端运动、国际教育等VIP礼遇。',
  164. imageSrc: 'https://images.unsplash.com/photo-1610701596007-11502861dcfa?q=80&w=800&auto=format&fit=crop',
  165. imageStyle: 'filter: sepia(0.6) hue-rotate(330deg) saturate(1.5);',
  166. features: [
  167. { title: '国际教育', desc: '享多项升学规划指导、专属国际化学校优惠及背景提升项目' },
  168. { title: '专属礼宾服务', desc: '高端酒店及商场会籍匹配、高尔夫练习场畅' },
  169. { title: '尊尚生日礼', desc: '尊享体验任选其一' },
  170. { title: '「汇享健康」', desc: '三重健康保障,包括专属健保管家、公立医院门诊预约及就医陪同服务等权益' }
  171. ]
  172. },
  173. global: {
  174. id: 'global', title: '环球私人银行', subtitle: '开启环球「创臻享」及「汇佑健康」之旅。',
  175. imageSrc: 'https://images.unsplash.com/photo-1550684848-fac1c5b4e853?q=80&w=800&auto=format&fit=crop',
  176. imageStyle: '',
  177. features: [
  178. { title: '高尔夫权益', desc: '练习场畅达及VIP高尔夫俱乐部免会籍预约' },
  179. { title: '臻享体验', desc: '享高端酒店及商场会籍匹配、米其林级别私宴预定服务等' },
  180. { title: '环球旅行', desc: '境外礼宾接送机服务及酒店升房礼遇' },
  181. { title: '私人生日礼', desc: '尊享体验任选其一' },
  182. { title: '「汇佑健康」', desc: '一站式健康管理,包括专属家庭医师团队、公立医院门诊预约及就医陪同服务等权益' }
  183. ]
  184. }
  185. };
  186. const baseAdvanceExclusives = [
  187. { icon: icons.gift, label: '卓越理财迎<br>新礼' }
  188. ];
  189. // 权益首页数据定制
  190. const zoneData = {
  191. 'prospect': {
  192. hasAd: false, hasDotsExclusives: false, hasDotsCredit: true, hideIdentity: true,
  193. exclusives: baseAdvanceExclusives
  194. },
  195. 'credit_only': {
  196. hasAd: false, hasDotsExclusives: false, hasDotsCredit: true, hideIdentity: true,
  197. exclusives: []
  198. },
  199. 'advance': {
  200. headerBannerUrl: 'https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?w=800&auto=format&fit=crop',
  201. tierTitle: 'HSBC Advance', tierSub: '汇丰运筹理财',
  202. hasAd: false, hasDotsExclusives: false, hasDotsCredit: true, hideIdentity: false,
  203. accountHtml: `
  204. <div class="flex justify-between items-end pt-1">
  205. <div>
  206. <div class="text-[14px] text-gray-800 flex items-center font-medium">账户月内日均余额 <span onclick="openBalanceRuleModal()" class="cursor-pointer ml-1 flex items-center">${icons.help}</span></div>
  207. <div class="text-[12px] text-gray-500 mt-1.5">截止日期 XXXX年X月X日</div>
  208. </div>
  209. <div class="text-[14px] text-gray-600 mb-1.5">8,000,000 人民币元</div>
  210. </div>
  211. `,
  212. exclusives: baseAdvanceExclusives
  213. },
  214. 'premier': {
  215. headerBannerUrl: 'https://images.unsplash.com/photo-1574678170884-cbabaf60df08?w=800&auto=format&fit=crop',
  216. tierTitle: 'HSBC Premier', tierSub: '汇丰卓越理财',
  217. hasAd: true, hasDotsExclusives: false, hasDotsCredit: true, hideIdentity: false,
  218. accountHtml: `
  219. <div class="border-b border-gray-100 pb-3.5 mb-3.5">
  220. <div class="text-[14px] text-gray-800 font-medium flex items-center">卓越理财客户</div>
  221. </div>
  222. <div class="flex justify-between items-end">
  223. <div>
  224. <div class="text-[14px] text-gray-800 flex items-center font-medium">账户月内日均余额 <span onclick="openBalanceRuleModal()" class="cursor-pointer ml-1 flex items-center">${icons.help}</span></div>
  225. <div class="text-[12px] text-gray-500 mt-1.5">截止日期 XXXX年X月X日</div>
  226. </div>
  227. <div class="text-[14px] text-gray-600 mb-1.5">8,000,000 人民币元</div>
  228. </div>
  229. `,
  230. exclusives: [
  231. { icon: icons.cap, label: '国际教育' },
  232. { icon: icons.heart, label: '优选健康荟' },
  233. { icon: icons.bulb, label: '酒店礼遇' }
  234. ]
  235. },
  236. 'elite': {
  237. headerBannerUrl: 'https://images.unsplash.com/photo-1610701596007-11502861dcfa?w=800&auto=format&fit=crop',
  238. tierTitle: 'HSBC Premier Elite', tierSub: '汇丰卓越理财·尊尚',
  239. hasAd: true, hasDotsExclusives: true, hasDotsCredit: true, hideIdentity: false,
  240. accountHtml: `
  241. <div class="flex justify-between items-center border-b border-gray-100 pb-3.5 mb-3.5">
  242. <div class="text-[14px] text-gray-800 font-medium flex items-center">卓越理财尊尚客户</div>
  243. <div class="text-[14px] text-gray-600 flex items-center">C1234567890 ${icons.copy}</div>
  244. </div>
  245. <div class="flex justify-between items-end">
  246. <div>
  247. <div class="text-[14px] text-gray-800 flex items-center font-medium">账户月内日均余额 <span onclick="openBalanceRuleModal()" class="cursor-pointer ml-1 flex items-center">${icons.help}</span></div>
  248. <div class="text-[12px] text-gray-500 mt-1.5">截止日期 XXXX年X月X日</div>
  249. </div>
  250. <div class="text-[14px] text-gray-600 mb-1.5">8,000,000 人民币元</div>
  251. </div>
  252. `,
  253. exclusives: [
  254. { icon: icons.cap, label: '国际教育' },
  255. { icon: icons.gift, label: '生日礼' },
  256. { icon: icons.diamond, label: '礼宾服务' },
  257. { icon: icons.heart, label: '汇享健康' }
  258. ]
  259. },
  260. 'global': {
  261. headerBannerUrl: 'https://images.unsplash.com/photo-1634024344558-8b20d7d3b0c6?w=800&auto=format&fit=crop',
  262. tierTitle: 'HSBC Private Bank', tierSub: '汇丰环球私人银行',
  263. hasAd: true, hasDotsExclusives: false, hasDotsCredit: true, hideIdentity: false,
  264. accountHtml: `
  265. <div class="flex justify-between items-center py-1">
  266. <div class="text-[14px] text-gray-800 font-medium flex items-center">私行业务ID</div>
  267. <div class="text-[14px] text-gray-600 flex items-center">C1234567890 ${icons.copy}</div>
  268. </div>
  269. `,
  270. exclusives: [
  271. { icon: icons.cap, label: '国际教育' },
  272. { icon: icons.heart, label: '创臻享礼宾<br>服务' },
  273. { icon: icons.medbox, label: '汇佑健康' },
  274. { icon: icons.heart, label: '优选健康荟' }
  275. ]
  276. }
  277. };
  278. const creditCardsData = [
  279. { icon: icons.car, title: '境外礼宾车', sub: '共2次', badge: '0/2' },
  280. { icon: icons.car, title: '境内礼宾车', sub: '共2次', badge: '0/2' },
  281. { icon: icons.plane, title: '贵宾厅', sub: '共2次', badge: '0/2' },
  282. { icon: icons.globe, title: '境外消费', sub: '点击查看' }
  283. ];
  284. let currentUserLevel = 'advance';
  285. let currentActiveTab = 'premier';
  286. document.addEventListener('DOMContentLoaded', () => {
  287. renderHomePage();
  288. updateControlPanelUI();
  289. });
  290. function renderHomePage() {
  291. renderHeaderBanner();
  292. renderTabsNav();
  293. renderContentArea();
  294. }
  295. function renderHeaderBanner() {
  296. const banner = document.getElementById('no-tier-banner');
  297. const isBasic = ['prospect', 'credit_only', 'advance'].includes(currentUserLevel);
  298. banner.style.display = isBasic ? 'flex' : 'none';
  299. }
  300. function renderTabsNav() {
  301. const tabs = ['premier', 'elite', 'global'];
  302. tabs.forEach((tab) => {
  303. const btn = document.getElementById(`tab-btn-${tab}`);
  304. if (tab === currentActiveTab) {
  305. btn.className = "flex-1 py-3 text-[14px] font-medium relative text-gray-900";
  306. } else {
  307. btn.className = "flex-1 py-3 text-[14px] font-medium relative text-gray-500";
  308. }
  309. });
  310. const indicator = document.getElementById('tab-indicator');
  311. indicator.style.left = `${tabs.indexOf(currentActiveTab) * 33.33}%`;
  312. }
  313. function renderContentArea() {
  314. const container = document.getElementById('content-area');
  315. const data = tabData[currentActiveTab];
  316. const levelWeights = { 'prospect': 0, 'credit_only': 0, 'advance': 0, 'premier': 1, 'elite': 2, 'global': 3 };
  317. const isUnlocked = levelWeights[currentUserLevel] >= levelWeights[currentActiveTab];
  318. let buttonHTML = isUnlocked ? `
  319. <button onclick="showZone()" class="w-full py-3 mt-4 mb-6 border border-gray-300 rounded text-[15px] font-medium text-gray-900 bg-white active:bg-gray-50 transition">
  320. 进入权益专区
  321. </button>
  322. ` : `
  323. <button class="w-full py-3 mt-4 mb-6 rounded text-[15px] font-medium text-[#b3b3b3] bg-[#f7f7f7] cursor-not-allowed">
  324. 待解锁
  325. </button>
  326. `;
  327. let featuresHTML = '';
  328. if (currentActiveTab === 'global') {
  329. // 环球私人银行使用带图片、标题、描述的图文列表样式
  330. featuresHTML = '<div class="flex flex-col border-t border-gray-100 pt-2">' + data.features.map(f => `
  331. <div class="flex items-center gap-4 py-4 border-b border-gray-100 last:border-0">
  332. <div class="w-12 h-12 rounded-full border border-gray-200 bg-[#fbfcfc] flex items-center justify-center text-gray-500 shrink-0">
  333. ${icons.clipboard}
  334. </div>
  335. <div class="flex-1">
  336. <div class="text-[15px] font-medium text-gray-900">${f.title}</div>
  337. <div class="text-[13px] text-gray-500 mt-1">${f.desc}</div>
  338. </div>
  339. </div>
  340. `).join('') + '</div>';
  341. } else {
  342. // 卓越理财 和 卓越理财·尊尚 保持小圆点样式
  343. featuresHTML = '<ul class="text-sm">' + data.features.map(f => `
  344. <li class="flex items-start mb-3 relative pl-3">
  345. <span class="absolute left-0 top-[8px] w-1 h-1 bg-gray-600 rounded-full"></span>
  346. <div>
  347. <span class="text-gray-900 font-medium text-[13px] mr-1">${f.title}</span>
  348. <p class="text-gray-500 text-[12px] leading-relaxed mt-0.5">${f.desc}</p>
  349. </div>
  350. </li>
  351. `).join('') + '</ul>';
  352. }
  353. container.innerHTML = `
  354. <div class="w-full h-[150px] overflow-hidden mb-4 rounded-sm">
  355. <img src="${data.imageSrc}" style="${data.imageStyle}" class="w-full h-full object-cover">
  356. </div>
  357. <h2 class="text-xl font-medium text-gray-900 mb-1.5">${data.title}</h2>
  358. <p class="text-[13px] text-gray-500 leading-snug">${data.subtitle}</p>
  359. ${buttonHTML}
  360. ${featuresHTML}
  361. `;
  362. }
  363. // --- ====== 专区内页视图逻辑 (Zone View) ====== ---
  364. function renderZonePage() {
  365. const data = zoneData[currentUserLevel];
  366. const container = document.getElementById('zone-content-area');
  367. const exclusiveHtml = data.exclusives.map(item => `
  368. <div class="flex flex-col items-center min-w-[70px]">
  369. <div class="w-12 h-12 rounded-full border border-gray-200 flex items-center justify-center text-gray-500 mb-2.5 shadow-sm bg-gray-50">
  370. ${item.icon}
  371. </div>
  372. <span class="text-[12px] text-gray-700 text-center leading-tight">${item.label}</span>
  373. </div>
  374. `).join('');
  375. const creditHtml = creditCardsData.map(item => `
  376. <div class="flex flex-col items-center relative min-w-[70px]">
  377. ${item.badge ? `<div class="absolute -top-1 right-0 bg-[#d70014] text-white text-[10px] px-1.5 py-0.5 rounded-full z-10 border-2 border-white font-bold tracking-tighter">${item.badge}</div>` : ''}
  378. <div class="w-12 h-12 rounded-full border border-gray-200 flex items-center justify-center text-gray-500 mb-2.5 shadow-sm bg-gray-50">
  379. ${item.icon}
  380. </div>
  381. <span class="text-[12px] text-gray-800 text-center leading-tight">${item.title}</span>
  382. <span class="text-[11px] text-gray-400 text-center leading-tight mt-1">${item.sub}</span>
  383. </div>
  384. `).join('');
  385. let html = '';
  386. if (!data.hideIdentity) {
  387. html += `
  388. <div class="w-full h-[140px] relative shrink-0">
  389. <img src="${data.headerBannerUrl}" class="w-full h-full object-cover">
  390. <div class="absolute inset-0 bg-gradient-to-r from-black/60 to-transparent"></div>
  391. <div class="absolute bottom-5 left-5 text-white">
  392. <div class="text-[14px] font-bold opacity-90 tracking-wide">${data.tierTitle}</div>
  393. <div class="text-[16px] font-medium tracking-widest mt-0.5">${data.tierSub}</div>
  394. </div>
  395. </div>
  396. <div class="bg-white px-5 py-4 mb-2">${data.accountHtml}</div>
  397. `;
  398. } else {
  399. html += `<div class="w-full h-2 bg-transparent shrink-0"></div>`;
  400. }
  401. if (data.exclusives && data.exclusives.length > 0) {
  402. html += `
  403. <div class="bg-white px-5 py-5 mb-2">
  404. <div class="flex justify-between items-center mb-6">
  405. <h3 class="text-[16px] font-medium text-gray-900">专属礼遇</h3>
  406. <div class="text-[13px] text-gray-900 font-medium flex items-center">我的权益 <svg class="w-4 h-4 ml-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 18l6-6-6-6"/></svg></div>
  407. </div>
  408. <div class="flex ${data.exclusives.length < 4 ? 'justify-start gap-8' : 'justify-between'} px-1">
  409. ${exclusiveHtml}
  410. </div>
  411. ${data.hasDotsExclusives ? `
  412. <div class="flex justify-center gap-2 mt-6">
  413. <div class="w-[5px] h-[5px] bg-black rounded-full"></div>
  414. <div class="w-[5px] h-[5px] border border-black rounded-full"></div>
  415. </div>` : ''}
  416. </div>
  417. `;
  418. }
  419. html += `
  420. <div class="bg-white px-5 py-5 mb-2">
  421. <h3 class="text-[16px] font-medium text-gray-900 mb-6">信用卡权益</h3>
  422. <div class="flex justify-between px-1">
  423. ${creditHtml}
  424. </div>
  425. ${data.hasDotsCredit ? `
  426. <div class="flex justify-center gap-2 mt-6">
  427. <div class="w-[5px] h-[5px] bg-black rounded-full"></div>
  428. <div class="w-[5px] h-[5px] border border-black rounded-full"></div>
  429. </div>` : ''}
  430. </div>
  431. `;
  432. if (data.hasAd) {
  433. html += `
  434. <div class="bg-white px-5 py-5 mb-2">
  435. <div class="w-full bg-gray-100 mb-4 h-[150px]">
  436. <img src="https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=800&auto=format&fit=crop" class="w-full h-full object-cover">
  437. </div>
  438. <h4 class="text-[18px] text-gray-900 font-medium mb-1.5">文案文案文案文案</h4>
  439. <p class="text-[13px] text-gray-500">报名参加汇丰活动,体验更多精彩礼遇</p>
  440. </div>
  441. `;
  442. }
  443. const isPointsExpanded = !['prospect', 'credit_only', 'advance'].includes(currentUserLevel);
  444. html += `
  445. <div class="bg-white px-5 py-5 pb-8">
  446. <div class="flex justify-between items-center mb-5">
  447. <h3 class="text-[16px] font-medium text-gray-900">积分商城</h3>
  448. <div class="text-[13px] text-gray-900 font-medium flex items-center">进入积分商城 <svg class="w-4 h-4 ml-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 18l6-6-6-6"/></svg></div>
  449. </div>
  450. <div class="flex justify-between items-center py-2 cursor-pointer border-b border-transparent" onclick="togglePoints()">
  451. <div>
  452. <div class="text-[20px] font-medium text-gray-800">3,000,000</div>
  453. <div class="text-[12px] text-gray-400 mt-1">我的总积分</div>
  454. </div>
  455. <svg id="points-chevron" class="w-5 h-5 text-gray-500 transition-transform duration-300 ${isPointsExpanded ? 'rotate-180' : ''}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/></svg>
  456. </div>
  457. <div id="points-details" class="overflow-hidden transition-all duration-300 ${isPointsExpanded ? 'h-[120px]' : 'h-0'}">
  458. <div class="border-t border-gray-100 pt-4 mt-2 text-[13px] space-y-4 pb-2">
  459. <div class="flex justify-between text-gray-600"><span>汇友荟积分</span><span class="font-medium text-gray-800">9,000 积分</span></div>
  460. <div class="flex justify-between text-gray-600"><span>信用卡积分</span><span class="font-medium text-gray-800">9,000 积分</span></div>
  461. <div class="flex justify-between text-gray-600"><span>2025年5月24日到期积分</span><span class="font-medium text-gray-800">5,000 积分</span></div>
  462. </div>
  463. </div>
  464. <div class="mt-6">
  465. <div class="flex justify-between items-center mb-4">
  466. <h3 class="text-[16px] font-medium text-gray-900">常用兑换</h3>
  467. <div class="text-[13px] text-gray-800 flex items-center font-medium">${icons.doc}积分明细</div>
  468. </div>
  469. <div class="flex overflow-x-auto no-scrollbar gap-3 pb-2 snap-x" onscroll="handleCarouselScroll(this, 'exchange-dots')">
  470. <div class="min-w-[100px] bg-white border border-gray-200 rounded-sm flex flex-col items-center snap-start shadow-sm">
  471. <div class="w-full h-[65px] bg-[#f7fbff] flex items-center justify-center">${icons.planeRed}</div>
  472. <div class="text-[13px] text-gray-700 py-2.5">航空里程</div>
  473. </div>
  474. <div class="min-w-[100px] bg-white border border-gray-200 rounded-sm flex flex-col items-center snap-start shadow-sm">
  475. <div class="w-full h-[65px] bg-[#fffaf5] flex items-center justify-center">${icons.coffee}</div>
  476. <div class="text-[13px] text-gray-700 py-2.5">贵宾厅</div>
  477. </div>
  478. <div class="min-w-[100px] bg-white border border-gray-200 rounded-sm flex flex-col items-center snap-start shadow-sm">
  479. <div class="w-full h-[65px] bg-[#fffdf5] flex items-center justify-center"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#d5aa11" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 12 10s-6.7.6-8.5 1.1C2.7 11.3 2 12.1 2 13v3c0 .6.4 1 1 1h2"/><rect width="16" height="8" x="4" y="10" rx="2"/><path d="M7 14h.01"/><path d="M17 14h.01"/><path d="m10 10-1.5-4h7l-1.5 4"/></svg></div>
  480. <div class="text-[13px] text-gray-700 py-2.5">礼宾接送机</div>
  481. </div>
  482. <div class="min-w-[100px] bg-white border border-gray-200 rounded-sm flex flex-col items-center snap-start shadow-sm">
  483. <div class="w-full h-[65px] bg-[#f9fafb] flex items-center justify-center"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#666" stroke-width="1.5"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg></div>
  484. <div class="text-[13px] text-gray-700 py-2.5">年费</div>
  485. </div>
  486. </div>
  487. <div class="flex justify-center gap-2 mt-3" id="exchange-dots">
  488. <div class="w-[5px] h-[5px] bg-black rounded-full transition-colors"></div>
  489. <div class="w-[5px] h-[5px] border border-black rounded-full transition-colors"></div>
  490. </div>
  491. <div class="flex justify-end mt-6">
  492. <div class="text-[12px] text-gray-900 font-medium flex items-center cursor-pointer" onclick="openRuleModal()">${icons.doc} 积分规则</div>
  493. </div>
  494. </div>
  495. </div>
  496. `;
  497. container.innerHTML = html;
  498. }
  499. function switchTab(tabId) {
  500. currentActiveTab = tabId;
  501. renderHomePage();
  502. }
  503. function setUserLevel(level) {
  504. currentUserLevel = level;
  505. const basicLevels = ['prospect', 'credit_only', 'advance'];
  506. currentActiveTab = basicLevels.includes(level) ? 'premier' : level;
  507. renderHomePage();
  508. updateControlPanelUI();
  509. if(document.getElementById('zone-view').classList.contains('translate-x-0')) {
  510. renderZonePage();
  511. }
  512. if (isSimPanelOpen) toggleSimPanel();
  513. }
  514. function showZone() {
  515. renderZonePage();
  516. const homeView = document.getElementById('home-view');
  517. const zoneView = document.getElementById('zone-view');
  518. homeView.classList.remove('translate-x-0');
  519. homeView.classList.add('-translate-x-full');
  520. zoneView.classList.remove('translate-x-full');
  521. zoneView.classList.add('translate-x-0');
  522. }
  523. function hideZone() {
  524. const homeView = document.getElementById('home-view');
  525. const zoneView = document.getElementById('zone-view');
  526. homeView.classList.remove('-translate-x-full');
  527. homeView.classList.add('translate-x-0');
  528. zoneView.classList.remove('translate-x-0');
  529. zoneView.classList.add('translate-x-full');
  530. }
  531. function openRuleModal() {
  532. document.getElementById('rule-modal-backdrop').classList.remove('opacity-0', 'pointer-events-none');
  533. document.getElementById('rule-modal').classList.remove('translate-y-full');
  534. }
  535. function closeRuleModal() {
  536. document.getElementById('rule-modal-backdrop').classList.add('opacity-0', 'pointer-events-none');
  537. document.getElementById('rule-modal').classList.add('translate-y-full');
  538. }
  539. function openBalanceRuleModal() {
  540. document.getElementById('balance-rule-modal-backdrop').classList.remove('opacity-0', 'pointer-events-none');
  541. document.getElementById('balance-rule-modal').classList.remove('translate-y-full');
  542. }
  543. function closeBalanceRuleModal() {
  544. document.getElementById('balance-rule-modal-backdrop').classList.add('opacity-0', 'pointer-events-none');
  545. document.getElementById('balance-rule-modal').classList.add('translate-y-full');
  546. }
  547. function togglePoints() {
  548. const details = document.getElementById('points-details');
  549. const chevron = document.getElementById('points-chevron');
  550. if (details.classList.contains('h-0')) {
  551. details.classList.remove('h-0');
  552. details.classList.add('h-[120px]');
  553. chevron.style.transform = 'rotate(180deg)';
  554. } else {
  555. details.classList.remove('h-[120px]');
  556. details.classList.add('h-0');
  557. chevron.style.transform = 'rotate(0deg)';
  558. }
  559. }
  560. function handleCarouselScroll(ele, dotsContainerId) {
  561. const index = Math.round(ele.scrollLeft / ele.clientWidth);
  562. const dots = document.getElementById(dotsContainerId)?.children;
  563. if(!dots) return;
  564. for(let i=0; i<dots.length; i++) {
  565. dots[i].className = (i === index)
  566. ? "w-[5px] h-[5px] rounded-full bg-black transition-colors"
  567. : "w-[5px] h-[5px] rounded-full border border-black transition-colors";
  568. }
  569. }
  570. function updateControlPanelUI() {
  571. const levels = ['prospect', 'credit_only', 'advance', 'premier', 'elite', 'global'];
  572. levels.forEach(lvl => {
  573. const btn = document.getElementById(`btn-state-${lvl}`);
  574. if (lvl === currentUserLevel) {
  575. btn.className = 'px-2 py-1.5 rounded bg-[#d70014] text-white transition font-medium';
  576. } else {
  577. btn.className = 'px-2 py-1.5 rounded bg-gray-100 text-gray-700 hover:bg-gray-200 transition';
  578. }
  579. });
  580. }
  581. let isSimPanelOpen = false;
  582. function toggleSimPanel() {
  583. isSimPanelOpen = !isSimPanelOpen;
  584. const panel = document.getElementById('sim-panel');
  585. if(isSimPanelOpen) {
  586. panel.classList.remove('scale-0', 'opacity-0', 'pointer-events-none');
  587. panel.classList.add('scale-100', 'opacity-100');
  588. } else {
  589. panel.classList.remove('scale-100', 'opacity-100');
  590. panel.classList.add('scale-0', 'opacity-0', 'pointer-events-none');
  591. }
  592. }
  593. </script>
  594. </body>
  595. </html>