sig-select sprint: SigReservation model + sig_reserve view (OK/NVM hold); full sig-select.js rewrite with stage preview, WS hover cursors, reservation lock (must NVM before OK-ing another card — enforced server-side 409 + JS guard); sizeSigModal() + sizeSigCard() in room.js (JS-based card sizing avoids libsass cqw/cqh limitation); stat block hidden until OK pressed; mobile touch: dismiss stage on outside-grid tap when unfocused; 17 IT + Jasmine specs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
{% load i18n %}{% comment %}
|
||||
Sig Select overlay — dark Gaussian modal over the dormant table hex.
|
||||
Rendered for the current user's polarity group only.
|
||||
Context: sig_cards, user_polarity, user_seat, sig_reserve_url, sig_reservations_json
|
||||
{% endcomment %}
|
||||
<div class="sig-backdrop"></div>
|
||||
<div class="sig-overlay"
|
||||
data-polarity="{{ user_polarity }}"
|
||||
data-user-role="{{ user_seat.role }}"
|
||||
data-reserve-url="{{ sig_reserve_url }}"
|
||||
data-reservations="{{ sig_reservations_json }}">
|
||||
|
||||
<div class="sig-modal">
|
||||
|
||||
<div class="sig-stage" id="id_sig_stage">
|
||||
|
||||
<div class="sig-stage-card" style="display:none">
|
||||
<div class="fan-card-corner fan-card-corner--tl">
|
||||
<span class="fan-corner-rank"></span>
|
||||
<i class="fa-solid stage-suit-icon" style="display:none"></i>
|
||||
</div>
|
||||
<div class="fan-card-face">
|
||||
<p class="fan-card-name-group"></p>
|
||||
<h3 class="fan-card-name"></h3>
|
||||
<p class="fan-card-arcana"></p>
|
||||
<p class="fan-card-correspondence"></p>
|
||||
</div>
|
||||
<div class="fan-card-corner fan-card-corner--br">
|
||||
<span class="fan-corner-rank"></span>
|
||||
<i class="fa-solid stage-suit-icon" style="display:none"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sig-stat-block"></div>
|
||||
</div>
|
||||
|
||||
<div class="sig-deck-grid" id="id_sig_deck">
|
||||
{% for card in sig_cards %}
|
||||
<div class="sig-card {{ user_polarity }}-deck"
|
||||
data-card-id="{{ card.id }}"
|
||||
data-suit-icon="{{ card.suit_icon }}"
|
||||
data-corner-rank="{{ card.corner_rank }}"
|
||||
data-name-group="{{ card.name_group }}"
|
||||
data-name-title="{{ card.name_title }}"
|
||||
data-arcana="{{ card.get_arcana_display }}"
|
||||
data-correspondence="{{ card.correspondence|default:'' }}">
|
||||
<div class="fan-card-corner fan-card-corner--tl">
|
||||
<span class="fan-corner-rank">{{ card.corner_rank }}</span>
|
||||
{% if card.suit_icon %}<i class="fa-solid {{ card.suit_icon }}"></i>{% endif %}
|
||||
</div>
|
||||
<div class="sig-card-actions">
|
||||
<button class="sig-ok-btn btn btn-confirm" type="button">OK</button>
|
||||
<button class="sig-nvm-btn btn btn-cancel" type="button">NVM</button>
|
||||
</div>
|
||||
<div class="sig-card-cursors">
|
||||
<span class="sig-cursor sig-cursor--left"></span>
|
||||
<span class="sig-cursor sig-cursor--mid"></span>
|
||||
<span class="sig-cursor sig-cursor--right"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,17 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if room.table_status == "SIG_SELECT" and sig_seats %}
|
||||
{% for seat in sig_seats %}
|
||||
<div class="table-seat{% if seat == sig_active_seat %} active{% endif %}" data-role="{{ seat.role }}" data-slot="{{ seat.slot_number }}">
|
||||
<div class="seat-portrait">{{ seat.slot_number }}</div>
|
||||
<div class="seat-card-arc"></div>
|
||||
<span class="seat-label">
|
||||
{% if seat.gamer %}@{{ seat.gamer.username|default:seat.gamer.email }}{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{# Seats — fa-chair layout persists from ROLE_SELECT through SIG_SELECT #}
|
||||
{% for pos in gate_positions %}
|
||||
<div class="table-seat{% if pos.role_label in starter_roles %} role-confirmed{% endif %}"
|
||||
data-slot="{{ pos.slot.slot_number }}" data-role="{{ pos.role_label }}">
|
||||
@@ -59,33 +49,13 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if room.table_status == "SIG_SELECT" and sig_cards %}
|
||||
<div id="id_sig_deck"
|
||||
data-select-sig-url="{% url 'epic:select_sig' room.id %}"
|
||||
data-user-role="{{ user_seat.role|default:'' }}">
|
||||
{% for card, deck_type in sig_cards %}
|
||||
<div class="sig-card {{ deck_type }}-deck" data-card-id="{{ card.id }}" data-deck="{{ deck_type }}">
|
||||
<div class="fan-card-corner fan-card-corner--tl">
|
||||
<span class="fan-corner-rank">{{ card.corner_rank }}</span>
|
||||
{% if card.suit_icon %}<i class="fa-solid {{ card.suit_icon }}"></i>{% endif %}
|
||||
</div>
|
||||
<div class="fan-card-face">
|
||||
{% if card.name_group %}<p class="fan-card-name-group">{{ card.name_group }}</p>{% endif %}
|
||||
<h3 class="fan-card-name">{{ card.name_title }}</h3>
|
||||
<p class="fan-card-arcana">{{ card.get_arcana_display }}</p>
|
||||
</div>
|
||||
<div class="fan-card-corner fan-card-corner--br">
|
||||
<span class="fan-corner-rank">{{ card.corner_rank }}</span>
|
||||
{% if card.suit_icon %}<i class="fa-solid {{ card.suit_icon }}"></i>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{# Sig Select overlay — only shown to seated gamers in this polarity #}
|
||||
{% if room.table_status == "SIG_SELECT" and user_polarity %}
|
||||
{% include "apps/gameboard/_partials/_sig_select_overlay.html" %}
|
||||
{% endif %}
|
||||
|
||||
{% if room.gate_status != "RENEWAL_DUE" and room.table_status != "SIG_SELECT" %}
|
||||
@@ -115,4 +85,4 @@
|
||||
<script src="{% static 'apps/epic/role-select.js' %}"></script>
|
||||
<script src="{% static 'apps/epic/sig-select.js' %}"></script>
|
||||
<script src="{% static 'apps/epic/tray.js' %}"></script>
|
||||
{% endblock scripts %}
|
||||
{% endblock scripts %}
|
||||
|
||||
Reference in New Issue
Block a user