signup.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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">
  6. <script src="https://cdn.tailwindcss.com"></script>
  7. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
  8. <script>
  9. tailwind.config = {
  10. theme: {
  11. extend: {
  12. colors: {
  13. primary: '#3372ac',
  14. }
  15. }
  16. }
  17. }
  18. </script>
  19. <style>
  20. @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700;800&display=swap');
  21. body { font-family: 'Nunito', sans-serif; }
  22. .no-scrollbar::-webkit-scrollbar { display: none; }
  23. .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
  24. .snap-mandatory { scroll-behavior: smooth; }
  25. .dropdown-enter {
  26. opacity: 0;
  27. transform: translateY(-10px) scale(0.95);
  28. }
  29. .dropdown-enter-active {
  30. opacity: 1;
  31. transform: translateY(0) scale(1);
  32. transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  33. }
  34. </style>
  35. </head>
  36. <body class="bg-slate-50 relative pb-24" onclick="closeDropdownOnClickOutside(event)">
  37. <!-- 1. 顶部 Header -->
  38. <div class="relative w-full h-[260px]">
  39. <img src="https://orienteering.beswell.com/card/nanning/cardtop1122-2.jpg"
  40. class="w-full h-full object-cover shadow-md" alt="Header BG">
  41. <div class="absolute inset-0 bg-gradient-to-b from-primary/60 via-transparent to-black/5"></div>
  42. <div class="absolute top-0 w-full pt-10 px-5 flex justify-between items-center z-10 text-white">
  43. <button class="bg-black/20 backdrop-blur-sm p-2 rounded-full w-9 h-9 flex items-center justify-center active:scale-90 transition">
  44. <i class="fas fa-chevron-left"></i>
  45. </button>
  46. <h1 class="text-lg font-bold tracking-wider shadow-sm">赛事报名</h1>
  47. <button onclick="openModal()" class="bg-black/20 backdrop-blur-sm px-3 py-1.5 rounded-full text-xs font-semibold flex items-center gap-1 active:scale-90 transition">
  48. <i class="fas fa-question-circle"></i> 说明
  49. </button>
  50. </div>
  51. </div>
  52. <!-- 2. 主体内容 -->
  53. <div class="relative z-20 px-4">
  54. <!-- A. 比赛时间 (字体已放大 text-xs -> text-sm) -->
  55. <div class="bg-white rounded-full shadow-lg py-2 px-4 -mt-6 mb-5 mx-2 flex items-center justify-between border border-white/60 relative z-30">
  56. <!-- 这里将 text-xs 改为了 text-sm -->
  57. <div class="flex items-center gap-2 w-full text-sm overflow-hidden whitespace-nowrap">
  58. <div class="bg-blue-50 text-primary w-6 h-6 rounded-full flex items-center justify-center shrink-0">
  59. <i class="fas fa-clock text-xs"></i>
  60. </div>
  61. <!-- 删除了 scale-90,保持原大 -->
  62. <span class="text-gray-400 font-bold uppercase origin-left shrink-0">比赛时间</span>
  63. <span class="text-gray-300">|</span>
  64. <span class="font-bold text-gray-800 font-mono truncate">11.28 08:00 - 11.30 18:00</span>
  65. </div>
  66. </div>
  67. <!-- B. 报名表单 -->
  68. <div class="bg-white rounded-xl shadow-sm p-5 mb-5 space-y-5 relative z-40">
  69. <!-- 昵称行 -->
  70. <div class="flex items-center gap-3">
  71. <label class="w-16 text-sm font-bold text-gray-500 text-right">报名昵称</label>
  72. <input type="text" id="userName" placeholder="请输入您的昵称"
  73. class="flex-1 bg-slate-50 rounded-lg px-3 py-2.5 text-sm focus:outline-none focus:bg-blue-50 focus:ring-1 focus:ring-primary/50 transition-all text-gray-800 font-bold placeholder-gray-400">
  74. </div>
  75. <!-- 战队行 -->
  76. <div class="flex items-center gap-3 relative">
  77. <label class="w-16 text-sm font-bold text-gray-500 text-right">选择战队</label>
  78. <div class="relative flex-1 group">
  79. <button type="button" id="dropdownBtn" onclick="toggleDropdown(event)"
  80. class="w-full bg-slate-50 rounded-lg px-3 py-2.5 text-sm font-bold text-left flex items-center justify-between focus:outline-none focus:ring-1 focus:ring-primary/50 transition-all active:bg-blue-50">
  81. <span id="selectedText" class="text-gray-400 font-normal flex items-center">
  82. 请选择或搜索...
  83. </span>
  84. <i class="fas fa-chevron-circle-down text-primary/70 transition-transform duration-300" id="dropdownArrow"></i>
  85. </button>
  86. <input type="hidden" id="teamSelect" value="">
  87. <div id="dropdownMenu" class="hidden absolute top-[110%] left-0 w-full bg-white rounded-xl shadow-2xl border border-gray-100 overflow-hidden origin-top z-50 dropdown-enter">
  88. <ul class="text-sm text-gray-700 max-h-48 overflow-y-auto no-scrollbar">
  89. <li onclick="selectOption('飞虎队', '飞虎队')" class="px-4 py-3 hover:bg-blue-50 cursor-pointer flex items-center justify-between border-b border-gray-50 last:border-0 transition-colors group/item">
  90. <div class="flex items-center">
  91. <i class="fas fa-user-friends text-blue-200 mr-2 group-hover/item:text-primary transition-colors"></i>
  92. <span class="font-bold">飞虎队 (兴隆山)</span>
  93. </div>
  94. <i class="fas fa-check text-primary opacity-0 check-icon"></i>
  95. </li>
  96. <li onclick="selectOption('火箭队', '火箭队')" class="px-4 py-3 hover:bg-blue-50 cursor-pointer flex items-center justify-between border-b border-gray-50 last:border-0 transition-colors group/item">
  97. <div class="flex items-center">
  98. <i class="fas fa-user-friends text-blue-200 mr-2 group-hover/item:text-primary transition-colors"></i>
  99. <span class="font-bold">火箭队 (中心校区)</span>
  100. </div>
  101. <i class="fas fa-check text-primary opacity-0 check-icon"></i>
  102. </li>
  103. <li onclick="selectOption('摸鱼队', '摸鱼队')" class="px-4 py-3 hover:bg-blue-50 cursor-pointer flex items-center justify-between border-b border-gray-50 last:border-0 transition-colors group/item">
  104. <div class="flex items-center">
  105. <i class="fas fa-user-friends text-blue-200 mr-2 group-hover/item:text-primary transition-colors"></i>
  106. <span class="font-bold">摸鱼队 (快乐组)</span>
  107. </div>
  108. <i class="fas fa-check text-primary opacity-0 check-icon"></i>
  109. </li>
  110. <li onclick="selectOption('汪汪队', '汪汪队')" class="px-4 py-3 hover:bg-blue-50 cursor-pointer flex items-center justify-between transition-colors group/item">
  111. <div class="flex items-center">
  112. <i class="fas fa-user-friends text-blue-200 mr-2 group-hover/item:text-primary transition-colors"></i>
  113. <span class="font-bold">汪汪队 (教职工)</span>
  114. </div>
  115. <i class="fas fa-check text-primary opacity-0 check-icon"></i>
  116. </li>
  117. </ul>
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. <!-- C. 赛事介绍 -->
  123. <div class="bg-white rounded-xl shadow-sm p-5 pb-8 relative z-10">
  124. <h3 class="font-bold text-base text-primary mb-4 flex items-center gap-2">
  125. <span class="w-1 h-4 bg-primary rounded-full"></span> 赛事介绍
  126. </h3>
  127. <div class="text-xs text-gray-600 space-y-3 leading-relaxed">
  128. <p class="font-bold text-sm text-gray-900 border-b border-gray-100 pb-2">
  129. 南宁学院40周年校庆 (暨「智跑南院」数字定向赛)
  130. </p>
  131. <div class="space-y-2">
  132. <div class="flex flex-col sm:flex-row gap-1">
  133. <span class="font-bold text-primary shrink-0">一、主办单位 /</span>
  134. <span class="text-gray-700">共青团南宁学院委员会、教育学院</span>
  135. </div>
  136. <div class="flex flex-col sm:flex-row gap-1">
  137. <span class="font-bold text-primary shrink-0">二、承办单位 /</span>
  138. <span class="text-gray-700">各二级学院团委</span>
  139. </div>
  140. <div class="flex flex-col sm:flex-row gap-1">
  141. <span class="font-bold text-primary shrink-0">三、协办单位 /</span>
  142. <span class="text-gray-700">南宁学院学生会、青年志愿者协会、教育学院大学生竞技中心、教育学院大学生运动健康促进中心</span>
  143. </div>
  144. <div class="flex flex-col sm:flex-row gap-1">
  145. <span class="font-bold text-primary shrink-0">四、参赛人员 /</span>
  146. <span class="text-gray-700">全校在校学生</span>
  147. </div>
  148. <div class="flex flex-col sm:flex-row gap-1">
  149. <span class="font-bold text-primary shrink-0">五、赞助单位 /</span>
  150. <span class="text-gray-700">一食堂三楼广西桂师傅餐饮管理有限公司</span>
  151. </div>
  152. </div>
  153. <div class="text-right mt-4 pt-2 font-bold text-primary opacity-90">
  154. 共青团南宁学院委员会
  155. </div>
  156. </div>
  157. </div>
  158. </div>
  159. <!-- 底部按钮 -->
  160. <div class="fixed bottom-0 w-full bg-white px-4 py-3 shadow-[0_-4px_15px_rgba(0,0,0,0.05)] z-50">
  161. <button onclick="openConfirm()" class="w-full bg-gradient-to-r from-orange-500 to-red-600 text-white font-bold text-lg py-2.5 rounded-full shadow-lg shadow-orange-100 active:scale-[0.98] transition-transform flex items-center justify-center gap-2">
  162. 立即报名 <i class="fas fa-paper-plane text-sm"></i>
  163. </button>
  164. </div>
  165. <!-- 说明模态框 -->
  166. <div id="infoModal" class="fixed inset-0 z-50 hidden transition-opacity duration-300">
  167. <div class="absolute inset-0 bg-slate-900/70 backdrop-blur-sm" onclick="closeModal()"></div>
  168. <div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-[90%] bg-white rounded-3xl p-6 shadow-2xl">
  169. <button onclick="closeModal()" class="absolute -top-12 right-0 text-white/80 hover:text-white w-10 h-10 border border-white/30 rounded-full flex items-center justify-center">
  170. <i class="fas fa-times text-lg"></i>
  171. </button>
  172. <h3 class="text-center font-bold text-xl mb-4 text-primary border-b border-gray-100 pb-3">
  173. <i class="fas fa-book-open mr-2"></i>比赛规则说明
  174. </h3>
  175. <div id="modalSlider" class="overflow-x-auto flex snap-x snap-mandatory no-scrollbar space-x-4 pb-2" onscroll="updateDots()">
  176. <!-- Slides... -->
  177. <div class="snap-center shrink-0 w-full bg-blue-50 rounded-2xl p-5 text-center border border-blue-100">
  178. <div class="w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-3">
  179. <i class="fas fa-map-marker-alt text-xl text-primary"></i>
  180. </div>
  181. <h4 class="font-bold text-base text-gray-800 mb-1">1. 定向寻宝</h4>
  182. <p class="text-gray-600 text-xs leading-relaxed">比赛设置12个隐藏打卡点,根据地图指引,规划最佳路线。</p>
  183. </div>
  184. <div class="snap-center shrink-0 w-full bg-blue-50 rounded-2xl p-5 text-center border border-blue-100">
  185. <div class="w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-3">
  186. <i class="fas fa-mobile-alt text-xl text-primary"></i>
  187. </div>
  188. <h4 class="font-bold text-base text-gray-800 mb-1">2. 扫码打卡</h4>
  189. <p class="text-gray-600 text-xs leading-relaxed">到达点位后,使用APP扫描二维码,系统自动记录时间。</p>
  190. </div>
  191. <div class="snap-center shrink-0 w-full bg-blue-50 rounded-2xl p-5 text-center border border-blue-100">
  192. <div class="w-12 h-12 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-3">
  193. <i class="fas fa-medal text-xl text-primary"></i>
  194. </div>
  195. <h4 class="font-bold text-base text-gray-800 mb-1">3. 完赛奖励</h4>
  196. <p class="text-gray-600 text-xs leading-relaxed">规定时间内完赛,前50名有精美礼品!加油!</p>
  197. </div>
  198. </div>
  199. <div class="flex justify-center gap-2 mt-4" id="dotsContainer">
  200. <div class="dot w-6 h-1.5 rounded-full bg-primary transition-all duration-300"></div>
  201. <div class="dot w-1.5 h-1.5 rounded-full bg-gray-300 transition-all duration-300"></div>
  202. <div class="dot w-1.5 h-1.5 rounded-full bg-gray-300 transition-all duration-300"></div>
  203. </div>
  204. </div>
  205. </div>
  206. <!-- 确认模态框 -->
  207. <div id="confirmModal" class="fixed inset-0 z-50 hidden flex items-center justify-center">
  208. <div class="absolute inset-0 bg-slate-900/60 backdrop-blur-sm" onclick="closeConfirm()"></div>
  209. <div class="bg-white w-[80%] rounded-2xl p-6 relative z-10 text-center shadow-xl">
  210. <div class="w-14 h-14 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
  211. <i class="fas fa-check text-2xl text-green-600"></i>
  212. </div>
  213. <h3 class="font-bold text-lg mb-2 text-gray-800">确认提交报名?</h3>
  214. <div class="bg-slate-50 rounded-lg p-4 mb-6 text-left border border-slate-100">
  215. <p class="mb-2"><span class="text-gray-500 text-sm">昵称:</span><span class="font-bold text-gray-800 ml-2" id="confirmName"></span></p>
  216. <p><span class="text-gray-500 text-sm">战队:</span><span class="font-bold text-primary ml-2" id="confirmTeamText"></span></p>
  217. </div>
  218. <div class="flex gap-3">
  219. <button onclick="closeConfirm()" class="flex-1 py-2.5 rounded-lg border border-gray-200 text-gray-600 font-bold text-sm">再想想</button>
  220. <button onclick="location.href='#'" class="flex-1 py-2.5 rounded-lg bg-gradient-to-r from-orange-500 to-red-600 text-white font-bold text-sm shadow-md">确认提交</button>
  221. </div>
  222. </div>
  223. </div>
  224. <script>
  225. const dropdownMenu = document.getElementById('dropdownMenu');
  226. const dropdownArrow = document.getElementById('dropdownArrow');
  227. const selectedText = document.getElementById('selectedText');
  228. const teamInput = document.getElementById('teamSelect');
  229. const checkIcons = document.querySelectorAll('.check-icon');
  230. function toggleDropdown(event) {
  231. event.stopPropagation();
  232. const isHidden = dropdownMenu.classList.contains('hidden');
  233. if (isHidden) {
  234. dropdownMenu.classList.remove('hidden');
  235. setTimeout(() => dropdownMenu.classList.add('dropdown-enter-active'), 10);
  236. dropdownArrow.style.transform = 'rotate(180deg)';
  237. } else {
  238. closeDropdown();
  239. }
  240. }
  241. function closeDropdown() {
  242. dropdownMenu.classList.remove('dropdown-enter-active');
  243. dropdownArrow.style.transform = 'rotate(0deg)';
  244. setTimeout(() => dropdownMenu.classList.add('hidden'), 200);
  245. }
  246. function selectOption(value, text) {
  247. teamInput.value = value;
  248. selectedText.innerHTML = '<i class="fas fa-user-friends text-primary mr-2"></i>' + text;
  249. selectedText.classList.remove('text-gray-400', 'font-normal');
  250. selectedText.classList.add('text-gray-800', 'font-bold');
  251. checkIcons.forEach(icon => icon.classList.add('opacity-0'));
  252. event.currentTarget.querySelector('.check-icon').classList.remove('opacity-0');
  253. closeDropdown();
  254. }
  255. function closeDropdownOnClickOutside(event) {
  256. if (!dropdownMenu.contains(event.target) && event.target.id !== 'dropdownBtn') {
  257. closeDropdown();
  258. }
  259. }
  260. function openModal() { document.getElementById('infoModal').classList.remove('hidden'); }
  261. function closeModal() { document.getElementById('infoModal').classList.add('hidden'); }
  262. function openConfirm() {
  263. const name = document.getElementById('userName').value || "未填写";
  264. const team = document.getElementById('teamSelect').value || "";
  265. const teamDisplay = document.getElementById('selectedText').innerText;
  266. document.getElementById('confirmName').innerText = name;
  267. document.getElementById('confirmTeamText').innerText = team === "" ? "未选择" : teamDisplay;
  268. document.getElementById('confirmModal').classList.remove('hidden');
  269. }
  270. function closeConfirm() { document.getElementById('confirmModal').classList.add('hidden'); }
  271. const slider = document.getElementById('modalSlider');
  272. const dots = document.querySelectorAll('.dot');
  273. function updateDots() {
  274. const index = Math.round(slider.scrollLeft / slider.offsetWidth);
  275. dots.forEach((dot, i) => {
  276. if (i === index) {
  277. dot.classList.remove('w-1.5', 'bg-gray-300');
  278. dot.classList.add('w-6', 'bg-primary');
  279. } else {
  280. dot.classList.remove('w-6', 'bg-primary');
  281. dot.classList.add('w-1.5', 'bg-gray-300');
  282. }
  283. });
  284. }
  285. </script>
  286. </body>
  287. </html>