index.html 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>GPX Visualizer</title>
  7. <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
  8. <link rel="stylesheet" href="css/style.css" />
  9. </head>
  10. <body>
  11. <!-- Auth page -->
  12. <div id="auth-page">
  13. <div class="auth-container">
  14. <h1 id="app-title">GPX Visualizer</h1>
  15. <div class="auth-tabs">
  16. <button class="auth-tab active" data-tab="login">Login</button>
  17. <button class="auth-tab" data-tab="register">Register</button>
  18. </div>
  19. <div id="auth-error" class="error-msg" style="display:none"></div>
  20. <form id="login-form">
  21. <input type="text" id="login-username" placeholder="Username" required>
  22. <input type="password" id="login-password" placeholder="Password" required>
  23. <button type="submit">Login</button>
  24. </form>
  25. <form id="register-form" style="display:none">
  26. <input type="text" id="reg-username" placeholder="Username (3-32 chars)" required>
  27. <input type="email" id="reg-email" placeholder="Email (optional)">
  28. <input type="password" id="reg-password" placeholder="Password (min 6 chars)" required>
  29. <button type="submit">Register</button>
  30. </form>
  31. <div style="margin-top:16px;text-align:center">
  32. <a id="guest-mode-link" href="#" style="color:var(--color-text-lighter);font-size:13px">Browse without account →</a>
  33. </div>
  34. </div>
  35. </div>
  36. <!-- Main app -->
  37. <div id="app" style="display:none">
  38. <div id="topbar">
  39. <div id="topbar-left">
  40. <button id="sidebar-toggle-btn" class="icon-btn" title="Toggle sidebar">☰</button>
  41. <span id="topbar-title">GPX Visualizer</span>
  42. </div>
  43. <div id="topbar-right">
  44. <span id="topbar-user"></span>
  45. <button id="admin-btn" class="topbar-btn" style="display:none">Admin</button>
  46. <button id="logout-btn" class="topbar-btn">Logout</button>
  47. </div>
  48. </div>
  49. <div id="main-content">
  50. <!-- Sidebar -->
  51. <div id="sidebar">
  52. <div id="sidebar-tabs">
  53. <button class="sidebar-tab active" data-tab="browser">Files</button>
  54. <button class="sidebar-tab" data-tab="stats">Stats</button>
  55. </div>
  56. <!-- Browser tab -->
  57. <div id="browser-tab" class="sidebar-tab-content">
  58. <div id="breadcrumb"></div>
  59. <div id="browser-actions">
  60. <button id="new-dir-btn" class="action-btn" title="New folder">+ Folder</button>
  61. <button id="upload-btn" class="action-btn" title="Upload GPX">+ GPX</button>
  62. <input type="file" id="file-input" accept=".gpx" multiple style="display:none">
  63. </div>
  64. <div id="browser-list"></div>
  65. </div>
  66. <!-- Stats tab -->
  67. <div id="stats-tab" class="sidebar-tab-content" style="display:none">
  68. <div id="stats-content"></div>
  69. </div>
  70. </div>
  71. <!-- Sidebar resize handle -->
  72. <div id="sidebar-resize-handle"></div>
  73. <!-- Map -->
  74. <div id="map-container">
  75. <div id="map"></div>
  76. <div id="track-info-panel" style="display:none">
  77. <div id="track-info-content"></div>
  78. <div id="elevation-chart-container">
  79. <canvas id="elevation-canvas"></canvas>
  80. <div id="elevation-tooltip"></div>
  81. </div>
  82. <button id="track-info-close">×</button>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. <!-- Admin panel (modal) -->
  88. <div id="admin-modal" class="modal" style="display:none">
  89. <div class="modal-content modal-large">
  90. <div class="modal-header">
  91. <h2>Admin Panel</h2>
  92. <button class="modal-close" data-modal="admin-modal">×</button>
  93. </div>
  94. <div id="admin-content"></div>
  95. </div>
  96. </div>
  97. <!-- Move track modal -->
  98. <div id="move-modal" class="modal" style="display:none">
  99. <div class="modal-content">
  100. <div class="modal-header">
  101. <h2>Move Track</h2>
  102. <button class="modal-close" data-modal="move-modal">×</button>
  103. </div>
  104. <div id="move-content">
  105. <p>Select destination directory:</p>
  106. <div id="move-dir-list"></div>
  107. <div style="margin-top:12px">
  108. <button id="move-confirm-btn" class="btn-primary">Move</button>
  109. <button class="btn-secondary modal-close" data-modal="move-modal">Cancel</button>
  110. </div>
  111. </div>
  112. </div>
  113. </div>
  114. <!-- Confirm modal -->
  115. <div id="confirm-modal" class="modal" style="display:none">
  116. <div class="modal-content">
  117. <div class="modal-header">
  118. <h2 id="confirm-title">Confirm</h2>
  119. <button class="modal-close" data-modal="confirm-modal">×</button>
  120. </div>
  121. <p id="confirm-message"></p>
  122. <div style="margin-top:16px; display:flex; gap:8px; justify-content:flex-end">
  123. <button id="confirm-ok-btn" class="btn-danger">Confirm</button>
  124. <button class="btn-secondary modal-close" data-modal="confirm-modal">Cancel</button>
  125. </div>
  126. </div>
  127. </div>
  128. <!-- Share link modal -->
  129. <div id="share-modal" class="modal" style="display:none">
  130. <div class="modal-content">
  131. <div class="modal-header">
  132. <h2>Share Track</h2>
  133. <button class="modal-close" data-modal="share-modal">×</button>
  134. </div>
  135. <div id="share-content"></div>
  136. </div>
  137. </div>
  138. <!-- Edit track modal -->
  139. <div id="edit-track-modal" class="modal" style="display:none">
  140. <div class="modal-content">
  141. <div class="modal-header">
  142. <h2>Edit Track</h2>
  143. <button class="modal-close" data-modal="edit-track-modal">×</button>
  144. </div>
  145. <div id="edit-track-content">
  146. <div class="form-group">
  147. <label for="edit-track-name">Name</label>
  148. <input type="text" id="edit-track-name" class="form-input" maxlength="255">
  149. </div>
  150. <div class="form-group">
  151. <label for="edit-track-type">Type</label>
  152. <select id="edit-track-type" class="form-input">
  153. <option value="">— unset —</option>
  154. <option value="hiking">🥾 Hiking</option>
  155. <option value="running">🏃 Running</option>
  156. <option value="cycling">🚴 Cycling</option>
  157. <option value="driving">🚗 Driving</option>
  158. <option value="train">🚆 Train</option>
  159. <option value="other">📍 Other</option>
  160. </select>
  161. </div>
  162. <div style="margin-top:16px;display:flex;gap:8px;justify-content:flex-end">
  163. <button id="edit-track-save-btn" class="btn-primary">Save</button>
  164. <button class="btn-secondary modal-close" data-modal="edit-track-modal">Cancel</button>
  165. </div>
  166. </div>
  167. </div>
  168. </div>
  169. <!-- Upload progress -->
  170. <div id="upload-toast" style="display:none">
  171. <div id="upload-toast-text">Uploading...</div>
  172. </div>
  173. <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
  174. <script src="config.js"></script>
  175. <script src="js/api.js"></script>
  176. <script src="js/auth.js"></script>
  177. <script src="js/map.js"></script>
  178. <script src="js/elevation.js"></script>
  179. <script src="js/browser.js"></script>
  180. <script src="js/stats.js"></script>
  181. <script src="js/local.js"></script>
  182. <script src="js/app.js"></script>
  183. </body>
  184. </html>