rs_maps/frontend/index.html
2026-08-03 09:42:13 +01:00

215 lines
9.4 KiB
HTML

<!-- frontend/index.html -->
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<!-- Injected by the backend from BASE_PATH. Trailing slash is mandatory,
and nothing in this app may use a leading-slash URL. -->
<base href="__BASE_HREF__">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Waymark</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- ───────────────────────────────── auth ───────────────────────────────── -->
<section id="auth" class="auth" hidden>
<div class="auth-card">
<header class="auth-head">
<span class="trig" aria-hidden="true"></span>
<h1>Waymark</h1>
<p class="auth-sub" id="auth-sub">Places worth going back to.</p>
</header>
<form class="pane" id="form-login" data-pane="login">
<label>Username or email<input name="username_or_email" autocomplete="username" required></label>
<label>Password<input name="password" type="password" autocomplete="current-password" required></label>
<p class="note" data-note></p>
<button class="primary" type="submit">Log in</button>
<p class="switch">
<a href="#" data-goto="forgot">Forgotten password</a>
<a href="#" data-goto="register">Create an account</a>
</p>
</form>
<form class="pane" id="form-register" data-pane="register" hidden>
<label>Username<input name="username" autocomplete="username" required></label>
<label>Email <span class="opt">optional — only used to reset your password</span>
<input name="email" type="email" autocomplete="email"></label>
<label>Password <span class="opt">at least 8 characters</span>
<input name="password" type="password" autocomplete="new-password" required minlength="8"></label>
<label>Registration token<input name="reg_token" required></label>
<p class="note" data-note></p>
<button class="primary" type="submit">Create account</button>
<p class="switch"><a href="#" data-goto="login">Back to log in</a></p>
</form>
<form class="pane" id="form-forgot" data-pane="forgot" hidden>
<label>Email<input name="email" type="email" autocomplete="email" required></label>
<p class="note" data-note></p>
<button class="primary" type="submit">Send reset link</button>
<p class="switch"><a href="#" data-goto="login">Back to log in</a></p>
</form>
<form class="pane" id="form-reset" data-pane="reset" hidden>
<label>New password <span class="opt">at least 8 characters</span>
<input name="new_password" type="password" autocomplete="new-password" required minlength="8"></label>
<label>Confirm new password<input name="confirm" type="password" autocomplete="new-password" required></label>
<p class="note" data-note></p>
<button class="primary" type="submit">Set new password</button>
<p class="switch"><a href="#" data-goto="login">Back to log in</a></p>
</form>
</div>
</section>
<!-- ───────────────────────────────── app ───────────────────────────────── -->
<main id="app" class="app" hidden>
<div id="map" role="application" aria-label="Map"></div>
<header class="bar">
<span class="trig small" aria-hidden="true"></span>
<form id="search" class="search" role="search">
<input name="q" type="search" placeholder="Search a place or address" aria-label="Search places">
<button type="submit" aria-label="Search">Find</button>
</form>
<button id="locate" class="ghost" aria-pressed="false">Live location</button>
<div class="account">
<button id="account-btn" class="ghost" aria-expanded="false" aria-haspopup="menu">
<span id="account-name"></span>
</button>
<div id="account-menu" class="menu" role="menu" hidden>
<button role="menuitem" data-action="settings">Account settings</button>
<button role="menuitem" data-action="logout">Log out</button>
</div>
</div>
</header>
<!-- signature: the map-margin grid readout -->
<div class="readout" id="readout" aria-live="off">
<span class="readout-label">CENTRE</span>
<span class="readout-val" id="readout-latlon"></span>
<span class="readout-label">ZOOM</span>
<span class="readout-val" id="readout-zoom"></span>
</div>
<aside class="rail">
<button class="tab" data-panel="places" aria-pressed="true">Places</button>
<button class="tab" data-panel="routes" aria-pressed="false">Routes</button>
</aside>
<!-- places -->
<section class="drawer" id="panel-places">
<header class="drawer-head">
<h2>Places</h2>
<button class="link" id="close-places" aria-label="Hide places">Hide</button>
</header>
<p class="hint">Click the map to drop a new place.</p>
<ul class="list" id="marker-list"></ul>
<p class="empty" id="marker-empty" hidden>Nothing saved yet. Click anywhere on the map to start.</p>
</section>
<!-- routes -->
<section class="drawer" id="panel-routes" hidden>
<header class="drawer-head">
<h2>Routes</h2>
<button class="link" id="close-routes" aria-label="Hide routes">Hide</button>
</header>
<div class="row">
<label class="filebtn">
Open from this device
<input type="file" id="gpx-local" accept=".gpx,application/gpx+xml" hidden>
</label>
<button class="ghost" id="gpx-clear">Clear from map</button>
</div>
<div id="local-actions" class="local-actions" hidden>
<span id="local-name" class="mono"></span>
<button class="primary small" id="gpx-save">Save to shared folder</button>
</div>
<h3 class="sub">Shared folder</h3>
<ul class="list" id="gpx-list"></ul>
<p class="empty" id="gpx-empty" hidden>No routes on the server yet.</p>
<p class="note" id="gpx-note"></p>
</section>
<!-- marker editor -->
<div class="scrim" id="scrim" hidden></div>
<section class="sheet" id="marker-sheet" hidden role="dialog" aria-modal="true" aria-labelledby="sheet-title">
<header class="drawer-head">
<h2 id="sheet-title">New place</h2>
<button class="link" data-close-sheet>Close</button>
</header>
<form id="marker-form">
<p class="coords mono" id="marker-coords"></p>
<label>Name<input name="name" required maxlength="120"></label>
<label>Kind
<select name="category">
<option value="">Unclassified</option>
<option value="campsite">Campsite</option>
<option value="water">Water</option>
<option value="viewpoint">Viewpoint</option>
<option value="parking">Parking</option>
<option value="shelter">Shelter</option>
<option value="food">Food</option>
<option value="hazard">Hazard</option>
<option value="__other">Other…</option>
</select>
</label>
<label id="category-other-wrap" hidden>Kind name<input name="category_other" maxlength="40"></label>
<label>Colour
<span class="swatches" id="swatches"></span>
</label>
<label>Notes<textarea name="description" rows="3" maxlength="2000"></textarea></label>
<label class="check">
<input type="checkbox" name="is_shared">
<span>Share with everyone</span>
</label>
<p class="note" data-note></p>
<div class="actions">
<button type="submit" class="primary">Save place</button>
<button type="button" class="danger" id="marker-delete" hidden>Delete</button>
</div>
</form>
</section>
<!-- account settings -->
<section class="sheet" id="account-sheet" hidden role="dialog" aria-modal="true" aria-labelledby="account-title">
<header class="drawer-head">
<h2 id="account-title">Account settings</h2>
<button class="link" data-close-sheet>Close</button>
</header>
<form id="email-form" class="block">
<h3 class="sub">Change email</h3>
<p class="current">Current: <span id="current-email" class="mono">Not set</span></p>
<label>New email <span class="opt">leave empty to remove it and give up password recovery</span>
<input name="new_email" type="email"></label>
<label>Current password<input name="current_password" type="password" autocomplete="current-password" required></label>
<p class="note" data-note></p>
<button class="primary" type="submit">Save email</button>
</form>
<form id="password-form" class="block">
<h3 class="sub">Change password</h3>
<label>Current password<input name="current_password" type="password" autocomplete="current-password" required></label>
<label>New password <span class="opt">at least 8 characters</span>
<input name="new_password" type="password" autocomplete="new-password" required minlength="8"></label>
<label>Confirm new password<input name="confirm" type="password" autocomplete="new-password" required></label>
<p class="note" data-note></p>
<button class="primary" type="submit">Save password</button>
</form>
</section>
<div class="toast" id="toast" hidden role="status"></div>
</main>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="app.js"></script>
</body>
</html>