Home/Calendar polish: person switcher placement, full-width Calendar, sponsors
- Home: the person switcher (chip row) now lives in the white content area instead of the navy header, matching the design canvas's own M1 markup, and renders smaller. Home is now the only screen that shows it at all. - Calendar: dropped the person switcher and the "My schedule"/"All members" toggle entirely -- it always shows every event self.managed_people is invited to, full stop. Rows now run edge-to-edge (-mx-4) instead of living in a rounded, inset card, matching the M3 design canvas's own full-bleed layout. (The design mock's List/Month/"Games only" controls aren't reproduced -- no real functionality behind them yet.) - Home's "Needs your answer" card caps at 5 items with a "+N more in Calendar" link, so it can't crowd the dues/news cards below it off the first screenful. - Home gains a sponsors strip at the very bottom (horizontally scrolling, scrollbar hidden) -- active sponsors only, reshuffled on every request. club.services.sponsors.active_sponsors factors the "what counts as active" query out of club/api.py's public sponsors endpoint so both it and Home share one definition. - Also removed mobile/views.py's now-fully-dead _PlaceholderScreen and its template -- every M1-M7 screen has had a real implementation for a while and nothing subclassed it anymore. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
warn for everything else) next to the date, per the design doc's M3 row
|
||||
description.
|
||||
{% endcomment %}
|
||||
<a class="flex items-center gap-3 bg-white p-3.5 {% if row.event.kind == "game" %}border-l-4 border-club{% endif %}" href="{% url "mobile:event_detail" row.event.pk %}">
|
||||
<a class="flex items-center gap-3 bg-white px-4 py-3 {% if row.event.kind == "game" %}border-l-4 border-club{% endif %}" href="{% url "mobile:event_detail" row.event.pk %}">
|
||||
<div class="w-9.5 shrink-0 text-center">
|
||||
<div class="font-mono text-[10px] tracking-wide text-muted uppercase">{{ row.event.start|date:"D" }}</div>
|
||||
<div class="font-display text-2xl leading-none font-extrabold text-ink">{{ row.event.start|date:"d" }}</div>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{% extends "mobile/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="m-card p-6 text-center">
|
||||
<p class="font-display text-lg font-bold text-ink uppercase">{{ screen_title }}</p>
|
||||
<p class="mt-1 text-sm text-muted">{% trans "This screen is coming soon." %}</p>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
@@ -70,23 +70,6 @@
|
||||
{% if unread_notification_count %}<span class="absolute top-1.5 right-1.5 h-2 w-2 rounded-full bg-club" style="border: 2px solid var(--color-navy)"></span>{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if managed_people|length > 1 %}
|
||||
<div class="scrollbar-hide mt-3 flex gap-2 overflow-x-auto pb-0.5">
|
||||
<a class="person-chip {% if scope_everyone %}person-chip-active{% endif %}" href="?as=all">
|
||||
<span class="person-chip-avatar">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="3"/><circle cx="17" cy="9" r="2.6"/><path d="M2.5 20c0-3.3 2.5-5.6 5.5-5.6s5.5 2.3 5.5 5.6"/><path d="M14 15c2.6.3 4.5 2.3 4.5 5"/></svg>
|
||||
</span>
|
||||
<span class="person-chip-label">{% trans "All" %}</span>
|
||||
</a>
|
||||
{% for person in managed_people %}
|
||||
<a class="person-chip {% if not scope_everyone and person == scope_person %}person-chip-active{% endif %}" href="?as={{ person.pk }}">
|
||||
<span class="person-chip-avatar">{{ person.first_name|slice:":1" }}</span>
|
||||
<span class="person-chip-label">{% if person == me %}{% trans "Me" %}{% else %}{{ person.first_name }}{% endif %}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
<main class="flex-1 overflow-y-auto">
|
||||
|
||||
@@ -2,56 +2,54 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% comment %}
|
||||
M3 -- design_handoff_rosterchief_platform/README.md's M3 section: a
|
||||
chronological agenda, grouped under "This week"/"Next week", scoped to
|
||||
scope_person's own invites by default or, with the "All members" toggle
|
||||
below, every club event. See CalendarView's own docstring for the
|
||||
browsing-window judgment call (current + next calendar week, no further
|
||||
paging).
|
||||
M3 -- design_handoff_rosterchief_platform/README.md's M3 section: a full-
|
||||
width chronological agenda, grouped under "This week"/"Next week" (see
|
||||
CalendarView's own docstring for the browsing-window judgment call --
|
||||
current + next calendar week, no further paging). No person switcher and
|
||||
no club-wide toggle here -- always every event self.managed_people is
|
||||
invited to, full stop. -mx-4 breaks the rows out of base.html's shared
|
||||
page padding so they run edge-to-edge, matching the design canvas's own
|
||||
M3 markup (the desktop List/Month/"Games only" controls in that mock
|
||||
aren't reproduced here -- no real functionality behind them yet).
|
||||
{% endcomment %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex gap-2">
|
||||
<a class="flex h-9 flex-1 items-center justify-center rounded-full font-display text-xs font-extrabold tracking-wide uppercase {% if not scope_all %}bg-ink text-white{% else %}border border-line bg-white text-muted{% endif %}"
|
||||
href="?{% if request.GET.as %}as={{ request.GET.as }}{% endif %}">
|
||||
{% trans "My schedule" %}
|
||||
</a>
|
||||
<a class="flex h-9 flex-1 items-center justify-center rounded-full font-display text-xs font-extrabold tracking-wide uppercase {% if scope_all %}bg-ink text-white{% else %}border border-line bg-white text-muted{% endif %}"
|
||||
href="?scope=all{% if request.GET.as %}&as={{ request.GET.as }}{% endif %}">
|
||||
{% trans "All members" %}
|
||||
</a>
|
||||
<div class="-mx-4">
|
||||
{% if not managed_people %}
|
||||
<div class="mx-4">
|
||||
<div class="m-card p-6 text-center">
|
||||
<p class="font-display text-lg font-extrabold text-ink uppercase">{% trans "No one to show yet" %}</p>
|
||||
<p class="mt-1 text-sm text-muted">{% trans "Once you're linked to a member record, their schedule will show up here." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% elif not this_week and not next_week %}
|
||||
<div class="mx-4">
|
||||
<div class="m-card p-6 text-center">
|
||||
<p class="text-sm text-muted">{% trans "Nothing scheduled in the next two weeks." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if this_week %}
|
||||
<div>
|
||||
<div class="sticky top-0 z-10 bg-paper px-4 py-2 font-display text-xs font-extrabold tracking-wide text-muted uppercase">{% trans "This week" %}</div>
|
||||
<div class="flex flex-col gap-px bg-line">
|
||||
{% for row in this_week %}
|
||||
{% include "mobile/_calendar_row.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if next_week %}
|
||||
<div>
|
||||
<div class="sticky top-0 z-10 bg-paper px-4 py-2 font-display text-xs font-extrabold tracking-wide text-muted uppercase">{% trans "Next week" %}</div>
|
||||
<div class="flex flex-col gap-px bg-line">
|
||||
{% for row in next_week %}
|
||||
{% include "mobile/_calendar_row.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if not scope_all and not managed_people %}
|
||||
<div class="m-card p-6 text-center">
|
||||
<p class="font-display text-lg font-extrabold text-ink uppercase">{% trans "No one to show yet" %}</p>
|
||||
<p class="mt-1 text-sm text-muted">{% trans "Once you're linked to a member record, their schedule will show up here." %}</p>
|
||||
</div>
|
||||
{% elif not this_week and not next_week %}
|
||||
<div class="m-card p-6 text-center">
|
||||
<p class="text-sm text-muted">{% trans "Nothing scheduled in the next two weeks." %}</p>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if this_week %}
|
||||
<div>
|
||||
<div class="sticky top-0 z-10 bg-paper py-1 font-display text-xs font-extrabold tracking-wide text-muted uppercase">{% trans "This week" %}</div>
|
||||
<div class="flex flex-col gap-px overflow-hidden rounded-box bg-line">
|
||||
{% for row in this_week %}
|
||||
{% include "mobile/_calendar_row.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if next_week %}
|
||||
<div>
|
||||
<div class="sticky top-0 z-10 bg-paper py-1 font-display text-xs font-extrabold tracking-wide text-muted uppercase">{% trans "Next week" %}</div>
|
||||
<div class="flex flex-col gap-px overflow-hidden rounded-box bg-line">
|
||||
{% for row in next_week %}
|
||||
{% include "mobile/_calendar_row.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
||||
@@ -2,16 +2,37 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% comment %}
|
||||
M1 -- design_handoff_rosterchief_platform/README.md's M1 section. Four
|
||||
independently-optional cards, scoped to people_in_scope (mobile/mixins.py)
|
||||
-- everyone the account manages once there's more than one (the header's
|
||||
"All" chip, on by default), or just the one person picked from the chip
|
||||
row. A hero for the soonest upcoming event with a quick In/Out RSVP, a
|
||||
"needs your answer" list, a season-dues card per person who owes money,
|
||||
and a news teaser.
|
||||
M1 -- design_handoff_rosterchief_platform/README.md's M1 section. The
|
||||
person switcher (chip row) sits in the white content area here, not the
|
||||
navy header -- matching the design canvas's own M1 markup, and Home is
|
||||
now the only screen that renders it at all (mobile/mixins.py's scope
|
||||
resolution still runs for every screen, but only Home's UI exposes it).
|
||||
Four independently-optional cards below it, scoped to people_in_scope --
|
||||
everyone the account manages once there's more than one ("All", on by
|
||||
default), or just the one person picked from the chip row. A hero for
|
||||
the soonest upcoming event with a quick In/Out RSVP, a "needs your
|
||||
answer" list, a season-dues card per person who owes money, and a news
|
||||
teaser.
|
||||
{% endcomment %}
|
||||
|
||||
{% block content %}
|
||||
{% if managed_people|length > 1 %}
|
||||
<div class="scrollbar-hide -mt-1 flex gap-2 overflow-x-auto pb-0.5">
|
||||
<a class="person-chip {% if scope_everyone %}person-chip-active{% endif %}" href="?as=all">
|
||||
<span class="person-chip-avatar">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="3"/><circle cx="17" cy="9" r="2.6"/><path d="M2.5 20c0-3.3 2.5-5.6 5.5-5.6s5.5 2.3 5.5 5.6"/><path d="M14 15c2.6.3 4.5 2.3 4.5 5"/></svg>
|
||||
</span>
|
||||
<span class="person-chip-label">{% trans "All" %}</span>
|
||||
</a>
|
||||
{% for person in managed_people %}
|
||||
<a class="person-chip {% if not scope_everyone and person == scope_person %}person-chip-active{% endif %}" href="?as={{ person.pk }}">
|
||||
<span class="person-chip-avatar">{{ person.first_name|slice:":1" }}</span>
|
||||
<span class="person-chip-label">{% if person == me %}{% trans "Me" %}{% else %}{{ person.first_name }}{% endif %}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if managed_people %}
|
||||
{% if hero_attendance %}
|
||||
<div class="m-card-dark overflow-hidden">
|
||||
@@ -56,7 +77,7 @@
|
||||
<div class="m-card p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-display text-xs font-extrabold text-muted uppercase tracking-wide">{% trans "Needs your answer" %}</span>
|
||||
<span class="font-display text-lg font-extrabold text-club">{{ needs_answer|length }}</span>
|
||||
<span class="font-display text-lg font-extrabold text-club">{{ needs_answer|length|add:needs_answer_remaining }}</span>
|
||||
</div>
|
||||
<div class="mt-3 flex flex-col gap-2.5">
|
||||
{% for attendance in needs_answer %}
|
||||
@@ -74,6 +95,11 @@
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if needs_answer_remaining %}
|
||||
<a class="mt-3 block text-center text-xs font-semibold text-club" href="{% url "mobile:calendar" %}">
|
||||
{% blocktrans count counter=needs_answer_remaining %}+{{ counter }} more in Calendar{% plural %}+{{ counter }} more in Calendar{% endblocktrans %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -128,4 +154,23 @@
|
||||
<p class="mt-1 text-sm text-muted">{% trans "Once you're linked to a member record, their schedule and updates will show up here." %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if sponsors %}
|
||||
<div>
|
||||
<div class="mb-2.5 font-display text-xs font-extrabold text-muted uppercase tracking-wide">{% trans "Sponsors" %}</div>
|
||||
<div class="scrollbar-hide flex gap-3 overflow-x-auto pb-0.5">
|
||||
{% for sponsor in sponsors %}
|
||||
{% if sponsor.url %}
|
||||
<a class="m-card flex h-14 w-28 shrink-0 items-center justify-center p-2" href="{{ sponsor.url }}" target="_blank" rel="noopener">
|
||||
{% if sponsor.logo %}<img class="max-h-full max-w-full object-contain" src="{{ sponsor.logo.url }}" alt="{{ sponsor.name }}">{% else %}<span class="text-xs font-semibold text-muted">{{ sponsor.name }}</span>{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="m-card flex h-14 w-28 shrink-0 items-center justify-center p-2">
|
||||
{% if sponsor.logo %}<img class="max-h-full max-w-full object-contain" src="{{ sponsor.logo.url }}" alt="{{ sponsor.name }}">{% else %}<span class="text-xs font-semibold text-muted">{{ sponsor.name }}</span>{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
||||
Reference in New Issue
Block a user