game kit gear menu + login form UX polish; left-side position indicator flip
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

game kit: new Applet model rows (context=game-kit) for Trinkets, Tokens, Card Decks, Dice Sets via applets migration 0008; _game_kit_context() helper in gameboard.views; toggle_game_kit_sections view + URL; new _game_kit_sections.html (HTMX-swappable, visibility-conditional) + _game_kit_applet_menu.html partials; game_kit.html wired to gear btn + menu; Dice Sets now renders _forthcoming.html partial; 16 new green ITs in GameKitViewTest + ToggleGameKitSectionsViewTest

login form: .input-group now position:fixed + vertically centred (top:50%) across all breakpoints as default; landscape block reduced to left/right sidebar offsets only; form-control width 24rem, text-align:center; alert block moved below h2 in base.html; alert margin 0.75rem all sides; home.html header switches between Howdy Stranger (anon) and Dashboard (authed)

room.html position indicators: slots 3/4/5 (AC/SC/EC) column order flipped via SCSS data-slot selectors so .fa-chair sits table-side and label+status icon sit outward

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-04-04 13:49:48 -04:00
parent 824f35590b
commit 188365f412
11 changed files with 301 additions and 102 deletions

View File

@@ -102,26 +102,48 @@ def equip_deck(request, deck_id):
return HttpResponse(status=405)
@login_required(login_url="/")
def game_kit(request):
coin = request.user.tokens.filter(token_type=Token.COIN).first()
pass_token = request.user.tokens.filter(token_type=Token.PASS).first() if request.user.is_staff else None
carte = request.user.tokens.filter(token_type=Token.CARTE).first()
free_tokens = list(request.user.tokens.filter(
def _game_kit_context(user):
coin = user.tokens.filter(token_type=Token.COIN).first()
pass_token = user.tokens.filter(token_type=Token.PASS).first() if user.is_staff else None
carte = user.tokens.filter(token_type=Token.CARTE).first()
free_tokens = list(user.tokens.filter(
token_type=Token.FREE, expires_at__gt=timezone.now()
).order_by("expires_at"))
tithe_tokens = list(request.user.tokens.filter(token_type=Token.TITHE))
return render(request, "apps/gameboard/game_kit.html", {
tithe_tokens = list(user.tokens.filter(token_type=Token.TITHE))
return {
"coin": coin,
"pass_token": pass_token,
"carte": carte,
"free_tokens": free_tokens,
"tithe_tokens": tithe_tokens,
"unlocked_decks": list(request.user.unlocked_decks.all()),
"unlocked_decks": list(user.unlocked_decks.all()),
"applets": applet_context(user, "game-kit"),
}
@login_required(login_url="/")
def game_kit(request):
return render(request, "apps/gameboard/game_kit.html", {
**_game_kit_context(request.user),
"page_class": "page-gameboard",
})
@login_required(login_url="/")
def toggle_game_kit_sections(request):
checked = request.POST.getlist("applets")
for applet in Applet.objects.filter(context="game-kit"):
UserApplet.objects.update_or_create(
user=request.user,
applet=applet,
defaults={"visible": applet.slug in checked},
)
if request.headers.get("HX-Request"):
return render(request, "apps/gameboard/_partials/_game_kit_sections.html",
_game_kit_context(request.user))
return redirect("game_kit")
@login_required(login_url="/")
def tarot_fan(request, deck_id):
from apps.epic.models import TarotCard