Various small bug fixes, break out pagination for cards into its own mixin and templatetag
This commit is contained in:
parent
05a279fa3a
commit
138a929da6
17 changed files with 225 additions and 136 deletions
|
|
@ -1,4 +1,5 @@
|
|||
{% load card_badge %}
|
||||
{% load pagination_tags %}
|
||||
{% if group_by and groups %}
|
||||
{% for group in groups %}
|
||||
<div class="divider">{{ group.group }}</div>
|
||||
|
|
@ -20,21 +21,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Pagination Controls -->
|
||||
<div class="mt-6">
|
||||
{% if is_paginated %}
|
||||
<div class="flex justify-center space-x-2">
|
||||
{% if page_obj.has_previous %}
|
||||
<button class="btn btn-outline" @click="$dispatch('change-page', { page: {{ page_obj.previous_page_number }} })">
|
||||
Previous
|
||||
</button>
|
||||
{% endif %}
|
||||
<span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
|
||||
{% if page_obj.has_next %}
|
||||
<button class="btn btn-outline" @click="$dispatch('change-page', { page: {{ page_obj.next_page_number }} })">
|
||||
Next
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- Somewhere in your template, e.g., after the card list: -->
|
||||
{% if page_obj %}
|
||||
{% render_pagination page_obj %}
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -18,35 +18,40 @@
|
|||
x-init="loadCards()"
|
||||
x-on:change-page.window="page = $event.detail.page; loadCards()"
|
||||
>
|
||||
<h1 class="text-2xl font-bold mb-4">Cards</h1>
|
||||
|
||||
<div class="flex flex-wrap items-center justify-between mb-6">
|
||||
<!-- Sort Dropdown -->
|
||||
<div class="dropdown dropdown-end m-1">
|
||||
<div tabindex="0" class="btn">
|
||||
<span x-text="order === 'absolute' ? 'Absolute' : (order === 'alphabetical' ? 'Alphabetical' : 'Rarity')"></span> 🞃
|
||||
</div>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li><a href="#" @click.prevent="order = 'absolute'; page = 1; loadCards()">Absolute</a></li>
|
||||
<li><a href="#" @click.prevent="order = 'alphabetical'; page = 1; loadCards()">Alphabetical</a></li>
|
||||
<li><a href="#" @click.prevent="order = 'rarity'; page = 1; loadCards()">Rarity</a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold">Cards</h1>
|
||||
</div>
|
||||
<!-- Grouping Dropdown -->
|
||||
<div class="dropdown dropdown-end m-1">
|
||||
<div tabindex="0" class="btn">
|
||||
<span x-text="groupBy === 'none' ? 'No Group' : (groupBy.charAt(0).toUpperCase() + groupBy.slice(1))"></span> 🞃
|
||||
<div>
|
||||
<!-- Sort Dropdown -->
|
||||
<div class="dropdown dropdown-end m-1">
|
||||
<div tabindex="0" class="btn">
|
||||
Sort by: <span x-text="order === 'absolute' ? 'None' : (order === 'alphabetical' ? 'Alphabetical' : 'Rarity')"></span> 🞃
|
||||
</div>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li><a href="#" @click.prevent="order = 'absolute'; page = 1; loadCards()">None</a></li>
|
||||
<li><a href="#" @click.prevent="order = 'alphabetical'; page = 1; loadCards()">Alphabetical</a></li>
|
||||
<li><a href="#" @click.prevent="order = 'rarity'; page = 1; loadCards()">Rarity</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Grouping Dropdown -->
|
||||
<div class="dropdown dropdown-end m-1">
|
||||
<div tabindex="0" class="btn">
|
||||
Group by: <span x-text="groupBy === 'none' ? 'None' : (groupBy.charAt(0).toUpperCase() + groupBy.slice(1))"></span> 🞃
|
||||
</div>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li><a href="#" @click.prevent="groupBy = 'none'; page = 1; loadCards()">None</a></li>
|
||||
<li><a href="#" @click.prevent="groupBy = 'deck'; page = 1; loadCards()">Deck</a></li>
|
||||
<li><a href="#" @click.prevent="groupBy = 'cardset'; page = 1; loadCards()">Cardset</a></li>
|
||||
<li><a href="#" @click.prevent="groupBy = 'rarity'; page = 1; loadCards()">Rarity</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li><a href="#" @click.prevent="groupBy = 'none'; page = 1; loadCards()">No Group</a></li>
|
||||
<li><a href="#" @click.prevent="groupBy = 'deck'; page = 1; loadCards()">Deck</a></li>
|
||||
<li><a href="#" @click.prevent="groupBy = 'cardset'; page = 1; loadCards()">Cardset</a></li>
|
||||
<li><a href="#" @click.prevent="groupBy = 'rarity'; page = 1; loadCards()">Rarity</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Container for the partial card list -->
|
||||
<div x-ref="cardList">
|
||||
<!-- The contents of _card_list.html will be loaded here via AJAX -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,21 +1,8 @@
|
|||
{% load card_badge %}
|
||||
{% comment %}
|
||||
This partial expects:
|
||||
- cards: a list of card objects
|
||||
- mode: a string that determines the render style.
|
||||
It should be "offered" for Most Offered Cards and "wanted" for Most Wanted Cards.
|
||||
- Optional:
|
||||
'show_zero' flag (default False): if True, also display cards with 0 offers.
|
||||
'layout' variable: if set to "auto", use an auto-fit grid based on available horizontal space.
|
||||
{% endcomment %}
|
||||
{% if cards %}
|
||||
<div class="mx-4 grid gap-3 grid-cols-[repeat(auto-fit,minmax(150px,1fr))] justify-items-center">
|
||||
{% for card in cards %}
|
||||
{% if mode == "offered" %}
|
||||
<a href="{% url 'cards:card_detail' card.id %}"
|
||||
{% else %}
|
||||
<a href="{% url 'cards:card_detail' card.id %}"
|
||||
{% endif %}
|
||||
class="flex justify-between items-center text-primary no-underline">
|
||||
{% card_badge card card.offer_count %}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
<div class="card-body my-4 p-0">
|
||||
{% cache 3600 most_offered_cards %}
|
||||
{% include "home/_card_list.html" with cards=most_offered_cards mode="wanted" %}
|
||||
{% include "home/_card_list.html" with cards=most_offered_cards %}
|
||||
{% endcache %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
</div>
|
||||
<div class="card-body my-4 p-0">
|
||||
{% cache 3600 most_wanted_cards %}
|
||||
{% include "home/_card_list.html" with cards=most_wanted_cards mode="offered" %}
|
||||
{% include "home/_card_list.html" with cards=most_wanted_cards %}
|
||||
{% endcache %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
<div class="card-body my-4 p-0">
|
||||
{% cache 3600 least_offered_cards %}
|
||||
{% include "home/_card_list.html" with cards=least_offered_cards mode="wanted" %}
|
||||
{% include "home/_card_list.html" with cards=least_offered_cards %}
|
||||
{% endcache %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -121,8 +121,8 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<!-- DaisyUI Tabs for Featured Offers -->
|
||||
<div class="card card-border bg-base-100 shadow-lg w-96 md:w-80 lg:w-96 mt-8 mx-auto">
|
||||
<!-- DaisyUI Tabs for Featured Offers (hidden for now) -->
|
||||
<div class="card card-border bg-base-100 shadow-lg w-96 md:w-80 lg:w-96 mt-8 mx-auto hidden">
|
||||
<!-- Tabs navigation using daisyUI tabs-box -->
|
||||
<div class="tabs tabs-box bg-white dark:bg-base-100 grid grid-cols-3 gap-1.5 justify-items-stretch">
|
||||
<!-- Radio inputs for controlling tab state -->
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@
|
|||
<div class="container mx-auto max-w-4xl mt-6" x-data="{ allExpanded: false }">
|
||||
<!-- Header-->
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<a href="{% url 'trade_offer_create' %}" class="btn btn-success">Create New Offer</a>
|
||||
<h1 class="text-2xl font-bold">All Trade Offers</h1>
|
||||
<div>
|
||||
<form method="get" class="flex items-center space-x-4" x-data>
|
||||
<label class="cursor-pointer flex items-center space-x-2">
|
||||
<form method="get" class="flex items-center gap-4" x-data>
|
||||
<label class="cursor-pointer flex items-center gap-2">
|
||||
<span x-text="allExpanded ? 'Collapse All' : 'Expand All'"></span>
|
||||
<input type="checkbox" name="all_expanded" value="true" class="toggle toggle-primary" @click="allExpanded = !allExpanded; $dispatch('toggle-all', { expanded: allExpanded })">
|
||||
</label>
|
||||
<label class="cursor-pointer flex items-center space-x-2">
|
||||
<label class="cursor-pointer flex items-center gap-2">
|
||||
<span>Only Closed</span>
|
||||
<input type="checkbox" name="show_closed" value="true" class="toggle toggle-primary" @change="$el.form.submit()" {% if show_closed %}checked{% endif %}>
|
||||
</label>
|
||||
|
|
@ -24,7 +24,9 @@
|
|||
</div>
|
||||
<!-- Trade Offers -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-bold mb-4">All Trade Offers</h2>
|
||||
<div class="flex justify-end mb-4">
|
||||
<a href="{% url 'trade_offer_create' %}" class="btn btn-success">Create New Offer</a>
|
||||
</div>
|
||||
<div
|
||||
id="all-trade-offers"
|
||||
x-data="tradeOffersPagination('{% url 'trade_offer_list' %}?')"
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
<div class="rarity row-start-2 col-span-2 truncate self-end align-bottom text-xs">{{ rarity }}</div>
|
||||
<div class="cardset row-start-2 col-start-3 col-span-2 text-right truncate self-end align-bottom font-semibold leading-none text-sm">{{ cardset }}</div>
|
||||
</div>
|
||||
{% if quantity %}<span class="card-quantity-badge freeze-bg-color absolute top-3.75 right-1.5 bg-gray-600 text-white text-sm font-semibold rounded-full px-1.5">{{ quantity }}</span>{% endif %}
|
||||
{% if quantity != "" %}<span class="card-quantity-badge freeze-bg-color absolute top-3.75 right-1.5 bg-gray-600 text-white text-sm font-semibold rounded-full px-1.5">{{ quantity }}</span>{% endif %}
|
||||
</div>
|
||||
38
theme/templatetags/pagination_controls.html
Normal file
38
theme/templatetags/pagination_controls.html
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<div class="flex justify-center items-center space-x-2">
|
||||
<!-- First Button -->
|
||||
<button class="btn btn-outline btn-md"
|
||||
{% if not page_obj.has_previous %}disabled{% endif %}
|
||||
@click="$dispatch('change-page', { page: 1 })">
|
||||
First
|
||||
</button>
|
||||
<!-- Previous Button -->
|
||||
<button class="btn btn-outline btn-md"
|
||||
{% if not page_obj.has_previous %}disabled{% endif %}
|
||||
@click="$dispatch('change-page', { page: {{ page_obj.previous_page }} })">
|
||||
Prev
|
||||
</button>
|
||||
<!-- Goto Page -->
|
||||
<span class="flex items-center space-x-1 gap-2">
|
||||
<input type="number" min="1" max="{{ page_obj.paginator.num_pages }}" value="{{ page_obj.number }}"
|
||||
class="input input-xs text-center" id="gotoPageInput">
|
||||
<button class="btn btn-outline btn-md"
|
||||
@click="(document.getElementById('gotoPageInput').value >= 1 && document.getElementById('gotoPageInput').value <= {{ page_obj.paginator.num_pages }}) && $dispatch('change-page', { page: parseInt(document.getElementById('gotoPageInput').value) })">
|
||||
Go
|
||||
</button>
|
||||
</span>
|
||||
<!-- Next Button -->
|
||||
<button class="btn btn-outline btn-md"
|
||||
{% if not page_obj.has_next %}disabled{% endif %}
|
||||
@click="$dispatch('change-page', { page: {{ page_obj.next_page }} })">
|
||||
Next
|
||||
</button>
|
||||
<!-- Last Button -->
|
||||
<button class="btn btn-outline btn-md"
|
||||
{% if page_obj.number == page_obj.paginator.num_pages %}disabled{% endif %}
|
||||
@click="$dispatch('change-page', { page: {{ page_obj.paginator.num_pages }} })">
|
||||
Last
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex items-center justify-center mt-2">
|
||||
<span>Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</span>
|
||||
</div>
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
<!-- Main Trade Offer Row -->
|
||||
<div class="flip-face-body self-start">
|
||||
<a href="{% url 'trade_offer_detail' pk=offer_pk %}" class="no-underline block">
|
||||
<div class="px-2 main-badges {% if not screenshot_mode and have_cards_available|length == 1 and want_cards_available|length == 1 %}py-[14px]{%else%}pb-0{% endif %}">
|
||||
<div class="px-2 main-badges pb-0">
|
||||
{% if screenshot_mode and num_cards_available >= 4 %}
|
||||
<!-- When screenshot_mode is true, use an outer grid with 3 columns: Has side, a vertical divider, and Wants side -->
|
||||
<div class="flex flex-row gap-2 justify-around">
|
||||
|
|
@ -151,6 +151,8 @@
|
|||
d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="h-5"></div>
|
||||
{% endif %}
|
||||
{% if not screenshot_mode %}
|
||||
<div class="flip-face-footer self-end">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue