From 9f4a0ea6876a319a2e8c30b0dbccf3943d93e7af Mon Sep 17 00:00:00 2001 From: Bernard Siebens Date: Sun, 16 Aug 2026 09:55:08 +0200 Subject: [PATCH] Make the management app responsive on mobile Replace the mobile nav's horizontal scroll strip (which wrapped into an unreadable jumble because daisyUI's .menu sets flex-wrap: wrap and .menu-horizontal never resets it) with a hamburger button that opens a proper left-side drawer, mirrored in controlpanel for the same bug. Move the theme toggle, "Management", and "Django admin" controls into that drawer below `lg`, leaving only the account icon in the navbar, so the club name has room to render in full instead of truncating to initials. Add a reusable `.table-cards` CSS pattern (app.css) that turns a list table into a stack of labelled cards below `md`, and apply it to every list/detail table in the management app -- members, families, teams, memberships, events, groups, locations, opponents, positions, referee levels/list, roles, sponsors, news, parent claims, team roster/staff, and the shared family-members table. Tables revert to normal desktop layout at `md` and up. Member list gets extra passes: search submits icon-only below `sm` so it fits next to the input, the Members/Guardians/Both tabs go full-width, and last/first name merge into one column. Action-button rows across every page stack full-width on mobile instead of wrapping mid-button (shared fix in base.html). Home dashboard's upcoming-events and news mini-tables become simple lists instead of overflowing tables. Also: brand truncates instead of overflowing on a long club name, a stray invalid xmlns attribute removed, a wrapping UUID badge hidden below `sm` on team detail. Co-Authored-By: Claude Sonnet 5 --- assets/app.css | 56 ++ controlpanel/templates/controlpanel/base.html | 64 +- .../management/_family_members_table.html | 14 +- .../management/_referee_assignment_panel.html | 2 +- management/templates/management/base.html | 51 +- .../templates/management/event_detail.html | 4 +- .../templates/management/event_list.html | 12 +- .../management/event_series_detail.html | 6 +- .../templates/management/family_list.html | 6 +- .../templates/management/group_bulk_add.html | 35 +- .../templates/management/group_detail.html | 6 +- .../templates/management/group_list.html | 6 +- management/templates/management/home.html | 64 +- .../templates/management/location_list.html | 10 +- .../templates/management/member_detail.html | 18 +- .../templates/management/member_list.html | 48 +- .../templates/management/membership_list.html | 49 +- .../templates/management/news_detail.html | 2 +- .../templates/management/news_list.html | 10 +- .../templates/management/opponent_list.html | 4 +- .../management/parent_claim_list.html | 10 +- .../templates/management/position_list.html | 12 +- .../management/referee_level_list.html | 8 +- .../templates/management/referee_list.html | 12 +- .../management/referee_management.html | 2 +- .../templates/management/role_list.html | 4 +- .../templates/management/sponsor_list.html | 10 +- .../templates/management/team_bulk_add.html | 43 +- .../templates/management/team_detail.html | 61 +- .../templates/management/team_list.html | 10 +- static/css/app.css | 624 ++++++------------ static/js/searchable-select.js | 29 +- templates/_base.html | 52 +- templates/_club_base.html | 19 +- templates/_platform_base.html | 10 +- 35 files changed, 674 insertions(+), 699 deletions(-) diff --git a/assets/app.css b/assets/app.css index fb94cd0..d157749 100644 --- a/assets/app.css +++ b/assets/app.css @@ -210,3 +210,59 @@ backface-visibility: hidden; transform: translateZ(0); } + +/* Below `md`, a `.table-cards` table reads as a stack of cards instead of a + horizontally-scrolling grid: each row becomes a bordered block, each cell + becomes a label/value line pulling its label from `data-label` (set on the + in the template -- there's no way to read the matching text from + pure CSS). A with no `data-label` renders as plain full-width content + instead of a label/value row -- for an image cell, a heading-style link, or + an actions row that already lays itself out. At `md` and up this reverts to + an ordinary table with nothing left over from the mobile styling. */ +@media (width < 48rem) { + .table-cards, .table-cards :is(thead, tbody, tr, th, td) { + display: block; + width: 100%; + } + + .table-cards thead { + display: none; + } + + .table-cards tbody tr { + border: 1px solid var(--color-base-300); + border-radius: var(--radius-box); + padding: 0 0.75rem; + } + + .table-cards tbody tr + tr { + margin-top: 0.75rem; + } + + .table-cards td { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + padding: 0.6rem 0; + border-bottom: 1px solid var(--color-base-200); + } + + .table-cards td:last-child { + border-bottom: none; + } + + .table-cards td[data-label]:before { + content: attr(data-label); + flex-shrink: 0; + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.02em; + text-transform: uppercase; + opacity: 0.5; + } + + .table-cards td:not([data-label]) { + justify-content: flex-start; + } +} diff --git a/controlpanel/templates/controlpanel/base.html b/controlpanel/templates/controlpanel/base.html index b1e1133..cb3597a 100644 --- a/controlpanel/templates/controlpanel/base.html +++ b/controlpanel/templates/controlpanel/base.html @@ -5,6 +5,15 @@ {% block panel_title %}Control panel{% endblock panel_title %} · RosterChief {% endblock title %} +{% block nav_toggle %} + +{% endblock nav_toggle %} + +{% comment %} Kept in the navbar itself only at `lg`+, where there's no hamburger drawer to hold them instead -- see the comment on `nav_icons_class` in _base.html. {% endcomment %} +{% block nav_icons_class %}hidden items-center lg:flex{% endblock nav_icons_class %} + {% block menu %} {% comment %} Outside
, so it never scrolls with the content. Its own overflow-y-auto is for @@ -18,6 +27,38 @@ {% endblock menu %} {% block main %} + {# Below `lg` the sidebar is hidden and {% block nav_toggle %} above opens this instead. #} + + + + + {% if maintenance_on %}
{% lucide "wrench" size=20 %} @@ -28,25 +69,22 @@ {% lucide "unlock" size=16 %} Reopen platform
{% endif %} -
- {% block logo %}{% endblock logo %} +
+
+ {% block logo %}{% endblock logo %} -
-

- {% block heading %}Control panel{% endblock heading %} -

- {% block subheading %}{% endblock subheading %} +
+

+ {% block heading %}Control panel{% endblock heading %} +

+ {% block subheading %}{% endblock subheading %} +
-
+
{% block actions %}{% endblock actions %}
- {# Below `lg` the sidebar is hidden, so the same links appear here rather than nowhere. #} - - {% block panel %}{% endblock panel %} {% endblock main %} diff --git a/management/templates/management/_family_members_table.html b/management/templates/management/_family_members_table.html index efc7f7e..a22f161 100644 --- a/management/templates/management/_family_members_table.html +++ b/management/templates/management/_family_members_table.html @@ -10,11 +10,10 @@ passes its own URL so admins land back on the member they were viewing; family_d leaves it unset, since staying on the family page is already the right place there. {% endcomment %}
- +
- - + @@ -23,10 +22,9 @@ leaves it unset, since staying on the family page is already the right place the {% for person in group.all %} - - - - + +
{% trans "Last name" %}{% trans "First name" %}{% trans "Name" %} {% trans "Email" %} {% trans "Type" %}
{{ person.last_name }}{{ person.first_name }}{{ person.contact_email|default:"-" }} + {{ person.last_name }}, {{ person.first_name }}{{ person.contact_email|default:"-" }} {% if is_club_admin %}
{% csrf_token %} @@ -43,7 +41,7 @@ leaves it unset, since staying on the family page is already the right place the
{% if is_club_admin %} -
+
{% if person.grant_login_form %} +{% endblock nav_toggle %} + +{% comment %} Kept in the navbar itself only at `lg`+, where there's no hamburger drawer to hold them instead -- see the comment on `nav_icons_class` in _base.html. {% endcomment %} +{% block nav_icons_class %}hidden items-center lg:flex{% endblock nav_icons_class %} + {% block menu %}