progress on conversion to tailwind
This commit is contained in:
parent
6a872124c6
commit
6e2843c60e
110 changed files with 4997 additions and 1691 deletions
92
cards/migrations/0001_initial.py
Normal file
92
cards/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Generated by Django 5.1.2 on 2025-03-07 01:04
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Card',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('cardnum', models.IntegerField()),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CardSet',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Rarity',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('icons', models.CharField(max_length=64)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CardNameTranslation',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('language', models.CharField(max_length=64)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('card', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='name_translations', to='cards.card')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='card',
|
||||
name='cardset',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cards', to='cards.cardset'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Deck',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('hex_color', models.CharField(max_length=9)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('cardset', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='decks', to='cards.cardset')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='card',
|
||||
name='decks',
|
||||
field=models.ManyToManyField(to='cards.deck'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DeckNameTranslation',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('language', models.CharField(max_length=64)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('deck', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='name_translations', to='cards.deck')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='card',
|
||||
name='rarity',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='cards', to='cards.rarity'),
|
||||
),
|
||||
]
|
||||
|
|
@ -52,6 +52,15 @@ class Rarity(models.Model):
|
|||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def normalized_id(self):
|
||||
"""
|
||||
For trading equivalence: treat Special Art Rare (pk 7) and Super Rare (pk 6) as the same.
|
||||
"""
|
||||
if self.pk in (6, 7):
|
||||
return 6
|
||||
return self.pk
|
||||
|
||||
class Card(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=64)
|
||||
|
|
@ -63,4 +72,12 @@ class Card(models.Model):
|
|||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name + " " + self.rarity.icons + " " + self.cardset.name
|
||||
# For display, we show the original rarity icons.
|
||||
return f"{self.name} {self.rarity.icons} {self.cardset.name}"
|
||||
|
||||
@property
|
||||
def normalized_rarity(self):
|
||||
"""
|
||||
Returns the canonical rarity id for trade logic.
|
||||
"""
|
||||
return self.rarity.normalized_id
|
||||
|
|
|
|||
|
|
@ -1,11 +1,28 @@
|
|||
from django import template
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.inclusion_tag("includes/card_badge.html")
|
||||
def card_badge(card):
|
||||
@register.inclusion_tag("templatetags/card_badge.html")
|
||||
def card_badge(card, quantity=1, show_single_count=True):
|
||||
return {
|
||||
'card': card,
|
||||
'quantity': quantity,
|
||||
'decks': card.decks.all() if card else None,
|
||||
'dropdown': card is None
|
||||
}
|
||||
'dropdown': card is None,
|
||||
'show_single_count': show_single_count,
|
||||
}
|
||||
|
||||
@register.filter
|
||||
def card_badge_inline(card, quantity=1):
|
||||
"""
|
||||
Renders an inline card badge.
|
||||
"""
|
||||
html = render_to_string("templatetags/card_badge.html", {
|
||||
'card': card,
|
||||
'quantity': quantity,
|
||||
'decks': card.decks.all() if card else None,
|
||||
'dropdown': card is None,
|
||||
})
|
||||
return mark_safe(html)
|
||||
|
|
@ -3,46 +3,69 @@ from cards.models import Card
|
|||
|
||||
register = template.Library()
|
||||
|
||||
@register.inclusion_tag('includes/card_multiselect.html')
|
||||
def card_multiselect(field_name, label, available_cards, placeholder, selected_values=None, cache_timeout=86400, cache_key="available_cards_options"):
|
||||
@register.inclusion_tag('templatetags/card_multiselect.html')
|
||||
def card_multiselect(field_name, label, placeholder, card_filter=None, selected_values=None, cache_timeout=86400, cache_key="available_cards_options"):
|
||||
"""
|
||||
Renders a Select2 field for choosing cards.
|
||||
|
||||
Renders a multiselect field for choosing cards, storing the card ID only as the option's value and
|
||||
the quantity in a dedicated data attribute.
|
||||
|
||||
Parameters:
|
||||
- field_name: The name attribute for the select tag.
|
||||
- label: Label text to show above the selector.
|
||||
- available_cards: A queryset or list of card objects that will populate the options.
|
||||
- placeholder: Placeholder text to show in the select.
|
||||
- selected_values: (Optional) A list of selected card IDs (will be compared as strings).
|
||||
- card_filter: (Optional) A dictionary of filter parameters to apply on the Card query.
|
||||
- selected_values: (Optional) A list of selected card values; if a value includes a quantity
|
||||
it should be in the format "card_id:quantity".
|
||||
- cache_timeout: (Optional) Cache timeout (in seconds) for the options block.
|
||||
- cache_key: (Optional) Cache key—by default both select fields use the same key so that caching is shared.
|
||||
"""
|
||||
if selected_values is None:
|
||||
selected_values = []
|
||||
# Normalize selected_values to strings.
|
||||
selected_values = [str(val) for val in selected_values]
|
||||
# Map the selected values into a dictionary: { card_id (str): quantity (str) }
|
||||
selected_cards = {}
|
||||
for val in selected_values:
|
||||
parts = str(val).split(':')
|
||||
card_id = parts[0]
|
||||
quantity = parts[1] if len(parts) > 1 else "1"
|
||||
selected_cards[card_id] = quantity
|
||||
|
||||
# If a card_filter is provided, use it; otherwise retrieve all cards.
|
||||
if card_filter:
|
||||
available_cards_qs = Card.objects.filter(**card_filter)
|
||||
else:
|
||||
available_cards_qs = Card.objects.all()
|
||||
|
||||
# --- Available cards for the search form ---
|
||||
available_cards = list(
|
||||
Card.objects.order_by("name", "rarity__pk")
|
||||
available_cards_qs.order_by("name", "rarity__pk")
|
||||
.select_related("rarity", "cardset")
|
||||
.prefetch_related("decks")
|
||||
)
|
||||
|
||||
for card in available_cards:
|
||||
if card.decks.count() == 1:
|
||||
card.style = "background-color: " + card.decks.all()[0].hex_color + "; color: white;"
|
||||
elif card.decks.count() == 2:
|
||||
card.style = "background: linear-gradient(to right, " + card.decks.all()[0].hex_color + ", " + card.decks.all()[1].hex_color + "); color: white;"
|
||||
elif card.decks.count() >= 3:
|
||||
card.style = "background: linear-gradient(to right, " + card.decks.all()[0].hex_color + ", " + card.decks.all()[1].hex_color + ", " + card.decks.all()[2].hex_color + "); color: white;"
|
||||
|
||||
# Apply styling based on deck count.
|
||||
deck_count = card.decks.count()
|
||||
if deck_count == 1:
|
||||
card.style = f"background-color: {card.decks.all()[0].hex_color}; color: white;"
|
||||
elif deck_count == 2:
|
||||
decks = card.decks.all()
|
||||
card.style = f"background: linear-gradient(to right, {decks[0].hex_color}, {decks[1].hex_color}); color: white;"
|
||||
elif deck_count >= 3:
|
||||
decks = card.decks.all()
|
||||
card.style = f"background: linear-gradient(to right, {decks[0].hex_color}, {decks[1].hex_color}, {decks[2].hex_color}); color: white;"
|
||||
|
||||
# Attach selected_quantity only if the card is pre‑selected.
|
||||
pk_str = str(card.pk)
|
||||
if pk_str in selected_cards:
|
||||
card.selected_quantity = selected_cards[pk_str]
|
||||
|
||||
return {
|
||||
'field_name': field_name,
|
||||
'field_id': field_name, # using the name as id for simplicity
|
||||
'label': label,
|
||||
'available_cards': available_cards,
|
||||
'placeholder': placeholder,
|
||||
'selected_values': selected_values,
|
||||
# For caching/selection checks, pass a list of the pre‑selected card IDs.
|
||||
'selected_values': list(selected_cards.keys()),
|
||||
'cache_timeout': cache_timeout,
|
||||
'cache_key': cache_key,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue