yggdrasil/api/comments/
list.rs1use crate::api::comments::types::*;
7use dioxus::prelude::*;
8
9#[server(GetPendingCount, "/api")]
13pub async fn get_pending_count() -> Result<PendingCountResponse, ServerFnError> {
14 #[cfg(feature = "server")]
15 {
16 use crate::api::auth::get_current_admin_user;
17 use crate::api::error::AppError;
18 use crate::cache;
19 use crate::db::pool::get_conn;
20
21 let _admin = get_current_admin_user().await?;
22
23 if let Some(cached) = cache::get_pending_count().await {
24 return Ok(PendingCountResponse { count: cached });
25 }
26
27 let client = get_conn().await.map_err(AppError::db_conn)?;
28
29 let count: i64 = client
30 .query_one(
31 "SELECT COUNT(*) FROM comments WHERE status = 'pending' AND deleted_at IS NULL",
32 &[],
33 )
34 .await
35 .map_err(AppError::query)?
36 .get(0);
37
38 cache::set_pending_count(count).await;
39
40 Ok(PendingCountResponse { count })
41 }
42 #[cfg(not(feature = "server"))]
43 unreachable!()
44}
45
46#[server(GetAllComments, "/api")]
50pub async fn get_all_comments(
51 page: i32,
52 status: Option<String>,
53) -> Result<AllCommentsResponse, ServerFnError> {
54 #[cfg(feature = "server")]
55 {
56 use crate::api::auth::get_current_admin_user;
57 use crate::api::comments::helpers::row_to_admin_comment;
58 use crate::api::error::AppError;
59 use crate::db::pool::get_conn;
60
61 let _admin = get_current_admin_user().await?;
62
63 let page = page.max(1);
64 let per_page: i64 = 20;
65 let offset: i64 = (page as i64 - 1) * per_page;
66
67 let client = get_conn().await.map_err(AppError::db_conn)?;
68
69 let (total, rows) = match status.as_deref() {
71 Some(s) if !s.is_empty() => {
72 let total: i64 = client
73 .query_one(
74 "SELECT COUNT(*) FROM comments WHERE status = $1 AND deleted_at IS NULL",
75 &[&s],
76 )
77 .await
78 .map_err(AppError::query)?
79 .get(0);
80
81 let rows = client
82 .query(
83 "SELECT c.id, c.post_id, c.parent_id, c.depth, c.author_name, c.author_email, \
84 c.author_url, c.content_md, c.status, c.created_at, \
85 c.user_id, u.display_name AS user_display_name, u.avatar_url AS user_avatar, \
86 p.title as post_title, p.slug as post_slug \
87 FROM comments c JOIN posts p ON c.post_id = p.id \
88 LEFT JOIN users u ON c.user_id = u.id \
89 WHERE c.status = $1 AND c.deleted_at IS NULL \
90 ORDER BY c.created_at DESC LIMIT $2 OFFSET $3",
91 &[&s, &per_page, &offset],
92 )
93 .await
94 .map_err(AppError::query)?;
95
96 (total, rows)
97 }
98 _ => {
99 let total: i64 = client
100 .query_one(
101 "SELECT COUNT(*) FROM comments WHERE deleted_at IS NULL",
102 &[],
103 )
104 .await
105 .map_err(AppError::query)?
106 .get(0);
107
108 let rows = client
109 .query(
110 "SELECT c.id, c.post_id, c.parent_id, c.depth, c.author_name, c.author_email, \
111 c.author_url, c.content_md, c.status, c.created_at, \
112 c.user_id, u.display_name AS user_display_name, u.avatar_url AS user_avatar, \
113 p.title as post_title, p.slug as post_slug \
114 FROM comments c JOIN posts p ON c.post_id = p.id \
115 LEFT JOIN users u ON c.user_id = u.id \
116 WHERE c.deleted_at IS NULL \
117 ORDER BY c.created_at DESC LIMIT $1 OFFSET $2",
118 &[&per_page, &offset],
119 )
120 .await
121 .map_err(AppError::query)?;
122
123 (total, rows)
124 }
125 };
126
127 let comments = rows.iter().map(row_to_admin_comment).collect();
128
129 Ok(AllCommentsResponse { comments, total })
130 }
131 #[cfg(not(feature = "server"))]
132 unreachable!()
133}