admin: dashboard instead of the invoice list

/admin redirected to the invoice list, which stopped making sense once
the admin also ran the bingo. Make it a dashboard with one tile per
area: invoice totals, outstanding amount per currency, overdue count and
the five latest invoices; the bingo score, reserve size, latest incident
and card cells still missing a photo. A shared nav links the sections.
Tiles are per area so they can follow user permissions later.

Assisted-by: Claude:opus-5
This commit is contained in:
Sergei Poljanski 2026-10-10 08:23:14 +04:00
commit c2020bf903
Signed by: asxpi
GPG key ID: 4F8851660FA4121B
8 changed files with 134 additions and 5 deletions

View file

@ -253,6 +253,30 @@ class BingoTest < Minitest::Test
assert_equal 401, last_response.status
end
def test_admin_dashboard
@app = AsxpioWeb
hit!(2)
DB.connection[:invoices].delete
inv = Invoice.build(client_name: 'ACME', client_email: 'b@example.com', currency: 'EUR', gel_rate: '3.05',
due_on: (Date.today - 1).to_s,
items: [{ 'description' => 'work', 'qty' => '2', 'unit_price' => '50' }])
inv.pdf_key = "invoices/#{inv.number}-#{inv.uuid}.pdf"
inv.save_changes
get '/admin', {}, admin_env
assert last_response.ok?, last_response.status.to_s
body = last_response.body
assert_includes body, '<h1>Dashboard</h1>'
assert_includes body, '1/25' # crossed out
assert_includes body, 'Авария 2' # latest incident
assert_includes body, 'href="/admin/invoices/new"'
assert_includes body, 'class="active">dashboard'
assert_includes body, inv.number
assert_includes body, 'EUR 100.00' # outstanding total
assert_match %r{<b>1</b><span>overdue</span>}, body
ensure
DB.connection[:invoices].delete
end
def test_admin_records_and_deletes_incident
@app = AsxpioWeb
get '/admin/bingo', {}, admin_env