yggdrasil/api/
admin_stats.rs1#![allow(clippy::unused_unit, deprecated)]
8
9use crate::api::error::ApiError;
10use leptos::prelude::*;
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
15pub struct AdminNavCounts {
16 pub posts: i64,
18 pub assets: i64,
20 pub comments: i64,
22 pub pending_comments: i64,
24}
25
26#[server(GetAdminNavCounts, endpoint = "get_admin_nav_counts", input = leptos::server_fn::codec::Json)]
28pub async fn get_admin_nav_counts() -> Result<AdminNavCounts, ApiError> {
29 #[cfg(feature = "server")]
30 {
31 use crate::api::error::AppError;
32 use crate::db::pool::get_conn;
33
34 crate::api::auth::get_current_admin_user().await?;
35 let stats = crate::api::posts::load_post_stats().await?;
36
37 let client = get_conn().await.map_err(AppError::db_conn)?;
38 let row = client
39 .query_one(
40 "SELECT
41 (SELECT COUNT(*) FROM assets) AS assets,
42 (SELECT COUNT(*) FROM comments
43 WHERE deleted_at IS NULL AND status IN ('pending', 'approved')) AS comments",
44 &[],
45 )
46 .await
47 .map_err(AppError::query)?;
48
49 let pending_comments = match crate::cache::get_pending_count().await {
50 Some(count) => count,
51 None => {
52 let count: i64 = client
53 .query_one(
54 "SELECT COUNT(*) FROM comments WHERE status = 'pending' AND deleted_at IS NULL",
55 &[],
56 )
57 .await
58 .map_err(AppError::query)?
59 .get(0);
60 crate::cache::set_pending_count(count).await;
61 count
62 }
63 };
64
65 Ok(AdminNavCounts {
66 posts: stats.total,
67 assets: row.get("assets"),
68 comments: row.get("comments"),
69 pending_comments,
70 })
71 }
72 #[cfg(not(feature = "server"))]
73 unreachable!()
74}