//! Dashboard statistics commands. //! //! Provides aggregated statistics for the dashboard view including //! overdue tasks, upcoming events, and high-urgency items. use serde::Serialize; use std::sync::Arc; use tauri::State; use tracing::instrument; use goingson_core::DashboardStats; use crate::state::{AppState, DESKTOP_USER_ID}; use super::ApiError; // ============ Types ============ #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct DashboardStatsResponse { pub overdue_count: i64, pub due_today_count: i64, pub due_this_week_count: i64, pub unread_emails: i64, pub upcoming_events: i64, pub active_projects: i64, pub high_urgency_tasks: Vec, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct HighUrgencyTaskResponse { pub id: String, pub description: String, pub urgency: f64, pub status: String, pub due: Option, } impl From for DashboardStatsResponse { fn from(s: DashboardStats) -> Self { DashboardStatsResponse { overdue_count: s.overdue_count, due_today_count: s.tasks_due_today, due_this_week_count: s.tasks_due_this_week, unread_emails: s.unread_emails, upcoming_events: s.upcoming_events, active_projects: s.active_projects, high_urgency_tasks: s.high_urgency_tasks .into_iter() .map(|t| HighUrgencyTaskResponse { id: t.id, description: t.description, urgency: t.urgency, status: t.status, due: t.due, }) .collect(), } } } // ============ Commands ============ /// Retrieves aggregated statistics for the dashboard. /// /// Returns counts for overdue tasks, tasks due today/this week, unread emails, /// upcoming events, active projects, and a list of high-urgency tasks. /// /// # Errors /// /// Returns `DATABASE_ERROR` if the query fails. #[tauri::command] #[instrument(skip_all)] pub async fn get_dashboard_stats(state: State<'_, Arc>) -> Result { let stats = state.stats.get_dashboard_stats(DESKTOP_USER_ID).await?; Ok(DashboardStatsResponse::from(stats)) }