yggdrasil/api/posts/
stats.rs1use dioxus::prelude::*;
8
9#[cfg(feature = "server")]
10use super::helpers::get_current_admin_user;
11use super::types::PostStatsResponse;
12#[cfg(feature = "server")]
13use crate::api::error::AppError;
14#[cfg(feature = "server")]
15use crate::db::pool::get_conn;
16#[cfg(feature = "server")]
17use crate::models::post::PostStats;
18
19#[server(GetPostStats, "/api")]
24pub async fn get_post_stats() -> Result<PostStatsResponse, ServerFnError> {
25 let _user = get_current_admin_user().await?;
26
27 #[cfg(feature = "server")]
28 {
29 if let Some(cached) = crate::cache::get_post_stats().await {
30 return Ok(PostStatsResponse { stats: cached });
31 }
32
33 let client = get_conn().await.map_err(AppError::db_conn)?;
34
35 let row = client
37 .query_one(
38 "SELECT
39 COUNT(*) FILTER (WHERE deleted_at IS NULL) AS total,
40 COUNT(*) FILTER (WHERE deleted_at IS NULL AND status = 'draft') AS drafts,
41 COUNT(*) FILTER (WHERE deleted_at IS NULL AND status = 'published') AS published,
42 COUNT(*) FILTER (WHERE deleted_at IS NOT NULL) AS trash
43 FROM posts",
44 &[],
45 )
46 .await
47 .map_err(AppError::query)?;
48
49 let stats = PostStats {
50 total: row.get("total"),
51 drafts: row.get("drafts"),
52 published: row.get("published"),
53 trash: row.get("trash"),
54 };
55 crate::cache::set_post_stats(stats.clone()).await;
56 Ok(PostStatsResponse { stats })
57 }
58
59 #[cfg(not(feature = "server"))]
60 {
61 Ok(PostStatsResponse {
62 stats: PostStats {
63 total: 0,
64 drafts: 0,
65 published: 0,
66 trash: 0,
67 },
68 })
69 }
70}