bingo: build the card from chosen providers
Let visitors tick providers (Yandex, IXcellerate, RTK-DC, Sber, …) and get the usual 5×5 card made of only those providers' datacenters, first 25 in ranking order, with lines scored as normal. A selection with fewer than 25 sites leaves the rest of the card empty, so the card is always 5×5. Each provider chip shows crossed/total for the current view. Datacenters get a provider slug, backfilled from the free-text operator, guessed for new rows and editable in the admin. Filtered URLs are noindex with canonical to the plain card. Assisted-by: Claude:opus-5
This commit is contained in:
parent
9ba108b6b0
commit
c64098813b
9 changed files with 155 additions and 8 deletions
|
|
@ -45,6 +45,13 @@
|
|||
<div class="field"><label for="city_<%= l %>">City (<%= l %>)</label><input type="text" id="city_<%= l %>" name="city_<%= l %>" value="<%= @dc[:"city_#{l}"] %>" <%= 'required' if l == 'ru' %> /></div>
|
||||
<% end %>
|
||||
<div class="field"><label for="operator">Operator</label><input type="text" id="operator" name="operator" value="<%= @dc.operator %>" required /></div>
|
||||
<div class="field">
|
||||
<label for="provider">Provider <span class="optional">(groups the per-provider card)</span></label>
|
||||
<select id="provider" name="provider">
|
||||
<option value="" <%= 'selected' unless @dc.provider %>>none</option>
|
||||
<% Bingo::PROVIDERS.each do |slug, names| %><option value="<%= slug %>" <%= 'selected' if @dc.provider == slug %>><%= names['ru'] %></option><% end %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field"><label for="mw">MW <span class="optional">(number or range)</span></label><input type="text" id="mw" name="mw" value="<%= @dc.mw %>" /></div>
|
||||
<div class="field">
|
||||
<label for="mw_type">Capacity type</label>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,20 @@
|
|||
</header>
|
||||
|
||||
<p class="lead"><%= t(:desc) %></p>
|
||||
<% provs = Bingo::Board.providers(@view) %>
|
||||
<form class="providers" method="get" action="/<%= @locale %>">
|
||||
<% if @view == 'all' %><input type="hidden" name="view" value="all"><% end %>
|
||||
<fieldset>
|
||||
<legend><%= t(:providers_label) %></legend>
|
||||
<% provs.each do |slug, total, crossed| %>
|
||||
<label><input type="checkbox" name="p[]" value="<%= slug %>" <%= 'checked' if @providers.include?(slug) %>> <%= Bingo.provider_name(slug, @locale) %> <span><%= crossed %>/<%= total %></span></label>
|
||||
<% end %>
|
||||
</fieldset>
|
||||
<div class="provider-actions">
|
||||
<button type="submit"><%= t(:providers_apply) %></button>
|
||||
<% if @board.filtered? %><a href="<%= card_path(@locale, @view, []) %>"><%= t(:providers_reset) %></a><% end %>
|
||||
</div>
|
||||
</form>
|
||||
<p class="meta">
|
||||
<%= t(:crossed) %> <b><%= b.hit.count(true) %></b>/<%= b.cells.size %>
|
||||
· <%= t(:lines) %> <b><%= b.wins.size %></b>
|
||||
|
|
@ -48,6 +62,7 @@
|
|||
<% if b.hit[idx] %><div class="stamp"><%= kind_icon(dc.incidents.first.kind) %></div><% end %>
|
||||
</a>
|
||||
<% end %>
|
||||
<% (b.cells.size...Bingo::SIZE**2).each do %><div class="cell empty" aria-hidden="true"></div><% end %>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,16 @@
|
|||
.banner { margin: 0 0 16px; padding: 12px 16px; border-radius: 10px; background: var(--win); color: var(--on-win); font-weight: 700; font-size: 18px; }
|
||||
|
||||
.letters, .grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
|
||||
.cell.empty { background: transparent; border-style: dashed; cursor: default; }
|
||||
.providers { margin: 0 0 16px; }
|
||||
.providers fieldset { border: 0; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 6px; }
|
||||
.providers legend { font-size: 13px; color: var(--muted); margin-bottom: 6px; padding: 0; }
|
||||
.providers label { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border: 1px solid var(--line); border-radius: 999px; font-size: 13px; cursor: pointer; white-space: nowrap; }
|
||||
.providers label:has(input:checked) { border-color: var(--ink); }
|
||||
.providers input { accent-color: var(--hit); margin: 0; }
|
||||
.providers label span { color: var(--muted); font-variant-numeric: tabular-nums; }
|
||||
.provider-actions { display: flex; gap: 12px; align-items: center; margin-top: 8px; font-size: 13px; }
|
||||
.provider-actions button { font: inherit; padding: 3px 12px; border-radius: 6px; border: 1px solid var(--line); background: var(--card); color: var(--ink); cursor: pointer; }
|
||||
.letters div { text-align: center; font-weight: 900; font-size: clamp(22px, 5vw, 36px); color: var(--hit); }
|
||||
.grid { margin-top: 6px; }
|
||||
.cell {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue