mirror of https://github.com/snachodog/mybuddy.git
Add feeding method history (#774)
* add feeding method history * Make it a specialized breastfeeding card instead. * Minor improvements: - don't print days for an empty card. - make the width of the bar for each day proportional to that day's total feeding time. * Don't make bar width proportional to feeding time, actually, it's kinda ugly. --------- Co-authored-by: ag <ag@ag.com> Co-authored-by: Christopher C. Wells <git-2022@chris-wells.net>
This commit is contained in:
parent
25d3c9f58c
commit
ab5bb66c8f
|
@ -73,6 +73,10 @@
|
|||
font-size: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: $progress-height * 2;
|
||||
}
|
||||
}
|
||||
|
||||
.card-sleep {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
{% extends 'cards/base.html' %}
|
||||
{% load duration i18n %}
|
||||
{% block header %}
|
||||
<a href="{% url "core:feeding-list" %}">{% trans "Breastfeeding" %}</a>
|
||||
{% endblock %}
|
||||
{% block title %}
|
||||
{% if total == 0 %}
|
||||
{% trans "None" %}
|
||||
{% else %}
|
||||
{% trans "Past Week" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
{% for key, info in stats.items %}
|
||||
{% if info.left_count > 0 or info.right_count > 0 %}
|
||||
<div class="progress mt-3" role="progressbar">
|
||||
<div class="progress-bar bg-primary lead"
|
||||
style="width: {{ info.left_pct|safe }}%">{{ info.left_count }} {% trans "left" %}</div>
|
||||
<div class="progress-bar bg-secondary lead"
|
||||
style="width: {{ info.right_pct|safe }}%">{{ info.right_count }} {% trans "right" %}</div>
|
||||
</div>
|
||||
<div class="text-center text-light small">
|
||||
{% if key == 0 %}
|
||||
{% trans "today" %}
|
||||
{% elif key == 1 %}
|
||||
{% trans "yesterday" %}
|
||||
{% else %}
|
||||
{% blocktrans with days_ago=key %}{{ days_ago }} days ago{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% if info.count > 0 %}
|
||||
({{ info.count }} {% trans "feedings in" %} {{ info.duration|duration_string:'m' }})
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -26,6 +26,7 @@
|
|||
<div class="col-sm-6 col-lg-4">{% card_sleep_naps_day object %}</div>
|
||||
<div class="col-sm-6 col-lg-4">{% card_tummytime_day object %}</div>
|
||||
<div class="col-sm-6 col-lg-4">{% card_diaperchange_types object %}</div>
|
||||
<div class="col-sm-6 col-lg-4">{% card_breastfeeding object %}</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block javascript %}
|
||||
|
|
|
@ -5,7 +5,8 @@ from django.db.models.functions import TruncDate
|
|||
from django.utils import timezone
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from datetime import date, datetime, time
|
||||
from datetime import date, datetime, time, timedelta
|
||||
import collections
|
||||
|
||||
from core import models
|
||||
|
||||
|
@ -107,6 +108,77 @@ def card_diaperchange_types(context, child, date=None):
|
|||
}
|
||||
|
||||
|
||||
@register.inclusion_tag("cards/breastfeeding.html", takes_context=True)
|
||||
def card_breastfeeding(context, child, date=None):
|
||||
"""
|
||||
Creates a break down of breasts used for breastfeeding, for the past
|
||||
seven days.
|
||||
:param child: an instance of the Child model.
|
||||
:param date: a Date object for the day to filter.
|
||||
:returns: a dictionary with the statistics.
|
||||
"""
|
||||
if date:
|
||||
time = timezone.datetime.combine(date, timezone.localtime().min.time())
|
||||
time = timezone.make_aware(time)
|
||||
else:
|
||||
time = timezone.localtime()
|
||||
|
||||
max_date = (time + timezone.timedelta(days=1)).replace(hour=0, minute=0, second=0)
|
||||
min_date = (max_date - timezone.timedelta(days=7)).replace(
|
||||
hour=0, minute=0, second=0
|
||||
)
|
||||
|
||||
instances = (
|
||||
models.Feeding.objects.filter(child=child)
|
||||
.filter(start__gt=min_date)
|
||||
.filter(start__lt=max_date)
|
||||
.filter(method__in=("left breast", "right breast", "both breasts"))
|
||||
.order_by("-start")
|
||||
)
|
||||
|
||||
empty = len(instances) == 0
|
||||
|
||||
# Create a `stats` dictionary, keyed by day for the past 7 days.
|
||||
stats = {}
|
||||
for x in range(7):
|
||||
stats[x] = {}
|
||||
|
||||
# Group feedings per day.
|
||||
per_day = collections.defaultdict(list)
|
||||
for instance in instances:
|
||||
key = (max_date - instance.start).days
|
||||
per_day[key].append(instance)
|
||||
|
||||
# Go through each day, set the stats dictionary for that day.
|
||||
for key, day_instances in per_day.items():
|
||||
left_count = 0
|
||||
right_count = 0
|
||||
for instance in day_instances:
|
||||
if instance.method in ("left breast", "both breasts"):
|
||||
left_count += 1
|
||||
if instance.method in ("right breast", "both breasts"):
|
||||
right_count += 1
|
||||
|
||||
stats[key] = {
|
||||
"count": len(day_instances),
|
||||
"duration": sum(
|
||||
(instance.duration for instance in day_instances), start=timedelta()
|
||||
),
|
||||
"left_count": left_count,
|
||||
"right_count": right_count,
|
||||
"left_pct": 100 * left_count // (left_count + right_count),
|
||||
"right_pct": 100 * right_count // (left_count + right_count),
|
||||
}
|
||||
|
||||
return {
|
||||
"type": "feeding",
|
||||
"stats": stats,
|
||||
"total": len(instances),
|
||||
"empty": empty,
|
||||
"hide_empty": _hide_empty(context),
|
||||
}
|
||||
|
||||
|
||||
@register.inclusion_tag("cards/feeding_recent.html", takes_context=True)
|
||||
def card_feeding_recent(context, child, end_date=None):
|
||||
"""
|
||||
|
|
|
@ -12145,6 +12145,10 @@ textarea.form-control-lg {
|
|||
.card-pumping .card-body .last-feeding-method {
|
||||
font-size: 2em;
|
||||
}
|
||||
.card-feeding .progress,
|
||||
.card-pumping .progress {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.card-sleep {
|
||||
border-color: #ff8f00;
|
Binary file not shown.
|
@ -12145,6 +12145,10 @@ textarea.form-control-lg {
|
|||
.card-pumping .card-body .last-feeding-method {
|
||||
font-size: 2em;
|
||||
}
|
||||
.card-feeding .progress,
|
||||
.card-pumping .progress {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.card-sleep {
|
||||
border-color: #ff8f00;
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue