use axum::extract::State;
use axum::response::Html;
use std::sync::atomic::Ordering;
use crate::{db, AppState};
use super::{page, err_page, fmt_ts_ago, short_pubkey, esc};
pub async fn handler(State(state): State) -> Html {
match render(&state).await {
Ok(h) => h,
Err(e) => err_page(&e),
}
}
async fn render(state: &AppState) -> anyhow::Result> {
let stats = db::ui_stats(&state.pool).await?;
let relays = db::list_relays_ui(&state.pool).await.unwrap_or_default();
let recent = db::recent_torrents(&state.pool, 12).await.unwrap_or_default();
// Stats row
let last_seen = stats
.last_event_at
.map(|ts| fmt_ts_ago(ts))
.unwrap_or_else(|| "never".into());
let stats_html = format!(
r#"
{}
Indexed
{}
Publishers
{}
Queued
{}
Published
{last_seen}
Last ingest
"#,
stats.torrent_count,
stats.publisher_count,
stats.queued_count,
stats.published_count,
);
// Network status
let network_html = build_network_html(state);
// Relay status
let relay_count = state.relay_count.load(Ordering::Relaxed);
let relay_rows: String = if relays.is_empty() {
"
No relays configured
".into()
} else {
relays
.iter()
.map(|r| {
let (dot, ts_str) = match r.last_event {
Some(ts) => ("dot-ok", format!("last event {}", fmt_ts_ago(ts))),
// "no events yet" is normal on a fresh start — the relay is connected
// but kindexr hasn't received any NIP-35 events from it this session.
None => ("dot-dim", "connected — no events received yet".into()),
};
format!(
r#"