219 lines
10 KiB
HTML
219 lines
10 KiB
HTML
<!doctype html>
|
||
<html lang="de" data-theme="dark">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta name="description" content="HexaWetter – Selfhosted Wetterportal mit DWD Radar, Warnungen und Forecast" />
|
||
<title>HexaWetter</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||
<link rel="stylesheet" href="style.css" />
|
||
</head>
|
||
<body>
|
||
<header class="site-header">
|
||
<div class="container header-inner">
|
||
<a class="brand-link" href="index.html">
|
||
<div class="brand-logo" aria-hidden="true">H</div>
|
||
<div>
|
||
<div class="brand-sub">HexaHost · Selfhosted Weather</div>
|
||
<div class="brand-title">HexaWetter</div>
|
||
</div>
|
||
</a>
|
||
<div class="header-actions">
|
||
<div class="status-pill" id="health">API: prüfe…</div>
|
||
<button id="themeToggle" class="btn btn-ghost icon-btn" title="Theme wechseln" aria-label="Theme wechseln">🌙</button>
|
||
<a href="admin.html" class="btn btn-secondary">Admin</a>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="app-main">
|
||
<div class="container">
|
||
<section class="hero-copy">
|
||
<h1>Wetter für deinen Standort</h1>
|
||
<p>Forecast, DWD-Beobachtungen, interaktive Radar-Karte mit Zeitleiste und standortgenaue Warnungen – gehostet auf deiner Infrastruktur.</p>
|
||
</section>
|
||
|
||
<section class="glass-card controls">
|
||
<div class="search-wrap">
|
||
<label for="placeSearch">Ortssuche / PLZ</label>
|
||
<input id="placeSearch" type="search" placeholder="z.B. Hauzenberg, 94051 Passau…" autocomplete="off" />
|
||
<ul id="searchResults" class="search-results hidden" role="listbox"></ul>
|
||
</div>
|
||
<div>
|
||
<label for="place">Ort / Label</label>
|
||
<input id="place" value="Hauzenberg" />
|
||
</div>
|
||
<div>
|
||
<label for="lat">Latitude</label>
|
||
<input id="lat" type="number" step="0.0001" value="48.6546" />
|
||
</div>
|
||
<div>
|
||
<label for="lon">Longitude</label>
|
||
<input id="lon" type="number" step="0.0001" value="13.6252" />
|
||
</div>
|
||
<div class="control-actions">
|
||
<button id="geoBtn" class="btn btn-secondary icon-btn" title="Browser-Standort">📍</button>
|
||
<button id="favBtn" class="btn btn-secondary icon-btn" title="Favorit">★</button>
|
||
<button id="loadBtn" class="btn btn-primary">Aktualisieren</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="glass-card favorites-panel hidden" id="favoritesPanel">
|
||
<div class="section-head">
|
||
<h2>Gespeicherte Orte</h2>
|
||
<span class="muted">Klicken zum Laden</span>
|
||
</div>
|
||
<div id="favoritesList" class="chip-row"></div>
|
||
</section>
|
||
|
||
<nav class="tabs" aria-label="Ansichten">
|
||
<button class="tab active" data-view="dashboard">Übersicht</button>
|
||
<button class="tab" data-view="radar">Radar-Karte</button>
|
||
<button class="tab" data-view="warnings">Warnungen</button>
|
||
<button class="tab" data-view="hourly">Stunden</button>
|
||
<button class="tab" data-view="daily">7 Tage</button>
|
||
<button class="tab" data-view="raw">Rohdaten</button>
|
||
<button class="tab" data-view="settings">Einstellungen</button>
|
||
</nav>
|
||
|
||
<section class="view active" data-view="dashboard">
|
||
<section class="grid">
|
||
<article class="glass-card card"><h2>Aktuelles Wetter</h2><p class="big" id="currentTemp">–</p><p id="currentMeta" class="muted">Lade…</p></article>
|
||
<article class="glass-card card"><h2>DWD-Beobachtung</h2><p class="big" id="obsTemp">–</p><p id="obsMeta" class="muted">Lade…</p></article>
|
||
<article class="glass-card card"><h2>Radar-Status</h2><p class="big" id="radarCount">–</p><p id="radarMeta" class="muted">Lade…</p></article>
|
||
<article class="glass-card card"><h2>Warnungen</h2><p class="big" id="warnCount">–</p><p id="warnMeta" class="muted">Lade…</p></article>
|
||
</section>
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>Details aktuell</h2><span class="muted" id="forecastSource"></span></div>
|
||
<div class="metrics" id="currentDetails"></div>
|
||
</section>
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>Kurzvorschau</h2><span class="muted">Nächste Stunden</span></div>
|
||
<div class="hour-strip" id="hourStrip"></div>
|
||
</section>
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>Datenquellen-Status</h2><span class="muted" id="sourceStatusSummary">Prüfe…</span></div>
|
||
<div class="source-status-grid" id="sourceStatusGrid"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section class="view" data-view="radar">
|
||
<section class="glass-card map-panel">
|
||
<div class="section-head">
|
||
<div><h2>Radar-Karte</h2><p class="muted no-margin">DWD WMS · OpenStreetMap · Zeitleiste</p></div>
|
||
<span class="muted" id="mapMeta">Lade…</span>
|
||
</div>
|
||
<div id="map"></div>
|
||
<div class="panel-inner" id="radarTimeline">
|
||
<div class="section-head"><strong>Radar-Zeitleiste</strong><span class="muted" id="radarTimeLabel">–</span></div>
|
||
<div class="timeline-controls">
|
||
<button id="radarFirstBtn" class="btn btn-secondary icon-btn">⏮</button>
|
||
<button id="radarPrevBtn" class="btn btn-secondary icon-btn">◀</button>
|
||
<button id="radarPlayBtn" class="btn btn-secondary icon-btn">▶</button>
|
||
<button id="radarNextBtn" class="btn btn-secondary icon-btn">▶</button>
|
||
<button id="radarLastBtn" class="btn btn-secondary icon-btn">⏭</button>
|
||
<input id="radarSlider" type="range" min="0" max="0" value="0" />
|
||
</div>
|
||
<div class="timeline-meta">
|
||
<label class="inline-check"><input type="checkbox" id="useLocalRadar" /> Lokale Render-Frames</label>
|
||
<label class="inline-check"><input type="checkbox" id="showWarningsOnMap" checked /> Warnungen</label>
|
||
<span class="muted" id="radarFrameInfo"></span>
|
||
</div>
|
||
</div>
|
||
<div class="map-actions">
|
||
<button id="centerMapBtn" class="btn btn-secondary">Auf Standort zentrieren</button>
|
||
<button id="reloadRadarLayersBtn" class="btn btn-secondary">Layer neu laden</button>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
|
||
<section class="view" data-view="warnings">
|
||
<section class="glass-card">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>Wetterwarnungen</h2>
|
||
<p class="muted no-margin">Standortgenau via DWD-Warncell-IDs (WFS)</p>
|
||
</div>
|
||
<label class="inline-check"><input type="checkbox" id="warningsLocalOnly" checked /> Nur Standort</label>
|
||
</div>
|
||
<div id="warncellInfo" class="warncell-info hidden"></div>
|
||
<div id="warningsList" class="warnings-list"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section class="view" data-view="hourly">
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>Stundenansicht</h2><span class="muted">48 Stunden</span></div>
|
||
<div class="table-wrap"><table><thead><tr><th>Zeit</th><th>Wetter</th><th>Temp.</th><th>Regen</th><th>Wolken</th><th>Wind</th><th>Böen</th></tr></thead><tbody id="hourlyTable"></tbody></table></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section class="view" data-view="daily">
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>7-Tage Forecast</h2><span class="muted" id="dailySource"></span></div>
|
||
<div class="days" id="dailyForecast"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section class="view" data-view="raw">
|
||
<section class="glass-card">
|
||
<div class="section-head">
|
||
<div><h2>Radar-Rohdaten</h2><p class="muted no-margin">DWD OpenData · lokaler Renderer</p></div>
|
||
<button id="syncRadarBtn" class="btn btn-secondary">Sync starten</button>
|
||
</div>
|
||
<div class="table-wrap"><table><thead><tr><th>Datei</th><th>Größe</th><th>Geändert</th><th>Download</th></tr></thead><tbody id="radarFiles"></tbody></table></div>
|
||
</section>
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>Gerenderte Frames</h2><span class="muted" id="renderedCount"></span></div>
|
||
<div class="rendered-grid" id="renderedFrames"></div>
|
||
</section>
|
||
<section class="glass-card">
|
||
<div class="section-head"><h2>Datenquellen</h2></div>
|
||
<div class="source-list" id="sourceList"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<section class="view" data-view="settings">
|
||
<section class="glass-card">
|
||
<h2>Einstellungen</h2>
|
||
<div class="settings-grid">
|
||
<label>Temperatureinheit<select id="unitTemp"><option value="celsius">°C</option><option value="fahrenheit">°F</option></select></label>
|
||
<label>Windeinheit<select id="unitWind"><option value="kmh">km/h</option><option value="ms">m/s</option><option value="kn">kn</option></select></label>
|
||
<label>Radar-Zeitleiste<select id="radarMinutes"><option value="60">60 Min.</option><option value="90">90 Min.</option><option value="120" selected>120 Min.</option></select></label>
|
||
<label>Standard-Standort<button id="saveDefaultLocationBtn" class="btn btn-secondary full-width">Aktuellen Ort speichern</button></label>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
</div>
|
||
</main>
|
||
|
||
<footer class="site-footer">
|
||
<div class="container footer-grid">
|
||
<div>
|
||
<strong>HexaWetter</strong>
|
||
<p>Selfhosted Wetterportal von HexaHost. Keine amtliche Wetterberatung.</p>
|
||
<p class="muted">Daten: DWD Open Data · Open-Meteo · Bright Sky · OpenStreetMap</p>
|
||
</div>
|
||
<div>
|
||
<strong>Rechtliches</strong>
|
||
<ul>
|
||
<li><a href="impressum.html">Impressum</a></li>
|
||
<li><a href="datenschutz.html">Datenschutz</a></li>
|
||
</ul>
|
||
</div>
|
||
<div>
|
||
<strong>System</strong>
|
||
<ul>
|
||
<li><a href="admin.html">Admin-Bereich</a></li>
|
||
<li><a href="/api/health" target="_blank" rel="noopener">API Health</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||
<script src="app.js"></script>
|
||
</body>
|
||
</html>
|