inital checkin

This commit is contained in:
2026-01-20 05:22:38 -06:00
parent 9784e14c77
commit c43603bfb5
75 changed files with 4327 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
{% extends 'base/layout.html' %}
{% block content %}
<div style="display: grid; grid-template-columns: 350px 1fr; gap: 2rem; height: calc(100vh - 100px);">
<!-- Card Search Sidebar -->
<div
style="background: var(--card-bg); border-right: 1px solid var(--border-color); display: flex; flex-direction: column; overflow: hidden; border-radius: 0.5rem; border: 1px solid var(--border-color);">
<div style="padding: 1rem; border-bottom: 1px solid var(--border-color);">
<h3 style="margin: 0 0 1rem;">Add Cards</h3>
<form method="get">
<input type="text" name="q" value="{{ query|default:'' }}"
placeholder="Search {{ deck.game.name }} cards..."
style="width: 100%; padding: 0.5rem; border-radius: 0.25rem; background: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color);">
</form>
</div>
<div style="overflow-y: auto; flex: 1; padding: 1rem;">
{% if search_results %}
{% for card in search_results %}
<div style="display: flex; gap: 0.5rem; margin-bottom: 1rem; align-items: center;">
{% if card.image_url %}
<img src="{{ card.image_url }}"
style="width: 40px; height: 56px; object-fit: cover; border-radius: 2px;">
{% endif %}
<div style="flex: 1;">
<div style="font-size: 0.875rem; font-weight: 500;">{{ card.name }}</div>
<div style="font-size: 0.75rem; color: #94a3b8;">{{ card.set.code }}</div>
</div>
<form method="post">
{% csrf_token %}
<input type="hidden" name="card_id" value="{{ card.id }}">
<button type="submit" class="btn" style="padding: 0.25rem 0.5rem; font-size: 1.25rem;">+</button>
</form>
</div>
{% endfor %}
{% elif query %}
<p style="text-align: center; color: #94a3b8;">No cards found.</p>
{% else %}
<p style="text-align: center; color: #94a3b8; margin-top: 2rem;">Search to add cards.</p>
{% endif %}
</div>
</div>
<!-- Deck View -->
<div style="display: flex; flex-direction: column; overflow: hidden;">
<div style="margin-bottom: 1rem; display: flex; justify-content: space-between; align-items: center;">
<div>
<h1 style="margin: 0;">{{ deck.name }}</h1>
<p style="margin: 0.25rem 0 0; color: #94a3b8;">{{ deck.game.name }} &bull; {{ deck.cards.count }} cards
</p>
</div>
<button class="btn">Save & Close</button>
</div>
<div
style="flex: 1; overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; align-content: start;">
{% for item in deck.cards.all %}
<div style="position: relative; group">
<div
style="aspect-ratio: 2.5/3.5; background: #000; border-radius: 4px; overflow: hidden; position: relative;">
{% if item.card.image_url %}
<img src="{{ item.card.image_url }}" style="width: 100%; height: 100%; object-fit: cover;">
{% endif %}
<div
style="position: absolute; bottom: 0; right: 0; background: rgba(0,0,0,0.8); color: white; padding: 0.25rem 0.5rem; border-top-left-radius: 4px; font-weight: 700;">
x{{ item.quantity }}
</div>
</div>
<div style="text-align: center; margin-top: 0.25rem;">
<a href="{% url 'decks:remove_card' deck.id item.card.id %}"
style="color: #ef4444; font-size: 0.75rem; text-decoration: none;">Remove</a>
</div>
</div>
{% empty %}
<div
style="grid-column: 1/-1; text-align: center; padding: 4rem; border: 2px dashed var(--border-color); border-radius: 0.5rem; color: #94a3b8;">
<p>Your deck is empty. Add cards from the left sidebar.</p>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,28 @@
{% extends 'base/layout.html' %}
{% block content %}
<div
style="max-width: 400px; margin: 4rem auto; background: var(--card-bg); padding: 2rem; border-radius: 0.5rem; border: 1px solid var(--border-color);">
<h2 style="margin-top: 0;">Create New Deck</h2>
<form method="post">
{% csrf_token %}
<div style="margin-bottom: 1rem;">
<label style="display: block; margin-bottom: 0.5rem;">Deck Name</label>
<input type="text" name="name" required
style="width: 100%; padding: 0.5rem; border-radius: 0.25rem; background: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color);">
</div>
<div style="margin-bottom: 1.5rem;">
<label style="display: block; margin-bottom: 0.5rem;">Game Format</label>
<select name="game" required
style="width: 100%; padding: 0.5rem; border-radius: 0.25rem; background: var(--bg-color); color: var(--text-color); border: 1px solid var(--border-color);">
{% for game in games %}
<option value="{{ game.id }}">{{ game.name }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn" style="width: 100%;">Create Deck</button>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,49 @@
{% extends 'base.html' %}
{% block content %}
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-sm">
<div class="card-header bg-white">
<h4 class="mb-0">Import Deck</h4>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="name" class="form-label">Deck Name</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="mb-3">
<label for="game" class="form-label">Game</label>
<select class="form-select" id="game" name="game" required>
{% for game in games %}
<option value="{{ game.id }}">{{ game.name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="deckList" class="form-label">Deck List</label>
<div class="form-text mb-2">
Supported formats: Arena, MTGO, Moxfield, Plain Text.
<br>Example: <code>4 Lightning Bolt</code> or <code>1 Sheoldred, the Apocalypse (DMU) 107</code>
</div>
<textarea class="form-control" id="deckList" name="deck_list" rows="15" required
placeholder="1 Card Name&#10;1 Another Card&#10;...&#10;SIDEBOARD:&#10;1 Sideboard Card"></textarea>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">Import Deck</button>
<a href="{% url 'decks:deck_list' %}" class="btn btn-outline-secondary">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,47 @@
{% extends 'base/layout.html' %}
{% block content %}
<div style="max-width: 800px; margin: 0 auto;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
<h1>My Decks</h1>
{% if user.profile.is_pro %}
<div class="col-md-6 text-end">
<a href="{% url 'decks:deck_import' %}" class="btn btn-outline-primary me-2">
<i class="bi bi-upload"></i> Import Deck
</a>
<a href="{% url 'decks:deck_create' %}" class="btn btn-primary">
<i class="bi bi-plus-lg"></i> Create New Deck
</a>
</div>
{% else %}
<a href="{% url 'users:profile' %}" class="btn" style="background: #475569;">Upgrade to Pro to Create Decks</a>
{% endif %}
</div>
{% if decks %}
<div class="card-grid">
{% for deck in decks %}
<div class="tcg-card">
<a href="{% url 'decks:deck_builder' deck.id %}"
style="text-decoration: none; color: inherit; display: block; height: 100%;">
<div
style="background: #334155; height: 120px; display: flex; align-items: center; justify-content: center; font-size: 3rem;">
🎴
</div>
<div class="tcg-card-body">
<h3 style="margin: 0;">{{ deck.name }}</h3>
<p style="margin: 0.25rem 0 0; color: #94a3b8; font-size: 0.875rem;">{{ deck.game.name }}</p>
<p style="margin: 0.5rem 0 0; font-size: 0.875rem;">{{ deck.cards.count }} cards</p>
</div>
</a>
</div>
{% endfor %}
</div>
{% else %}
<div style="text-align: center; padding: 4rem; background: var(--card-bg); border-radius: 0.5rem; color: #94a3b8;">
<p style="font-size: 1.25rem;">You haven't created any decks yet.</p>
</div>
{% endif %}
</div>
{% endblock %}