//! Admin dashboard (HTML home + JSON stats).
use axum_extra::extract::cookie::CookieJar;
use loco_rs::prelude::*;
use sea_orm::{EntityTrait, PaginatorTrait};
use serde::Serialize;
use serde_json::json;
use crate::{controllers::i18n::current_lang, models::_entities, shared::guard};
#[derive(Debug, Serialize)]
struct DashboardResponse {
users: u64,
products: u64,
categories: u64,
orders: u64,
audit_logs: u64,
}
/// JSON dashboard stats, served under `/api/admin`.
#[debug_handler]
async fn dashboard_json(auth: auth::JWT, State(ctx): State) -> Result {
guard::current_admin(auth, &ctx).await?;
format::json(DashboardResponse {
users: _entities::users::Entity::find().count(&ctx.db).await?,
products: _entities::products::Entity::find().count(&ctx.db).await?,
categories: _entities::categories::Entity::find().count(&ctx.db).await?,
orders: _entities::orders::Entity::find().count(&ctx.db).await?,
audit_logs: _entities::audit_logs::Entity::find().count(&ctx.db).await?,
})
}
/// HTML admin home page.
#[debug_handler]
async fn dashboard_page(
auth: auth::JWT,
jar: CookieJar,
ViewEngine(v): ViewEngine,
State(ctx): State,
) -> Result {
let admin_user = guard::current_admin(auth, &ctx).await?;
format::view(
&v,
"admin/index.html",
json!({ "admin": admin_user, "lang": current_lang(&jar) }),
)
}
pub fn routes() -> Routes {
Routes::new()
.add("/admin/dashboard", get(dashboard_page))
.add("/api/admin/dashboard", get(dashboard_json))
}