176 lines
9.8 KiB
HTML
176 lines
9.8 KiB
HTML
{% extends 'base/layout.html' %}
|
|
|
|
{% block title %}{{ card.name }} - TCGKof{% endblock %}
|
|
|
|
{% block meta_description %}Buy {{ card.name }} ({{ card.set.name }}) on TCGKof. {{ listings|length }} listings available starting from ${{ listings.first.price|default:'0.00' }}.{% endblock %}
|
|
|
|
{% block meta_keywords %}{{ card.name }}, {{ card.set.name }}, {{ card.rarity }}, {{ card.set.game.name }}, buy {{ card.name }}, sell {{ card.name }}{% endblock %}
|
|
|
|
{% block og_title %}{{ card.name }} - {{ card.set.name }} | TCGKof{% endblock %}
|
|
{% block og_description %}Buy {{ card.name }} from {{ card.set.name }} set. best prices on TCGKof.{% endblock %}
|
|
{% block og_image %}{{ card.image_url|default:'' }}{% endblock %}
|
|
{% block og_type %}product{% endblock %}
|
|
|
|
{% block twitter_title %}{{ card.name }} - {{ card.set.name }}{% endblock %}
|
|
{% block twitter_description %}Find the best deals for {{ card.name }} on TCGKof.{% endblock %}
|
|
{% block twitter_image %}{{ card.image_url|default:'' }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org/",
|
|
"@type": "Product",
|
|
"name": "{{ card.name }}",
|
|
"image": "{{ card.image_url }}",
|
|
"description": "Buy {{ card.name }} from the {{ card.set.name }} set.",
|
|
"sku": "{{ card.uuid }}",
|
|
"brand": {
|
|
"@type": "Brand",
|
|
"name": "{{ card.set.game.name }}"
|
|
},
|
|
"offers": {
|
|
"@type": "AggregateOffer",
|
|
"url": "{{ request.build_absolute_uri }}",
|
|
"priceCurrency": "USD",
|
|
"lowPrice": "{{ listings.first.price|default:'0.00' }}",
|
|
"offerCount": "{{ listings|length }}",
|
|
"availability": "https://schema.org/InStock"
|
|
}
|
|
}
|
|
</script>
|
|
<div style="display: grid; grid-template-columns: 1fr 2fr; gap: 3rem;">
|
|
<!-- Image Column -->
|
|
<div>
|
|
<div
|
|
style="background: var(--card-bg); border-radius: 0.75rem; overflow: hidden; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5);">
|
|
{% if card.image_url %}
|
|
<img src="{{ card.image_url }}" alt="{{ card.name }}" style="width: 100%; display: block;">
|
|
{% else %}
|
|
style="aspect-ratio: 2.5/3.5; display: flex; align-items: center; justify-content: center; color: var(--muted-text-color); background: var(--border-color);">
|
|
No Image</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- External Links -->
|
|
<div style="margin-top: 1.5rem; display: grid; gap: 0.5rem;">
|
|
{% if card.tcgplayer_id %}
|
|
<a href="https://www.tcgplayer.com/product/{{ card.tcgplayer_id }}" target="_blank"
|
|
style="display: block; text-align: center; padding: 0.75rem; background: var(--card-bg); color: var(--text-color); border-radius: 0.375rem; text-decoration: none; font-size: 0.875rem;">
|
|
View on TCGPlayer
|
|
</a>
|
|
{% endif %}
|
|
<a href="https://www.ebay.com/sch/i.html?_nkw={{ card.name|urlencode }}+{{ card.set.name|urlencode }}"
|
|
target="_blank"
|
|
style="display: block; text-align: center; padding: 0.75rem; background: var(--card-bg); color: var(--text-color); border-radius: 0.375rem; text-decoration: none; font-size: 0.875rem;">
|
|
Search on eBay
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Info Column -->
|
|
<div>
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4 style="margin: 0; color: var(--primary-color);">{{ card.set.game.name }} • {{ card.set.name }}</h4>
|
|
<h1 style="margin: 0.5rem 0 0; font-size: 2.5rem;">{{ card.name }}</h1>
|
|
<div style="margin-top: 1rem; display: flex; gap: 1rem; color: var(--muted-text-color);">
|
|
<span>Rarity: <strong style="color: var(--text-color);">{{ card.rarity }}</strong></span>
|
|
<span>Collector #: <strong style="color: var(--text-color);">{{ card.collector_number }}</strong></span>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 style="border-bottom: 1px solid var(--border-color); padding-bottom: 0.5rem; margin-bottom: 1rem;">Available
|
|
Listings</h3>
|
|
|
|
<div style="margin-bottom: 1rem;">
|
|
<label style="font-size: 0.875rem; color: var(--muted-text-color);">Filter Condition:</label>
|
|
<div style="display: flex; gap: 0.5rem; margin-top: 0.25rem;">
|
|
<button onclick="filterCondition('ALL')" class="btn" style="padding: 0.25rem 0.75rem; font-size: 0.75rem; background: var(--card-bg); border: 1px solid var(--border-color);">All</button>
|
|
<button onclick="filterCondition('NM')" class="btn" style="padding: 0.25rem 0.75rem; font-size: 0.75rem; background: var(--card-bg); border: 1px solid var(--border-color);">NM</button>
|
|
<button onclick="filterCondition('LP')" class="btn" style="padding: 0.25rem 0.75rem; font-size: 0.75rem; background: var(--card-bg); border: 1px solid var(--border-color);">LP</button>
|
|
<button onclick="filterCondition('MP')" class="btn" style="padding: 0.25rem 0.75rem; font-size: 0.75rem; background: var(--card-bg); border: 1px solid var(--border-color);">MP</button>
|
|
<button onclick="filterCondition('HP')" class="btn" style="padding: 0.25rem 0.75rem; font-size: 0.75rem; background: var(--card-bg); border: 1px solid var(--border-color);">HP</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="listings-container" style="display: flex; flex-direction: column; gap: 1rem;">
|
|
{% for listing in listings %}
|
|
<div class="listing-item" data-condition="{{ listing.condition }}"
|
|
style="display: flex; justify-content: space-between; align-items: center; background: var(--card-bg); padding: 1rem; border-radius: 0.5rem; border: 1px solid var(--border-color);">
|
|
<div style="display: flex; gap: 1rem; align-items: center;">
|
|
{% if listing.image %}
|
|
<img src="{{ listing.image.url }}" alt="Listing Image" style="width: 50px; height: 70px; object-fit: cover; border-radius: 4px; border: 1px solid #444;">
|
|
{% endif %}
|
|
<span style="font-weight: 700; font-size: 1.25rem;">
|
|
{{ listing.get_condition_display }}</span>
|
|
<div>
|
|
<div style="font-size: 0.875rem; color: var(--muted-text-color);">Condition</div>
|
|
{% if listing.is_foil %}
|
|
<span
|
|
style="background: linear-gradient(45deg, #f59e0b, #d97706); -webkit-background-clip: text; background-clip: text; color: transparent; font-weight: 700; font-size: 0.75rem; text-transform: uppercase;">Foil</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; align-items: center; gap: 2rem;">
|
|
<div style="min-width: 150px;">
|
|
<div style="font-size: 0.875rem; color: var(--muted-text-color);">Seller</div>
|
|
<div style="font-weight: 500;">
|
|
{% if listing.seller %}
|
|
<a href="{% url 'store:seller_profile' listing.seller.slug %}" style="color: var(--info-color); text-decoration: none;">{{ listing.seller.store_name }}</a>
|
|
{% else %}
|
|
<span style="color: var(--muted-text-color);">TCGKof Direct</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div style="text-align: right;">
|
|
<div style="font-weight: 700; font-size: 1.5rem;">${{ listing.price }}</div>
|
|
<div style="font-size: 0.75rem; color: var(--muted-text-color);">{{ listing.quantity }} available</div>
|
|
</div>
|
|
|
|
{% if user.is_authenticated %}
|
|
<form action="{% url 'store:add_to_cart' listing.uuid %}" method="post">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn">Add to Cart</button>
|
|
</form>
|
|
{% else %}
|
|
<a href="{% url 'login' %}?next={{ request.path }}" class="btn" style="background: var(--border-color);">Login
|
|
to Buy</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div
|
|
style="text-align: center; padding: 2rem; background: var(--card-bg); border-radius: 0.5rem; border: 1px dashed var(--border-color);">
|
|
<p style="margin: 0; color: var(--muted-text-color);">No listings currently available for this card.</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<!-- Proxy Service -->
|
|
{% if FEATURE_PLAYTEST_PROXY %}
|
|
<div style="margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--border-color);">
|
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
<div>
|
|
<h3 style="margin: 0 0 0.5rem;">Playtest Proxy Service</h3>
|
|
<p style="margin: 0; color: var(--muted-text-color); font-size: 0.875rem;">Download a high-res proxy for playtesting. Credit offered if you buy later.</p>
|
|
</div>
|
|
<button onclick="alert('Proxy PDF generated! (Mockup)')" class="btn" style="background: transparent; border: 1px solid var(--border-color);">Download Proxy</button>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<script>
|
|
function filterCondition(cond) {
|
|
const items = document.querySelectorAll('.listing-item');
|
|
items.forEach(item => {
|
|
if (cond === 'ALL' || item.dataset.condition === cond) {
|
|
item.style.display = 'flex';
|
|
} else {
|
|
item.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
</div>
|
|
</div>
|
|
{% endblock %} |