The site now lives in a public repo; point readers at it in all three languages. Both pages had the same footer, so it becomes one partial (absorbing the credits partial). Assisted-by: Claude:opus-5
113 lines
4.9 KiB
Text
113 lines
4.9 KiB
Text
<% b = @board %>
|
|
<main>
|
|
<header>
|
|
<h1><%= t(:lead) %> <span><%= t(:accent) %></span> <small><%= t(:tagline) %></small></h1>
|
|
<div class="switches">
|
|
<nav class="toggle" aria-label="<%= t(:view_label) %>">
|
|
<% Bingo::VIEWS.each do |v| %>
|
|
<a href="<%= card_path(@locale, v) %>" <%== 'aria-current="page"' if v == @view %>><%= t(:"view_#{v}") %></a>
|
|
<% end %>
|
|
</nav>
|
|
<nav class="langs">
|
|
<% Bingo::LOCALES.each do |l| %>
|
|
<a href="<%= card_path(l) %>" hreflang="<%= l %>" lang="<%= l %>" <%== 'aria-current="page"' if l == @locale %>><%= l %></a>
|
|
<% end %>
|
|
</nav>
|
|
</div>
|
|
</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>
|
|
<% if b.updated_on %>· <%= t(:updated) %> <b><%= fmt_date(b.updated_on) %></b><% end %>
|
|
</p>
|
|
|
|
<% if b.wins.any? %>
|
|
<div class="banner">
|
|
<%= b.wins.size == Bingo::LINES.size ? t(:full) : b.wins.size > 1 ? format(t(:bingo_n), b.wins.size) : t(:bingo) %>
|
|
</div>
|
|
<% end %>
|
|
|
|
<div class="letters" aria-hidden="true"><% t(:letters).each do |ch| %><div><%= ch %></div><% end %></div>
|
|
<div class="grid">
|
|
<% b.cells.each_with_index do |dc, idx| %>
|
|
<% photo = photo_path(dc, 480) %>
|
|
<a href="<%= dc_path(dc) %>" data-dlg="dlg-<%= dc.slug %>"
|
|
class="cell<%= ' photo' if photo %><%= ' hit' if b.hit[idx] %><%= ' win' if b.win_cells.include?(idx) %>"
|
|
aria-label="<%= dc.l(:name, @locale) %><%= " — #{kind_label(dc.incidents.first.kind)}" if b.hit[idx] %>">
|
|
<% if photo %><img class="bg" src="<%= photo %>" alt="" width="480" height="480" decoding="async"<%== ' loading="lazy"' if idx >= 10 %>><% end %>
|
|
<div>
|
|
<div class="n">#<%= idx + 1 %><%= " · #{mw(dc, tag: false)}" if mw(dc) %></div>
|
|
<% if status_label(dc) %><div class="tag"><%= status_label(dc) %></div><% end %>
|
|
</div>
|
|
<div>
|
|
<div class="name"><%= dc.l(:name, @locale) %></div>
|
|
<div class="sub"><%= dc.l(:city, @locale) %></div>
|
|
</div>
|
|
<% 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>
|
|
<h2><%= t(:log) %></h2>
|
|
<ul class="log">
|
|
<% if b.incidents.empty? %>
|
|
<li class="empty"><%= t(:empty) %></li>
|
|
<% end %>
|
|
<% b.incidents.each do |i| %>
|
|
<li>
|
|
<time datetime="<%= i.occurred_on %>"><%= fmt_date(i.occurred_on) %></time>
|
|
<span><%= kind_icon(i.kind) %></span>
|
|
<div>
|
|
<% if i.url %><a href="<%= i.url %>" target="_blank" rel="noopener nofollow"><%= i.l(:title, @locale) %></a><% else %><%= i.l(:title, @locale) %><% end %>
|
|
<div class="dc"><a href="<%= dc_path(i.datacenter) %>"><%= i.datacenter.l(:name, @locale) %></a> · <%= kind_label(i.kind) %></div>
|
|
</div>
|
|
</li>
|
|
<% end %>
|
|
</ul>
|
|
</section>
|
|
|
|
<%== erb :_footer, layout: false %>
|
|
</main>
|
|
|
|
<% b.cells.each do |dc| %>
|
|
<dialog id="dlg-<%= dc.slug %>">
|
|
<% if (photo = photo_path(dc, 1200)) %><img src="<%= photo %>" alt="<%= dc.l(:name, @locale) %>, <%= dc.l(:city, @locale) %>" loading="lazy" decoding="async"><% end %>
|
|
<div class="body">
|
|
<h3><%= dc.l(:name, @locale) %></h3>
|
|
<%== erb :_dc_meta, layout: false, locals: { dc: dc } %>
|
|
<%== erb :_dc_incidents, layout: false, locals: { dc: dc } %>
|
|
<div class="actions">
|
|
<a href="<%= dc_path(dc) %>"><%= t(:dc_page) %></a>
|
|
<form method="dialog"><button><%= t(:close) %></button></form>
|
|
</div>
|
|
</div>
|
|
</dialog>
|
|
<% end %>
|
|
|
|
<script>
|
|
// Cells are links to the datacenter pages; a plain click opens the dialog
|
|
// instead, modified clicks (new tab etc.) keep the link.
|
|
document.querySelectorAll('[data-dlg]').forEach(a => a.addEventListener('click', e => {
|
|
if (e.button || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
e.preventDefault();
|
|
document.getElementById(a.dataset.dlg).showModal();
|
|
}));
|
|
</script>
|