Bundled fix for the PAID-DRAW-loops-to-GATE-VIEW bug surfaced 2026-05-20 in live testing: previously the view reset `created_at = now()` + cleared the hand, but the row's continued existence meant `quota_spent=True` on the next render → landing rendered GATE VIEW → user clicked it → back to gatekeeper → loop. Now PAID DRAW does `active_draw.delete()` after debiting the token + then redirects to `/gameboard/my-sea/?phase=picker`. The my_sea view honors `?phase=picker` (only when no active_draw exists — can't bypass post-DEL GATE VIEW) by forcing `show_picker=True` so the user lands in the picker ready to draw. First card draw creates a fresh row w. fresh `created_at`, starting the new 24h quota cycle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
101 lines
5.2 KiB
HTML
101 lines
5.2 KiB
HTML
{% extends "core/base.html" %}
|
|
{% load static %}
|
|
{% load lyric_extras %}
|
|
|
|
{% block title_text %}Game Sea Gate{% endblock title_text %}
|
|
{% block header_text %}<span>Game</span><span>Gate</span>{% endblock header_text %}
|
|
|
|
{% block content %}
|
|
{# Sprint 6 iter 6a — solo my-sea gatekeeper. Token-deposit-to-redraw #}
|
|
{# within the 24h window after the user's daily free draw is spent. #}
|
|
{# Layout: `--duoUser` page bg + darkened Gaussian-glass modal centered #}
|
|
{# over it (mirrors the room gatekeeper's `.gate-overlay` + `.gate- #}
|
|
{# modal` chrome). No hex / chair-seats — the gatekeeper is a transient #}
|
|
{# in-flight UI; seats live on the my-sea picker page itself. #}
|
|
<div class="my-sea-page my-sea-gate-page"
|
|
data-phase="gate"
|
|
data-polarity="{% if significator_reversed %}gravity{% else %}levity{% endif %}">
|
|
|
|
<div id="id_gate_wrapper" class="my-sea-gate-wrapper">
|
|
<div class="gate-backdrop"></div>
|
|
<div class="gate-overlay my-sea-gate-overlay">
|
|
<div class="gate-modal my-sea-gate-modal" role="dialog" aria-label="My Sea Gatekeeper">
|
|
|
|
{# Title panel — mirrors room's `<h1>{{ room.name }}</h1>` #}
|
|
{# inside `.gate-title-panel`. For solo my-sea the page #}
|
|
{# title reads "@<handle>'s Sea" (rendered via the #}
|
|
{# `at_handle` filter so handle-less users fall back to #}
|
|
{# their email prefix). #}
|
|
<div class="gate-title-panel">
|
|
<header class="gate-header">
|
|
<h1>{{ user|at_handle }}'s Sea</h1>
|
|
</header>
|
|
</div>
|
|
|
|
{# Top row — token slot (main panel) + PAID DRAW square #}
|
|
{# (roles panel). Both share `.gate-main-panel` / #}
|
|
{# `.gate-roles-panel` `--priUser` bg styling from #}
|
|
{# `_room.scss`. Layout mirrors the room gatekeeper. #}
|
|
<div class="gate-top-row">
|
|
<div class="gate-main-panel">
|
|
<div class="token-slot{% if not deposit_reserved %} active{% else %} pending{% endif %}">
|
|
{% if not deposit_reserved %}
|
|
<form method="POST" action="{% url 'my_sea_insert_token' %}" style="display:contents">
|
|
{% csrf_token %}
|
|
<button type="submit" class="token-rails" aria-label="Insert token to play">
|
|
<span class="rail"></span>
|
|
<span class="rail"></span>
|
|
</button>
|
|
</form>
|
|
{% else %}
|
|
<div class="token-rails">
|
|
<span class="rail"></span>
|
|
<span class="rail"></span>
|
|
</div>
|
|
{% endif %}
|
|
<div class="token-panel">
|
|
<div class="token-denomination">1</div>
|
|
<span class="token-insert-label">INSERT TOKEN TO PLAY</span>
|
|
<span class="token-return-label">PUSH TO RETURN</span>
|
|
</div>
|
|
{% if deposit_reserved %}
|
|
<form method="POST" action="{% url 'my_sea_refund_token' %}" style="display:contents">
|
|
{% csrf_token %}
|
|
<button type="submit" class="token-return-btn" aria-label="Push to return"></button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="gate-roles-panel">
|
|
{% if deposit_reserved %}
|
|
<form method="POST" action="{% url 'my_sea_paid_draw' %}" style="display:contents">
|
|
{% csrf_token %}
|
|
<button type="submit"
|
|
id="id_my_sea_paid_draw_btn"
|
|
class="launch-game-btn btn btn-primary">PAID<br>DRAW</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# Sprint 6 iter 6c — bud-btn invite stub (multiplayer-coming-soon) #}
|
|
{# + gear-btn NVM-only menu. Both render outside .gate-modal so the #}
|
|
{# bud-btn lives at viewport fixed position (per `_bud.scss`) and #}
|
|
{# the gear-btn sits atop `#id_kit_btn` in the bottom-right corner. #}
|
|
{% include "apps/gameboard/_partials/_my_sea_bud_panel.html" %}
|
|
{% include "apps/gameboard/_partials/_my_sea_gear.html" %}
|
|
</div>
|
|
{% endblock content %}
|
|
|
|
{% block scripts %}
|
|
{# Brief module — needed by _my_sea_bud_panel's OK handler so the #}
|
|
{# 'Multiplayer my-sea coming soon' banner shows on a successful #}
|
|
{# (stub) invite. #}
|
|
<script src="{% static 'apps/dashboard/note.js' %}"></script>
|
|
{% endblock scripts %}
|