From d78e483ad2064a5956f59e68dcebefdee49585d0 Mon Sep 17 00:00:00 2001 From: Wojciech Kwolek Date: Mon, 31 Aug 2020 21:03:31 +0200 Subject: [PATCH] allow deleting accomplishment Squashed commit of the following: commit 846aa01f3bb2e88cc2141506dbad8fefce1cf75b Author: Wojciech Kwolek Date: Mon Aug 31 21:02:58 2020 +0200 remove unimplemented edit link commit d094e321c7e9d526646adad411d47fd03dc4d37b Author: Wojciech Kwolek Date: Mon Aug 31 20:59:53 2020 +0200 implement deleting accomplishments commit 5c33caba1baf0ad6a0c62cccba35209c7e28a71c Author: Wojciech Kwolek Date: Mon Aug 31 17:33:12 2020 +0200 add edit buttons to the day view commit 6cc826c5cbb0a0260f5745a8392c3bc92afb6c71 Author: Wojciech Kwolek Date: Mon Aug 31 16:38:35 2020 +0200 add __pycache__ to gitignore commit 1593e4c6cfa1a45096421292152185579a449e53 Author: Wojciech Kwolek Date: Mon Aug 31 16:35:40 2020 +0200 extract a method for getting all day related data for a template --- .gitignore | 1 + app/css/main.css | 14 +++-- app/main.py | 106 ++++++++++++++++++++++++--------- app/static/style.css | 12 ++-- app/templates/main/app.html | 50 +++++++++++----- app/templates/main/delete.html | 19 ++++++ app/timeutils.py | 2 + 7 files changed, 152 insertions(+), 52 deletions(-) create mode 100644 app/templates/main/delete.html diff --git a/.gitignore b/.gitignore index 4d26965..992f5bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ *.db +__pycache__ diff --git a/app/css/main.css b/app/css/main.css index bbf6484..bd26d47 100644 --- a/app/css/main.css +++ b/app/css/main.css @@ -40,31 +40,35 @@ form input[type=password]:focus { } form input[type=submit] { - @apply w-full px-4 py-2 mt-2 font-bold rounded; + @apply px-4 py-2 mt-2 font-bold rounded; } form.auth-form input[type=submit] { - @apply text-white bg-blue-500; + @apply w-full text-white bg-blue-500; } .green-btn { @apply text-white bg-green-500; } +.accomplishment .text { + @apply flex-grow; +} + .accomplishment .difficulty { @apply flex-shrink-0 pl-1 font-bold text-right; min-width: 3em; } -.accomplishment .difficulty-easy { +.difficulty-easy { @apply text-green-700; } -.accomplishment .difficulty-medium { +.difficulty-medium { @apply text-orange-700; } -.accomplishment .difficulty-hard { +.difficulty-hard { @apply text-red-700; } diff --git a/app/main.py b/app/main.py index 6783c2d..a906878 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,6 @@ from . import timeutils -from flask import Blueprint, render_template, redirect, url_for -from flask_login import current_user +from flask import Blueprint, render_template, redirect, url_for, abort +from flask_login import current_user, login_required from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired, Length @@ -35,22 +35,45 @@ def handle_accomplishment_submission(form): return redirect(url_for('main.index')) +def get_day_template_data(day_string): + day_datetime = None + if day_string == "today": + day_datetime = timeutils.today() + else: + day_datetime = timeutils.from_str(day_string) + + day_string_clean = timeutils.as_str(day_datetime) + + accomplishments = list(reversed( + Accomplishment.get_day(current_user.id, day_datetime))) + total = sum(a.difficulty for a in accomplishments) + + yesterday = timeutils.day_before(day_datetime) + tomorrow = timeutils.day_after(day_datetime) + if timeutils.is_future(tomorrow): + tomorrow = None + + return { + "day": { + "datetime": day_datetime, + "string": day_string_clean, + "fancy": timeutils.as_fancy_str(day_datetime), + "is_today": timeutils.is_today(day_datetime) + }, + + "links": { + "yesterday": url_for('main.index', day=timeutils.as_str(yesterday)), + "tomorrow": url_for('main.index', day=timeutils.as_str(tomorrow)) if tomorrow is not None else None + }, + + "accomplishments": accomplishments, + "total_xp": sum(a.difficulty for a in accomplishments), + } + + @main.route('/', defaults={'day': 'today'}, methods=['GET', 'POST']) @main.route('/day/') def index(day): - day_datetime = None - day_string = None - is_today = False - if day == "today": - day_datetime = timeutils.today() - day_string = "Today" - is_today = True - else: - day_datetime = timeutils.from_str(day) - if timeutils.is_today(day_datetime): - return redirect('/') - day_string = timeutils.as_fancy_str(day_datetime) - if not current_user.is_authenticated: return render_template('index.html') @@ -58,23 +81,50 @@ def index(day): if form.validate_on_submit(): return handle_accomplishment_submission(form) - accomplishments = list(reversed(Accomplishment.get_day( - current_user.id, day_datetime))) - total = sum(a.difficulty for a in accomplishments) + return render_template( + 'main/app.html', + form=form, + **get_day_template_data(day) + ) - tomorrow = timeutils.day_after(day_datetime) - yesterday = timeutils.day_before(day_datetime) - if timeutils.is_future(tomorrow): - tomorrow = None +@main.route('/day//edit') +@login_required +def edit_day(day): + form = NewAccomplishementForm() + if form.validate_on_submit(): + return handle_accomplishment_submission(form) return render_template( 'main/app.html', form=form, - day=day_string, - accomplishments=accomplishments, - total=total, - tomorrow=timeutils.as_str(tomorrow), - yesterday=timeutils.as_str(yesterday), - is_today=is_today, + edit=True, + **get_day_template_data(day) ) + + +class DeleteForm(FlaskForm): + submit = SubmitField('Delete') + + +@main.route('/accomplishment//delete', methods=['GET', 'POST']) +@login_required +def delete_accomplishment(accomplishment_id): + a = Accomplishment.query.get_or_404(accomplishment_id) + if a.user_id != current_user.id: + abort(403) + + back_url = url_for( + 'main.edit_day', day=timeutils.as_str(timeutils.day(a.time))) + + form = DeleteForm() + if form.validate_on_submit(): + db.session.delete(a) + db.session.commit() + return redirect(back_url) + + return render_template( + 'main/delete.html', + form=form, + accomplishment=a, + cancel=back_url) diff --git a/app/static/style.css b/app/static/style.css index 38d053e..da1bbb7 100644 --- a/app/static/style.css +++ b/app/static/style.css @@ -22083,7 +22083,6 @@ form input[type=password]:focus { } form input[type=submit] { - width: 100%; padding-left: 1rem; padding-right: 1rem; padding-top: 0.5rem; @@ -22094,6 +22093,7 @@ form input[type=submit] { } form.auth-form input[type=submit] { + width: 100%; --text-opacity: 1; color: #fff; color: rgba(255, 255, 255, var(--text-opacity)); @@ -22111,6 +22111,10 @@ form.auth-form input[type=submit] { background-color: rgba(72, 187, 120, var(--bg-opacity)); } +.accomplishment .text { + flex-grow: 1; +} + .accomplishment .difficulty { flex-shrink: 0; padding-left: 0.25rem; @@ -22119,19 +22123,19 @@ form.auth-form input[type=submit] { min-width: 3em; } -.accomplishment .difficulty-easy { +.difficulty-easy { --text-opacity: 1; color: #2f855a; color: rgba(47, 133, 90, var(--text-opacity)); } -.accomplishment .difficulty-medium { +.difficulty-medium { --text-opacity: 1; color: #c05621; color: rgba(192, 86, 33, var(--text-opacity)); } -.accomplishment .difficulty-hard { +.difficulty-hard { --text-opacity: 1; color: #c53030; color: rgba(197, 48, 48, var(--text-opacity)); diff --git a/app/templates/main/app.html b/app/templates/main/app.html index 026367b..f304b4f 100644 --- a/app/templates/main/app.html +++ b/app/templates/main/app.html @@ -1,7 +1,7 @@ {% extends "_skel.html" %} -{% block title %}{% if is_today %}Home{% else %}{{ day }}{% endif %}{% endblock %} +{% block title %}{{ day.fancy }}{% endblock %} {% block content %} -
+
{{ form.csrf_token }} {{ form.text(placeholder="What did you accomplish today?", class_="placeholder-black", autofocus=True) }} @@ -13,19 +13,40 @@
-

{{ day }}

- {% for accomplishment in accomplishments %} -
-
{{ accomplishment.text }}
-
{{ accomplishment.difficulty }} XP +
+
+

{{ day.fancy }}

+ {% if edit %} + + {% else %} + {% if accomplishments %} + + {% endif %} + {% endif %} +
+ {% for accomplishment in accomplishments %} +
+
{{ accomplishment.text }}
+
+ {{ accomplishment.difficulty }} XP +
+ {% if edit %} +
+
+ delete +
+
+ {% endif %}

{% else %}
{% if false %} - {% endif %} - {% if is_today %} + + {% endif %} + {% if day.is_today %}

No accomplishments today... yet!

{% else %}

Nothing logged that day... but it's okay to take a break!

@@ -33,14 +54,13 @@
{% endfor %}
-
total: {{ total }} XP
+
total: {{ total_xp }} XP
- - {% if tomorrow %}Next day -
{% endif %} + + {% if links.tomorrow %}Next day + {% endif %} +
-
-
{% endblock %} diff --git a/app/templates/main/delete.html b/app/templates/main/delete.html new file mode 100644 index 0000000..2ea334f --- /dev/null +++ b/app/templates/main/delete.html @@ -0,0 +1,19 @@ +{% extends "_skel.html" %} +{% block content %} +
+

+ {{ accomplishment.text }} +

+

({{ accomplishment.difficulty }} + XP) +

+
+
+

Are you sure you want to remove this accomplishment?

+
+ {{ form.csrf_token }} + {{ form.submit(class_="hover:bg-red-500 bg-red-700 text-white") }} + cancel +
+
+{% endblock %} diff --git a/app/timeutils.py b/app/timeutils.py index dd989e1..d16a7a4 100644 --- a/app/timeutils.py +++ b/app/timeutils.py @@ -25,6 +25,8 @@ def _suffix(d): def as_fancy_str(day_): if day_ is None: return None + if is_today(day_): + return "Today" return day_.strftime("%B {S}, %Y").replace('{S}', str(day_.day) + _suffix(day_.day))