pkmntrade.club/theme/templates/home/home.html

331 lines
No EOL
12 KiB
HTML

{% 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">
<span aria-hidden="true">
<span class="inline-block relative left-2 text-4xl">Welcome to</span>
<sup class="inline-block relative left-4 text-4xl">P</sup>
<sub class="inline-block relative text-4xl">K</sub>
<sup class="inline-block relative -left-2 text-4xl">M</sup>
<sub class="inline-block relative -left-4 text-4xl">N</sub>
<span class="inline-block relative -left-2 text-4xl">Trade Club</span>
</span>
<span aria-hidden="false" class="sr-only">Welcome to Pokemon Trade Club</span>
</h1>
<!-- Search Form Section -->
<section id="trade-search" class="mb-8">
<form method="post" action="." class="space-y-4">
{% csrf_token %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
{% card_multiselect "have_cards" "Have:" "Select zero or more cards..." available_cards have_cards %}
</div>
<div>
{% card_multiselect "want_cards" "Want:" "Select zero or more cards..." available_cards want_cards %}
</div>
</div>
{% if user.is_authenticated %}
<div class="flex flex-col md:flex-row gap-4">
<button type="submit" class="btn btn-primary flex-1">Find a Trade Offer</button>
<a href="{% url 'trade_offer_create' %}" id="createTradeOfferBtn" class="btn btn-secondary flex-1 text-center">Create Trade Offer</a>
</div>
{% else %}
<div>
<button type="submit" class="btn btn-primary w-full">Find a Trade Offer</button>
</div>
{% endif %}
</form>
</section>
<!-- Search Results Section -->
<section id="search-results" class="mb-8">
{% include "home/_search_results.html" %}
</section>
<!-- Market Stats Section -->
<section aria-labelledby="stats-heading" class="mb-8">
<h2 id="stats-heading" class="text-2xl font-semibold mb-4">Market Stats</h2>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
<!-- Most Offered Cards -->
<div>
<div class="card bg-base-100 shadow">
<div class="card-header text-base-content p-4">
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Offered Cards</h5>
</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" %}
{% endcache %}
</div>
</div>
</div>
<!-- Most Wanted Cards -->
<div>
<div class="card bg-base-100 shadow">
<div class="card-header text-base-content p-4">
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Most Wanted Cards</h5>
</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" %}
{% endcache %}
</div>
</div>
</div>
<!-- Least Offered Cards -->
<div>
<div class="card bg-base-100 shadow">
<div class="card-header text-base-content p-4">
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Least Offered Cards</h5>
</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" show_zero=True %}
{% endcache %}
</div>
</div>
</div>
</div>
</section>
<!-- Featured Offers and Recent Offers Section -->
<section class="mb-8">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<!-- Featured Offers -->
<div>
{% cache 86400 featured_offers %}
<div class="card bg-base-100 shadow">
<div class="card-header text-base-content p-4">
<h5 class="text-xl text-center font-semibold whitespace-nowrap truncate mb-0">Featured Offers</h5>
</div>
<div class="card-body p-4">
<!-- New pure-CSS tabs for Featured Offers -->
<div class="featured-offers-tabs">
<!-- Radio inputs for all tabs -->
<input type="radio" name="featured_offers_tabs" id="tab-all" class="hidden" checked>
{% for rarity, offers in featured_offers.items %}
{% if rarity != "All" %}
<input type="radio" name="featured_offers_tabs" id="tab-{{ forloop.counter }}" class="hidden">
{% endif %}
{% endfor %}
<!-- Tab navigation: all tab labels appear together -->
<div class="tabs tabs-box grid grid-cols-3 gap-2">
<label for="tab-all" class="tab text-xs md:text-base">All</label>
{% for rarity, offers in featured_offers.items %}
{% if rarity != "All" %}
<label for="tab-{{ forloop.counter }}" class="tab text-xs md:text-base">{{ rarity }}</label>
{% endif %}
{% endfor %}
</div>
<!-- All tab content panels are placed in one content container -->
<div class="tab-contents">
<!-- Panel for All offers -->
<div class="tab-content" id="content-tab-all">
{% if featured_offers.All %}
<div class="flex flex-col items-center gap-3 w-auto mx-auto">
{% for offer in featured_offers.All %}
{% render_trade_offer offer %}
{% endfor %}
</div>
{% else %}
<p class="text-center">No featured offers available.</p>
{% endif %}
</div>
<!-- Panels for each additional rarity -->
{% for rarity, offers in featured_offers.items %}
{% if rarity != "All" %}
<div class="tab-content" id="content-tab-{{ forloop.counter }}">
{% if offers %}
<div class="flex flex-col items-center gap-3 w-auto mx-auto">
{% for offer in offers %}
{% render_trade_offer offer %}
{% endfor %}
</div>
{% else %}
<p class="text-center">No featured offers for {{ rarity }}.</p>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endcache %}
</div>
<!-- Recent Offers -->
<div>
{% cache 60 recent_offers %}
<div class="card bg-base-100 shadow">
<div class="card-header text-center text-base-content p-4">
<h5 class="text-xl font-semibold whitespace-nowrap truncate mb-0">Recent Offers</h5>
</div>
<div class="card-body my-4 p-4">
<div class="flex flex-col items-center gap-3">
{% for offer in recent_offers %}
{% render_trade_offer offer %}
{% empty %}
<p>No recent offers available.</p>
{% endfor %}
</div>
</div>
</div>
{% endcache %}
</div>
</div>
</section>
{% endblock content %}
{% block css %}
<style>
/* Hide the hidden radio inputs */
.featured-offers-tabs input[type="radio"] {
display: none;
}
/* Styles for the tabs navigation */
.tabs.tabs-box {
margin-bottom: 1rem;
width: 100%;
}
.tabs.tabs-box .tab {
flex: 1; /* Each tab will equally expand */
text-align: center;
cursor: pointer;
padding: 0.5rem 1rem;
border: 1px solid transparent;
transition: border-color 0.3s;
}
.tabs.tabs-box .tab:hover {
border-color: currentColor;
}
/* Active tab styling based on the radio input state */
#tab-all:checked ~ .tabs.tabs-box label[for="tab-all"] {
border-color: #2563eb; /* Example blue highlight */
}
{% for rarity, offers in featured_offers.items %}
{% if rarity != "All" %}
#tab-{{ forloop.counter }}:checked ~ .tabs.tabs-box label[for="tab-{{ forloop.counter }}"] {
border-color: #2563eb;
font-weight: bold;
}
{% endif %}
{% endfor %}
/* Hide all content panels by default */
.featured-offers-tabs .tab-contents > .tab-content {
display: none;
transition: opacity 0.3s ease-in-out;
}
/* Display the panel corresponding to the checked radio input */
#tab-all:checked ~ .tab-contents #content-tab-all {
display: block;
}
{% for rarity, offers in featured_offers.items %}
{% if rarity != "All" %}
#tab-{{ forloop.counter }}:checked ~ .tab-contents #content-tab-{{ forloop.counter }} {
display: block;
}
{% endif %}
{% endfor %}
</style>
{% endblock %}
{% block javascript %}
<script defer>
document.addEventListener('DOMContentLoaded', function() {
// AJAX trade search form submission with vanilla JavaScript
const tradeSearchForm = document.querySelector('#trade-search form');
if (tradeSearchForm) {
tradeSearchForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(tradeSearchForm);
fetch(tradeSearchForm.action, {
method: tradeSearchForm.method,
headers: {
"X-Requested-With": "XMLHttpRequest"
},
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'));
}
});
// Updated: JS to carry over selections (including quantities) to the Create Trade Offer page.
const createBtn = document.getElementById('createTradeOfferBtn');
if (createBtn) {
createBtn.addEventListener('click', function(e) {
e.preventDefault();
// Use the standardized field names for both "have_cards" and "want_cards"
const haveSelect = document.querySelector('select[name="have_cards"]');
const wantSelect = document.querySelector('select[name="want_cards"]');
const url = new URL(createBtn.href, window.location.origin);
if (haveSelect) {
// For each selected option, include the quantity from data-quantity (defaulting to "1")
const selectedHave = Array.from(haveSelect.selectedOptions).map(opt => {
const cardId = opt.value;
const quantity = opt.getAttribute('data-quantity') || '1';
return cardId + ':' + quantity;
});
selectedHave.forEach(val => url.searchParams.append('have_cards', val));
}
if (wantSelect) {
const selectedWant = Array.from(wantSelect.selectedOptions).map(opt => {
const cardId = opt.value;
const quantity = opt.getAttribute('data-quantity') || '1';
return cardId + ':' + quantity;
});
selectedWant.forEach(val => url.searchParams.append('want_cards', val));
}
window.location.href = url.href;
});
}
});
</script>
{% endblock %}