From c88c23cbacbccdcd8ebc94b2a2cf8a75a2d370f5 Mon Sep 17 00:00:00 2001 From: CyferShepard Date: Tue, 15 Oct 2024 00:03:49 +0200 Subject: [PATCH] centeralized global stat component to be reconfigured and used in multiple places instead of having multiple copies of the same component --- .../{user-info => general}/globalStats.jsx | 10 +-- .../globalstats/watchtimestats.jsx | 0 src/pages/components/item-info.jsx | 12 ++- .../components/item-info/globalStats.jsx | 73 ------------------- .../item-info/globalstats/watchtimestats.jsx | 61 ---------------- src/pages/components/library-info.jsx | 9 ++- .../library/globalstats/watchtimestats.jsx | 64 ---------------- .../components/library/library-stats.jsx | 73 ------------------- src/pages/components/user-info.jsx | 11 ++- 9 files changed, 28 insertions(+), 285 deletions(-) rename src/pages/components/{user-info => general}/globalStats.jsx (93%) rename src/pages/components/{user-info => general}/globalstats/watchtimestats.jsx (100%) delete mode 100644 src/pages/components/item-info/globalStats.jsx delete mode 100644 src/pages/components/item-info/globalstats/watchtimestats.jsx delete mode 100644 src/pages/components/library/globalstats/watchtimestats.jsx delete mode 100644 src/pages/components/library/library-stats.jsx diff --git a/src/pages/components/user-info/globalStats.jsx b/src/pages/components/general/globalStats.jsx similarity index 93% rename from src/pages/components/user-info/globalStats.jsx rename to src/pages/components/general/globalStats.jsx index e98d137..a2c2acb 100644 --- a/src/pages/components/user-info/globalStats.jsx +++ b/src/pages/components/general/globalStats.jsx @@ -21,10 +21,10 @@ function GlobalStats(props) { function fetchStats(hours = 24, setMethod = setDayStats) { axios .post( - `/stats/getGlobalUserStats`, + `/stats/${props.endpoint ?? "getGlobalUserStats"}`, { hours: hours, - userid: props.UserId, + [props.param]: props.id, }, { headers: { @@ -55,13 +55,11 @@ function GlobalStats(props) { fetchData(); const intervalId = setInterval(fetchData, 60000 * 5); return () => clearInterval(intervalId); - }, [props.UserId, token]); + }, [props.id, token]); return (
-

- -

+

{props.title}

{!prefs.includes("1") && } />} {!prefs.includes("7") && } />} diff --git a/src/pages/components/user-info/globalstats/watchtimestats.jsx b/src/pages/components/general/globalstats/watchtimestats.jsx similarity index 100% rename from src/pages/components/user-info/globalstats/watchtimestats.jsx rename to src/pages/components/general/globalstats/watchtimestats.jsx diff --git a/src/pages/components/item-info.jsx b/src/pages/components/item-info.jsx index 70bacec..d88f229 100644 --- a/src/pages/components/item-info.jsx +++ b/src/pages/components/item-info.jsx @@ -10,7 +10,6 @@ import ExternalLinkFillIcon from "remixicon-react/ExternalLinkFillIcon"; import ArchiveDrawerFillIcon from "remixicon-react/ArchiveDrawerFillIcon"; import ArrowLeftSLineIcon from "remixicon-react/ArrowLeftSLineIcon"; -import GlobalStats from "./item-info/globalStats"; import "../css/items/item-details.css"; import MoreItems from "./item-info/more-items"; @@ -27,6 +26,7 @@ import FilmLineIcon from "remixicon-react/FilmLineIcon"; import FileMusicLineIcon from "remixicon-react/FileMusicLineIcon"; import CheckboxMultipleBlankLineIcon from "remixicon-react/CheckboxMultipleBlankLineIcon"; import baseUrl from "../../lib/baseurl"; +import GlobalStats from "./general/globalStats"; function ItemInfo() { const { Id } = useParams(); @@ -208,7 +208,8 @@ function ItemInfo() { - + } + /> {["Series", "Season"].includes(data && data.Type) ? : <>} diff --git a/src/pages/components/item-info/globalStats.jsx b/src/pages/components/item-info/globalStats.jsx deleted file mode 100644 index 3034928..0000000 --- a/src/pages/components/item-info/globalStats.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import { useState, useEffect } from "react"; -import axios from "../../../lib/axios_instance"; -import "../../css/globalstats.css"; - -import WatchTimeStats from "./globalstats/watchtimestats"; -import { Trans } from "react-i18next"; - -function GlobalStats(props) { - const [dayStats, setDayStats] = useState({}); - const [weekStats, setWeekStats] = useState({}); - const [monthStats, setMonthStats] = useState({}); - const [d180Stats, setd180Stats] = useState({}); - const [d365Stats, setd365Stats] = useState({}); - const [allStats, setAllStats] = useState({}); - const token = localStorage.getItem("token"); - - function fetchStats(hours = 24, setMethod = setDayStats) { - axios - .post( - `/stats/getGlobalItemStats`, - { - hours: hours, - itemid: props.ItemId, - }, - { - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - } - ) - .then((dayData) => { - setMethod(dayData.data); - }); - } - - useEffect(() => { - const fetchData = async () => { - try { - fetchStats(24, setDayStats); - fetchStats(24 * 7, setWeekStats); - fetchStats(24 * 30, setMonthStats); - fetchStats(24 * 180, setd180Stats); - fetchStats(24 * 365, setd365Stats); - fetchStats(24 * 999, setAllStats); - } catch (error) { - console.log(error); - } - }; - - fetchData(); - const intervalId = setInterval(fetchData, 60000 * 5); - return () => clearInterval(intervalId); - }, [props.ItemId, token]); - - return ( -
-

- -

-
- } /> - } /> - } /> - } /> - } /> - } /> -
-
- ); -} - -export default GlobalStats; diff --git a/src/pages/components/item-info/globalstats/watchtimestats.jsx b/src/pages/components/item-info/globalstats/watchtimestats.jsx deleted file mode 100644 index b7f95c7..0000000 --- a/src/pages/components/item-info/globalstats/watchtimestats.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import "../../../css/globalstats.css"; -import i18next from "i18next"; -import { Trans } from "react-i18next"; - -function WatchTimeStats(props) { - function formatTime(totalSeconds, numberClassName, labelClassName) { - const units = [ - { label: "UNITS.DAY", seconds: 86400 }, - { label: "UNITS.HOUR", seconds: 3600 }, - { label: "UNITS.MINUTE", seconds: 60 }, - ]; - - const parts = units.reduce((result, { label, seconds }) => { - const value = Math.floor(totalSeconds / seconds); - if (value) { - const formattedValue =

{value}

; - const labelPlural = label.toUpperCase() + "S"; - const formattedLabel = {value === 1 ? i18next.t(label) : i18next.t(labelPlural)}; - result.push( - - {formattedValue} {formattedLabel} - - ); - totalSeconds -= value * seconds; - } - return result; - }, []); - - if (parts.length === 0) { - return ( - <> -

0

{" "} -

- -

- - ); - } - - return parts; - } - - return ( -
-
-
{props.heading}
-
- -
-

{props.data.Plays || 0}

-

- / -

- - <>{formatTime(props.data.total_playback_duration || 0, "stat-value", "stat-unit")} -
-
- ); -} - -export default WatchTimeStats; diff --git a/src/pages/components/library-info.jsx b/src/pages/components/library-info.jsx index 320d4ab..9ac9d23 100644 --- a/src/pages/components/library-info.jsx +++ b/src/pages/components/library-info.jsx @@ -6,7 +6,6 @@ import FilmLineIcon from "remixicon-react/FilmLineIcon"; // import LibraryDetails from './library/library-details'; import Loading from "./general/loading"; -import LibraryGlobalStats from "./library/library-stats"; import LibraryLastWatched from "./library/last-watched"; import RecentlyAdded from "./library/recently-added"; import LibraryActivity from "./library/library-activity"; @@ -16,6 +15,7 @@ import ErrorBoundary from "./general/ErrorBoundary"; import { Tabs, Tab, Button, ButtonGroup } from "react-bootstrap"; import { Trans } from "react-i18next"; import LibraryOptions from "./library/library-options"; +import GlobalStats from "./general/globalStats"; function LibraryInfo() { const { LibraryId } = useParams(); @@ -103,7 +103,12 @@ function LibraryInfo() {
- + } + /> {!data.archived && ( diff --git a/src/pages/components/library/globalstats/watchtimestats.jsx b/src/pages/components/library/globalstats/watchtimestats.jsx deleted file mode 100644 index 075e509..0000000 --- a/src/pages/components/library/globalstats/watchtimestats.jsx +++ /dev/null @@ -1,64 +0,0 @@ -import "../../../css/globalstats.css"; -import i18next from "i18next"; -import { Trans } from "react-i18next"; - -function WatchTimeStats(props) { - - function formatTime(totalSeconds, numberClassName, labelClassName) { - const units = [ - { label: [i18next.t("UNITS.DAY"),i18next.t("UNITS.DAYS")], seconds: 86400 }, - { label: [i18next.t("UNITS.HOUR"),i18next.t("UNITS.HOURS")], seconds: 3600 }, - { label: [i18next.t("UNITS.MINUTE"),i18next.t("UNITS.MINUTES")], seconds: 60 }, - ]; - - const parts = units.reduce((result, { label, seconds }) => { - const value = Math.floor(totalSeconds / seconds); - if (value) { - const formattedValue =

{value}

; - const formattedLabel = ( - - {value === 1 ? label[0] : label[1] } - - ); - result.push( - - {formattedValue} {formattedLabel} - - ); - totalSeconds -= value * seconds; - } - return result; - }, []); - - if (parts.length === 0) { - return ( - <> -

0

{' '} -

- - ); - } - - return parts; - } - - - - return ( -
-
-
{props.heading}
-
- -
-

{props.data.Plays || 0}

-

/

- - <>{formatTime(props.data.total_playback_duration || 0,'stat-value','stat-unit')} - -
-
- ); -} - -export default WatchTimeStats; diff --git a/src/pages/components/library/library-stats.jsx b/src/pages/components/library/library-stats.jsx deleted file mode 100644 index dcd1ee5..0000000 --- a/src/pages/components/library/library-stats.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import { useState, useEffect } from "react"; -import axios from "../../../lib/axios_instance"; -import "../../css/globalstats.css"; - -import WatchTimeStats from "./globalstats/watchtimestats"; -import { Trans } from "react-i18next"; - -function LibraryGlobalStats(props) { - const [dayStats, setDayStats] = useState({}); - const [weekStats, setWeekStats] = useState({}); - const [monthStats, setMonthStats] = useState({}); - const [d180Stats, setd180Stats] = useState({}); - const [d365Stats, setd365Stats] = useState({}); - const [allStats, setAllStats] = useState({}); - const token = localStorage.getItem("token"); - - function fetchStats(hours = 24, setMethod = setDayStats) { - axios - .post( - `/stats/getGlobalLibraryStats`, - { - hours: hours, - libraryid: props.LibraryId, - }, - { - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - } - ) - .then((dayData) => { - setMethod(dayData.data); - }); - } - - useEffect(() => { - const fetchData = async () => { - try { - fetchStats(24, setDayStats); - fetchStats(24 * 7, setWeekStats); - fetchStats(24 * 30, setMonthStats); - fetchStats(24 * 180, setd180Stats); - fetchStats(24 * 365, setd365Stats); - fetchStats(24 * 999, setAllStats); - } catch (error) { - console.log(error); - } - }; - - fetchData(); - const intervalId = setInterval(fetchData, 60000 * 5); - return () => clearInterval(intervalId); - }, [props.LibraryId, token]); - - return ( -
-

- -

-
- } /> - } /> - } /> - } /> - } /> - } /> -
-
- ); -} - -export default LibraryGlobalStats; diff --git a/src/pages/components/user-info.jsx b/src/pages/components/user-info.jsx index 5010407..15c6f38 100644 --- a/src/pages/components/user-info.jsx +++ b/src/pages/components/user-info.jsx @@ -5,12 +5,12 @@ import AccountCircleFillIcon from "remixicon-react/AccountCircleFillIcon"; import Config from "../../lib/config"; import { Tabs, Tab, Button, ButtonGroup } from "react-bootstrap"; -import GlobalStats from "./user-info/globalStats"; import LastPlayed from "./user-info/lastplayed"; import UserActivity from "./user-info/user-activity"; import "../css/users/user-details.css"; import { Trans } from "react-i18next"; import baseUrl from "../../lib/baseurl"; +import GlobalStats from "./general/globalStats"; function UserInfo() { const { UserId } = useParams(); @@ -77,7 +77,7 @@ function UserInfo() { ) : ( @@ -109,7 +109,12 @@ function UserInfo() { - + } + />