Codex-Handover P0: Daten-Ehrlichkeit (Seed=Demo statt 'live/verfügbar', Fake-Namen+Mojibake raus), Finder modell-Param, LIVE_URL via Env, 404-Seite+Favicon, Umami nur mit echter ID, ehrliche Texte/Semantik, Demo-CTA entschärft

This commit is contained in:
2026-06-28 16:32:06 +00:00
parent fba01a70bb
commit ed41ea54d2
9 changed files with 50 additions and 29 deletions
+12 -9
View File
@@ -15,7 +15,7 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
<WeatherBanner />
<span class="eyebrow" style="margin-top:1rem"><span class="dot ok live"></span>Live-Verfügbarkeit · eigener Scraper</span>
<h1>Wo gibt es gerade ein&nbsp;Klimagerät?</h1>
<p class="lead">Bei Hitze ist alles vergriffen. Kühlfinder ist dein Kontrollzentrum: <strong>live sehen, welcher Markt in der Nähe eins auf Lager hat</strong> Baumärkte, Elektromärkte, Online &amp; eBay mit Prognose, Preis-Check gegen Wucher und Alarm. <em>Die nächste Hitzewelle kommt bestimmt.</em></p>
<p class="lead">Bei Hitze ist alles vergriffen. Kühlfinder prüft <strong>Preise live direkt bei Händlern</strong> und zeigt ehrlich, wo geprüft ist plus Standort-Abdeckung, Preis-Check gegen Wucher und Alarm. <em>Die nächste Hitzewelle kommt bestimmt.</em></p>
<form class="herobar" action="/karte" method="get">
<input name="plz" inputmode="numeric" placeholder="PLZ oder Ort …" aria-label="PLZ oder Ort" />
<button class="btn" type="submit" data-umami-event="hero_plz_suche">Verfügbarkeit zeigen</button>
@@ -23,12 +23,12 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
</form>
<div class="livewrap reveal">
<div class="pills">
<span class="pill-stat"><b class="num" id="p-ac" data-count="0">…</b>&nbsp;Märkte mit Klimagerät jetzt</span>
<span class="pill-stat"><b class="num" id="p-total" data-count="0">…</b>&nbsp;Märkte überwacht</span>
<span class="pill-stat"><b class="num" id="p-ac">…</b>&nbsp;Live-Preise geprüft</span>
<span class="pill-stat"><b class="num" id="p-total" data-count="0">…</b>&nbsp;Märkte (Abdeckung)</span>
<span class="pill-stat"><b class="num">6</b>&nbsp;Länder · <span id="p-chains">…</span> Ketten</span>
</div>
<div class="livecard card">
<div class="lc-head"><span class="dot ok live"></span> Gerade verfügbar</div>
<div class="lc-head"><span class="dot ok live"></span> Live geprüfte Preise</div>
<ul class="livelist" id="livelist"><li class="skel" style="height:40px"></li><li class="skel" style="height:40px"></li><li class="skel" style="height:40px"></li></ul>
<a class="btn sm" href="/karte">Alle auf der Karte →</a>
</div>
@@ -122,13 +122,16 @@ const Bell='<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="
<script>
const euro=(n,c)=>n==null?'':new Intl.NumberFormat('de-DE',{style:'currency',currency:c||'EUR',maximumFractionDigits:0}).format(n);
document.getElementById('locbtn')?.addEventListener('click',e=>{ if(navigator.geolocation){ /* Karte hat eigene Standortfunktion */ } });
const CRAWLER=(import.meta.env.PUBLIC_CRAWLER_URL)||'http://vnqwgi4gq520hs1p4bsgi4w6.46.224.49.66.sslip.io';
fetch('/data/monitor.json').then(r=>r.json()).then(d=>{
const ac=document.getElementById('p-ac'), tot=document.getElementById('p-total');
ac.setAttribute('data-count', d.stats.withAC); ac.removeAttribute('data-done');
const tot=document.getElementById('p-total');
tot.setAttribute('data-count', d.stats.storesTotal); tot.removeAttribute('data-done');
const chains=new Set(d.stores.map(s=>s.c)); document.getElementById('p-chains').textContent=chains.size;
document.getElementById('p-chains').textContent=new Set(d.stores.map(s=>s.c)).size;
window.kfAnim && window.kfAnim();
const avail=d.stores.filter(s=>s.any.a && s.any.minP).sort(()=>Math.random()-0.5).slice(0,6);
document.getElementById('livelist').innerHTML = avail.map(s=>`<li><span><span class="flag">${s.flag||''}</span> <span class="lm">${s.c}</span> <span class="lc">${s.ci}</span></span><span class="lp">${euro(s.any.minP,s.cur)}</span></li>`).join('') || '<li class="lc">Aktuell sehr knapp Alarm setzen lohnt sich.</li>';
}).catch(()=>{});
fetch(CRAWLER+'/api/live').then(r=>r.json()).then(d=>{
const offers=(d.offers||[]).filter(o=>o.price);
document.getElementById('p-ac').textContent=offers.length;
document.getElementById('livelist').innerHTML = offers.slice(0,6).map(o=>`<li><span><span class="lm">${o.chain}</span> <span class="lc">${o.name}</span></span><span class="lp">${euro(o.price)}</span></li>`).join('') || '<li class="lc">Crawler startet gleich wieder reinschauen.</li>';
}).catch(()=>{document.getElementById('p-ac').textContent='';document.getElementById('livelist').innerHTML='<li class="lc">Live-Preise gerade nicht erreichbar.</li>';});
</script>