feat: month strip display, fix dashboard counter, styled month form
- Add month_strip template tag rendering JFMAMJJASOND circles, active months dark green, inactive light grey - Replace raw number list in pruning_strip with visual month strip - Restyle pruning month checkboxes as clickable circles in plant form - Fix dashboard 'Need pruning' counter (broken filter chain always showed 0) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
35bf5eee70
commit
36e4570141
8 changed files with 35 additions and 9 deletions
|
|
@ -13,7 +13,16 @@
|
||||||
.care-chip { display: inline-block; padding: .2rem .55rem; border-radius: 1rem; font-size: .8rem; margin: .15rem; }
|
.care-chip { display: inline-block; padding: .2rem .55rem; border-radius: 1rem; font-size: .8rem; margin: .15rem; }
|
||||||
.pruning-strip { border-left: 4px solid #ffc107; background: #fff9c4; padding: .5rem .75rem; border-radius: 0 .375rem .375rem 0; }
|
.pruning-strip { border-left: 4px solid #ffc107; background: #fff9c4; padding: .5rem .75rem; border-radius: 0 .375rem .375rem 0; }
|
||||||
.pruning-strip.overdue { border-color: #dc3545; background: #fff5f5; }
|
.pruning-strip.overdue { border-color: #dc3545; background: #fff5f5; }
|
||||||
.month-checkboxes .form-check { display: inline-flex; margin-right: .5rem; }
|
/* Month strip — display */
|
||||||
|
.month-strip { display: flex; gap: 3px; }
|
||||||
|
.month-dot { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; font-size: 10px; font-weight: 700; letter-spacing: 0; background: #e9ecef; color: #adb5bd; }
|
||||||
|
.month-dot--on { background: #2d6a4f; color: #fff; }
|
||||||
|
/* Month toggle — form */
|
||||||
|
.month-toggle-group { display: flex; flex-wrap: wrap; gap: 5px; }
|
||||||
|
.month-toggle { position: relative; }
|
||||||
|
.month-toggle input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
|
||||||
|
.month-toggle label { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; font-size: 13px; font-weight: 700; cursor: pointer; background: #e9ecef; color: #6c757d; transition: background .15s, color .15s; user-select: none; }
|
||||||
|
.month-toggle input:checked + label { background: #2d6a4f; color: #fff; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<div class="card text-center h-100" style="background:#ffe8cc;">
|
<div class="card text-center h-100" style="background:#ffe8cc;">
|
||||||
<div class="card-body py-3">
|
<div class="card-body py-3">
|
||||||
<div class="display-5 fw-bold" style="color:#7d4a00;">
|
<div class="display-5 fw-bold" style="color:#7d4a00;">
|
||||||
{{ overdue|length|add:due_this_month|length }}
|
{{ needs_pruning_count }}
|
||||||
</div>
|
</div>
|
||||||
<div class="small" style="color:#7d4a00;">Need pruning</div>
|
<div class="small" style="color:#7d4a00;">Need pruning</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
1
plants/templates/plants/partials/month_strip.html
Normal file
1
plants/templates/plants/partials/month_strip.html
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<div class="month-strip">{% for m in months %}<span class="month-dot{% if m.active %} month-dot--on{% endif %}">{{ m.letter }}</span>{% endfor %}</div>
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
|
{% load plant_extras %}
|
||||||
<div id="pruning-strip" class="pruning-strip {% if pruning_status == 'overdue' %}overdue{% endif %} mb-3 rounded-end">
|
<div id="pruning-strip" class="pruning-strip {% if pruning_status == 'overdue' %}overdue{% endif %} mb-3 rounded-end">
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
<div>
|
<div>
|
||||||
<strong>✂️ Pruning</strong>
|
<strong>✂️ Pruning</strong>
|
||||||
{% if plant.pruning_months %}
|
{% if plant.pruning_months %}
|
||||||
<div class="small">
|
<div class="mt-1">{% month_strip plant.pruning_months %}</div>
|
||||||
Scheduled: {{ plant.pruning_months|join:", " }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% with plant.pruning_logs.first as last_log %}
|
{% with plant.pruning_logs.first as last_log %}
|
||||||
{% if last_log %}
|
{% if last_log %}
|
||||||
<div class="small text-muted">Last pruned: {{ last_log.pruned_on|date:"j M Y" }}</div>
|
<div class="small text-muted mt-1">Last pruned: {{ last_log.pruned_on|date:"j M Y" }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,11 @@
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label fw-semibold">Pruning months</label>
|
<label class="form-label fw-semibold">Pruning months</label>
|
||||||
<div class="month-checkboxes d-flex flex-wrap gap-1">
|
<div class="month-toggle-group">
|
||||||
{% for widget in form.pruning_months %}
|
{% for widget in form.pruning_months %}
|
||||||
<div class="form-check form-check-inline border rounded px-2 py-1">
|
<div class="month-toggle">
|
||||||
{{ widget.tag }}
|
{{ widget.tag }}
|
||||||
<label class="form-check-label" for="{{ widget.id_for_label }}">{{ widget.choice_label }}</label>
|
<label for="{{ widget.id_for_label }}">{{ widget.choice_label|slice:":1" }}</label>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
0
plants/templatetags/__init__.py
Normal file
0
plants/templatetags/__init__.py
Normal file
16
plants/templatetags/plant_extras.py
Normal file
16
plants/templatetags/plant_extras.py
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
_LETTERS = list('JFMAMJJASOND')
|
||||||
|
|
||||||
|
|
||||||
|
@register.inclusion_tag('plants/partials/month_strip.html')
|
||||||
|
def month_strip(pruning_months):
|
||||||
|
months_set = set(pruning_months or [])
|
||||||
|
return {
|
||||||
|
'months': [
|
||||||
|
{'letter': _LETTERS[i], 'active': (i + 1) in months_set}
|
||||||
|
for i in range(12)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -21,5 +21,6 @@ def dashboard(request):
|
||||||
'total_plants': len(all_plants),
|
'total_plants': len(all_plants),
|
||||||
'overdue': overdue,
|
'overdue': overdue,
|
||||||
'due_this_month': due_this_month,
|
'due_this_month': due_this_month,
|
||||||
|
'needs_pruning_count': len(overdue) + len(due_this_month),
|
||||||
'today': today,
|
'today': today,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue