Skip to main content

max / goingson

2.3 KB · 79 lines History Blame Raw
1 //! Dashboard statistics commands.
2 //!
3 //! Provides aggregated statistics for the dashboard view including
4 //! overdue tasks, upcoming events, and high-urgency items.
5
6 use serde::Serialize;
7 use std::sync::Arc;
8 use tauri::State;
9 use tracing::instrument;
10
11 use goingson_core::DashboardStats;
12
13 use crate::state::{AppState, DESKTOP_USER_ID};
14 use super::ApiError;
15
16 // ============ Types ============
17
18 #[derive(Debug, Serialize)]
19 #[serde(rename_all = "camelCase")]
20 pub struct DashboardStatsResponse {
21 pub overdue_count: i64,
22 pub due_today_count: i64,
23 pub due_this_week_count: i64,
24 pub unread_emails: i64,
25 pub upcoming_events: i64,
26 pub active_projects: i64,
27 pub high_urgency_tasks: Vec<HighUrgencyTaskResponse>,
28 }
29
30 #[derive(Debug, Serialize)]
31 #[serde(rename_all = "camelCase")]
32 pub struct HighUrgencyTaskResponse {
33 pub id: String,
34 pub description: String,
35 pub urgency: f64,
36 pub status: String,
37 pub due: Option<String>,
38 }
39
40 impl From<DashboardStats> for DashboardStatsResponse {
41 fn from(s: DashboardStats) -> Self {
42 DashboardStatsResponse {
43 overdue_count: s.overdue_count,
44 due_today_count: s.tasks_due_today,
45 due_this_week_count: s.tasks_due_this_week,
46 unread_emails: s.unread_emails,
47 upcoming_events: s.upcoming_events,
48 active_projects: s.active_projects,
49 high_urgency_tasks: s.high_urgency_tasks
50 .into_iter()
51 .map(|t| HighUrgencyTaskResponse {
52 id: t.id,
53 description: t.description,
54 urgency: t.urgency,
55 status: t.status,
56 due: t.due,
57 })
58 .collect(),
59 }
60 }
61 }
62
63 // ============ Commands ============
64
65 /// Retrieves aggregated statistics for the dashboard.
66 ///
67 /// Returns counts for overdue tasks, tasks due today/this week, unread emails,
68 /// upcoming events, active projects, and a list of high-urgency tasks.
69 ///
70 /// # Errors
71 ///
72 /// Returns `DATABASE_ERROR` if the query fails.
73 #[tauri::command]
74 #[instrument(skip_all)]
75 pub async fn get_dashboard_stats(state: State<'_, Arc<AppState>>) -> Result<DashboardStatsResponse, ApiError> {
76 let stats = state.stats.get_dashboard_stats(DESKTOP_USER_ID).await?;
77 Ok(DashboardStatsResponse::from(stats))
78 }
79