dudi/templates/app.html.twig
Simon Kühn a8f6692de4 Add stopwatch fill button and asset cache-busting
- Stopwatch ⏱ button appears in add/quick-book rows when sw >= 1s, fills input with floor(seconds)
- AppController passes md5 hashes of app.js/style.css to template for automatic cache-busting

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 11:00:54 +02:00

332 lines
13 KiB
Twig
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">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
<meta name="theme-color" content="#f5f4f0"/>
<meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<title>Dudi</title>
<link rel="stylesheet" href="style.css?v={{ cssv }}"/>
</head>
<body>
<div class="main-wrap">
<div class="hdr">
<div>
<img src="logo.png" alt="Dudi" class="hdr-logo"/>
<div class="hdr-sub" id="tlbl"></div>
</div>
<span id="sw" class="sw">0.00s</span>
<div class="hdr-btns">
<button class="btn-menu" id="btnData">⋯</button>
<button class="btn-add" id="btnNew">+</button>
</div>
</div>
<div class="main" id="main"></div>
</div>
<div id="ov" style="display:none"></div>
<!-- ── Templates ──────────────────────────────────────────────────────────── -->
<template id="tpl-hint">
<div class="hint">Menü → "Zum Startbildschirm" für App-Icon<button class="hclose">×</button></div>
</template>
<template id="tpl-empty">
<div class="empty"><div style="font-size:40px;opacity:.4;margin-bottom:12px">🎯</div>Noch keine Ziele.<br>Tippe auf <strong>+</strong> um zu starten.</div>
</template>
<template id="tpl-dot">
<div></div>
</template>
<template id="tpl-nosets">
<div class="nosets">Noch kein Eintrag</div>
</template>
<template id="tpl-set-row">
<div class="set-row">
<span></span>
<button class="sdel">×</button>
</div>
</template>
<template id="tpl-add-row">
<div class="add-row">
<input class="num-in" type="number" min="1"/>
<span class="ulbl"></span>
<button class="btn-sw-fill" style="display:none">⏱</button>
<button class="btn-as">Eintragen</button>
</div>
</template>
<template id="tpl-panel">
<div class="dpanel">
<div class="dpanel-hdr">
<span class="dpanel-title"></span>
<span class="dpanel-sub"></span>
</div>
<div class="dpanel-body"></div>
</div>
</template>
<template id="tpl-qb-row">
<div class="qb-row">
<div class="qb-name"></div>
<div class="qb-stat"></div>
<input class="num-in" type="number" min="1"/>
<button class="btn-sw-fill" style="display:none">⏱</button>
<button class="btn-as">Eintragen</button>
</div>
</template>
<template id="tpl-name-view">
<div class="name-wrap">
<div class="goal-name"></div>
<button class="btn-ren">✎</button>
</div>
</template>
<template id="tpl-name-edit">
<div class="name-wrap">
<input class="ren-input" type="text"/>
</div>
</template>
<template id="tpl-card-collapsed">
<div class="card">
<div class="card-hdr">
<div class="card-bd" style="flex:1;min-width:0">
<div class="goal-meta">Noch <span class="m-dr"></span>T · endet <span class="m-end"></span> · heute: <span class="m-heute"></span><br>total: <span class="m-total"></span></div>
</div>
<span class="badge"></span>
<span class="chevron">▸</span>
</div>
<div style="padding:0 16px 12px">
<div class="prog-track"><div class="prog-fill"></div></div>
</div>
</div>
</template>
<template id="tpl-card-expanded">
<div class="card">
<div class="card-hdr">
<div class="card-bd" style="flex:1;min-width:0">
<div class="goal-meta">Noch <span class="m-dr"></span>T · endet <span class="m-end"></span></div>
</div>
<span class="badge"></span>
<span class="chevron">▴</span>
</div>
<div class="prog-wrap">
<div class="prog-track"><div class="prog-fill"></div></div>
<div class="prog-row">
<span class="pr-done"></span>
<span class="pr-pct"></span>
</div>
</div>
<div class="heute-stats">
<div class="heute-group">
<div class="heute-lbl">Heute</div>
<div class="heute-inner">
<div class="stat">
<div class="slbl">Gemacht</div>
<div class="sval"><span class="sv-tdone"></span><div class="sunit"></div></div>
</div>
<div class="stat">
<div class="slbl">Tagesziel</div>
<div class="sval"><span class="sv-daily"></span><div class="sunit"></div></div>
</div>
<div class="stat">
<div class="slbl">Noch</div>
<div class="sval sv-noch"><span class="sv-st"></span><div class="sunit"></div></div>
</div>
</div>
</div>
</div>
<div class="dots-sec">
<div class="dots-lbl">Verlauf — heute &amp; gestern bearbeitbar</div>
<div class="dots-wrap"></div>
<div class="legend">
<span class="leg"><span class="ldot" style="background:rgba(37,99,235,.3)"></span>Puffer</span>
<span class="leg"><span class="ldot" style="background:rgba(22,163,74,.3)"></span>Erreicht</span>
<span class="leg"><span class="ldot" style="background:rgba(217,119,6,.3)"></span>Teilweise</span>
<span class="leg"><span class="ldot" style="background:rgba(220,38,38,.3)"></span>Verpasst</span>
</div>
</div>
<div class="card-foot"><button class="btn-del">Ziel löschen</button></div>
</div>
</template>
<template id="tpl-sheet">
<div class="sheet">
<div class="shandle"></div>
</div>
</template>
<template id="tpl-login">
<div>
<div class="stitle">Anmelden</div>
<div class="ssub">Dudi</div>
<div class="login-err" style="display:none"></div>
<div class="ff"><label>E-Mail</label><input class="fi lf-email" type="email" autocomplete="email"/></div>
<div class="ff"><label>Passwort</label><input class="fi lf-pass" type="password" autocomplete="current-password"/></div>
<div class="factions"><button class="btn-p lf-sub">Anmelden</button></div>
<div style="text-align:center;margin-top:8px"><button class="btn-lnk lf-fgt">Passwort vergessen?</button></div>
</div>
</template>
<template id="tpl-forgot-pw">
<div>
<div class="stitle">Passwort vergessen</div>
<div class="ssub">Wir schicken dir einen Reset-Link</div>
<div class="ff"><label>E-Mail</label><input class="fi fp-email" type="email" autocomplete="email"/></div>
<div class="login-err" style="display:none"></div>
<div class="factions">
<button class="btn-p fp-sub">Link senden</button>
<button class="btn-c fp-back">Zurück</button>
</div>
</div>
</template>
<template id="tpl-email-sent">
<div>
<div class="stitle">E-Mail gesendet</div>
<div class="ssub">Falls die Adresse bekannt ist, erhältst du in Kürze einen Reset-Link.</div>
<div class="factions"><button class="btn-p es-ok">OK</button></div>
</div>
</template>
<template id="tpl-reset-pw">
<div>
<div class="stitle">Neues Passwort</div>
<div class="ff"><label>Neues Passwort</label><input class="fi rp-pass" type="password" autocomplete="new-password" placeholder="mind. 8 Zeichen"/></div>
<div class="login-err" style="display:none"></div>
<div class="factions"><button class="btn-p rp-sub">Passwort setzen</button></div>
</div>
</template>
<template id="tpl-pw-changed">
<div>
<div class="stitle">Passwort geändert</div>
<div class="ssub">Du kannst dich jetzt anmelden.</div>
<div class="factions"><button class="btn-p pc-ok">Anmelden</button></div>
</div>
</template>
<template id="tpl-change-name">
<div>
<div class="stitle">Name ändern</div>
<div class="ff"><label>Dein Name</label><input class="fi cn-name" type="text" autocomplete="name"/></div>
<div class="login-err" style="display:none"></div>
<div class="factions">
<button class="btn-p cn-sub">Speichern</button>
<button class="btn-c cn-can">Abbrechen</button>
</div>
</div>
</template>
<template id="tpl-change-pw">
<div>
<div class="stitle">Passwort ändern</div>
<div class="ff"><label>Aktuelles Passwort</label><input class="fi cp-old" type="password" autocomplete="current-password"/></div>
<div class="ff"><label>Neues Passwort</label><input class="fi cp-new" type="password" autocomplete="new-password" placeholder="mind. 8 Zeichen"/></div>
<div class="ff"><label>Neues Passwort bestätigen</label><input class="fi cp-new2" type="password" autocomplete="new-password" placeholder="mind. 8 Zeichen"/></div>
<div class="login-err" style="display:none"></div>
<div class="factions">
<button class="btn-p cp-sub">Ändern</button>
<button class="btn-c cp-can">Abbrechen</button>
</div>
</div>
</template>
<template id="tpl-register">
<div>
<div class="stitle">Konto erstellen</div>
<div class="ssub">Du wurdest eingeladen</div>
<div class="ff"><label>Dein Name</label><input class="fi rg-name" type="text" autocomplete="name" placeholder="Wie sollen wir dich nennen?"/></div>
<div class="ff"><label>E-Mail</label><input class="fi rg-email" type="email" autocomplete="email"/></div>
<div class="ff"><label>Passwort</label><input class="fi rg-pass" type="password" autocomplete="new-password" placeholder="mind. 8 Zeichen"/></div>
<div class="ff"><label>Passwort bestätigen</label><input class="fi rg-pass2" type="password" autocomplete="new-password" placeholder="Passwort wiederholen"/></div>
<div class="login-err" style="display:none"></div>
<div class="factions"><button class="btn-p rg-sub">Registrieren</button></div>
</div>
</template>
<template id="tpl-new-goal">
<div>
<div class="stitle">Neues Ziel</div>
<div class="ff"><label>Übung / Gewohnheit</label><input class="fi ng-name" type="text" placeholder="Liegestütz, Plank …"/></div>
<div class="fgrid">
<div class="ff"><label>Einheit</label><input class="fi ng-unit" type="text" value="Stück"/></div>
<div class="ff"><label>Tagesziel</label><input class="fi ng-daily" type="number" min="1" value="50"/></div>
</div>
<div class="ff"><label>Dauer in Tagen</label><input class="fi ng-days" type="number" min="7" max="365" value="30"/></div>
<div class="factions">
<button class="btn-p ng-sub">Ziel starten</button>
<button class="btn-c ng-can">Abbrechen</button>
</div>
</div>
</template>
<template id="tpl-data-menu">
<div>
<div class="stitle">Daten verwalten</div>
<div class="ssub">Export, Import und Backup</div>
<button class="dbtn dm-exp"><span class="dico">⬇</span><span class="dlbl">Exportieren<span class="dsub">Alle Ziele als JSON-Datei speichern</span></span></button>
<button class="dbtn dm-imp"><span class="dico">⬆</span><span class="dlbl">Importieren<span class="dsub">Backup laden oder zusammenführen</span></span></button>
<div class="ddiv"></div>
<button class="dbtn dm-inv"><span class="dico">🔗</span><span class="dlbl">Freund einladen<span class="dsub">Einladungslink generieren</span></span></button>
<button class="dbtn dm-invlist"><span class="dico">📋</span><span class="dlbl">Meine Einladungen<span class="dsub">Status aller gesendeten Einladungen</span></span></button>
<div class="ddiv"></div>
<button class="dbtn dm-name"><span class="dico">✏️</span><span class="dlbl">Name ändern</span></button>
<button class="dbtn dm-cpw"><span class="dico">🔑</span><span class="dlbl">Passwort ändern</span></button>
<button class="dbtn dm-lgout"><span class="dico">→</span><span class="dlbl">Abmelden</span></button>
<button class="btn-c dm-cls" style="width:100%;margin-top:4px;text-align:center">Schließen</button>
<div class="ddiv" style="margin-top:16px"></div>
<button class="dbtn ddanger dm-clr"><span class="dico">✕</span><span class="dlbl">Alle Daten löschen<span class="dsub">Kann nicht rückgängig gemacht werden</span></span></button>
</div>
</template>
<template id="tpl-invite-form">
<div>
<div class="stitle">Freund einladen</div>
<div class="ssub">Link gilt 7 Tage und kann nur einmal verwendet werden</div>
<div class="ff"><label>Name (für deine Übersicht)</label><input class="fi inv-name" type="text" placeholder="z.B. Max"/></div>
<div class="factions">
<button class="btn-p inv-gen">Link generieren</button>
<button class="btn-c inv-cancel">Abbrechen</button>
</div>
</div>
</template>
<template id="tpl-invite-link">
<div>
<div class="stitle"></div>
<div class="ssub">Link gilt 7 Tage und kann nur einmal verwendet werden</div>
<div class="ff"><input class="fi il-url" type="text" readonly/></div>
<div class="factions">
<button class="btn-p il-copy">Link kopieren</button>
<button class="btn-c il-close">Schließen</button>
</div>
</div>
</template>
<template id="tpl-invite-list">
<div>
<div class="stitle">Meine Einladungen</div>
<div class="dpanel-body"></div>
<div class="factions"><button class="btn-c il-close">Schließen</button></div>
</div>
</template>
<template id="tpl-invite-row">
<div class="set-row">
<span style="flex:1"><strong class="ir-label"></strong><span class="ir-detail" style="opacity:.6;font-size:.85em"></span></span>
<button class="ir-copy btn-lnk" style="font-size:.8em;display:none">🔗 Link</button>
<span class="ir-status" style="font-size:.85em;font-weight:600"></span>
</div>
</template>
<script src="app.js?v={{ jsv }}"></script>
</body>
</html>