同趣U.html 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  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. <title>大学生兴趣伙伴 App - 页面预览</title>
  7. <style>
  8. body {
  9. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  10. margin: 0;
  11. padding: 0;
  12. background-color: #f0f2f5;
  13. display: flex;
  14. justify-content: center;
  15. align-items: flex-start; /* Align items to the top */
  16. padding-top: 20px; /* Add some top padding */
  17. padding-bottom: 100px; /* Add padding to see all content */
  18. }
  19. .phone-mockup {
  20. width: 375px; /* Typical phone width */
  21. height: 750px; /* Typical phone height */
  22. border: 10px solid #333;
  23. border-radius: 40px;
  24. background-color: #fff;
  25. box-shadow: 0 10px 30px rgba(0,0,0,0.2);
  26. position: relative; /* Needed for absolute positioning of header/footer */
  27. overflow: hidden; /* Hide content that overflows */
  28. display: flex;
  29. flex-direction: column;
  30. }
  31. .app-header {
  32. background-color: #007bff;
  33. color: white;
  34. padding: 15px;
  35. text-align: center;
  36. font-weight: bold;
  37. font-size: 1.1em;
  38. flex-shrink: 0; /* Prevent header from shrinking */
  39. position: sticky; /* Keep header visible when scrolling content */
  40. top: 0;
  41. z-index: 10;
  42. display: flex;
  43. align-items: center;
  44. justify-content: space-between; /* Align items */
  45. }
  46. .app-header .icon, .app-header .back-button {
  47. color: white;
  48. text-decoration: none;
  49. font-size: 1.2em;
  50. padding: 0 10px;
  51. }
  52. .app-header .back-button {
  53. font-size: 1.5em; /* Make back arrow slightly larger */
  54. }
  55. .app-content {
  56. flex-grow: 1; /* Allow content to fill available space */
  57. overflow-y: auto; /* Enable scrolling for content */
  58. padding: 15px;
  59. }
  60. .app-footer {
  61. display: flex;
  62. justify-content: space-around;
  63. padding: 10px 0;
  64. border-top: 1px solid #eee;
  65. background-color: #fff;
  66. flex-shrink: 0; /* Prevent footer from shrinking */
  67. position: sticky; /* Keep footer visible */
  68. bottom: 0;
  69. z-index: 10;
  70. }
  71. .tab-item {
  72. text-align: center;
  73. color: #888;
  74. text-decoration: none;
  75. font-size: 0.8em;
  76. }
  77. .tab-item.active {
  78. color: #007bff;
  79. }
  80. .tab-item span { /* Icon placeholder */
  81. display: block;
  82. font-size: 1.5em;
  83. margin-bottom: 3px;
  84. }
  85. /* Basic Element Styles */
  86. h2, h3 { margin-top: 10px; margin-bottom: 10px; color: #333; }
  87. p { color: #555; line-height: 1.5; margin-bottom: 10px; }
  88. button, .button-link {
  89. display: inline-block;
  90. padding: 10px 15px;
  91. background-color: #007bff;
  92. color: white;
  93. border: none;
  94. border-radius: 20px;
  95. cursor: pointer;
  96. text-align: center;
  97. font-size: 0.9em;
  98. margin: 5px 0;
  99. text-decoration: none;
  100. }
  101. button:hover, .button-link:hover { background-color: #0056b3; }
  102. button.secondary, .button-link.secondary { background-color: #6c757d; }
  103. button.secondary:hover, .button-link.secondary:hover { background-color: #5a6268; }
  104. button.outline, .button-link.outline { background-color: transparent; border: 1px solid #007bff; color: #007bff; }
  105. button.outline:hover, .button-link.outline:hover { background-color: rgba(0, 123, 255, 0.1); }
  106. input[type="text"], input[type="password"], input[type="email"], textarea, select {
  107. width: calc(100% - 22px); /* Adjust for padding and border */
  108. padding: 10px;
  109. margin-bottom: 10px;
  110. border: 1px solid #ccc;
  111. border-radius: 5px;
  112. font-size: 1em;
  113. }
  114. textarea { height: 80px; resize: vertical; }
  115. /* Component Styles */
  116. .card {
  117. background-color: #fff;
  118. border: 1px solid #eee;
  119. border-radius: 8px;
  120. padding: 15px;
  121. margin-bottom: 15px;
  122. box-shadow: 0 2px 5px rgba(0,0,0,0.05);
  123. }
  124. .user-card, .message-item, .group-item, .event-item, .notification-item, .skill-item {
  125. display: flex;
  126. align-items: center;
  127. margin-bottom: 15px;
  128. padding-bottom: 10px;
  129. border-bottom: 1px solid #f0f0f0;
  130. }
  131. .user-card:last-child, .message-item:last-child, .group-item:last-child, .event-item:last-child, .notification-item:last-child, .skill-item:last-child {
  132. border-bottom: none;
  133. margin-bottom: 0;
  134. padding-bottom: 0;
  135. }
  136. .avatar {
  137. width: 50px;
  138. height: 50px;
  139. border-radius: 50%;
  140. background-color: #e0e0e0;
  141. margin-right: 15px;
  142. object-fit: cover; /* Make images fit well */
  143. flex-shrink: 0;
  144. }
  145. .content-details { flex-grow: 1; }
  146. .content-details h3 { margin: 0 0 5px 0; font-size: 1em; }
  147. .content-details p { margin: 0; font-size: 0.9em; color: #777; }
  148. .user-card .actions { margin-left: auto; }
  149. .interest-tag {
  150. display: inline-block;
  151. background-color: #e7f3ff;
  152. color: #007bff;
  153. padding: 3px 8px;
  154. border-radius: 15px;
  155. font-size: 0.8em;
  156. margin: 2px;
  157. border: 1px solid #cce5ff;
  158. }
  159. .interest-category h3 { font-size: 1em; margin-bottom: 5px; border-bottom: 1px solid #eee; padding-bottom: 5px;}
  160. .interest-category .tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 15px;}
  161. .interest-category .tag-button {
  162. background-color: #f0f0f0;
  163. border: 1px solid #ddd;
  164. color: #555;
  165. padding: 5px 10px;
  166. border-radius: 15px;
  167. font-size: 0.9em;
  168. cursor: pointer;
  169. }
  170. .interest-category .tag-button.selected {
  171. background-color: #007bff;
  172. color: white;
  173. border-color: #007bff;
  174. }
  175. .chat-bubble {
  176. max-width: 75%;
  177. padding: 10px 15px;
  178. border-radius: 18px;
  179. margin-bottom: 10px;
  180. line-height: 1.4;
  181. word-wrap: break-word;
  182. }
  183. .chat-bubble.sent {
  184. background-color: #007bff;
  185. color: white;
  186. margin-left: auto;
  187. border-bottom-right-radius: 5px;
  188. }
  189. .chat-bubble.received {
  190. background-color: #e9ecef;
  191. color: #333;
  192. margin-right: auto;
  193. border-bottom-left-radius: 5px;
  194. }
  195. .chat-input {
  196. display: flex;
  197. padding: 10px;
  198. border-top: 1px solid #eee;
  199. background: #f8f9fa;
  200. }
  201. .chat-input input { flex-grow: 1; margin-right: 10px; margin-bottom: 0; }
  202. .profile-header { text-align: center; margin-bottom: 20px; }
  203. .profile-header .avatar { width: 100px; height: 100px; margin: 0 auto 10px auto; }
  204. .profile-header h2 { margin: 5px 0; }
  205. .profile-header p { color: #666; font-size: 0.9em; }
  206. .section-title { font-weight: bold; margin-top: 20px; margin-bottom: 10px; border-bottom: 1px solid #eee; padding-bottom: 5px;}
  207. .map-placeholder {
  208. width: 100%;
  209. height: 300px;
  210. background-color: #e0e0e0;
  211. display: flex;
  212. justify-content: center;
  213. align-items: center;
  214. color: #999;
  215. font-style: italic;
  216. text-align: center;
  217. border-radius: 8px;
  218. border: 1px dashed #ccc;
  219. position: relative;
  220. }
  221. .map-placeholder::after { /* Simple pin example */
  222. content: '📍';
  223. font-size: 2em;
  224. position: absolute;
  225. top: 40%;
  226. left: 50%;
  227. transform: translate(-50%, -50%);
  228. }
  229. .map-placeholder p { padding: 0 20px;}
  230. /* Hide all pages initially */
  231. .app-page { display: none; }
  232. /* Show the default page (Home) */
  233. #page-home { display: block; }
  234. </style>
  235. </head>
  236. <body>
  237. <div class="phone-mockup">
  238. <!-- Dynamic Header will be controlled by JS in a real app -->
  239. <!-- Placeholder Header -->
  240. <div class="app-header" id="app-header">
  241. <!-- Content changes based on active page -->
  242. </div>
  243. <!-- Content Area: Contains all pages -->
  244. <div class="app-content">
  245. <!-- PAGE: Home / Feed -->
  246. <div class="app-page" id="page-home">
  247. <script>document.getElementById('app-header').innerHTML = '<span>兴趣伙伴</span><a href="#page-notifications" class="icon">🔔</a>';</script>
  248. <h2>为你推荐</h2>
  249. <div class="card user-card">
  250. <img src="https://via.placeholder.com/50/FFA500/FFFFFF?text=U1" alt="User Avatar" class="avatar">
  251. <div class="content-details">
  252. <h3>张伟 <span style="font-size: 0.8em; color: #777;">(北京大学)</span></h3>
  253. <p>共同兴趣: <span class="interest-tag">摄影</span> <span class="interest-tag">爬山</span></p>
  254. <p style="font-size: 0.8em; color: #999;">"周末想找人一起去奥森拍照~"</p>
  255. </div>
  256. <div class="actions">
  257. <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">打招呼</a>
  258. </div>
  259. </div>
  260. <div class="card user-card">
  261. <img src="https://via.placeholder.com/50/4682B4/FFFFFF?text=U2" alt="User Avatar" class="avatar">
  262. <div class="content-details">
  263. <h3>李静 <span style="font-size: 0.8em; color: #777;">(清华大学)</span></h3>
  264. <p>共同兴趣: <span class="interest-tag">日语学习</span> <span class="interest-tag">看动漫</span></p>
  265. <p style="font-size: 0.8em; color: #999;">"寻找N1备考伙伴,互相监督!"</p>
  266. </div>
  267. <div class="actions">
  268. <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">打招呼</a>
  269. </div>
  270. </div>
  271. <div class="card user-card">
  272. <img src="https://via.placeholder.com/50/32CD32/FFFFFF?text=U3" alt="User Avatar" class="avatar">
  273. <div class="content-details">
  274. <h3>王磊 <span style="font-size: 0.8em; color: #777;">(人民大学)</span></h3>
  275. <p>共同兴趣: <span class="interest-tag">篮球</span> <span class="interest-tag">说唱音乐</span></p>
  276. <p style="font-size: 0.8em; color: #999;">"下午东操场3v3,来不来?"</p>
  277. </div>
  278. <div class="actions">
  279. <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">打招呼</a>
  280. </div>
  281. </div>
  282. <h2>附近的活动</h2>
  283. <div class="card event-item">
  284. <img src="https://via.placeholder.com/50/FF6347/FFFFFF?text=E" alt="Event Icon" class="avatar" style="border-radius: 8px;">
  285. <div class="content-details">
  286. <h3>周末狼人杀局</h3>
  287. <p>时间: 周六 14:00</p>
  288. <p>地点: 学校咖啡厅</p>
  289. </div>
  290. <div class="actions">
  291. <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">查看详情</a>
  292. </div>
  293. </div>
  294. </div>
  295. <!-- PAGE: Discover / Search -->
  296. <div class="app-page" id="page-discover">
  297. <script>document.getElementById('app-header').innerHTML = '<span>发现</span>';</script>
  298. <input type="text" placeholder="搜索用户、兴趣、小组、活动...">
  299. <button style="width: 100%; margin-bottom: 15px;">搜索</button>
  300. <h3>按兴趣浏览</h3>
  301. <div>
  302. <span class="interest-tag">摄影</span>
  303. <span class="interest-tag">篮球</span>
  304. <span class="interest-tag">吉他</span>
  305. <span class="interest-tag">Python</span>
  306. <span class="interest-tag">日语学习</span>
  307. <span class="interest-tag">电影</span>
  308. <span class="interest-tag">爬山</span>
  309. <span class="interest-tag">桌游</span>
  310. <a href="#page-interests" style="font-size: 0.9em; color: #007bff;">更多...</a>
  311. </div>
  312. <h3 style="margin-top: 20px;">推荐用户</h3>
  313. <!-- User cards like on home page -->
  314. <div class="card user-card">
  315. <img src="https://via.placeholder.com/50/8A2BE2/FFFFFF?text=U4" alt="User Avatar" class="avatar">
  316. <div class="content-details">
  317. <h3>赵敏 <span style="font-size: 0.8em; color: #777;">(北京师范大学)</span></h3>
  318. <p>兴趣: <span class="interest-tag">志愿者活动</span> <span class="interest-tag">阅读</span></p>
  319. </div>
  320. <div class="actions"> <a href="#page-profile-other" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">查看资料</a> </div>
  321. </div>
  322. <h3 style="margin-top: 20px;">热门小组</h3>
  323. <div class="card group-item">
  324. <img src="https://via.placeholder.com/50/FFD700/000000?text=G1" alt="Group Icon" class="avatar" style="border-radius: 8px;">
  325. <div class="content-details">
  326. <h3>北邮吉他社</h3>
  327. <p>128 成员 | 活跃度高</p>
  328. </div>
  329. <div class="actions"> <a href="#page-group-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">加入</a> </div>
  330. </div>
  331. <a href="#page-groups" class="button-link secondary" style="width: 100%; text-align: center; margin-top: 10px;">查看所有小组</a>
  332. <h3 style="margin-top: 20px;">推荐活动</h3>
  333. <div class="card event-item">
  334. <img src="https://via.placeholder.com/50/00CED1/FFFFFF?text=E2" alt="Event Icon" class="avatar" style="border-radius: 8px;">
  335. <div class="content-details">
  336. <h3>校园编程马拉松</h3>
  337. <p>时间: 下周五 9:00</p>
  338. <p>地点: 计算机学院楼</p>
  339. </div>
  340. <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">感兴趣</a> </div>
  341. </div>
  342. <a href="#page-events" class="button-link secondary" style="width: 100%; text-align: center; margin-top: 10px;">查看所有活动</a>
  343. <h3 style="margin-top: 20px;">技能交换</h3>
  344. <div class="card skill-item">
  345. <img src="https://via.placeholder.com/50/6495ED/FFFFFF?text=S1" alt="User Avatar" class="avatar">
  346. <div class="content-details">
  347. <h3>刘洋 <span style="font-size: 0.8em; color: #777;">(北京航空航天大学)</span></h3>
  348. <p><strong>提供:</strong> PPT美化 <span style="color: green;">|</span> <strong>需要:</strong> 英语口语练习</p>
  349. </div>
  350. <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
  351. </div>
  352. <a href="#page-skills" class="button-link secondary" style="width: 100%; text-align: center; margin-top: 10px;">查看技能交换</a>
  353. <h3 style="margin-top: 20px;">附近的人 (地图)</h3>
  354. <a href="#page-map" class="button-link" style="width: 100%; text-align: center;">查看地图模式</a>
  355. </div>
  356. <!-- PAGE: Messages List -->
  357. <div class="app-page" id="page-messages">
  358. <script>document.getElementById('app-header').innerHTML = '<span>消息</span><a href="#page-chat" class="icon">+</a>';</script>
  359. <div class="message-item">
  360. <img src="https://via.placeholder.com/50/4682B4/FFFFFF?text=U2" alt="User Avatar" class="avatar">
  361. <div class="content-details">
  362. <h3>李静</h3>
  363. <p>好的,那我们周二晚上图书馆见!</p>
  364. </div>
  365. <span style="font-size: 0.8em; color: #999; margin-left: auto;">10:35</span>
  366. </div>
  367. <div class="message-item">
  368. <img src="https://via.placeholder.com/50/FFA500/FFFFFF?text=U1" alt="User Avatar" class="avatar">
  369. <div class="content-details">
  370. <h3>张伟</h3>
  371. <p>[图片]</p>
  372. </div>
  373. <span style="font-size: 0.8em; color: #999; margin-left: auto;">昨天</span>
  374. </div>
  375. <div class="message-item">
  376. <img src="https://via.placeholder.com/50/FFD700/000000?text=G1" alt="Group Icon" class="avatar" style="border-radius: 8px;">
  377. <div class="content-details">
  378. <h3>北邮吉他社 (群)</h3>
  379. <p>@所有人 周五晚上有迎新演出!</p>
  380. </div>
  381. <span style="font-size: 0.8em; color: red; background: red; color: white; border-radius: 50%; padding: 2px 6px; margin-left: auto;">3</span>
  382. </div>
  383. </div>
  384. <!-- PAGE: Chat / Direct Message -->
  385. <div class="app-page" id="page-chat">
  386. <script>document.getElementById('app-header').innerHTML = '<a href="#page-messages" class="back-button">‹</a><span>李静</span><a href="#" class="icon">···</a>';</script>
  387. <div style="height: calc(100% - 60px); overflow-y: auto; display: flex; flex-direction: column-reverse; padding-bottom: 10px;"> <!-- Chat history area -->
  388. <!-- Messages would load here, newest at the bottom -->
  389. <div class="chat-bubble sent">好的,那我们周二晚上图书馆见!</div>
  390. <div class="chat-bubble received">太好了!我正好也在复习,可以一起。</div>
  391. <div class="chat-bubble sent">我看到你也选了高数,下周考试一起复习怎么样?地点图书馆?</div>
  392. <div class="chat-bubble received">你好,看到你也喜欢日语学习,我也是!😊</div>
  393. <div class="chat-bubble sent">[系统提示] 你们都对“日语学习”感兴趣,可以聊聊哦~</div>
  394. </div>
  395. <div class="chat-input">
  396. <input type="text" placeholder="输入消息...">
  397. <button>发送</button>
  398. </div>
  399. </div>
  400. <!-- PAGE: User Profile (Self) -->
  401. <div class="app-page" id="page-profile-self">
  402. <script>document.getElementById('app-header').innerHTML = '<span>我的资料</span><a href="#page-settings" class="icon">⚙️</a>';</script>
  403. <div class="profile-header">
  404. <img src="https://via.placeholder.com/100/007BFF/FFFFFF?text=ME" alt="My Avatar" class="avatar">
  405. <h2>你的昵称</h2>
  406. <p>北京邮电大学 | 计算机科学 | 大二</p>
  407. <p>"努力成为有趣的人 | Coding & Reading"</p>
  408. <a href="#page-interests" class="button-link outline" style="margin-top: 10px;">编辑兴趣标签</a>
  409. </div>
  410. <div class="section-title">我的兴趣</div>
  411. <div class="card">
  412. <span class="interest-tag">Python</span>
  413. <span class="interest-tag">机器学习</span>
  414. <span class="interest-tag">科幻电影</span>
  415. <span class="interest-tag">羽毛球</span>
  416. <span class="interest-tag">独立音乐</span>
  417. </div>
  418. <div class="section-title">我的小组</div>
  419. <div class="card group-item">
  420. <img src="https://via.placeholder.com/50/20B2AA/FFFFFF?text=G2" alt="Group Icon" class="avatar" style="border-radius: 8px;">
  421. <div class="content-details">
  422. <h3>BUPT算法交流群</h3>
  423. <p>55 成员</p>
  424. </div>
  425. </div>
  426. <a href="#page-groups" class="button-link secondary" style="width: 100%; text-align: center;">查看所有小组</a>
  427. <div class="section-title">我发布的活动</div>
  428. <p style="text-align: center; color: #999;">暂无活动</p>
  429. <a href="#page-event-post" class="button-link" style="width: 100%; text-align: center;">发布新活动</a>
  430. <div class="section-title">我的技能/需求</div>
  431. <div class="card skill-item">
  432. <img src="https://via.placeholder.com/50/007BFF/FFFFFF?text=ME" alt="User Avatar" class="avatar">
  433. <div class="content-details">
  434. <p><strong>提供:</strong> Python基础教学 <span style="color: green;">|</span> <strong>需要:</strong> 羽毛球球友</p>
  435. </div>
  436. <div class="actions"> <a href="#page-skills" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">编辑</a> </div>
  437. </div>
  438. <a href="#page-skills" class="button-link" style="width: 100%; text-align: center;">发布技能/需求</a>
  439. </div>
  440. <!-- PAGE: User Profile (Other) -->
  441. <div class="app-page" id="page-profile-other">
  442. <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>用户资料</span><a href="#" class="icon">···</a>';</script>
  443. <div class="profile-header">
  444. <img src="https://via.placeholder.com/100/FFA500/FFFFFF?text=U1" alt="User Avatar" class="avatar">
  445. <h2>张伟</h2>
  446. <p>北京大学 | 艺术学院 | 大三</p>
  447. <p>"周末想找人一起去奥森拍照~"</p>
  448. <a href="#page-chat" class="button-link" style="margin-top: 10px;">发消息</a>
  449. <button class="secondary">关注</button>
  450. </div>
  451. <div class="section-title">Ta的兴趣</div>
  452. <div class="card">
  453. <span class="interest-tag">摄影</span>
  454. <span class="interest-tag">后期制作</span>
  455. <span class="interest-tag">爬山</span>
  456. <span class="interest-tag">纪录片</span>
  457. </div>
  458. <div class="section-title">共同兴趣</div>
  459. <div class="card">
  460. <span class="interest-tag">摄影</span>
  461. <span class="interest-tag">爬山</span>
  462. </div>
  463. <div class="section-title">Ta的小组</div>
  464. <p style="text-align: center; color: #999;">用户尚未加入任何小组</p>
  465. <div class="section-title">Ta发布的活动</div>
  466. <div class="card event-item">
  467. <img src="https://via.placeholder.com/50/FFA500/FFFFFF?text=U1" alt="Host Avatar" class="avatar">
  468. <div class="content-details">
  469. <h3>奥森公园外拍活动</h3>
  470. <p>时间: 本周六 10:00</p>
  471. <p>地点: 奥林匹克森林公园南门</p>
  472. </div>
  473. <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">查看详情</a> </div>
  474. </div>
  475. </div>
  476. <!-- PAGE: Interest Selection/Editing -->
  477. <div class="app-page" id="page-interests">
  478. <script>document.getElementById('app-header').innerHTML = '<a href="#page-profile-self" class="back-button">‹</a><span>选择我的兴趣</span><a href="#page-profile-self" class="icon" style="font-size: 0.9em;">保存</a>';</script>
  479. <input type="text" placeholder="搜索兴趣标签...">
  480. <div class="interest-category">
  481. <h3>运动</h3>
  482. <div class="tags">
  483. <button class="tag-button selected">羽毛球</button>
  484. <button class="tag-button">篮球</button>
  485. <button class="tag-button">跑步</button>
  486. <button class="tag-button">游泳</button>
  487. <button class="tag-button">健身</button>
  488. <button class="tag-button">瑜伽</button>
  489. <button class="tag-button">乒乓球</button>
  490. <button class="tag-button">爬山</button>
  491. </div>
  492. </div>
  493. <div class="interest-category">
  494. <h3>音乐</h3>
  495. <div class="tags">
  496. <button class="tag-button selected">独立音乐</button>
  497. <button class="tag-button">摇滚</button>
  498. <button class="tag-button">流行</button>
  499. <button class="tag-button">古典</button>
  500. <button class="tag-button">吉他</button>
  501. <button class="tag-button">钢琴</button>
  502. </div>
  503. </div>
  504. <div class="interest-category">
  505. <h3>学术/技术</h3>
  506. <div class="tags">
  507. <button class="tag-button selected">Python</button>
  508. <button class="tag-button selected">机器学习</button>
  509. <button class="tag-button">Web开发</button>
  510. <button class="tag-button">算法</button>
  511. <button class="tag-button">考研</button>
  512. <button class="tag-button">四六级</button>
  513. </div>
  514. </div>
  515. <div class="interest-category">
  516. <h3>艺术/生活</h3>
  517. <div class="tags">
  518. <button class="tag-button selected">科幻电影</button>
  519. <button class="tag-button">摄影</button>
  520. <button class="tag-button">阅读</button>
  521. <button class="tag-button">绘画</button>
  522. <button class="tag-button">桌游</button>
  523. <button class="tag-button">美食探店</button>
  524. </div>
  525. </div>
  526. <p style="color: #888; font-size: 0.9em;">找不到你的兴趣?可以尝试搜索或 <a href="#">创建新标签</a>。</p>
  527. </div>
  528. <!-- PAGE: Notifications -->
  529. <div class="app-page" id="page-notifications">
  530. <script>document.getElementById('app-header').innerHTML = '<a href="#page-home" class="back-button">‹</a><span>通知</span>';</script>
  531. <div class="notification-item">
  532. <img src="https://via.placeholder.com/50/32CD32/FFFFFF?text=U3" alt="User Avatar" class="avatar">
  533. <div class="content-details">
  534. <p><strong>王磊</strong> 赞了你的动态。</p>
  535. <p style="font-size: 0.8em; color: #999;">5分钟前</p>
  536. </div>
  537. </div>
  538. <div class="notification-item">
  539. <img src="https://via.placeholder.com/50/FF6347/FFFFFF?text=E" alt="Event Icon" class="avatar" style="border-radius: 8px;">
  540. <div class="content-details">
  541. <p>你报名的活动 <strong>周末狼人杀局</strong> 将在1小时后开始。</p>
  542. <p style="font-size: 0.8em; color: #999;">15分钟前</p>
  543. </div>
  544. </div>
  545. <div class="notification-item">
  546. <img src="https://via.placeholder.com/50/8A2BE2/FFFFFF?text=U4" alt="User Avatar" class="avatar">
  547. <div class="content-details">
  548. <p><strong>赵敏</strong> 开始关注你了。</p>
  549. <p style="font-size: 0.8em; color: #999;">1小时前</p>
  550. </div>
  551. <div class="actions"> <a href="#page-profile-other" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">回关</a> </div>
  552. </div>
  553. <div class="notification-item">
  554. <img src="https://via.placeholder.com/50/FFD700/000000?text=G1" alt="Group Icon" class="avatar" style="border-radius: 8px;">
  555. <div class="content-details">
  556. <p><strong>北邮吉他社</strong> 有新公告。</p>
  557. <p style="font-size: 0.8em; color: #999;">3小时前</p>
  558. </div>
  559. </div>
  560. </div>
  561. <!-- PAGE: Settings -->
  562. <div class="app-page" id="page-settings">
  563. <script>document.getElementById('app-header').innerHTML = '<a href="#page-profile-self" class="back-button">‹</a><span>设置</span>';</script>
  564. <ul style="list-style: none; padding: 0;">
  565. <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#page-profile-self" style="text-decoration: none; color: #333;">编辑个人资料</a></li>
  566. <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">账号与安全</a></li>
  567. <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">隐私设置</a></li>
  568. <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#page-notifications" style="text-decoration: none; color: #333;">通知设置</a></li>
  569. <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">关于我们</a></li>
  570. <li style="padding: 15px 0; border-bottom: 1px solid #eee;"><a href="#" style="text-decoration: none; color: #333;">帮助与反馈</a></li>
  571. </ul>
  572. <button style="width: 100%; background-color: #dc3545; margin-top: 30px;">退出登录</button>
  573. </div>
  574. <!-- PAGE: Group List -->
  575. <div class="app-page" id="page-groups">
  576. <script>document.getElementById('app-header').innerHTML = '<a href="#page-profile-self" class="back-button">‹</a><span>我的小组</span><a href="#" class="icon">+</a>';</script>
  577. <!-- Add Tabs for My Groups / Discover Groups -->
  578. <div class="card group-item">
  579. <img src="https://via.placeholder.com/50/20B2AA/FFFFFF?text=G2" alt="Group Icon" class="avatar" style="border-radius: 8px;">
  580. <div class="content-details">
  581. <h3>BUPT算法交流群</h3>
  582. <p>55 成员</p>
  583. </div>
  584. <div class="actions"> <a href="#page-group-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">进入</a> </div>
  585. </div>
  586. <div class="card group-item">
  587. <img src="https://via.placeholder.com/50/DAA520/FFFFFF?text=G3" alt="Group Icon" class="avatar" style="border-radius: 8px;">
  588. <div class="content-details">
  589. <h3>电影爱好者协会</h3>
  590. <p>210 成员</p>
  591. </div>
  592. <div class="actions"> <a href="#page-group-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">进入</a> </div>
  593. </div>
  594. <p style="text-align: center; margin-top: 20px;"><a href="#page-discover" style="color: #007bff;">发现更多小组...</a></p>
  595. </div>
  596. <!-- PAGE: Group Detail -->
  597. <div class="app-page" id="page-group-detail">
  598. <script>document.getElementById('app-header').innerHTML = '<a href="#page-groups" class="back-button">‹</a><span>BUPT算法交流群</span><a href="#" class="icon">···</a>';</script>
  599. <div style="text-align: center; margin-bottom: 15px;">
  600. <img src="https://via.placeholder.com/80/20B2AA/FFFFFF?text=G2" alt="Group Icon" class="avatar" style="width: 80px; height: 80px; border-radius: 15px; margin: 0 auto 10px auto;">
  601. <h2>BUPT算法交流群</h2>
  602. <p>55 成员 | <a href="#">查看成员</a></p>
  603. <p style="font-size: 0.9em; color: #666;">欢迎对算法、数据结构、ACM竞赛感兴趣的同学加入讨论!</p>
  604. <button class="secondary">已加入</button>
  605. </div>
  606. <hr>
  607. <h3>小组动态</h3>
  608. <div class="card"> <!-- Post within group -->
  609. <div class="user-card" style="border-bottom: none; margin-bottom: 10px; padding-bottom: 0;">
  610. <img src="https://via.placeholder.com/40/CD5C5C/FFFFFF?text=U5" alt="User Avatar" class="avatar" style="width: 40px; height: 40px;">
  611. <div class="content-details">
  612. <h3 style="font-size: 0.9em;">陈晨</h3>
  613. <p style="font-size: 0.8em;">5小时前</p>
  614. </div>
  615. </div>
  616. <p>LeetCode今天这道Hard题有人AC了吗?求思路分享!#每日一题</p>
  617. <div style="font-size: 0.8em; color: #888;">👍 5    💬 2</div>
  618. </div>
  619. <div class="card"> <!-- Post within group -->
  620. <div class="user-card" style="border-bottom: none; margin-bottom: 10px; padding-bottom: 0;">
  621. <img src="https://via.placeholder.com/40/4682B4/FFFFFF?text=U2" alt="User Avatar" class="avatar" style="width: 40px; height: 40px;">
  622. <div class="content-details">
  623. <h3 style="font-size: 0.9em;">李静 (管理员)</h3>
  624. <p style="font-size: 0.8em;">昨天</p>
  625. </div>
  626. </div>
  627. <p>【公告】下周三晚上7点,邀请学长分享蓝桥杯备赛经验,地点教三201,欢迎参加!</p>
  628. <div style="font-size: 0.8em; color: #888;">👍 15    💬 1</div>
  629. </div>
  630. <button style="width: 100%; margin-top: 15px;">发布新动态</button>
  631. </div>
  632. <!-- PAGE: Event Listing -->
  633. <div class="app-page" id="page-events">
  634. <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>活动广场</span><a href="#page-event-post" class="icon">+</a>';</script>
  635. <!-- Add Tabs for Upcoming / My Events / Discover -->
  636. <div class="card event-item">
  637. <img src="https://via.placeholder.com/50/FF6347/FFFFFF?text=E" alt="Event Icon" class="avatar" style="border-radius: 8px;">
  638. <div class="content-details">
  639. <h3>周末狼人杀局</h3>
  640. <p>时间: 周六 14:00</p>
  641. <p>地点: 学校咖啡厅 | 发起人: 王磊</p>
  642. </div>
  643. <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">详情</a> </div>
  644. </div>
  645. <div class="card event-item">
  646. <img src="https://via.placeholder.com/50/00CED1/FFFFFF?text=E2" alt="Event Icon" class="avatar" style="border-radius: 8px;">
  647. <div class="content-details">
  648. <h3>校园编程马拉松</h3>
  649. <p>时间: 下周五 9:00 - 周日 17:00</p>
  650. <p>地点: 计算机学院楼 | 主办方: 计算机学院</p>
  651. </div>
  652. <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">详情</a> </div>
  653. </div>
  654. <div class="card event-item">
  655. <img src="https://via.placeholder.com/50/9370DB/FFFFFF?text=E3" alt="Event Icon" class="avatar" style="border-radius: 8px;">
  656. <div class="content-details">
  657. <h3>草坪音乐分享会</h3>
  658. <p>时间: 周日 16:00</p>
  659. <p>地点: 学校大草坪 | 发起人: 赵敏</p>
  660. </div>
  661. <div class="actions"> <a href="#page-event-detail" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">详情</a> </div>
  662. </div>
  663. </div>
  664. <!-- PAGE: Event Detail -->
  665. <div class="app-page" id="page-event-detail">
  666. <script>document.getElementById('app-header').innerHTML = '<a href="#page-events" class="back-button">‹</a><span>活动详情</span><a href="#" class="icon">☆</a>';</script>
  667. <img src="https://via.placeholder.com/345x150/FF6347/FFFFFF?text=Event+Banner" alt="Event Image" style="width: 100%; height: 150px; object-fit: cover; border-radius: 8px; margin-bottom: 15px;">
  668. <h2>周末狼人杀局</h2>
  669. <p><strong>时间:</strong> 本周六 14:00 - 18:00</p>
  670. <p><strong>地点:</strong> 学校南门咖啡厅二楼</p>
  671. <p><strong>发起人:</strong> <a href="#page-profile-other">王磊</a> (人民大学)</p>
  672. <p><strong>活动介绍:</strong> 找个地方一起玩狼人杀,新手友好,欢迎各种板子!目前已有3人,还差5-7人。费用AA(场地费)。</p>
  673. <p><strong>兴趣标签:</strong> <span class="interest-tag">桌游</span> <span class="interest-tag">狼人杀</span> <span class="interest-tag">线下聚会</span></p>
  674. <p><strong>已报名 (3/10):</strong> <img src="https://via.placeholder.com/30/32CD32/FFFFFF?text=U3" class="avatar" style="width:30px; height:30px; margin-right: 5px;"> <img src="https://via.placeholder.com/30/1E90FF/FFFFFF?text=U6" class="avatar" style="width:30px; height:30px; margin-right: 5px;"> <img src="https://via.placeholder.com/30/FF4500/FFFFFF?text=U7" class="avatar" style="width:30px; height:30px; margin-right: 5px;"> <a href="#">查看全部</a></p>
  675. <button style="width: 100%;">我要报名</button>
  676. <button class="secondary" style="width: 100%; margin-top: 10px;">分享活动</button>
  677. </div>
  678. <!-- PAGE: Event Posting -->
  679. <div class="app-page" id="page-event-post">
  680. <script>document.getElementById('app-header').innerHTML = '<a href="#page-events" class="back-button">‹</a><span>发布新活动</span><a href="#page-events" class="icon" style="font-size: 0.9em;">发布</a>';</script>
  681. <label for="event-title">活动标题:</label>
  682. <input type="text" id="event-title" placeholder="如:周日图书馆约学习">
  683. <label for="event-desc">活动描述:</label>
  684. <textarea id="event-desc" placeholder="详细说明活动内容、目的、要求等..."></textarea>
  685. <label for="event-time">时间:</label>
  686. <input type="text" id="event-time" placeholder="如:本周日 下午2点-5点">
  687. <label for="event-loc">地点:</label>
  688. <input type="text" id="event-loc" placeholder="如:学校图书馆三楼自习室">
  689. <label for="event-tags">关联兴趣标签 (可选):</label>
  690. <input type="text" id="event-tags" placeholder="如:考研, 学习伙伴, 图书馆">
  691. <label for="event-limit">人数限制 (可选):</label>
  692. <input type="number" id="event-limit" placeholder="如:5 (留空表示不限)">
  693. <label for="event-cover">上传封面图 (可选):</label>
  694. <button class="outline">选择图片</button>
  695. </div>
  696. <!-- PAGE: Skill Exchange Listing -->
  697. <div class="app-page" id="page-skills">
  698. <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>技能交换</span><a href="#page-skill-post" class="icon">+</a>';</script>
  699. <!-- Add Tabs: 提供 / 需求 / 浏览 -->
  700. <div class="card skill-item">
  701. <img src="https://via.placeholder.com/50/6495ED/FFFFFF?text=S1" alt="User Avatar" class="avatar">
  702. <div class="content-details">
  703. <h3>刘洋 <span style="font-size: 0.8em; color: #777;">(北航)</span></h3>
  704. <p><strong style="color: green;">提供:</strong> PPT美化, 海报设计</p>
  705. <p><strong style="color: orange;">需要:</strong> 英语口语练习</p>
  706. </div>
  707. <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
  708. </div>
  709. <div class="card skill-item">
  710. <img src="https://via.placeholder.com/50/DC143C/FFFFFF?text=S2" alt="User Avatar" class="avatar">
  711. <div class="content-details">
  712. <h3>孙悦 <span style="font-size: 0.8em; color: #777;">(北理)</span></h3>
  713. <p><strong style="color: green;">提供:</strong> 日语N2辅导</p>
  714. <p><strong style="color: orange;">需要:</strong> Python爬虫教学</p>
  715. </div>
  716. <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
  717. </div>
  718. <div class="card skill-item">
  719. <img src="https://via.placeholder.com/50/FF8C00/FFFFFF?text=S3" alt="User Avatar" class="avatar">
  720. <div class="content-details">
  721. <h3>周峰 <span style="font-size: 0.8em; color: #777;">(北交大)</span></h3>
  722. <p><strong style="color: green;">提供:</strong> 吉他弹唱教学 (入门)</p>
  723. <p><strong style="color: orange;">需要:</strong> 无</p>
  724. </div>
  725. <div class="actions"> <a href="#page-chat" class="button-link outline" style="padding: 5px 10px; font-size: 0.8em;">联系Ta</a> </div>
  726. </div>
  727. </div>
  728. <!-- PAGE: Skill Post/Edit -->
  729. <div class="app-page" id="page-skill-post">
  730. <script>document.getElementById('app-header').innerHTML = '<a href="#page-skills" class="back-button">‹</a><span>发布技能/需求</span><a href="#page-skills" class="icon" style="font-size: 0.9em;">发布</a>';</script>
  731. <label for="skill-provide">我能提供的技能/帮助:</label>
  732. <textarea id="skill-provide" placeholder="详细描述你能提供的技能或帮助,如:Python数据分析入门、日语五十音教学..."></textarea>
  733. <label for="skill-need">我需要的技能/帮助:</label>
  734. <textarea id="skill-need" placeholder="详细描述你需要的技能或帮助,如:寻找英语口语语伴、求PS修图指导..."></textarea>
  735. <p style="font-size: 0.9em; color: #888;">可以只填写一项或两项都填。</p>
  736. </div>
  737. <!-- PAGE: Map View (Conceptual) -->
  738. <div class="app-page" id="page-map">
  739. <script>document.getElementById('app-header').innerHTML = '<a href="#page-discover" class="back-button">‹</a><span>附近 (<span style="color:red;">隐私保护模式</span>)</span><a href="#" class="icon">⚙️</a>';</script>
  740. <p style="font-size: 0.85em; color: #dc3545; text-align: center; border: 1px solid #f5c6cb; background-color: #f8d7da; padding: 8px; border-radius: 5px; margin-bottom: 15px;">
  741. <strong>注意:</strong> 为保护隐私,地图仅显示模糊位置和共同兴趣,不会暴露精确坐标或个人身份。你需要明确授权才能使用此功能。
  742. </p>
  743. <div class="map-placeholder">
  744. <p>模拟地图区域<br/>(显示附近有相同兴趣的用户或活动的大致位置)</p>
  745. </div>
  746. <div style="margin-top: 15px;">
  747. <label for="map-filter-interest">筛选兴趣:</label>
  748. <select id="map-filter-interest">
  749. <option>所有兴趣</option>
  750. <option>摄影</option>
  751. <option>篮球</option>
  752. <option>学习伙伴</option>
  753. </select>
  754. <label for="map-filter-radius">范围:</label>
  755. <select id="map-filter-radius">
  756. <option>1公里内</option>
  757. <option>3公里内</option>
  758. <option>5公里内</option>
  759. </select>
  760. </div>
  761. <!-- List nearby items below the map? -->
  762. <p style="text-align: center; color: #999; margin-top: 20px;">地图下方可列出匹配项</p>
  763. </div>
  764. <!-- PAGE: Login -->
  765. <div class="app-page" id="page-login">
  766. <script>document.getElementById('app-header').innerHTML = '<span>登录</span>';</script>
  767. <h2 style="text-align: center; margin-top: 40px;">欢迎回来</h2>
  768. <label for="login-email">邮箱/手机号:</label>
  769. <input type="email" id="login-email" placeholder="输入你的注册邮箱或手机号">
  770. <label for="login-password">密码:</label>
  771. <input type="password" id="login-password" placeholder="输入密码">
  772. <button style="width: 100%; margin-top: 20px;">登录</button>
  773. <div style="display: flex; justify-content: space-between; margin-top: 15px; font-size: 0.9em;">
  774. <a href="#" style="color: #007bff;">忘记密码?</a>
  775. <a href="#page-signup" style="color: #007bff;">没有账号?去注册</a>
  776. </div>
  777. <p style="text-align: center; color: #aaa; margin: 30px 0 15px 0;">--- 第三方登录 ---</p>
  778. <div style="text-align: center;">
  779. <button class="outline" style="margin: 5px; border-radius: 50%; width: 50px; height: 50px; font-size: 1.5em;">微</button>
  780. <button class="outline" style="margin: 5px; border-radius: 50%; width: 50px; height: 50px; font-size: 1.5em;">Q</button>
  781. <button class="outline" style="margin: 5px; border-radius: 50%; width: 50px; height: 50px; font-size: 1.5em;"></button>
  782. </div>
  783. </div>
  784. <!-- PAGE: Signup -->
  785. <div class="app-page" id="page-signup">
  786. <script>document.getElementById('app-header').innerHTML = '<span>注册</span>';</script>
  787. <h2 style="text-align: center; margin-top: 20px;">创建新账号</h2>
  788. <label for="signup-school-email">学校邮箱 (.edu):</label>
  789. <input type="email" id="signup-school-email" placeholder="推荐使用edu邮箱验证身份">
  790. <label for="signup-nickname">昵称:</label>
  791. <input type="text" id="signup-nickname" placeholder="给自己取个名字吧">
  792. <label for="signup-password">设置密码:</label>
  793. <input type="password" id="signup-password" placeholder="至少8位,包含字母和数字">
  794. <label for="signup-password-confirm">确认密码:</label>
  795. <input type="password" id="signup-password-confirm" placeholder="再次输入密码">
  796. <button style="width: 100%; margin-top: 20px;">注册</button>
  797. <p style="font-size: 0.8em; color: #888; margin-top: 10px; text-align: center;">
  798. 点击注册表示同意 <a href="#" style="color: #007bff;">用户协议</a> 和 <a href="#" style="color: #007bff;">隐私政策</a>
  799. </p>
  800. <p style="text-align: center; margin-top: 15px;">
  801. <a href="#page-login" style="color: #007bff;">已有账号?去登录</a>
  802. </p>
  803. </div>
  804. </div> <!-- End .app-content -->
  805. <!-- Footer / Tab Bar -->
  806. <div class="app-footer" id="app-footer">
  807. <a href="#page-home" class="tab-item active" onclick="setActiveTab(this)"><span>🏠</span>首页</a>
  808. <a href="#page-discover" class="tab-item" onclick="setActiveTab(this)"><span>🔍</span>发现</a>
  809. <a href="#page-messages" class="tab-item" onclick="setActiveTab(this)"><span>💬</span>消息</a>
  810. <a href="#page-profile-self" class="tab-item" onclick="setActiveTab(this)"><span>👤</span>我的</a>
  811. </div>
  812. </div> <!-- End .phone-mockup -->
  813. <script>
  814. // Simple JavaScript for page navigation simulation and tab highlighting
  815. const pages = document.querySelectorAll('.app-page');
  816. const footerTabs = document.querySelectorAll('.app-footer .tab-item');
  817. const header = document.getElementById('app-header');
  818. function showPage(pageId) {
  819. pages.forEach(page => {
  820. page.style.display = 'none'; // Hide all pages
  821. });
  822. const targetPage = document.getElementById(pageId);
  823. if (targetPage) {
  824. targetPage.style.display = 'block'; // Show the target page
  825. // Find the script inside the target page and run it to update the header
  826. const headerScript = targetPage.querySelector('script');
  827. if (headerScript) {
  828. try {
  829. eval(headerScript.innerText); // Execute the script to set the header
  830. } catch (e) {
  831. console.error("Error executing header script for page:", pageId, e);
  832. // Set a default header if script fails
  833. header.innerHTML = '<span>App Name</span>';
  834. }
  835. } else {
  836. // Set a default header if no script found
  837. header.innerHTML = '<span>App Name</span>';
  838. }
  839. // Scroll content to top when changing pages
  840. targetPage.parentElement.scrollTop = 0;
  841. } else {
  842. console.warn("Page not found:", pageId);
  843. document.getElementById('page-home').style.display = 'block'; // Fallback to home
  844. header.innerHTML = '<span>兴趣伙伴</span><a href="#page-notifications" class="icon">🔔</a>';
  845. }
  846. }
  847. function setActiveTab(selectedTab) {
  848. footerTabs.forEach(tab => {
  849. tab.classList.remove('active');
  850. });
  851. selectedTab.classList.add('active');
  852. // Navigate to the page specified in the tab's href
  853. const pageId = selectedTab.getAttribute('href').substring(1); // Remove #
  854. showPage(pageId);
  855. }
  856. // Handle initial page load based on URL hash, or default to home
  857. window.addEventListener('load', () => {
  858. const hash = window.location.hash;
  859. if (hash) {
  860. const pageId = hash.substring(1);
  861. showPage(pageId);
  862. // Update active tab based on hash
  863. footerTabs.forEach(tab => {
  864. if(tab.getAttribute('href') === hash) {
  865. setActiveTab(tab);
  866. } else {
  867. tab.classList.remove('active');
  868. }
  869. });
  870. // Ensure at least one tab is active if hash matches a main page
  871. const activeTabs = document.querySelectorAll('.app-footer .tab-item.active');
  872. if(activeTabs.length === 0 && ['page-home', 'page-discover', 'page-messages', 'page-profile-self'].includes(pageId)) {
  873. document.querySelector(`.app-footer .tab-item[href="#${pageId}"]`).classList.add('active');
  874. } else if (activeTabs.length === 0) {
  875. document.querySelector('.app-footer .tab-item[href="#page-home"]').classList.add('active'); // Default active tab
  876. }
  877. } else {
  878. showPage('page-home'); // Default page
  879. document.querySelector('.app-footer .tab-item[href="#page-home"]').classList.add('active'); // Default active tab
  880. }
  881. });
  882. // Optional: Handle browser back/forward navigation
  883. window.addEventListener('hashchange', () => {
  884. const hash = window.location.hash;
  885. if (hash) {
  886. const pageId = hash.substring(1);
  887. showPage(pageId);
  888. // Update active tab based on hash
  889. footerTabs.forEach(tab => {
  890. if(tab.getAttribute('href') === hash) {
  891. setActiveTab(tab); // This already calls showPage
  892. } else {
  893. tab.classList.remove('active');
  894. }
  895. });
  896. // Ensure at least one tab is active if hash matches a main page
  897. const activeTabs = document.querySelectorAll('.app-footer .tab-item.active');
  898. if(activeTabs.length === 0 && ['page-home', 'page-discover', 'page-messages', 'page-profile-self'].includes(pageId)) {
  899. document.querySelector(`.app-footer .tab-item[href="#${pageId}"]`).classList.add('active');
  900. } else if (activeTabs.length === 0) {
  901. document.querySelector('.app-footer .tab-item[href="#page-home"]').classList.add('active'); // Default active tab
  902. }
  903. } else {
  904. showPage('page-home'); // Default to home if hash is empty
  905. setActiveTab(document.querySelector('.app-footer .tab-item[href="#page-home"]'));
  906. }
  907. });
  908. // Make internal links work for navigation
  909. document.addEventListener('click', function(event) {
  910. let target = event.target;
  911. // Traverse up the DOM if the click was inside a link
  912. while(target && target.tagName !== 'A') {
  913. target = target.parentElement;
  914. }
  915. if (target && target.tagName === 'A' && target.getAttribute('href') && target.getAttribute('href').startsWith('#')) {
  916. const href = target.getAttribute('href');
  917. // Check if it's a tab bar link (already handled by setActiveTab)
  918. if (!target.classList.contains('tab-item')) {
  919. event.preventDefault(); // Prevent default anchor jump
  920. const pageId = href.substring(1);
  921. window.location.hash = pageId; // Change hash to trigger navigation
  922. } else {
  923. // If it IS a tab item, ensure setActiveTab is called (covers cases where onclick might fail or be absent)
  924. setActiveTab(target);
  925. }
  926. }
  927. });
  928. </script>
  929. </body>
  930. </html>