Files
python-tdd/src/templates/apps/wallet/_partials/_applet-wallet-tokens.html

91 lines
3.8 KiB
HTML
Raw Normal View History

<section
class="wallet-tokens"
style="--applet-cols: {{ entry.applet.grid_cols }}; --applet-rows: {{ entry.applet.grid_rows }};"
>
<h2>Tokens</h2>
<div class="token-row">
{% if pass_token %}
<div id="id_pass_token" class="token">
<i class="fa-solid fa-clipboard"></i>
<div class="tt">
<h4 class="tt-title">{{ pass_token.tooltip_name }}</h4>
<p class="tt-description">{{ pass_token.tooltip_description }}</p>
{% if pass_token.tooltip_shoptalk %}
<p class="tt-shoptalk"><em>{{ pass_token.tooltip_shoptalk }}</em></p>
{% endif %}
<p class="tt-expiry">{{ pass_token.tooltip_expiry }}</p>
</div>
</div>
feat: `Token.BAND` (Wristband) — non-admin variant of PASS, admin-awarded via Django admin to any user (NOT auto-granted on signal, NO `is_staff` coupling, NO model-layer guard). Mirrors PASS at runtime — fills 1 gate slot, never consumed, stays equipped, no `current_room` tie, no expiry, no In-Use microtooltip — but separates the policy concerns so PASS stays a deliberate staff-only trinket while BAND becomes the regular-user version (promotional / play-reward / staging give-away). Tooltip prose: name "Wristband", desc "Admit All Entry" (shared w. PASS — phrasing reflects the never-depleted lifetime, not multi-slot semantics), shoptalk "Unlimited free entry (BYOB)", expiry "no expiry". `fa-ring` icon across all 4 surfaces (Game Kit applet `#id_kit_wristband` between PASS + CARTE, gk-trinkets section, kit-bag dialog Trinket slot, wallet PASS→BAND→COIN elif chain). Priority chain — PASS → BAND → COIN → FREE → TITHE — wired identically into both `apps.epic.models.select_token` (room gatekeeper) + `apps.gameboard.models._select_my_sea_token` (my-sea gatekeeper); BAND wins over consumables for any holder while PASS still wins for staff who happen to hold both. `debit_token` + `debit_my_sea_token` treat BAND same as PASS: slot marked FILLED w. `debited_token_type=BAND`, token row preserved, `current_room` untouched, `equipped_trinket` unchanged. View contexts (`gameboard`, `toggle_game_applets`, `_game_kit_context`, `wallet`, `toggle_wallet_applets`) pass a `band` key — universal lookup, NO `is_staff` filter. Migration `lyric/0007_alter_token_token_type` — choices-only AlterField. TDD — 5 FTs in `test_trinket_wristband.py` (`test_band_not_auto_equipped_after_award`, `test_band_tooltip_renders_full_prose`, `test_band_uses_fa_ring_icon`, `test_equipped_band_shows_equipped_mini_tooltip`, `test_equipped_band_shows_doff_active_don_disabled`); 4 tooltip UTs (`BandTokenTooltipTest`); 5 model ITs (`BandTokenAdminAwardTest` — no-auto-grant for non-staff + staff, admin-can-award to either branch, not-auto-equipped); 2 priority-chain ITs (`test_returns_band_when_held_and_no_pass`, `test_pass_still_wins_over_band_for_staff`); 1 debit IT (`test_debit_band_does_not_consume_or_unequip`). 1145 IT/UT + 5 FT green. A boost-pass / promo-band w. richer semantics (multi-slot admit, time-window, etc.) lands as YET-ANOTHER token_type later — keep BAND the minimal "PASS minus admin gate" trinket so the policy axis stays clean. Captured in [[sprint-band-trinket-may21]] alongside the standing auto-commit rule [[feedback-auto-commit-after-build]] Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:33:09 -04:00
{% elif band %}
<div id="id_band_token" class="token">
<i class="fa-solid fa-ring"></i>
<div class="tt">
<h4 class="tt-title">{{ band.tooltip_name }}</h4>
<p class="tt-description">{{ band.tooltip_description }}</p>
{% if band.tooltip_shoptalk %}
<p class="tt-shoptalk"><em>{{ band.tooltip_shoptalk }}</em></p>
{% endif %}
<p class="tt-expiry">{{ band.tooltip_expiry }}</p>
</div>
</div>
{% elif coin %}
<div id="id_coin_on_a_string" class="token">
<i class="fa-solid fa-medal"></i>
<div class="tt">
<h4 class="tt-title">{{ coin.tooltip_name }}</h4>
<p class="tt-description">{{ coin.tooltip_description }}</p>
{% if coin.tooltip_shoptalk %}
<p class="tt-shoptalk"><em>{{ coin.tooltip_shoptalk }}</em></p>
{% endif %}
<p class="tt-expiry">{{ coin.tooltip_expiry }}</p>
</div>
</div>
{% endif %}
{% if free_tokens %}
{% with free_tokens.0 as token %}
<div id="id_free_token" class="token">
<i class="fa-solid fa-coins"></i>
<div class="tt">
<h4 class="tt-title">{{ token.tooltip_name }}{% if free_count > 1 %} <span class="token-count">(×{{ free_count }})</span>{% endif %}</h4>
<p class="tt-description">{{ token.tooltip_description }}</p>
{% if token.tooltip_shoptalk %}
<p class="tt-shoptalk"><em>{{ token.tooltip_shoptalk }}</em></p>
{% endif %}
<p class="tt-expiry">{{ token.tooltip_expiry }}</p>
</div>
</div>
{% endwith %}
{% else %}
<div id="id_free_token_empty" class="token token--empty">
<i class="fa-solid fa-coins"></i>
<div class="tt">
<h4 class="tt-title">Free Token</h4>
<p class="tt-description">0 owned</p>
<p class="tt-expiry">find one around</p>
</div>
</div>
{% endif %}
{% if tithe_tokens %}
{% with tithe_tokens.0 as token %}
<div id="id_tithe_token" class="token">
<i class="fa-solid fa-piggy-bank"></i>
<div class="tt">
<h4 class="tt-title">{{ token.tooltip_name }}{% if tithe_count > 1 %} <span class="token-count">(×{{ tithe_count }})</span>{% endif %}</h4>
<p class="tt-description">{{ token.tooltip_description }}</p>
<p class="tt-expiry">{{ token.tooltip_expiry }}</p>
</div>
</div>
{% endwith %}
{% else %}
<div id="id_tithe_token_empty" class="token token--empty">
<i class="fa-solid fa-piggy-bank"></i>
<div class="tt">
<h4 class="tt-title">Tithe Token</h4>
<p class="tt-description">0 owned</p>
<p class="tt-expiry">purchase one above</p>
</div>
</div>
{% endif %}
</div>
</section>