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,8 +4,9 @@
{% block title %}All Trade Offers{% endblock title %}
{% block content %}
<div class="container mx-auto max-w-4xl mt-6">
<div class="flex justify-end mb-4">
<div class="container mx-auto max-w-4xl mt-6" x-data="{ allExpanded: false }">
<div class="flex justify-between items-center mb-4">
<div>
<form method="get" class="flex items-center space-x-4">
<label class="cursor-pointer flex items-center space-x-2">
<span class="font-medium">Only Closed</span>
@ -14,6 +15,15 @@
<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>
<!-- Trade Offers -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-4">All Trade Offers</h2>

View file

@ -4,9 +4,10 @@
{% block title %}Trade Offer & Acceptance List{% endblock title %}
{% block content %}
<div class="container mx-auto max-w-4xl mt-6">
<!-- Filter Form: Friend Code Selector + Toggle for Closed Offers -->
<div class="flex justify-end mb-4">
<div class="container mx-auto max-w-4xl mt-6" x-data="{ allExpanded: false }">
<!-- Global Header: Filter Form and Expand All Toggle -->
<div class="flex justify-between items-center mb-4">
<div>
<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" %}
@ -17,8 +18,63 @@
<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>
<!-- 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">
<h2 class="text-2xl font-bold mb-4">My Trade Offers</h2>
{% if my_trade_offers_paginated.object_list %}
@ -41,52 +97,6 @@
{% endif %}
</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">
<a href="{% url 'trade_offer_create' %}" class="btn btn-success">Create New Offer</a>
</div>

View file

@ -1,11 +1,30 @@
{% 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 dynamic height adjustment (x-init & x-effect with x-ref) has been removed.
-->
<div x-data="{ flipped: false, badgeExpanded: false, acceptanceExpanded: false }"
class="transition-all duration-700">
<div x-data="tradeOfferCard()" class="transition-all duration-700 trade-offer-card"
@toggle-all.window="setBadge($event.detail.expanded)">
<!-- Flip container providing perspective -->
<div class="flip-container" style="perspective: 1000px;">