Files
HexaWetter/frontend/index.html

230 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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">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="settings">Einstellungen</button>
</nav>
<section class="view active" data-view="dashboard">
<section class="grid">
<article class="glass-card card card-accent"><h2>Aktuelles Wetter</h2><p class="big" id="currentTemp"></p><p id="currentMeta" class="muted">Lade…</p></article>
<article class="glass-card card card-accent"><h2>Regen · 24 h</h2><p class="big" id="rainOutlookBig"></p><p id="rainOutlookMeta" 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>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>
<section class="view" data-view="radar">
<section class="glass-card map-panel">
<div class="section-head">
<div>
<h2>Wetterkarte</h2>
<p class="muted no-margin">DWD-Radar · Open-Meteo-Regenvorhersage · OpenStreetMap</p>
</div>
<span class="muted" id="mapMeta">Lade…</span>
</div>
<div class="map-mode-toggle" role="tablist" aria-label="Kartenmodus">
<button type="button" class="map-mode-btn active" data-map-mode="radar">Radar · Vergangenheit</button>
<button type="button" class="map-mode-btn" data-map-mode="forecast">Regenvorhersage · Zukunft</button>
</div>
<div id="map"></div>
<div class="panel-inner" id="radarTimeline">
<div class="section-head"><strong id="timelineTitle">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 map-mode-radar-only"><input type="checkbox" id="showWarningsOnMap" checked /> Warnungen</label>
<span class="muted" id="radarFrameInfo"></span>
</div>
<p class="muted no-margin" id="timelineHint" style="margin-top:8px;font-size:0.85rem">Vergangenheit · 5-Min-Schritte · DWD-Radar</p>
<div class="precip-legend map-mode-forecast-only hidden" id="precipLegend">
<span><i class="swatch light"></i> leicht</span>
<span><i class="swatch medium"></i> mäßig</span>
<span><i class="swatch heavy"></i> stark</span>
<span class="muted">Modell · ~25 km · Open-Meteo</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">Karte 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 · Temperatur, Regen & Wind</span>
</div>
<div class="hourly-chart-wrap">
<canvas id="hourlyChart" aria-label="Stundenverlauf Temperatur, Regen und Wind"></canvas>
</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 daily-forecast-panel">
<div class="section-head">
<div>
<h2>7-Tage Forecast</h2>
<p class="muted no-margin">Temperatur, Regen &amp; Wind · Open-Meteo</p>
</div>
<span class="muted" id="dailySource"></span>
</div>
<div class="days days-forecast" id="dailyForecast"></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>Regen-Karte<select id="forecastHours"><option value="6">6 h</option><option value="12">12 h</option><option value="24" selected>24 h</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="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<script src="app.js"></script>
</body>
</html>