asxpio/views/admin/bingo/edit.erb
Sergei Poljanski c64098813b
All checks were successful
Build and Deploy to Production / test (push) Successful in 27s
Build and Deploy to Production / build (push) Successful in 1m1s
Build and Deploy to Production / deploy (push) Successful in 38s
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
2026-10-11 21:12:47 +04:00

91 lines
6.5 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<% fresh = @dc.new? %>
<div class="header">
<h1><%= fresh ? 'New datacenter' : "##{@dc.position} #{@dc.name_ru}" %></h1>
<p class="tagline"><a href="/admin/bingo">← bingo</a><% if !fresh && @dc.position > Bingo::SIZE**2 %> · off card (reserve)<% end %></p>
</div>
<% if @flash %><div class="form-error-base"><div><%= @flash %></div></div><% end %>
<% unless fresh %>
<section class="section">
<h2>Photo</h2>
<% if @dc.photo_file %>
<p><img src="/admin/bingo/p/<%= @dc.photo_file %>" alt="" style="max-width: 100%; max-height: 280px" /></p>
<% if can?('bingo', 'delete') %>
<form method="post" action="/admin/bingo/dc/<%= @dc.id %>/photo/delete">
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
<button type="submit" class="link-button">remove from card</button>
</form>
<% end %>
<% end %>
<% if can?('bingo', 'write') %>
<form class="invoice-form" method="post" action="/admin/bingo/dc/<%= @dc.id %>/photo" enctype="multipart/form-data">
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
<div class="field"><label for="photo">Upload <span class="optional">(JPEG/PNG/WebP, ≤ 8 MB)</span></label><input type="file" id="photo" name="photo" accept="image/jpeg,image/png,image/webp" /></div>
<div class="field"><label for="photo_url">…or import from URL <span class="optional">(blank = saved source URL)</span></label><input type="url" id="photo_url" name="url" placeholder="<%= @dc.photo_source_url %>" /></div>
<button type="submit" class="download-button">Store photo</button>
</form>
<% end %>
</section>
<% end %>
<section class="section">
<h2>Details</h2>
<form class="invoice-form" method="post" action="<%= fresh ? '/admin/bingo/dc' : "/admin/bingo/dc/#{@dc.id}" %>" autocomplete="off">
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
<fieldset class="plain" <%= 'disabled' unless can?('bingo', 'write') %>>
<% if fresh %>
<div class="field"><label for="slug">Slug <span class="optional">(permanent; used in photo names, e.g. ix-mos7)</span></label><input type="text" id="slug" name="slug" value="<%= @dc.slug %>" required pattern="[a-z0-9]+(-[a-z0-9]+)*" /></div>
<% end %>
<div class="invoice-grid">
<% %w[ru en uk].each do |l| %>
<div class="field"><label for="name_<%= l %>">Name (<%= l %>)</label><input type="text" id="name_<%= l %>" name="name_<%= l %>" value="<%= @dc[:"name_#{l}"] %>" <%= 'required' if l == 'ru' %> /></div>
<% end %>
<% %w[ru en uk].each do |l| %>
<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>
<select id="mw_type" name="mw_type">
<option value="" <%= 'selected' unless @dc.mw_type %>>not stated</option>
<% Bingo::MW_TYPES.each do |m| %><option value="<%= m %>" <%= 'selected' if @dc.mw_type == m %>><%= m %></option><% end %>
</select>
</div>
<div class="field">
<label for="status">Status</label>
<select id="status" name="status">
<% Bingo::STATUSES.each do |s| %><option <%= 'selected' if @dc.status == s %>><%= s %></option><% end %>
</select>
</div>
<div class="field"><label for="year">Year</label><input type="text" id="year" name="year" value="<%= @dc.year %>" inputmode="numeric" /></div>
<div class="field"><label for="position">Position <span class="optional">(inserts here; 1–<%= Bingo::SIZE**2 %> are on the card<%= ', blank = last' if fresh %>)</span></label><input type="text" id="position" name="position" value="<%= @dc.position %>" inputmode="numeric" /></div>
</div>
<div class="field"><label for="photo_credit">Photo credit</label><input type="text" id="photo_credit" name="photo_credit" value="<%= @dc.photo_credit %>" /></div>
<div class="field"><label for="photo_source_url">Photo source URL</label><input type="url" id="photo_source_url" name="photo_source_url" value="<%= @dc.photo_source_url %>" /></div>
<div class="field"><label for="info_url">Info / fact source URL</label><input type="url" id="info_url" name="info_url" value="<%= @dc.info_url %>" /></div>
<% %w[ru en uk].each do |l| %>
<div class="field"><label for="about_<%= l %>">About (<%= l %>) <span class="optional">(datacenter page; blank lines split paragraphs; not translated automatically, blank = hidden)</span></label><textarea id="about_<%= l %>" name="about_<%= l %>" rows="4" maxlength="5000"><%= @dc[:"about_#{l}"] %></textarea></div>
<% end %>
<% if can?('bingo', 'write') %><button type="submit" class="download-button"><%= fresh ? 'Add datacenter' : 'Save' %></button><% end %>
</fieldset>
</form>
</section>
<% if !fresh && can?('bingo', 'delete') %>
<section class="section">
<h2>Danger zone</h2>
<form method="post" action="/admin/bingo/dc/<%= @dc.id %>/delete" onsubmit="return confirm('Delete this datacenter and all its incidents? This cannot be undone.')">
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
<button type="submit" class="link-button">delete this datacenter<%= " (and #{@dc.incidents.size} incident(s))" if @dc.incidents.any? %></button>
</form>
</section>
<% end %>