feat(admin): DAU chart — events markers, week separators, weekend coloring
Some checks are pending
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Some checks are pending
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
- Events shown as red 📅(N) above bars with attendee count
- Monday bars have dashed left border as week separator
- Weekend bars (Sat/Sun) in gray to distinguish from weekdays
- Hover tooltip shows event title and attendee count
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1a160add8c
commit
96232200f9
@ -169,6 +169,22 @@ def admin_user_activity():
|
||||
.all()
|
||||
)
|
||||
|
||||
# Events in this period (for chart markers)
|
||||
from database import NordaEvent, EventAttendee
|
||||
events_in_range = db.query(NordaEvent).filter(
|
||||
NordaEvent.event_date >= start_date,
|
||||
NordaEvent.event_date <= start_date + timedelta(days=30),
|
||||
).all()
|
||||
event_map = {} # date → {'title': ..., 'attendees': ...}
|
||||
for ev in events_in_range:
|
||||
att_count = db.query(func.count(EventAttendee.id)).filter(
|
||||
EventAttendee.event_id == ev.id
|
||||
).scalar() or 0
|
||||
event_map[ev.event_date] = {
|
||||
'title': ev.title[:30] + ('...' if len(ev.title) > 30 else ''),
|
||||
'attendees': att_count,
|
||||
}
|
||||
|
||||
# Fill in missing days with 0
|
||||
dau_map = {row.day: row.users for row in dau_q}
|
||||
daily_active = []
|
||||
@ -178,10 +194,16 @@ def admin_user_activity():
|
||||
count = dau_map.get(d, 0)
|
||||
if count > max_dau:
|
||||
max_dau = count
|
||||
is_weekend = d.weekday() >= 5 # 5=Saturday, 6=Sunday
|
||||
is_monday = d.weekday() == 0
|
||||
ev = event_map.get(d)
|
||||
daily_active.append({
|
||||
'date': d,
|
||||
'label': d.strftime('%d.%m'),
|
||||
'count': count,
|
||||
'is_weekend': is_weekend,
|
||||
'is_monday': is_monday,
|
||||
'event': ev,
|
||||
})
|
||||
|
||||
# Add percentage for CSS bar heights
|
||||
|
||||
@ -152,6 +152,20 @@
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bar-col.weekend .bar {
|
||||
background: linear-gradient(to top, #94a3b8, #b0bec5);
|
||||
}
|
||||
.bar-col.weekend .bar-label {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.bar-col.monday-start {
|
||||
border-left: 1px dashed #cbd5e1;
|
||||
margin-left: 2px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.bar-value {
|
||||
@ -159,7 +173,18 @@
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
line-height: 1;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.bar-event {
|
||||
font-size: 8px;
|
||||
color: #dc2626;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
margin-bottom: 2px;
|
||||
white-space: nowrap;
|
||||
max-width: 40px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.bar-wrapper {
|
||||
@ -254,8 +279,11 @@
|
||||
<div class="chart-container">
|
||||
<div class="bar-chart">
|
||||
{% for day in daily_active %}
|
||||
<div class="bar-col" title="{{ day.label }}: {{ day.count }} użytkowników">
|
||||
<div class="bar-col{{ ' weekend' if day.is_weekend }}{{ ' monday-start' if day.is_monday }}" title="{{ day.label }}: {{ day.count }} użytkowników{% if day.event %} | {{ day.event.title }} ({{ day.event.attendees }} zapisanych){% endif %}">
|
||||
<span class="bar-value">{% if day.count > 0 %}{{ day.count }}{% endif %}</span>
|
||||
{% if day.event %}
|
||||
<span class="bar-event">📅({{ day.event.attendees }})</span>
|
||||
{% endif %}
|
||||
<div class="bar-wrapper">
|
||||
<div class="bar" style="height: {{ [day.pct, 5]|max if day.count > 0 else 0 }}%;"></div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user