Add expand all/collapse all button for trades listings

This commit is contained in:
badblocks 2025-03-12 00:57:23 -07:00
parent 0990340cbc
commit d942632811
3 changed files with 108 additions and 69 deletions

View file

@ -4,15 +4,25 @@
{% block title %}All Trade Offers{% endblock title %} {% block title %}All Trade Offers{% endblock title %}
{% block content %} {% block content %}
<div class="container mx-auto max-w-4xl mt-6"> <div class="container mx-auto max-w-4xl mt-6" x-data="{ allExpanded: false }">
<div class="flex justify-end mb-4"> <div class="flex justify-between items-center mb-4">
<form method="get" class="flex items-center space-x-4"> <div>
<label class="cursor-pointer flex items-center space-x-2"> <form method="get" class="flex items-center space-x-4">
<span class="font-medium">Only Closed</span> <label class="cursor-pointer flex items-center space-x-2">
<input type="checkbox" name="show_closed" value="true" class="toggle toggle-primary" {% if show_closed %}checked{% endif %}> <span class="font-medium">Only Closed</span>
</label> <input type="checkbox" name="show_closed" value="true" class="toggle toggle-primary" {% if show_closed %}checked{% endif %}>
<button type="submit" class="btn btn-primary">Apply</button> </label>
</form> <button type="submit" class="btn btn-primary">Apply</button>
</form>
</div>
<div>
<!-- Global toggle button using Alpine only -->
<button type="button"
@click="allExpanded = !allExpanded; $dispatch('toggle-all', { expanded: allExpanded })"
class="btn btn-secondary">
<span x-text="allExpanded ? 'Collapse All' : 'Expand All'"></span>
</button>
</div>
</div> </div>
<!-- Trade Offers --> <!-- Trade Offers -->
<section class="mb-12"> <section class="mb-12">

View file

@ -4,21 +4,77 @@
{% block title %}Trade Offer & Acceptance List{% endblock title %} {% block title %}Trade Offer & Acceptance List{% endblock title %}
{% block content %} {% block content %}
<div class="container mx-auto max-w-4xl mt-6"> <div class="container mx-auto max-w-4xl mt-6" x-data="{ allExpanded: false }">
<!-- Filter Form: Friend Code Selector + Toggle for Closed Offers --> <!-- Global Header: Filter Form and Expand All Toggle -->
<div class="flex justify-end mb-4"> <div class="flex justify-between items-center mb-4">
<form method="get" class="flex items-center space-x-4"> <div>
{% include "trades/_friend_code_select.html" with friend_codes=friend_codes selected_friend_code=selected_friend_code field_name="friend_code" label="Filter by Friend Code" %} <form method="get" class="flex items-center space-x-4">
{% include "trades/_friend_code_select.html" with friend_codes=friend_codes selected_friend_code=selected_friend_code field_name="friend_code" label="Filter by Friend Code" %}
<label class="cursor-pointer flex items-center space-x-2"> <label class="cursor-pointer flex items-center space-x-2">
<span class="font-medium">Only Closed</span> <span class="font-medium">Only Closed</span>
<input type="checkbox" name="show_closed" value="true" class="toggle toggle-primary" {% if show_closed %}checked{% endif %}> <input type="checkbox" name="show_closed" value="true" class="toggle toggle-primary" {% if show_closed %}checked{% endif %}>
</label> </label>
<button type="submit" class="btn btn-primary">Apply</button> <button type="submit" class="btn btn-primary">Apply</button>
</form> </form>
</div>
<div>
<!-- Global toggle button using Alpine only -->
<button type="button"
@click="allExpanded = !allExpanded; $dispatch('toggle-all', { expanded: allExpanded })"
class="btn btn-secondary">
<span x-text="allExpanded ? 'Collapse All' : 'Expand All'"></span>
</button>
</div>
</div> </div>
<!-- Section 1: My Trade Offers --> <!-- Section: Waiting for Your Response -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-4">Waiting for Your Response</h2>
{% if trade_acceptances_waiting_paginated.object_list %}
{% include "trades/_trade_offer_list.html" with offers=trade_acceptances_waiting_paginated %}
<div class="flex justify-between items-center mt-4">
{% if trade_acceptances_waiting_paginated.has_previous %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'waiting_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}waiting_page={{ trade_acceptances_waiting_paginated.previous_page_number }}" class="btn btn-sm">Previous</a>
{% else %}
<span></span>
{% endif %}
<span>Page {{ trade_acceptances_waiting_paginated.number }} of {{ trade_acceptances_waiting_paginated.paginator.num_pages }}</span>
{% if trade_acceptances_waiting_paginated.has_next %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'waiting_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}waiting_page={{ trade_acceptances_waiting_paginated.next_page_number }}" class="btn btn-sm">Next</a>
{% else %}
<span></span>
{% endif %}
</div>
{% else %}
<p>None at this time.</p>
{% endif %}
</section>
<!-- Section: Waiting for Trade Partner's Response -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-4">Waiting for Trade Partner's Response</h2>
{% if other_party_trade_acceptances_paginated.object_list %}
{% include "trades/_trade_offer_list.html" with offers=other_party_trade_acceptances_paginated %}
<div class="flex justify-between items-center mt-4">
{% if other_party_trade_acceptances_paginated.has_previous %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'other_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}other_page={{ other_party_trade_acceptances_paginated.previous_page_number }}" class="btn btn-sm">Previous</a>
{% else %}
<span></span>
{% endif %}
<span>Page {{ other_party_trade_acceptances_paginated.number }} of {{ other_party_trade_acceptances_paginated.paginator.num_pages }}</span>
{% if other_party_trade_acceptances_paginated.has_next %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'other_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}other_page={{ other_party_trade_acceptances_paginated.next_page_number }}" class="btn btn-sm">Next</a>
{% else %}
<span></span>
{% endif %}
</div>
{% else %}
<p>None at this time.</p>
{% endif %}
</section>
<!-- Section: My Trade Offers -->
<section class="mb-12"> <section class="mb-12">
<h2 class="text-2xl font-bold mb-4">My Trade Offers</h2> <h2 class="text-2xl font-bold mb-4">My Trade Offers</h2>
{% if my_trade_offers_paginated.object_list %} {% if my_trade_offers_paginated.object_list %}
@ -41,52 +97,6 @@
{% endif %} {% endif %}
</section> </section>
<!-- Section 2: Waiting for Your Response -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-4">Waiting for Your Response</h2>
{% if trade_acceptances_waiting_paginated.object_list %}
{% include "trades/_trade_offer_list.html" with offers=trade_acceptances_waiting_paginated %}
<div class="flex justify-between items-center mt-4">
{% if trade_acceptances_waiting_paginated.has_previous %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'waiting_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}waiting_page={{ trade_acceptances_waiting_paginated.previous_page_number }}" class="btn btn-sm">Previous</a>
{% else %}
<span></span>
{% endif %}
<span>Page {{ trade_acceptances_waiting_paginated.number }} of {{ trade_acceptances_waiting_paginated.paginator.num_pages }}</span>
{% if trade_acceptances_waiting_paginated.has_next %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'waiting_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}waiting_page={{ trade_acceptances_waiting_paginated.next_page_number }}" class="btn btn-sm">Next</a>
{% else %}
<span></span>
{% endif %}
</div>
{% else %}
<p>No pending acceptances at this time.</p>
{% endif %}
</section>
<!-- Section 3: Waiting for Trade Partner's Response -->
<section>
<h2 class="text-2xl font-bold mb-4">Waiting for Trade Partner's Response</h2>
{% if other_party_trade_acceptances_paginated.object_list %}
{% include "trades/_trade_offer_list.html" with offers=other_party_trade_acceptances_paginated %}
<div class="flex justify-between items-center mt-4">
{% if other_party_trade_acceptances_paginated.has_previous %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'other_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}other_page={{ other_party_trade_acceptances_paginated.previous_page_number }}" class="btn btn-sm">Previous</a>
{% else %}
<span></span>
{% endif %}
<span>Page {{ other_party_trade_acceptances_paginated.number }} of {{ other_party_trade_acceptances_paginated.paginator.num_pages }}</span>
{% if other_party_trade_acceptances_paginated.has_next %}
<a href="?{% for key, value in request.GET.items %}{% if key != 'other_page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}other_page={{ other_party_trade_acceptances_paginated.next_page_number }}" class="btn btn-sm">Next</a>
{% else %}
<span></span>
{% endif %}
</div>
{% else %}
<p>No pending acceptances found.</p>
{% endif %}
</section>
<div class="mt-6"> <div class="mt-6">
<a href="{% url 'trade_offer_create' %}" class="btn btn-success">Create New Offer</a> <a href="{% url 'trade_offer_create' %}" class="btn btn-success">Create New Offer</a>
</div> </div>

View file

@ -1,11 +1,30 @@
{% load gravatar card_badge %} {% load gravatar card_badge %}
<!--
Define the Alpine component only once.
-->
<script>
if (!window.tradeOfferCard) {
window.tradeOfferCard = function() {
return {
flipped: false,
badgeExpanded: false,
acceptanceExpanded: false,
// Helper method to set the badgeExpanded state
setBadge(expanded) {
this.badgeExpanded = expanded;
},
};
}
}
</script>
<!-- <!--
The outer div now only establishes Alpine's data context. The outer div now only establishes Alpine's data context.
The dynamic height adjustment (x-init & x-effect with x-ref) has been removed. The dynamic height adjustment (x-init & x-effect with x-ref) has been removed.
--> -->
<div x-data="{ flipped: false, badgeExpanded: false, acceptanceExpanded: false }" <div x-data="tradeOfferCard()" class="transition-all duration-700 trade-offer-card"
class="transition-all duration-700"> @toggle-all.window="setBadge($event.detail.expanded)">
<!-- Flip container providing perspective --> <!-- Flip container providing perspective -->
<div class="flip-container" style="perspective: 1000px;"> <div class="flip-container" style="perspective: 1000px;">