From 955b18b53334e95a3c168875a7745d3d76f4ef15 Mon Sep 17 00:00:00 2001 From: Domenic Horner Date: Tue, 31 Oct 2023 21:20:14 +0800 Subject: [PATCH 1/4] dashboard work --- package-lock.json | 29 ++ package.json | 2 + src/App.jsx | 22 + src/components/Dashboard/StatCards.jsx | 565 +++++++++++++++++++++++++ src/components/SiteHeader.jsx | 42 +- src/hooks/useLVQueryCache.js | 31 ++ src/pages/Dashboard.jsx | 143 +++++++ 7 files changed, 829 insertions(+), 5 deletions(-) create mode 100644 src/components/Dashboard/StatCards.jsx create mode 100644 src/hooks/useLVQueryCache.js create mode 100644 src/pages/Dashboard.jsx diff --git a/package-lock.json b/package-lock.json index 938df41..ac4e018 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "@reduxjs/toolkit": "^1.9.7", "@tanstack/react-query": "^5.4.3", "@tanstack/react-query-devtools": "^5.4.3", + "axios": "^1.6.0", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", @@ -34,6 +35,7 @@ "react-dom": "^18.2.0", "react-intersection-observer": "^9.5.2", "react-moment": "^1.1.3", + "react-number-format": "^5.3.1", "react-redux": "^8.1.1", "react-router-dom": "^6.17.0", "redux": "^4.2.1", @@ -3128,6 +3130,16 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", @@ -6834,6 +6846,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -6959,6 +6976,18 @@ "react": "^16.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-number-format": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.3.1.tgz", + "integrity": "sha512-qpYcQLauIeEhCZUZY9jXZnnroOtdy3jYaS1zQ3M1Sr6r/KMOBEIGNIb7eKT19g2N1wbYgFgvDzs19hw5TrB8XQ==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-redux": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", diff --git a/package.json b/package.json index d01323f..97e875b 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@reduxjs/toolkit": "^1.9.7", "@tanstack/react-query": "^5.4.3", "@tanstack/react-query-devtools": "^5.4.3", + "axios": "^1.6.0", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", @@ -39,6 +40,7 @@ "react-dom": "^18.2.0", "react-intersection-observer": "^9.5.2", "react-moment": "^1.1.3", + "react-number-format": "^5.3.1", "react-redux": "^8.1.1", "react-router-dom": "^6.17.0", "redux": "^4.2.1", diff --git a/src/App.jsx b/src/App.jsx index 3c1764a..07efe35 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -17,6 +17,7 @@ import { Toaster, toast } from "sonner"; import SiteHeader from "./components/SiteHeader"; +import Dashboard from "./pages/Dashboard"; import Actions from "./pages/Actions"; import Approvals from "./pages/Approvals"; import Reports from "./pages/Reports"; @@ -99,6 +100,27 @@ function PageRouter() { + + + + + } + /> + + {iconClone && ( + + {iconClone} + + )} + + {title} + + {value} + + {description && {description}} + + + ); +} + +export function ReportsStat({ title, value, icon = false, color = "primary", description = "", sx = {} }) { + const { + isLoading: reportCountsLoading, + isFetching: reportCountsFetching, + error: reportCountsError, + data: reportCountsData, + } = useLemmyHttp("getReportCount"); + + const totalReports = + reportCountsData?.post_reports + + reportCountsData?.comment_reports + + reportCountsData?.private_message_reports; + + //loading + if (reportCountsLoading) { + return ( + + + Counts Loading.... + + + + + + ); + } + + return ( + 0 ? "danger" : "success"} + orientation="horizontal" + sx={{ + ...sx, + borderRadius: "8px", + display: "flex", + flexDirection: "column", + + // justifyContent: "center", + alignItems: "center", + + // space aroudn + // justifyContent: "space-between", + + maxWidth: "100%", + width: "100%", + overflow: "hidden", + }} + > + + Content Reports + + + + 0 ? "danger" : "success"} + sx={{ display: "flex", alignItems: "center", gap: 1 }} + > + {reportCountsData?.post_reports} + + 0 ? "danger" : "success"} + sx={{ display: "flex", alignItems: "center", gap: 1 }} + > + {reportCountsData?.comment_reports} + + 0 ? "danger" : "success"} + sx={{ display: "flex", alignItems: "center", gap: 1 }} + > + {reportCountsData?.private_message_reports} + + {/* */} + + + ); +} + +export function ApprovalStat({ title, value, icon = false, color = "primary", description = "", sx = {} }) { + const { + isLoading: regAppCountIsLoading, + isFetching: regAppCountIsFetching, + error: regCountAppError, + data: regCountAppData, + } = useLemmyHttp("getUnreadRegistrationApplicationCount"); + + //loading + if (regAppCountIsLoading) { + return ( + + + Counts Loading.... + + + + + + ); + } + + return ( + 0 ? "danger" : "success"} + orientation="horizontal" + sx={{ + ...sx, + borderRadius: "8px", + display: "flex", + flexDirection: "column", + + // justifyContent: "center", + alignItems: "center", + + // space aroudn + // justifyContent: "space-between", + + maxWidth: "100%", + width: "100%", + overflow: "hidden", + }} + > + + Pending Registrations + + + + 0 ? "danger" : "success"} + sx={{ display: "flex", alignItems: "center", gap: 1 }} + > + {regCountAppData?.registration_applications} + + + + ); +} + +export function UserStat({ title, value, icon = false, color = "primary", description = "", sx = {} }) { + const { baseUrl, siteData, localPerson, userRole } = getSiteData(); + + return ( + 0 ? "danger" : "success"} + orientation="horizontal" + sx={{ + ...sx, + borderRadius: "8px", + display: "flex", + flexDirection: "column", + + // justifyContent: "center", + alignItems: "center", + + // space aroudn + // justifyContent: "space-between", + + maxWidth: "100%", + width: "100%", + overflow: "hidden", + }} + > + + User Stats + + + + 0 ? "danger" : "success"} + sx={{ display: "flex", alignItems: "center", gap: 1 }} + > + 123123 + + + + ); +} + +export function SiteStat({ title, value, icon = false, color = "primary", description = "", sx = {} }) { + const { baseUrl, siteData, localPerson, userRole } = getSiteData(); + + console.log("siteData", siteData); + + return ( + 0 ? "danger" : "success"} + orientation="horizontal" + sx={{ + ...sx, + borderRadius: "8px", + display: "flex", + flexDirection: "column", + + // justifyContent: "center", + alignItems: "center", + + // space aroudn + // justifyContent: "space-between", + + maxWidth: "100%", + width: "100%", + overflow: "hidden", + }} + > + + Site Config + + + + 0 ? "danger" : "success"} + sx={{ display: "flex", alignItems: "center", gap: 1 }} + > + 123123 + + + + ); +} + +export function NumberStat({ value, ...props }) { + return } />; +} + +export const SimpleNumberFormat = React.memo(({ value }) => { + return ; +}); + +export const TinyNumber = React.memo(({ value }) => { + const number = React.useMemo(() => { + if (value >= 1000000) { + return (value / 1000000).toFixed(1).replace(/\.0$/, "") + "m"; + } + if (value >= 1000) { + return (value / 1000).toFixed(1).replace(/\.0$/, "") + "k"; + } + return value; + }, [value]); + + return {number}; +}); diff --git a/src/components/SiteHeader.jsx b/src/components/SiteHeader.jsx index a8f2f18..6e0b3df 100644 --- a/src/components/SiteHeader.jsx +++ b/src/components/SiteHeader.jsx @@ -33,7 +33,7 @@ import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import VerifiedUserIcon from "@mui/icons-material/VerifiedUser"; import SupervisedUserCircleIcon from "@mui/icons-material/SupervisedUserCircle"; import AccountBoxIcon from "@mui/icons-material/AccountBox"; - +import DashboardIcon from "@mui/icons-material/Dashboard"; import SwitchAccountIcon from "@mui/icons-material/SwitchAccount"; import GitHubIcon from "@mui/icons-material/GitHub"; @@ -89,14 +89,46 @@ function SiteMenu() { return ( <> + + + + {userRole != "user" && (