From 29780ee3f60532954549d02401b61f7b119769cb Mon Sep 17 00:00:00 2001 From: patsy Date: Sat, 8 Aug 2026 03:00:29 +0200 Subject: [PATCH] phase 2 --- README.md | 6 +- app/static/css/style.css | 202 ++++++++++++++++++++++++++- app/tasks/forms.py | 7 +- app/templates/base.html | 3 +- app/templates/core/index.html | 4 +- app/templates/tasks/_task_card.html | 25 ++++ app/templates/tasks/detail.html | 72 ++++++++++ app/templates/tasks/form.html | 54 ++++++++ app/templates/tasks/list.html | 34 +++++ app/templates/tasks/today.html | 27 ++++ design.md | 28 ++-- progress.md | 45 +++++- tests/conftest.py | 3 +- tests/tasks/test_tasks.py | 206 ++++++++++++++++++++++++++++ 14 files changed, 686 insertions(+), 30 deletions(-) create mode 100644 app/templates/tasks/_task_card.html create mode 100644 app/templates/tasks/detail.html create mode 100644 app/templates/tasks/form.html create mode 100644 app/templates/tasks/list.html create mode 100644 app/templates/tasks/today.html create mode 100644 tests/tasks/test_tasks.py diff --git a/README.md b/README.md index ca0684e..f77e308 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Steady -Steady is an ADHD-friendly task manager built with Flask. Phase 1 provides the -application factory, database and migration setup, secure authentication, and -the shared visual foundation. +Steady is an ADHD-friendly task manager built with Flask. It provides a modular +application foundation, secure authentication, task and subtask management, a +seven-item Today view, status filters, priorities, and progress indicators. ## Local setup diff --git a/app/static/css/style.css b/app/static/css/style.css index f223c62..0af4077 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -111,6 +111,23 @@ input:focus-visible { font: inherit; } +.field textarea, +.field select { + width: 100%; + padding: 0.6rem 0.75rem; + border: 1px solid var(--border); + border-radius: 0.5rem; + background: var(--surface); + color: var(--text); + font: inherit; +} + +.field__help { + margin-block: 0.35rem 0; + color: var(--muted); + font-size: 0.9rem; +} + .field__errors { margin-block: 0.35rem 0; padding-left: 1.25rem; @@ -151,6 +168,178 @@ input:focus-visible { border-color: var(--orange); } +.page-heading, +.task-card__header, +.form-actions, +.progress-row { + display: flex; + align-items: center; + gap: 1rem; +} + +.page-heading, +.task-card__header { + justify-content: space-between; +} + +.page-heading { + margin-bottom: 2rem; +} + +.page-heading h1 { + margin-block: 0; +} + +.filters { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1.5rem; +} + +.filters a { + padding: 0.4rem 0.8rem; + border-radius: 2rem; + text-decoration: none; +} + +.filters a[aria-current="page"] { + background: var(--lavender); + color: var(--text); + font-weight: 700; +} + +.task-list { + display: grid; + gap: 1rem; +} + +.task-card, +.task-detail, +.empty-state { + padding: var(--space); + border: 1px solid var(--border); + border-radius: 1rem; + background: var(--surface); +} + +.task-card { + border-left-width: 0.45rem; +} + +.task-card--urgent { + border-left-color: var(--yellow); +} + +.task-card--important { + border-left-color: var(--lavender); +} + +.task-card--normal { + border-left-color: var(--blue); +} + +.task-card h2 { + margin-bottom: 0.4rem; +} + +.badge, +.status { + display: inline-block; + padding: 0.2rem 0.55rem; + border-radius: 2rem; + font-size: 0.85rem; +} + +.badge--urgent { + background: var(--yellow); + color: #423916; +} + +.badge--important { + background: var(--lavender); + color: #2d2d3a; +} + +.badge--normal, +.status { + background: var(--blue); + color: #20373e; +} + +.progress-row { + margin-top: 1rem; +} + +.progress-row progress { + flex: 1; + min-width: 6rem; + accent-color: var(--lavender); +} + +.progress-row--large { + margin-block: 2rem; +} + +.form-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1rem; +} + +.form-actions { + margin-top: 1.5rem; +} + +.task-description { + white-space: pre-wrap; +} + +.subtask-list { + padding: 0; + list-style: none; +} + +.subtask { + padding-block: 0.4rem; + border-bottom: 1px solid var(--border); +} + +.subtask form { + margin: 0; +} + +.subtask__toggle { + width: 100%; + padding: 0.5rem; + border: 0; + background: transparent; + color: var(--text); + cursor: pointer; + font: inherit; + text-align: left; +} + +.subtask--done .subtask__toggle { + color: var(--muted); + text-decoration: line-through; +} + +.subtask-form { + max-width: 30rem; + margin-top: 1.5rem; +} + +.danger-zone { + margin-top: 3rem; + color: var(--muted); +} + +.button--danger { + border-color: #855347; + background: var(--orange); +} + .skip-link { position: absolute; top: 0; @@ -203,5 +392,16 @@ input { flex-direction: column; padding-block: 1rem; } -} + .nav__actions, + .page-heading, + .task-card__header, + .form-grid { + align-items: flex-start; + flex-direction: column; + } + + .form-grid { + display: flex; + } +} diff --git a/app/tasks/forms.py b/app/tasks/forms.py index 9553aa5..c1c4682 100644 --- a/app/tasks/forms.py +++ b/app/tasks/forms.py @@ -1,7 +1,7 @@ from flask_wtf import FlaskForm from wtforms import SelectField, StringField, SubmitField, TextAreaField from wtforms.fields import DateTimeLocalField -from wtforms.validators import DataRequired, Length, Optional, ValidationError +from wtforms.validators import Length, Optional, ValidationError from .models import TASK_PRIORITIES, TASK_STATUSES @@ -26,7 +26,7 @@ def not_blank(_form: FlaskForm, field: StringField) -> None: class TaskForm(FlaskForm): title = StringField( "Task title", - validators=[DataRequired(), not_blank, Length(max=200)], + validators=[not_blank, Length(max=200)], ) description = TextAreaField( "Notes", @@ -53,11 +53,10 @@ class TaskForm(FlaskForm): class SubtaskForm(FlaskForm): title = StringField( "Next small step", - validators=[DataRequired(), not_blank, Length(max=100)], + validators=[not_blank, Length(max=100)], ) submit = SubmitField("Add step") class ActionForm(FlaskForm): submit = SubmitField() - diff --git a/app/templates/base.html b/app/templates/base.html index b85547a..ccd8123 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -14,6 +14,8 @@ Steady