Redesign backend layout: dark sidebar + slim topbar
Moves from a floating-card sidebar to a full-height dark sidebar (bg-neutral) with the club logo at the top and logged-in user pinned to the bottom. The topbar becomes a slim bar containing only the mobile hamburger, notifications, and logout — no duplicate logo. - base.html: DaisyUI drawer with h-screen/overflow-hidden so the sidebar is sticky and the content column scrolls independently. The #content div is now the white card (bg-base-100 rounded-xl) so HTMX innerHTML swaps stay inside it. - member_filter.html: replaces the .action_bar component with a clean flex row (title + Add button) above a plain filter form. Table and mobile card list are unchanged. - styles.css: adds .sidebar-nav scoped overrides for menu link hover/active colours on the dark sidebar; reduces h1.page-title bottom margin from mb-12 to mb-4. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,13 +12,68 @@
|
||||
{% include "backend/partials/messages.html" %}
|
||||
{% endif %}
|
||||
|
||||
<h1 class="page-title">{% translate "Members" %}</h1>
|
||||
<!-- ── Page header: title + primary action ──────────────────────────── -->
|
||||
<div class="flex items-start justify-between gap-4 mb-5">
|
||||
<h1 class="text-2xl font-bold tracking-tight">{% translate "Members" %}</h1>
|
||||
|
||||
<div class="lg:hidden collapse collapse-plus bg-base-100 border-neutral border">
|
||||
<div class="flex items-center gap-2 shrink-0">
|
||||
{% flag "TF_MASS_UPLOAD" %}
|
||||
<a class="btn btn-ghost btn-sm hidden lg:flex"
|
||||
href="{% url "backend:members:load" %}"
|
||||
hx-get="{% url "backend:members:load" %}"
|
||||
hx-target="#content">
|
||||
<i class="fa-solid fa-file-upload"></i>
|
||||
{% translate "Load from file" %}
|
||||
</a>
|
||||
{% endflag %}
|
||||
|
||||
<a class="btn btn-neutral btn-outline btn-sm"
|
||||
href="{% url "backend:members:add" %}"
|
||||
hx-get="{% url "backend:members:add" %}"
|
||||
hx-target="#content">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
{% translate "Add member" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Desktop filter row ───────────────────────────────────────────── -->
|
||||
<!-- Visible on lg+. Sits between the page header and the table. -->
|
||||
<form class="hidden lg:flex flex-wrap items-end gap-2 mb-4"
|
||||
hx-get="{% url "backend:members:list" %}"
|
||||
hx-target="#content">
|
||||
{% for field in filter.form %}
|
||||
{% form_field field show_label=False size="extra-small" %}
|
||||
{% endfor %}
|
||||
|
||||
<button type="submit" class="btn btn-outline btn-xs">
|
||||
<i class="fa-solid fa-filter"></i>{% translate "Filter" %}
|
||||
</button>
|
||||
|
||||
{% if filter.is_bound %}
|
||||
<a class="btn btn-outline btn-error btn-xs"
|
||||
href="{% url "backend:members:list" %}"
|
||||
hx-get="{% url "backend:members:list" %}"
|
||||
hx-target="#content">
|
||||
<i class="fa-solid fa-times"></i>{% translate "Clear" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
<!-- ── Mobile filter (collapsible) ─────────────────────────────────── -->
|
||||
<div class="lg:hidden collapse collapse-plus bg-base-100 border border-base-300 mb-4">
|
||||
<input type="checkbox"/>
|
||||
<div class="collapse-title text-sm font-semibold"><i class="fa-solid fa-filter mr-2"></i>{% translate "Filter" %}{% if filter.is_bound %}<span class="ml-2 badge badge-sm badge-neutral">active</span>{% endif %}</div>
|
||||
<div class="collapse-title text-sm font-semibold">
|
||||
<i class="fa-solid fa-filter mr-2"></i>
|
||||
{% translate "Filter" %}
|
||||
{% if filter.is_bound %}
|
||||
<span class="ml-2 badge badge-sm badge-neutral">active</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="collapse-content">
|
||||
<form class="flex flex-col gap-2" hx-get="{% url "backend:members:list" %}" hx-target="#content">
|
||||
<form class="flex flex-col gap-2"
|
||||
hx-get="{% url "backend:members:list" %}"
|
||||
hx-target="#content">
|
||||
{% for field in filter.form %}
|
||||
{% form_field field show_label=False size="small" %}
|
||||
{% endfor %}
|
||||
@@ -27,9 +82,11 @@
|
||||
<button type="submit" class="btn btn-sm btn-outline btn-neutral grow">
|
||||
<i class="fa-solid fa-filter"></i>{% translate "Filter" %}
|
||||
</button>
|
||||
|
||||
{% if filter.is_bound %}
|
||||
<a class="btn btn-outline btn-error btn-sm grow" href="{% url "backend:members:list" %}" hx-get="{% url "backend:members:list" %}" hx-target="#content">
|
||||
<a class="btn btn-outline btn-error btn-sm grow"
|
||||
href="{% url "backend:members:list" %}"
|
||||
hx-get="{% url "backend:members:list" %}"
|
||||
hx-target="#content">
|
||||
<i class="fa-solid fa-times"></i>{% translate "Clear" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
@@ -38,41 +95,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action_bar">
|
||||
<div class="filter hidden lg:flex">
|
||||
<form hx-get="{% url "backend:members:list" %}" hx-target="#content">
|
||||
{% for field in filter.form %}
|
||||
{% form_field field show_label=False size="extra-small" %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="flex flex-row w-full gap-2 lg:w-fit">
|
||||
<button type="submit">
|
||||
<i class="fa-solid fa-filter"></i>{% translate "Filter" %}
|
||||
</button>
|
||||
|
||||
{% if filter.is_bound %}
|
||||
<a class="btn btn-outline btn-error btn-xs grow" href="{% url "backend:members:list" %}" hx-get="{% url "backend:members:list" %}" hx-target="#content">
|
||||
<i class="fa-solid fa-times"></i>{% translate "Clear" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="add">
|
||||
{% flag "TF_MASS_UPLOAD" %}
|
||||
<a class="btn btn-accent btn-sm grow hidden lg:flex" href="{% url "backend:members:load" %}" hx-get="{% url "backend:members:load" %}" hx-target="#content">
|
||||
<i class="fa-solid fa-file-upload"></i>{% translate "Load members from file" %}
|
||||
</a>
|
||||
{% endflag %}
|
||||
|
||||
<a class="btn btn-neutral btn-outline btn-sm grow" href="{% url "backend:members:add" %}" hx-get="{% url "backend:members:add" %}" hx-target="#content">
|
||||
<i class="fa-solid fa-plus"></i>{% translate "Add member" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden lg:flex mt-4">
|
||||
<!-- ── Desktop table ────────────────────────────────────────────────── -->
|
||||
<div class="hidden lg:block">
|
||||
<table class="table table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -148,6 +172,7 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- ── Mobile card list ─────────────────────────────────────────────── -->
|
||||
<div class="lg:hidden">
|
||||
{% if object_list|length == 0 %}
|
||||
<div class="text-center w-full">{% translate "No members found" %}</div>
|
||||
@@ -183,31 +208,26 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- ── Pagination ───────────────────────────────────────────────────── -->
|
||||
{% if is_paginated %}
|
||||
<div class="flex justify-center mt-4">
|
||||
<div class="join">
|
||||
{% if page_obj.has_previous %}
|
||||
<a class="join-item btn" href="?{% url_replace request "page" 1 %}" hx-get="?{% url_replace request "page" 1 %}" hx-target="#content">«<span
|
||||
class="hidden lg:inline"> {% translate "first" %}</span></a>
|
||||
<a class="join-item btn"
|
||||
href="?{% url_replace request "page" page_obj.previous_page_number %}" hx-get="?{% url_replace request "page" page_obj.previous_page_number %}" hx-target="#content"><span
|
||||
class="hidden lg:inline">{% translate "previous" %}</span><span
|
||||
class="lg:hidden"><</span></a>
|
||||
<a class="join-item btn" href="?{% url_replace request "page" 1 %}" hx-get="?{% url_replace request "page" 1 %}" hx-target="#content">«<span class="hidden lg:inline"> {% translate "first" %}</span></a>
|
||||
<a class="join-item btn" href="?{% url_replace request "page" page_obj.previous_page_number %}" hx-get="?{% url_replace request "page" page_obj.previous_page_number %}" hx-target="#content"><span class="hidden lg:inline">{% translate "previous" %}</span><span class="lg:hidden"><</span></a>
|
||||
{% endif %}
|
||||
|
||||
<button class="join-item btn btn-disabled">
|
||||
{% blocktranslate with page=page_obj.number num_pages=page_obj.paginator.num_pages %}page {{ page }}
|
||||
of {{ num_pages }}{% endblocktranslate %}</button>
|
||||
{% blocktranslate with page=page_obj.number num_pages=page_obj.paginator.num_pages %}page {{ page }} of {{ num_pages }}{% endblocktranslate %}
|
||||
</button>
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<a class="join-item btn" href="?{% url_replace request "page" page_obj.next_page_number %}" hx-get="?{% url_replace request "page" page_obj.next_page_number %}" hx-target="#content"><span
|
||||
class="hidden lg:inline">{% translate "next" %}</span><span
|
||||
class="lg:hidden">></span></a>
|
||||
<a class="join-item btn" href="?{% url_replace request "page" page_obj.paginator.num_pages %}" hx-get="?{% url_replace request "page" page_obj.paginator.num_pages %}" hx-target="#content"><span
|
||||
class="hidden lg:inline"> {% translate "last" %}</span> »</a>
|
||||
<a class="join-item btn" href="?{% url_replace request "page" page_obj.next_page_number %}" hx-get="?{% url_replace request "page" page_obj.next_page_number %}" hx-target="#content"><span class="hidden lg:inline">{% translate "next" %}</span><span class="lg:hidden">></span></a>
|
||||
<a class="join-item btn" href="?{% url_replace request "page" page_obj.paginator.num_pages %}" hx-get="?{% url_replace request "page" page_obj.paginator.num_pages %}" hx-target="#content"><span class="hidden lg:inline"> {% translate "last" %}</span> »</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endpartialdef content %}
|
||||
{% endblock content %}
|
||||
{% endblock content %}
|
||||
|
||||
Reference in New Issue
Block a user