first commit

This commit is contained in:
2026-04-13 08:32:28 +02:00
commit 1074a91487
72 changed files with 4078 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
{% extends "base.html" %}
{% from "partials/macros.html" import task_card %}
{% block title %}Alle Aufgaben · Putzliga{% endblock %}
{% block page_title %}Alle Aufgaben{% endblock %}
{% block content %}
<section class="panel">
<form method="get" class="filter-bar">
<div class="field field--compact">
<label for="status">Status</label>
<select name="status" id="status">
<option value="all" {% if filters.status == 'all' %}selected{% endif %}>Alle</option>
<option value="open" {% if filters.status == 'open' %}selected{% endif %}>Offen</option>
<option value="soon" {% if filters.status == 'soon' %}selected{% endif %}>Bald fällig</option>
<option value="overdue" {% if filters.status == 'overdue' %}selected{% endif %}>Überfällig</option>
<option value="completed" {% if filters.status == 'completed' %}selected{% endif %}>Erledigt</option>
</select>
</div>
<div class="field field--compact">
<label for="user_id">Nutzer</label>
<select name="user_id" id="user_id">
<option value="">Alle</option>
{% for user in users %}
<option value="{{ user.id }}" {% if filters.user_id == user.id %}selected{% endif %}>{{ user.name }}</option>
{% endfor %}
</select>
</div>
<div class="field field--compact">
<label for="sort">Sortierung</label>
<select name="sort" id="sort">
<option value="due" {% if filters.sort == 'due' %}selected{% endif %}>Fälligkeit</option>
<option value="points" {% if filters.sort == 'points' %}selected{% endif %}>Punkte</option>
<option value="user" {% if filters.sort == 'user' %}selected{% endif %}>Nutzer</option>
</select>
</div>
<label class="checkbox checkbox--compact">
<input type="checkbox" name="mine" value="1" {% if filters.mine == '1' %}checked{% endif %}>
<span>Nur meine</span>
</label>
<button type="submit" class="button">Filter anwenden</button>
</form>
</section>
<section class="task-grid">
{% for task in tasks %}
{{ task_card(task, current_user) }}
{% else %}
<div class="empty-state">Für diese Filter gibt es gerade keine Aufgaben.</div>
{% endfor %}
</section>
{% endblock %}

View File

@@ -0,0 +1,66 @@
{% extends "base.html" %}
{% from "partials/macros.html" import status_badge %}
{% block title %}Kalender · Putzliga{% endblock %}
{% block page_title %}Kalender & Liste{% endblock %}
{% block content %}
<section class="panel panel--toolbar">
<div>
<p class="eyebrow">Monatsansicht</p>
<h2>{{ current_label }}</h2>
</div>
<div class="toolbar-actions">
<a class="button button--secondary" href="{{ url_for('tasks.calendar_view', year=current_year if current_month > 1 else current_year - 1, month=current_month - 1 if current_month > 1 else 12, view=view) }}">Zurück</a>
<a class="button button--secondary" href="{{ url_for('tasks.calendar_view', year=current_year if current_month < 12 else current_year + 1, month=current_month + 1 if current_month < 12 else 1, view=view) }}">Weiter</a>
<div class="segmented">
<a href="{{ url_for('tasks.calendar_view', year=current_year, month=current_month, view='calendar') }}" class="{% if view == 'calendar' %}is-active{% endif %}">Kalender</a>
<a href="{{ url_for('tasks.calendar_view', year=current_year, month=current_month, view='list') }}" class="{% if view == 'list' %}is-active{% endif %}">Liste</a>
</div>
</div>
</section>
{% if view == 'calendar' %}
<section class="calendar-grid">
<div class="calendar-grid__weekdays">
{% for label in ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'] %}
<span>{{ label }}</span>
{% endfor %}
</div>
{% for week in month_calendar %}
{% for day in week %}
<article class="calendar-day {% if day == 0 %}calendar-day--empty{% endif %}">
{% if day != 0 %}
<strong>{{ day }}</strong>
<div class="calendar-day__tasks">
{% for task in tasks_by_day.get(day, []) %}
<a href="{{ url_for('tasks.edit', task_id=task.id) }}" class="calendar-task calendar-task--{{ task.status }}">
<span>{{ task.title }}</span>
<small>{{ task.points_awarded }} P</small>
</a>
{% endfor %}
</div>
{% endif %}
</article>
{% endfor %}
{% endfor %}
</section>
{% else %}
<section class="stack">
{% for task in tasks %}
<article class="panel list-row">
<div>
<strong>{{ task.title }}</strong>
<p class="muted">{{ task.description or 'Ohne Zusatzbeschreibung' }}</p>
</div>
<div class="list-row__meta">
{{ status_badge(task) }}
<span>{{ task.due_date|date_de }}</span>
<a href="{{ url_for('tasks.edit', task_id=task.id) }}" class="text-link">Bearbeiten</a>
</div>
</article>
{% else %}
<div class="empty-state">In diesem Monat sind noch keine Aufgaben hinterlegt.</div>
{% endfor %}
</section>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,88 @@
{% extends "base.html" %}
{% from "partials/macros.html" import task_card, nav_icon %}
{% block title %}Meine Aufgaben · Putzliga{% endblock %}
{% block page_title %}Meine Aufgaben{% endblock %}
{% block content %}
<section class="hero-grid">
<article class="hero-card">
<p class="eyebrow">Heute im Fokus</p>
<h2>{{ current_user.name }}, deine Liga für den Haushalt läuft.</h2>
<p>Erledige offene Aufgaben, sammle Punkte und halte deinen Monatslauf stabil.</p>
<div class="progress-card">
<div class="progress-card__top">
<span>Erledigungsquote</span>
<strong>{{ completion_ratio }}%</strong>
</div>
<div class="progress"><span style="width: {{ completion_ratio }}%"></span></div>
</div>
</article>
<article class="panel highlight-panel">
<p class="eyebrow">Schnellzugriff</p>
<a class="button button--wide" href="{{ url_for('tasks.create') }}">
{{ nav_icon('plus') }}
<span>Neue Aufgabe anlegen</span>
</a>
<a class="button button--secondary button--wide" href="{{ url_for('scoreboard.index') }}">
{{ nav_icon('trophy') }}
<span>Zum aktuellen Highscore</span>
</a>
</article>
</section>
<section class="stack">
<div class="section-heading">
<h2>Überfällig</h2>
<span class="section-heading__count">{{ sections.overdue|length }}</span>
</div>
<div class="task-grid">
{% for task in sections.overdue %}
{{ task_card(task, current_user) }}
{% else %}
<div class="empty-state">Nichts überfällig. Genau so darf es bleiben.</div>
{% endfor %}
</div>
</section>
<section class="stack">
<div class="section-heading">
<h2>Bald fällig</h2>
<span class="section-heading__count">{{ sections.soon|length }}</span>
</div>
<div class="task-grid">
{% for task in sections.soon %}
{{ task_card(task, current_user) }}
{% else %}
<div class="empty-state">Gerade nichts, was in den nächsten Tagen drängt.</div>
{% endfor %}
</div>
</section>
<section class="stack">
<div class="section-heading">
<h2>Offen</h2>
<span class="section-heading__count">{{ sections.open|length }}</span>
</div>
<div class="task-grid">
{% for task in sections.open %}
{{ task_card(task, current_user) }}
{% else %}
<div class="empty-state">Alles leer. Zeit für eine kleine Siegerrunde.</div>
{% endfor %}
</div>
</section>
<section class="stack">
<div class="section-heading">
<h2>Erledigt</h2>
<span class="section-heading__count">{{ sections.completed|length }}</span>
</div>
<div class="task-grid">
{% for task in sections.completed %}
{{ task_card(task, current_user, compact=true) }}
{% else %}
<div class="empty-state">Noch keine erledigten Aufgaben in deiner Liste.</div>
{% endfor %}
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,64 @@
{% extends "base.html" %}
{% block title %}{% if mode == 'edit' %}Aufgabe bearbeiten{% else %}Aufgabe erstellen{% endif %} · Putzliga{% endblock %}
{% block page_title %}{% if mode == 'edit' %}Aufgabe bearbeiten{% else %}Aufgabe erstellen{% endif %}{% endblock %}
{% block content %}
<section class="panel form-panel">
<p class="eyebrow">{% if mode == 'edit' %}Bestehende Aufgabe anpassen{% else %}Neue Aufgabe und Vorlage{% endif %}</p>
<h2>{% if mode == 'edit' %}Änderungen für {{ task.title }}{% else %}Neue Aufgabe anlegen{% endif %}</h2>
<form method="post" class="form-grid form-grid--two">
{{ form.hidden_tag() }}
<div class="field field--full">
{{ form.title.label }}
{{ form.title(placeholder="Zum Beispiel: Küche wischen") }}
{% for error in form.title.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>
<div class="field field--full">
{{ form.description.label }}
{{ form.description(rows="4", placeholder="Optional: kurze Hinweise zur Aufgabe") }}
{% for error in form.description.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>
<div class="field">
{{ form.default_points.label }}
{{ form.default_points() }}
{% for error in form.default_points.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>
<div class="field">
{{ form.assigned_user_id.label }}
{{ form.assigned_user_id() }}
{% for error in form.assigned_user_id.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>
<div class="field">
{{ form.due_date.label }}
{{ form.due_date() }}
{% for error in form.due_date.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>
<div class="field">
{{ form.recurrence_interval_unit.label }}
{{ form.recurrence_interval_unit() }}
</div>
<div class="field">
{{ form.recurrence_interval_value.label }}
{{ form.recurrence_interval_value() }}
{% for error in form.recurrence_interval_value.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>
<label class="checkbox">
{{ form.active() }}
<span>Vorlage bleibt aktiv und erzeugt bei Wiederholung weitere Aufgaben</span>
</label>
<div class="form-actions field--full">
{{ form.submit(class_='button') }}
<a class="button button--ghost" href="{{ url_for('tasks.all_tasks') }}">Abbrechen</a>
</div>
</form>
</section>
{% endblock %}