Ein Wunschtag ohne Tauschpartner bedeutet jetzt: die Person übernimmt dort einen offenen Platz; ihr alter Platz wird beim Ausführen sofort fair nachbesetzt, ohne sie selbst. Rollen werden bei allen Tauschformen geprüft. Bearbeiter können Person und Wunschtag einer Anfrage nachtragen, etwa aus der Notiz. Der Anfragedialog zeigt, was am Wunschtag los ist. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
347 lines
24 KiB
HTML
347 lines
24 KiB
HTML
<!doctype html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||
<meta name="color-scheme" content="light">
|
||
<title>Rotatory – Morning-Meeting-Moderation</title>
|
||
<link rel="stylesheet" href="fonts/fonts.css">
|
||
<link rel="stylesheet" href="style.css">
|
||
<link rel="icon" href="logo/favicon.svg" type="image/svg+xml">
|
||
</head>
|
||
<body>
|
||
<header class="topbar">
|
||
<h1><svg class="logo" viewBox="0 0 800 800" aria-hidden="true" focusable="false"><g class="arc arc-a" transform="rotate(41.105 400 400)"><g transform="matrix(0.577,0.597,-0.597,0.577,400,400)"><g transform="matrix(0.9,0,0,0.9,0,0)"><ellipse rx="400" ry="400" cx="0" cy="0" fill="none" stroke="currentColor" stroke-width="55" stroke-linecap="round" stroke-dasharray="40 60" pathLength="100"/></g><g transform="matrix(1,0,0,1,15,12)"><path fill="currentColor" d="M168,185C168,185,95,346,95,346C95,346,288,329,288,329C288,329,168,185,168,185Z"/></g></g></g><g class="arc arc-b" transform="rotate(220.305 400 400)"><g transform="matrix(0.577,0.597,-0.597,0.577,400,400)"><g transform="matrix(0.9,0,0,0.9,0,0)"><ellipse rx="400" ry="400" cx="0" cy="0" fill="none" stroke="currentColor" stroke-width="55" stroke-linecap="round" stroke-dasharray="40 60" pathLength="100"/></g><g transform="matrix(1,0,0,1,15,12)"><path fill="currentColor" d="M168,185C168,185,95,346,95,346C95,346,288,329,288,329C288,329,168,185,168,185Z"/></g></g></g></svg><span>Rotatory</span></h1>
|
||
<nav aria-label="Bereiche">
|
||
<a href="#kalender" data-view="kalender">Kalender</a>
|
||
<a href="#personen" data-view="personen">Personen</a>
|
||
<a href="#abwesenheiten" data-view="abwesenheiten">Abwesenheiten</a>
|
||
<a href="#anfragen" data-view="anfragen">Anfragen <span id="requests-count" class="count" hidden></span></a>
|
||
<a href="#bugs" data-view="bugs">Bugs <span id="bugs-count" class="count" hidden></span></a>
|
||
<a href="#einstellungen" data-view="einstellungen">Einstellungen</a>
|
||
</nav>
|
||
<button type="button" id="auth-button" class="topbar-action" hidden>Anmelden</button>
|
||
</header>
|
||
|
||
<main id="main">
|
||
<!-- Kalender -->
|
||
<section id="view-kalender" class="view" aria-labelledby="cal-title">
|
||
<div class="toolbar">
|
||
<div class="month-nav">
|
||
<button type="button" id="prev-month" class="icon-button" aria-label="Vorheriger Monat"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button>
|
||
<h2 id="cal-title">Monat</h2>
|
||
<button type="button" id="next-month" class="icon-button" aria-label="Nächster Monat"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button>
|
||
<button type="button" id="today-month" class="ghost">Heute</button>
|
||
</div>
|
||
<div class="actions">
|
||
<button type="button" id="open-request" class="primary" hidden>Tausch anfragen …</button>
|
||
<button type="button" id="open-plan" class="primary">Auslosen …</button>
|
||
<button type="button" id="open-nextcloud">Nextcloud …</button>
|
||
<a id="download-ics" class="button ghost" href="#" download>ICS-Datei</a>
|
||
</div>
|
||
</div>
|
||
<p id="cal-hint" class="hint" hidden></p>
|
||
<div class="calendar" aria-labelledby="cal-title">
|
||
<div class="weekdays" aria-hidden="true">
|
||
<div>Mo</div><div>Di</div><div>Mi</div><div>Do</div><div>Fr</div>
|
||
</div>
|
||
<div id="cal-grid" class="days"></div>
|
||
</div>
|
||
<div class="legend">
|
||
<span><span class="badge main">H</span> Hauptmoderation</span>
|
||
<span><span class="badge co">N</span> Nebenmoderation</span>
|
||
<span><span class="lock" aria-hidden="true"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="11" width="14" height="10" rx="1.5"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg></span> fixiert</span>
|
||
<span><span class="avatar empty small" aria-hidden="true">?</span> unbesetzt</span>
|
||
<span><span class="req-mark" aria-hidden="true"></span> Tauschanfrage offen</span>
|
||
</div>
|
||
<section class="stats" aria-labelledby="stats-title">
|
||
<h3 id="stats-title">Einsätze in diesem Monat</h3>
|
||
<div id="stats"></div>
|
||
</section>
|
||
</section>
|
||
|
||
<!-- Personen -->
|
||
<section id="view-personen" class="view" hidden aria-labelledby="persons-title">
|
||
<h2 id="persons-title">Personen</h2>
|
||
<form id="person-form" class="card form-grid" autocomplete="off">
|
||
<input type="hidden" name="id">
|
||
<label>Vorname <input name="firstName" required maxlength="60"></label>
|
||
<label>Nachname <input name="lastName" required maxlength="60"></label>
|
||
<label>E-Mail (optional, für Kalendereinladungen) <input name="email" type="email" maxlength="120"></label>
|
||
<label>Notiz / Grund (optional) <input name="note" maxlength="300" placeholder="z. B. Azubi, nur Nebenmoderation"></label>
|
||
<div class="photo-field wide" id="photo-field" tabindex="0" aria-label="Foto: Datei ablegen oder mit Strg+V einfügen">
|
||
<span class="avatar plain photo-preview" id="photo-preview" aria-hidden="true"></span>
|
||
<div class="photo-text">
|
||
<strong>Foto</strong>
|
||
<span id="photo-status" class="hint">Kein Foto. Datei wählen, hierher ziehen oder mit Strg+V aus der Zwischenablage einfügen.</span>
|
||
<div class="photo-actions">
|
||
<button type="button" id="photo-choose">Datei wählen</button>
|
||
<button type="button" id="photo-paste" class="ghost">Aus Zwischenablage einfügen</button>
|
||
<button type="button" id="photo-clear" class="ghost" hidden>Foto entfernen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<fieldset class="checks">
|
||
<legend>Rolle in der Rotation</legend>
|
||
<label><input type="checkbox" name="canMain" checked> Hauptmoderation möglich</label>
|
||
<label><input type="checkbox" name="canCo" checked> Nebenmoderation möglich</label>
|
||
<label><input type="checkbox" name="active" checked> Aktiv (in der Belegschaft)</label>
|
||
</fieldset>
|
||
<fieldset class="checks">
|
||
<legend>Feste freie Wochentage (Teilzeit)</legend>
|
||
<label><input type="checkbox" name="freeDays" value="1"> Mo</label>
|
||
<label><input type="checkbox" name="freeDays" value="2"> Di</label>
|
||
<label><input type="checkbox" name="freeDays" value="3"> Mi</label>
|
||
<label><input type="checkbox" name="freeDays" value="4"> Do</label>
|
||
<label><input type="checkbox" name="freeDays" value="5"> Fr</label>
|
||
</fieldset>
|
||
<p class="hint">Beide Rollen abwählen = Nicht-Moderator (bleibt angelegt, wird nie ausgelost).</p>
|
||
<div class="form-actions">
|
||
<button type="submit" class="primary" id="person-submit">Person anlegen</button>
|
||
<button type="button" class="ghost" id="person-cancel" hidden>Abbrechen</button>
|
||
<span class="spacer"></span>
|
||
<button type="button" id="open-contacts">Aus Nextcloud importieren …</button>
|
||
</div>
|
||
</form>
|
||
<div class="list-tools">
|
||
<button type="button" class="ghost" id="remove-placeholders">Platzhalter-Fotos entfernen</button>
|
||
<span class="hint" id="placeholder-hint"></span>
|
||
</div>
|
||
<ul id="person-list" class="person-list"></ul>
|
||
<input type="file" id="photo-input" accept="image/*" hidden>
|
||
</section>
|
||
|
||
<!-- Abwesenheiten -->
|
||
<section id="view-abwesenheiten" class="view" hidden aria-labelledby="absences-title">
|
||
<h2 id="absences-title">Abwesenheiten</h2>
|
||
<form id="absence-form" class="card form-grid" autocomplete="off">
|
||
<label>Person <select name="personId" required></select></label>
|
||
<label>Art
|
||
<select name="type">
|
||
<option value="urlaub">Urlaub</option>
|
||
<option value="krankheit">Krankheit (geplant)</option>
|
||
<option value="frei">Frei (Gleittag, Teilzeit)</option>
|
||
<option value="sonstiges">Sonstiges</option>
|
||
</select>
|
||
</label>
|
||
<label>Von <input type="date" name="from" required></label>
|
||
<label>Bis <input type="date" name="to" required></label>
|
||
<label class="wide">Notiz (optional) <input name="note" maxlength="200"></label>
|
||
<div class="form-actions">
|
||
<button type="submit" class="primary">Abwesenheit eintragen</button>
|
||
</div>
|
||
</form>
|
||
<form id="absence-import" class="card form-grid" autocomplete="off">
|
||
<h3 class="wide">Aus Nextcloud-Kalender übernehmen</h3>
|
||
<label class="wide">Quellkalender (Termine wie „Vorname Nachname (Urlaub)", „… (krank)", „… (frei)")
|
||
<select name="calendarHref" required><option value="">– Kalender laden …</option></select>
|
||
</label>
|
||
<label>Von Monat <input type="month" name="from" required></label>
|
||
<label>Bis Monat <input type="month" name="to" required></label>
|
||
<p class="hint">Bereits importierte Einträge im Zeitraum werden ersetzt, manuelle bleiben. Namen, die keiner Person zugeordnet werden können, werden aufgelistet.</p>
|
||
<p id="absence-import-result" class="result wide" hidden></p>
|
||
<div class="form-actions">
|
||
<button type="submit" class="primary" id="absence-import-go">Importieren</button>
|
||
</div>
|
||
</form>
|
||
<p class="hint">Abwesenheiten wirken auf die nächste Auslosung. Bereits ausgeloste Tage werden markiert und lassen sich im Kalender neu auslosen.</p>
|
||
<label class="inline" id="absence-toggle"><input type="checkbox" id="absence-show-past"> Vergangene anzeigen</label>
|
||
<ul id="absence-list" class="list"></ul>
|
||
</section>
|
||
|
||
<!-- Anfragen (nur Bearbeiter) -->
|
||
<section id="view-anfragen" class="view" hidden aria-labelledby="requests-title">
|
||
<h2 id="requests-title">Tauschanfragen</h2>
|
||
<p class="hint">Teammitglieder melden hier, wenn sie an einem Tag nicht können. Nichts wird automatisch geändert: „Ausführen" tauscht wie gewünscht, „Tag öffnen" lässt dich selbst wählen.</p>
|
||
<ul id="request-list" class="list"></ul>
|
||
<label class="inline" id="requests-toggle"><input type="checkbox" id="requests-show-done"> Erledigte und abgelehnte anzeigen</label>
|
||
<ul id="request-list-done" class="list" hidden></ul>
|
||
</section>
|
||
|
||
<!-- Bugs (nur Bearbeiter) -->
|
||
<section id="view-bugs" class="view" hidden aria-labelledby="bugs-title">
|
||
<h2 id="bugs-title">Bugs</h2>
|
||
<p class="hint">Gemeldet über den Käfer-Button unten rechts. „Prompt kopieren" legt eine fertige Anweisung für Claude in die Zwischenablage, „Screenshot kopieren" das Bild dazu. Beides zusammen in Claude Code einfügen, dann wird der Bug direkt bearbeitet.</p>
|
||
<p class="hint" id="bugs-clipboard-hint" hidden>Diese Adresse ist nicht verschlüsselt (http). Bilder kann der Browser hier nicht direkt in die Zwischenablage legen: „Screenshot öffnen" nutzen und dort mit Rechtsklick „Bild kopieren" wählen. Über eine https-Adresse geht es mit einem Klick.</p>
|
||
<ul id="bug-list" class="list bug-list"></ul>
|
||
<label class="inline" id="bugs-toggle"><input type="checkbox" id="bugs-show-done"> Erledigte anzeigen</label>
|
||
<ul id="bug-list-done" class="list bug-list" hidden></ul>
|
||
</section>
|
||
|
||
<!-- Einstellungen -->
|
||
<section id="view-einstellungen" class="view" hidden aria-labelledby="settings-title">
|
||
<h2 id="settings-title">Einstellungen</h2>
|
||
<form id="settings-form" class="card form-grid" autocomplete="off">
|
||
<label>Uhrzeit des Meetings (leer = ganztägig) <input type="time" name="meetingTime"></label>
|
||
<label>Dauer in Minuten <input type="number" name="durationMinutes" min="5" max="480"></label>
|
||
<label>Bundesland (für Feiertage) <select name="bundesland"></select></label>
|
||
<label>Fairness-Fenster in Tagen <input type="number" name="historyWindowDays" min="0" max="365"></label>
|
||
<label>Kalendername in Nextcloud <input name="calendarDisplayName" maxlength="60"></label>
|
||
<label class="inline wide"><input type="checkbox" name="inviteAttendees"> Moderatoren als Teilnehmer eintragen (E-Mail nötig; Nextcloud verschickt dann Einladungen)</label>
|
||
<label class="wide">Vorlage für den Bug-Prompt <textarea name="bugPromptTemplate" rows="7" maxlength="4000"></textarea></label>
|
||
<p class="hint">Platzhalter: {text} Beschreibung, {reporter} Name, {date} Zeitpunkt, {page} Ansicht, {browser}, {viewport}, {version}, {url}. Leer lassen stellt die Vorlage wieder her.</p>
|
||
<div class="form-actions"><button type="submit" class="primary">Speichern</button></div>
|
||
</form>
|
||
|
||
<h3>Feiertage und betriebsfreie Tage</h3>
|
||
<div class="card">
|
||
<form id="holiday-generate" class="row">
|
||
<label>Gesetzliche Feiertage erzeugen für <input type="number" name="year" min="2000" max="2100" required></label>
|
||
<button type="submit">Erzeugen</button>
|
||
</form>
|
||
<form id="holiday-add" class="row">
|
||
<label>Tag <input type="date" name="date" required></label>
|
||
<label>Bezeichnung <input name="name" maxlength="80" placeholder="z. B. Betriebsausflug"></label>
|
||
<button type="submit">Hinzufügen</button>
|
||
</form>
|
||
<ul id="holiday-list" class="list compact"></ul>
|
||
</div>
|
||
|
||
<h3>Nextcloud</h3>
|
||
<div class="card" id="nextcloud-status"></div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- Dialog: Tag bearbeiten -->
|
||
<dialog id="day-dialog">
|
||
<form method="dialog" class="dialog-form" id="day-form">
|
||
<div class="dialog-head"><h2 id="day-dialog-title">Tag</h2><button type="button" class="ghost icon-button dialog-bug" aria-label="Bug in diesem Dialog melden" title="Bug melden"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button></div>
|
||
<p id="day-dialog-info" class="hint"></p>
|
||
<label>Hauptmoderation <select name="main"></select></label>
|
||
<label>Nebenmoderation <select name="co"></select></label>
|
||
<label class="inline"><input type="checkbox" name="locked"> Fixieren (bleibt bei jeder Auslosung erhalten)</label>
|
||
<label class="inline"><input type="checkbox" name="off"> Kein Meeting an diesem Tag</label>
|
||
<div class="form-actions">
|
||
<button type="button" id="day-reroll">Neu auslosen</button>
|
||
<button type="button" id="day-clear" class="ghost danger">Entfernen</button>
|
||
<span class="spacer"></span>
|
||
<button type="button" id="day-close" class="ghost">Abbrechen</button>
|
||
<button type="submit" class="primary">Speichern</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- Dialog: Auslosen -->
|
||
<dialog id="plan-dialog">
|
||
<form method="dialog" class="dialog-form" id="plan-form">
|
||
<div class="dialog-head"><h2>Moderation auslosen</h2><button type="button" class="ghost icon-button dialog-bug" aria-label="Bug in diesem Dialog melden" title="Bug melden"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button></div>
|
||
<label>Von Monat <input type="month" name="from" required></label>
|
||
<label>Bis Monat <input type="month" name="to" required></label>
|
||
<label class="inline"><input type="checkbox" name="overwrite"> Bereits ausgeloste, nicht fixierte Tage neu auslosen</label>
|
||
<p class="hint">Werktage ohne Feiertag. Abwesende werden übersprungen, niemand zwei Werktage in Folge, Einsätze möglichst gleich verteilt.</p>
|
||
<p id="plan-result" class="result" hidden></p>
|
||
<div class="form-actions">
|
||
<button type="button" id="plan-clear" class="ghost danger">Zeitraum leeren</button>
|
||
<span class="spacer"></span>
|
||
<button type="button" class="ghost" id="plan-close">Schließen</button>
|
||
<button type="submit" class="primary">Auslosen</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- Dialog: Nextcloud -->
|
||
<dialog id="nextcloud-dialog">
|
||
<form method="dialog" class="dialog-form" id="nextcloud-form">
|
||
<div class="dialog-head"><h2>In Nextcloud schreiben</h2><button type="button" class="ghost icon-button dialog-bug" aria-label="Bug in diesem Dialog melden" title="Bug melden"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button></div>
|
||
<p id="nextcloud-info" class="hint"></p>
|
||
<label>Zielkalender
|
||
<select name="target"><option value="">– Kalender laden …</option></select>
|
||
</label>
|
||
<label>Von Monat <input type="month" name="from" required></label>
|
||
<label>Bis Monat <input type="month" name="to" required></label>
|
||
<label class="inline"><input type="checkbox" name="removeForeign"> Andere Termine im Zeitraum aus dem Zielkalender entfernen (z. B. alte Morning-Meeting-Termine)</label>
|
||
<p class="hint">Je Werktag ein Termin. Wiederholtes Schreiben aktualisiert bestehende Termine; entfallene Tage werden im Kalender gelöscht.</p>
|
||
<p id="nextcloud-result" class="result" hidden></p>
|
||
<div class="form-actions">
|
||
<button type="button" id="nextcloud-test">Verbindung testen</button>
|
||
<span class="spacer"></span>
|
||
<button type="button" class="ghost" id="nextcloud-close">Schließen</button>
|
||
<button type="submit" class="primary" id="nextcloud-go">In Nextcloud schreiben</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- Dialog: Kontakte importieren -->
|
||
<dialog id="contacts-dialog">
|
||
<form method="dialog" class="dialog-form" id="contacts-form">
|
||
<div class="dialog-head"><h2>Personen aus Nextcloud</h2><button type="button" class="ghost icon-button dialog-bug" aria-label="Bug in diesem Dialog melden" title="Bug melden"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button></div>
|
||
<label>Adressbuch <select name="addressbook"></select></label>
|
||
<p id="contacts-info" class="hint">Lade Kontakte …</p>
|
||
<div class="contacts-tools">
|
||
<button type="button" class="ghost" id="contacts-all">Alle neuen wählen</button>
|
||
<button type="button" class="ghost" id="contacts-none">Keine</button>
|
||
</div>
|
||
<ul id="contacts-list" class="contacts-list"></ul>
|
||
<p id="contacts-result" class="result" hidden></p>
|
||
<div class="form-actions">
|
||
<span class="spacer"></span>
|
||
<button type="button" class="ghost" id="contacts-close">Schließen</button>
|
||
<button type="submit" class="primary" id="contacts-go">Ausgewählte anlegen</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- Dialog: Tausch anfragen (für alle) -->
|
||
<dialog id="request-dialog">
|
||
<form method="dialog" class="dialog-form" id="request-form">
|
||
<div class="dialog-head"><h2>Tausch anfragen</h2><button type="button" class="ghost icon-button dialog-bug" aria-label="Bug in diesem Dialog melden" title="Bug melden"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button></div>
|
||
<p id="request-info" class="hint"></p>
|
||
<label>Ich bin <select name="personId" required></select></label>
|
||
<label>Tag, an dem ich nicht kann <input type="date" name="date" required></label>
|
||
<label>Ich würde gern tauschen mit (optional) <select name="partnerId"><option value="">– niemand Bestimmtes –</option></select></label>
|
||
<label>Wunschtag (optional) <input type="date" name="partnerDate"></label>
|
||
<p class="hint" id="request-wish-info">Mit Person: ihr tauscht die Tage. Ohne Person: du übernimmst am Wunschtag einen noch offenen Platz, deiner wird neu besetzt.</p>
|
||
<label>Notiz (optional) <input name="note" maxlength="300" placeholder="z. B. Arzttermin, bin erst ab 10 Uhr da"></label>
|
||
<p id="request-result" class="result" hidden></p>
|
||
<div class="form-actions">
|
||
<span class="spacer"></span>
|
||
<button type="button" class="ghost" id="request-close">Abbrechen</button>
|
||
<button type="submit" class="primary" id="request-submit">Anfrage senden</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- Dialog: Anmelden zum Bearbeiten -->
|
||
<dialog id="login-dialog">
|
||
<form method="dialog" class="dialog-form" id="login-form">
|
||
<div class="dialog-head"><h2>Zum Bearbeiten anmelden</h2><button type="button" class="ghost icon-button dialog-bug" aria-label="Bug in diesem Dialog melden" title="Bug melden"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button></div>
|
||
<p class="hint">Ansehen kann jeder. Auslosen, Personen, Abwesenheiten und Nextcloud erfordern das Bearbeitungspasswort.</p>
|
||
<label>Passwort <input type="password" name="password" id="login-password" autocomplete="current-password" required></label>
|
||
<p id="login-result" class="result error" hidden></p>
|
||
<div class="form-actions">
|
||
<span class="spacer"></span>
|
||
<button type="button" class="ghost" id="login-close">Abbrechen</button>
|
||
<button type="submit" class="primary">Anmelden</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<!-- Bug melden: Käfer-Button und Panel, für alle sichtbar -->
|
||
<div id="bug-widget">
|
||
<button type="button" id="bug-button" class="bug-button" aria-label="Bug melden" title="Bug melden" aria-expanded="false" aria-controls="bug-panel"><svg class="icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="6.5" r="2.5"/><path d="M7 14a5 5 0 0 1 10 0v2a5 5 0 0 1-10 0z"/><path d="M12 9v12"/><path d="M7 13H3.5"/><path d="M7 17H4l-1 2.5"/><path d="M17 13h3.5"/><path d="M17 17h3l1 2.5"/><path d="M8.5 9.5 5.5 7"/><path d="M15.5 9.5 18.5 7"/></svg></button>
|
||
<dialog id="bug-panel" class="bug-panel" aria-labelledby="bug-title">
|
||
<h2 id="bug-title">Bug melden</h2>
|
||
<p id="bug-status" class="hint">Bildschirm wird aufgenommen …</p>
|
||
<div class="bug-shot" id="bug-shot" hidden>
|
||
<canvas id="bug-canvas" aria-label="Screenshot der Seite. Markiere die Stelle mit einem roten Rechteck."></canvas>
|
||
</div>
|
||
<p class="hint bug-shot-hint" id="bug-shot-hint" hidden>Ziehe ein rotes Rechteck auf, um die Stelle zu markieren. <button type="button" class="link" id="bug-clear-marks" hidden>Markierungen entfernen</button></p>
|
||
<form id="bug-form" class="bug-form" autocomplete="off">
|
||
<label>Was läuft falsch? <textarea name="text" id="bug-text" rows="3" maxlength="2000" required placeholder="z. B. Beim Klick auf Auslosen passiert nichts"></textarea></label>
|
||
<label>Dein Name (optional) <input name="reporter" id="bug-reporter" maxlength="80" autocomplete="name"></label>
|
||
<p id="bug-result" class="result" hidden></p>
|
||
<div class="form-actions">
|
||
<span class="spacer"></span>
|
||
<button type="button" class="ghost" id="bug-cancel">Abbrechen</button>
|
||
<button type="submit" class="primary" id="bug-submit">Senden</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
</div>
|
||
|
||
<div id="toast" class="toast" role="status" aria-live="polite" hidden></div>
|
||
<script src="vendor/html2canvas.min.js" defer></script>
|
||
<script type="module" src="app.js"></script>
|
||
</body>
|
||
</html>
|