finished conversion to tailwind

This commit is contained in:
badblocks 2025-03-11 23:45:27 -07:00
parent 6e2843c60e
commit d62956d465
50 changed files with 2490 additions and 1273 deletions

View file

@ -0,0 +1,10 @@
{% load trade_offer_tags %}
{% if offered_cards or wanted_cards %}
<hr class="my-8 border-t border-base-300">
<h2 class="text-2xl font-bold mb-4">Results</h2>
{% if search_results %}
{% include "trades/_trade_offer_list.html" with offers=search_results %}
{% else %}
<div class="alert alert-info mt-4">No trade offers found.</div>
{% endif %}
{% endif %}

View file

@ -1,18 +1,18 @@
{% load trade_offer_tags %}
{% comment %}
This snippet renders a grid of trade offer cards along with pagination controls,
using the trade_offer templatetag (i.e. {% render_trade_offer offer %}).
It expects a context variable:
- offers: an iterable or a paginated page of TradeOffer objects.
This snippet renders a grid of trade offer cards (or acceptance cards) along with pagination controls.
For a TradeOffer, we use {% render_trade_offer %}; for a TradeAcceptance, {% render_trade_acceptance %}.
{% endcomment %}
<div class="flex flex-row gap-4 flex-wrap justify-center items-start">
{% for offer in offers %}
<div class="flex flex-none">
<a href="{% url 'trade_offer_detail' pk=offer.pk %}" class="no-underline">
{% if offer.accepted_by %}
{# Render a trade acceptance using our new tag #}
{% render_trade_acceptance offer %}
{% else %}
{% render_trade_offer offer %}
</a>
{% endif %}
</div>
{% empty %}
<div>No trade offers available.</div>

View file

@ -1,16 +1,70 @@
{% extends 'base.html' %}
{% load trade_offer_tags %}
{% block title %}Update Trade Acceptance{% endblock title %}
{% block content %}
<div class="container mx-auto max-w-xl mt-6">
<h2 class="text-2xl font-bold">Update Trade Acceptance</h2>
<form method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">Update</button>
</form>
{% if form.errors %}
<div class="text-center py-8">
<ul class="steps">
{% if object.is_thanked %}
<li class="step step-primary">Accepted</li>
<li class="step step-primary">Card Sent</li>
<li class="step step-primary">Card Received</li>
<li class="step step-primary">Thanks Sent</li>
<li class="step step-primary">Thanks Received</li>
<li class="step step-primary">Completed</li>
{% elif object.is_rejected %}
<li class="step step-primary">Accepted</li>
<li class="step step-error">
<span class="step-icon">X</span>{{ object.get_state_display }}
</li>
{% else %}
<li class="step step-primary">Accepted</li>
<li class="step {% if object.get_step_number >= 2 %}step-primary{% endif %}">Card Sent</li>
<li class="step {% if object.get_step_number >= 3 %}step-primary{% endif %}">Card Received</li>
{% if object.state == 'THANKED_BY_INITIATOR' %}
<li class="step step-primary">Thanked by Initiator</li>
<li class="step">Thanked by Acceptor</li>
<li class="step">Completed</li>
{% elif object.state == 'THANKED_BY_ACCEPTOR' %}
<li class="step step-primary">Thanked by Acceptor</li>
<li class="step">Thanked by Initiator</li>
<li class="step">Completed</li>
{% elif object.state == 'THANKED_BY_BOTH' %}
<li class="step step-primary">Thanked by Initiator</li>
<li class="step step-primary">Thanked by Acceptor</li>
<li class="step step-primary">Completed</li>
{% else %}
<li class="step">Thanked by Initiator</li>
<li class="step">Thanked by Acceptor</li>
<li class="step">Completed</li>
{% endif %}
{% endif %}
</ul>
</div>
<div class="py-8">
{% render_trade_acceptance object %}
</div>
<div class="mt-6">
<h3 class="text-xl font-semibold mb-4">Select an action:</h3>
{% if form.fields.state.choices %}
{% for state_value, state_label in form.fields.state.choices %}
<form method="post" class="mb-2">
{% csrf_token %}
<input type="hidden" name="state" value="{{ state_value }}">
<button type="submit" class="btn btn-primary w-full">{{ state_label }}</button>
</form>
{% endfor %}
{% else %}
<p>No available actions.</p>
{% endif %}
</div>
{% if form and form.errors %}
<div class="alert alert-error mt-4">
<strong>Please correct the errors below:</strong>
<ul>
@ -25,8 +79,11 @@
</ul>
</div>
{% endif %}
<div class="mt-6">
<a href="{% url 'trade_offer_detail' pk=object.trade_offer.pk %}" class="btn btn-secondary">Back to Offer Details</a>
<a href="{% url 'trade_offer_detail' pk=object.trade_offer.pk %}" class="btn btn-secondary">
Back to Offer Details
</a>
</div>
</div>
{% endblock content %}

View file

@ -9,10 +9,10 @@
<form method="post" novalidate class="space-y-4">
{% csrf_token %}
{# Use the DRY friend code selector fragment #}
{# Use our DRY friend code selector #}
{% include "trades/_friend_code_select.html" with friend_codes=friend_codes selected_friend_code=selected_friend_code field_name=form.initiated_by.html_name label="Initiated by" %}
<!-- Grid layout for Card Selectors: "Have" and "Want" -->
<!-- Card Selectors: "Have" and "Want" -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="form-control">
{% card_multiselect "have_cards" "Have:" "Select one or more cards..." available_cards form.initial.have_cards %}
@ -67,8 +67,6 @@ document.addEventListener('DOMContentLoaded', () => {
};
},
});
// Style the Choices control as needed
choicesInstance.containerOuter.element.classList.add('bg-secondary', 'select', 'select-bordered', 'w-full');
choicesInstance.containerInner.element.classList.add('bg-secondary', 'text-white');
}

View file

@ -14,6 +14,10 @@
{% endif %}
</h2>
<p>
<strong>Status:</strong> {% if object.is_active %}Open{% else %}Closed{% endif %}
</p>
{% if messages %}
{% for message in messages %}
<div class="alert {{ message.tags }}">{{ message }}</div>

View file

@ -1,47 +1,14 @@
{% extends 'base.html' %}
{% load trade_offer_tags %}
{% block title %}Trade Offer Detail{% endblock title %}
{% block content %}
<div class="container mx-auto max-w-2xl mt-6">
<h2 class="text-2xl font-bold">Trade Offer Details</h2>
<div class="card bg-base-100 shadow-lg p-4">
<p>
<strong>Hash:</strong> {{ object.hash }}<br>
<strong>Initiated By:</strong> {{ object.initiated_by }}<br>
<strong>Cards You Have (Offer):</strong>
{% for through in object.trade_offer_have_cards.all %}
{{ through.card.name }} x{{ through.quantity }}{% if not forloop.last %}, {% endif %}
{% endfor %}<br>
<strong>Cards You Want:</strong>
{% for through in object.trade_offer_want_cards.all %}
{{ through.card.name }} x{{ through.quantity }}{% if not forloop.last %}, {% endif %}
{% endfor %}<br>
<strong>Created At:</strong> {{ object.created_at|date:"M d, Y H:i" }}<br>
<strong>Updated At:</strong> {{ object.updated_at|date:"M d, Y H:i" }}<br>
<strong>Status:</strong> {% if object.is_closed %}Closed{% else %}Open{% endif %}
</p>
<div>
{% render_trade_offer object %}
</div>
<h3 class="text-xl font-semibold mt-6">Acceptances</h3>
{% if acceptances %}
<ul class="space-y-2">
{% for acceptance in acceptances %}
<li class="card p-4">
<p>
<strong>Accepted By:</strong> {{ acceptance.accepted_by }}<br>
<strong>Requested Card:</strong> {{ acceptance.requested_card.name }}<br>
<strong>Offered Card:</strong> {{ acceptance.offered_card.name }}<br>
<strong>State:</strong> {{ acceptance.get_state_display }}
</p>
<a href="{% url 'trade_acceptance_update' acceptance.pk %}" class="btn btn-sm">Update</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>No acceptances yet.</p>
{% endif %}
{% if acceptance_form %}
<h3 class="text-xl font-semibold mt-6">Accept This Offer</h3>
<div class="card p-4">
@ -54,10 +21,9 @@
{% endif %}
<div class="mt-6">
<!-- Show delete/close button for the initiator -->
{% if is_initiator %}
<a href="{{ delete_close_url }}" class="btn btn-danger">Delete/Close Trade Offer</a>
{% endif %}
{% if is_initiator %}
<a href="{{ delete_close_url }}" class="btn btn-danger">Delete/Close Trade Offer</a>
{% endif %}
<a href="{% url 'trade_offer_list' %}" class="btn btn-secondary">Back to Trade Offers</a>
</div>
</div>

View file

@ -5,14 +5,14 @@
{% block content %}
<div class="container mx-auto max-w-4xl mt-6">
<!-- Filter Form: Friend Code Selector + Toggle for Completed view -->
<!-- Filter Form: Friend Code Selector + Toggle for Closed Offers -->
<div class="flex justify-end mb-4">
<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">
<span class="font-medium">Only Completed</span>
<input type="checkbox" name="show_completed" value="true" class="toggle toggle-primary" {% if show_completed %}checked{% endif %}>
<span class="font-medium">Only Closed</span>
<input type="checkbox" name="show_closed" value="true" class="toggle toggle-primary" {% if show_closed %}checked{% endif %}>
</label>
<button type="submit" class="btn btn-primary">Apply</button>
</form>
@ -41,9 +41,9 @@
{% endif %}
</section>
<!-- Section 2: Trade Acceptances Waiting For Your Response -->
<!-- Section 2: Waiting for Your Response -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-4">Trade Acceptances Waiting For Your Response</h2>
<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">
@ -64,26 +64,26 @@
{% endif %}
</section>
<!-- Section 3: Other Trade Acceptances -->
<!-- Section 3: Waiting for Trade Partner's Response -->
<section>
<h2 class="text-2xl font-bold mb-4">Other Trade Acceptances</h2>
{% if other_trade_acceptances_paginated.object_list %}
{% include "trades/_trade_offer_list.html" with offers=other_trade_acceptances_paginated %}
<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_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_trade_acceptances_paginated.previous_page_number }}" class="btn btn-sm">Previous</a>
{% 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_trade_acceptances_paginated.number }} of {{ other_trade_acceptances_paginated.paginator.num_pages }}</span>
{% if other_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_trade_acceptances_paginated.next_page_number }}" class="btn btn-sm">Next</a>
<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 other acceptances found.</p>
<p>No pending acceptances found.</p>
{% endif %}
</section>

View file

@ -0,0 +1,86 @@
{% extends 'base.html' %}
{% load static trade_offer_tags card_badge cache card_multiselect %}
{% block content %}
<h1 class="text-center text-4xl font-bold mb-8 pt-4">Trade Offer Search</h1>
<!-- Search Form Section -->
<section id="trade-search" class="mb-8">
<form method="post" action="{% url 'trade_offer_search' %}" class="space-y-4">
{% csrf_token %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
{% card_multiselect "offered_cards" "Have:" "Select zero or more cards..." available_cards offered_cards %}
</div>
<div>
{% card_multiselect "wanted_cards" "Want:" "Select zero or more cards..." available_cards wanted_cards %}
</div>
</div>
<div class="flex flex-col md:flex-row gap-4">
<button type="submit" class="btn btn-primary flex-1">Find a Trade Offer</button>
</div>
</form>
</section>
<!-- Search Results Section -->
<section id="search-results" class="mb-8">
{% include "trades/_search_results.html" %}
</section>
{% endblock content %}
{% block javascript %}
<script defer>
document.addEventListener('DOMContentLoaded', function() {
const tradeSearchForm = document.querySelector('#trade-search form');
if (tradeSearchForm) {
tradeSearchForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(tradeSearchForm);
document.querySelector("#search-results").innerHTML = "<div class='text-center text-2xl font-bold'>Searching...</div>";
fetch(tradeSearchForm.action, {
method: "POST",
headers: {
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": document.querySelector('[name=csrfmiddlewaretoken]').value
},
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.text();
})
.then(data => {
document.querySelector("#search-results").innerHTML = data;
})
.catch(error => {
alert("There was an error processing your search.");
console.error("Error:", error);
});
});
// AJAX pagination click handling
document.addEventListener('click', function(e) {
const target = e.target.closest('.ajax-page-link');
if (target) {
e.preventDefault();
const page = target.getAttribute('data-page');
let pageInput = document.getElementById('page');
if (pageInput) {
pageInput.value = page;
} else {
pageInput = document.createElement('input');
pageInput.type = 'hidden';
pageInput.id = 'page';
pageInput.name = 'page';
pageInput.value = page;
tradeSearchForm.appendChild(pageInput);
}
tradeSearchForm.dispatchEvent(new Event('submit'));
}
});
}
});
</script>
{% endblock %}

View file

@ -28,7 +28,7 @@
{% for card in object.want_cards.all %}
{{ card.name }}{% if not forloop.last %}, {% endif %}
{% endfor %}<br>
<strong>Current State:</strong> {{ object.get_state_display }}
<strong>Status:</strong> {% if object.is_active %}Open{% else %}Closed{% endif %}
</p>
</div>
</div>