From 4a0ec0391d7ca99c0f3402f4a70a2c852c8bdad7 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Thu, 8 Jun 2023 18:16:00 -0500 Subject: [PATCH] stats board --- .../migrations/20230608093603_initial.sql | 5 +- src-tauri/src/srs.rs | 41 +++++++++++-- .../DashboardReviewStats.module.scss | 7 +++ src/components/DashboardReviewStats.tsx | 59 ++++++++++++++++++- src/components/KanjiDisplay.module.scss | 1 + src/panes/SrsPane.tsx | 8 ++- 6 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 src/components/DashboardReviewStats.module.scss diff --git a/src-tauri/migrations/20230608093603_initial.sql b/src-tauri/migrations/20230608093603_initial.sql index b8a3c20..2fbf5b8 100644 --- a/src-tauri/migrations/20230608093603_initial.sql +++ b/src-tauri/migrations/20230608093603_initial.sql @@ -1,4 +1,4 @@ -CREATE TABLE [SrsEntrySet] ( +CREATE TABLE IF NOT EXISTS [SrsEntrySet] ( [ID] integer NOT NULL PRIMARY KEY AUTOINCREMENT, [CreationDate] bigint NOT NULL DEFAULT CURRENT_TIMESTAMP, [NextAnswerDate] bigint, @@ -15,4 +15,5 @@ CREATE TABLE [SrsEntrySet] ( [Tags] [nvarchar(300)], [LastUpdateDate] BIGINT, [IsDeleted] BOOLEAN NOT NULL DEFAULT false, - [ServerId] integer); \ No newline at end of file + [ServerId] integer +); \ No newline at end of file diff --git a/src-tauri/src/srs.rs b/src-tauri/src/srs.rs index a55ba0b..c4cb1f6 100644 --- a/src-tauri/src/srs.rs +++ b/src-tauri/src/srs.rs @@ -1,9 +1,42 @@ -use sqlx::SqlitePool; +use sqlx::{Row, SqlitePool}; use tauri::State; pub struct SrsDb(pub SqlitePool); -#[tauri::command] -pub async fn get_srs_stats(db: State<'_, SrsDb>) -> Result<(), ()> { - Ok(()) +#[derive(Debug, Serialize, Deserialize)] +pub struct SrsStats { + reviews_available: u32, + + reviews_today: u32, + total_items: u32, + total_reviews: u32, + + /// Used to calculate average success + num_success: u32, + num_failure: u32, +} + +#[tauri::command] +pub async fn get_srs_stats(db: State<'_, SrsDb>) -> Result { + let row = sqlx::query( + r#" + SELECT + COUNT(*) AS total_items, + SUM(SuccessCount) AS num_success, + SUM(FailureCount) AS num_failure + FROM SrsEntrySet + "#, + ) + .fetch_one(&db.0) + .await + .map_err(|err| err.to_string())?; + + Ok(SrsStats { + reviews_available: 0, + reviews_today: 0, + total_items: row.get("total_items"), + total_reviews: 0, + num_success: row.get("num_success"), + num_failure: row.get("num_failure"), + }) } diff --git a/src/components/DashboardReviewStats.module.scss b/src/components/DashboardReviewStats.module.scss new file mode 100644 index 0000000..b265a2f --- /dev/null +++ b/src/components/DashboardReviewStats.module.scss @@ -0,0 +1,7 @@ +.top-row { +} + +.reviews-stats { + background-color: gray; + color: white; +} diff --git a/src/components/DashboardReviewStats.tsx b/src/components/DashboardReviewStats.tsx index d79e5eb..51920e5 100644 --- a/src/components/DashboardReviewStats.tsx +++ b/src/components/DashboardReviewStats.tsx @@ -1,3 +1,58 @@ -export default function DashboardReviewStats() { - return <>; +import { + Grid, + GridItem, + Stat, + StatArrow, + StatGroup, + StatHelpText, + StatLabel, + StatNumber, +} from "@chakra-ui/react"; +import styles from "./DashboardReviewStats.module.scss"; +import useSWR from "swr"; +import { invoke } from "@tauri-apps/api/tauri"; + +interface SrsStats { + reviews_available: number; + + reviews_today: number; + total_items: number; + total_reviews: number; + + /// Used to calculate average success + num_success: number; + num_failure: number; +} + +export default function DashboardReviewStats() { + const { + data: srsStats, + error, + isLoading, + } = useSWR(["get_srs_stats"], ([command]) => invoke(command)); + + if (!srsStats) return <>Loading...; + + const averageSuccess = srsStats.num_success / (srsStats.num_success + srsStats.num_failure); + const averageSuccessStr = `${Math.round(averageSuccess * 10000) / 100}%`; + + const generateStat = (stat) => { + return ( + + {stat.label} + {stat.value} + + ); + }; + + return ( + <> + {/* JSON.stringify([srsStats, error, isLoading]) */} + + + {generateStat({ label: "total items", value: srsStats.total_items })} + {generateStat({ label: "average success", value: averageSuccessStr })} + + + ); } diff --git a/src/components/KanjiDisplay.module.scss b/src/components/KanjiDisplay.module.scss index 01b9844..d5e34e2 100644 --- a/src/components/KanjiDisplay.module.scss +++ b/src/components/KanjiDisplay.module.scss @@ -4,6 +4,7 @@ $kanjiDisplaySize: 80px; border: 1px solid rgb(87, 87, 210); width: $kanjiDisplaySize; height: $kanjiDisplaySize; + line-height: $kanjiDisplaySize; font-size: $kanjiDisplaySize * 0.8; text-align: center; vertical-align: middle; diff --git a/src/panes/SrsPane.tsx b/src/panes/SrsPane.tsx index fde7e52..db99c5c 100644 --- a/src/panes/SrsPane.tsx +++ b/src/panes/SrsPane.tsx @@ -1,3 +1,9 @@ +import DashboardReviewStats from "../components/DashboardReviewStats"; + export default function SrsPane() { - return <>; + return ( +
+ +
+ ); }