From b4243e694c9d83495cb1a4a152c8f8273641d619 Mon Sep 17 00:00:00 2001 From: Thegan Govender Date: Wed, 7 Feb 2024 21:14:38 +0200 Subject: [PATCH] Added Localisation Framework Converted Below pages to use localization: Navbar Home Page Libraries (Library Overview only) Rest is WIP --- package-lock.json | 135 +++++++++++++++++- package.json | 4 + public/locales/en/translation.json | 72 ++++++++++ src/index.jsx | 6 +- src/lib/navdata.jsx | 18 ++- src/localization.js | 18 +++ src/pages/components/HomeStatisticCards.jsx | 12 +- src/pages/components/general/navbar.jsx | 5 +- src/pages/components/general/version-card.jsx | 5 +- src/pages/components/library/library-card.jsx | 28 ++-- src/pages/components/libraryOverview.jsx | 14 +- .../library-stat-component.jsx | 1 - src/pages/components/sessions/sessions.jsx | 10 +- .../statCards/most_active_users.jsx | 5 +- .../components/statCards/most_used_client.jsx | 5 +- src/pages/components/statCards/mp_movies.jsx | 5 +- src/pages/components/statCards/mp_music.jsx | 5 +- src/pages/components/statCards/mp_series.jsx | 5 +- .../components/statCards/mv_libraries.jsx | 5 +- src/pages/components/statCards/mv_movies.jsx | 5 +- src/pages/components/statCards/mv_music.jsx | 5 +- src/pages/components/statCards/mv_series.jsx | 5 +- src/pages/home.jsx | 2 - src/pages/libraries.jsx | 8 +- 24 files changed, 309 insertions(+), 74 deletions(-) create mode 100644 public/locales/en/translation.json create mode 100644 src/localization.js diff --git a/package-lock.json b/package-lock.json index a97934f..de90b9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jfstat", - "version": "1.0.9", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jfstat", - "version": "1.0.9", + "version": "1.1.0", "dependencies": { "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", @@ -34,6 +34,9 @@ "file-saver": "^2.0.5", "github-api": "^3.4.0", "http-proxy-middleware": "^2.0.6", + "i18next": "^23.8.2", + "i18next-browser-languagedetector": "^7.2.0", + "i18next-http-backend": "^2.4.3", "knex": "^2.4.2", "moment": "^2.29.4", "multer": "^1.4.5-lts.1", @@ -47,6 +50,7 @@ "react-bootstrap": "^2.7.2", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", + "react-i18next": "^14.0.5", "react-router-dom": "^6.8.1", "react-scripts": "5.0.1", "react-toastify": "^9.1.3", @@ -2322,9 +2326,9 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -7998,6 +8002,14 @@ "node": ">=10" } }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", + "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -11026,6 +11038,14 @@ "node": ">= 12" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/html-webpack-plugin": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", @@ -11202,6 +11222,44 @@ "node": ">=10.17.0" } }, + "node_modules/i18next": { + "version": "23.8.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.8.2.tgz", + "integrity": "sha512-Z84zyEangrlERm0ZugVy4bIt485e/H8VecGUZkZWrH7BDePG6jT73QdL9EA1tRTTVVMpry/MgWIP1FjEn0DRXA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.2.0.tgz", + "integrity": "sha512-U00DbDtFIYD3wkWsr2aVGfXGAj2TgnELzOX9qv8bT0aJtvPV9CRO77h+vgmHFBMe7LAxdwvT/7VkCWGya6L3tA==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-http-backend": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.4.3.tgz", + "integrity": "sha512-jo2M03O6n1/DNb51WSQ8PsQ0xEELzLZRdYUTbf17mLw3rVwnJF9hwNgMXvEFSxxb+N8dT+o0vtigA6s5mGWyPA==", + "dependencies": { + "cross-fetch": "4.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -14813,6 +14871,44 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -17853,6 +17949,27 @@ "react": ">=16.3.0" } }, + "node_modules/react-i18next": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.0.5.tgz", + "integrity": "sha512-5+bQSeEtgJrMBABBL5lO7jPdSNAbeAZ+MlFWDw//7FnVacuVu3l9EeWFzBQvZsKy+cihkbThWOAThEdH8YjGEw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -21026,6 +21143,14 @@ } } }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/package.json b/package.json index 5b89010..355b8ca 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,9 @@ "file-saver": "^2.0.5", "github-api": "^3.4.0", "http-proxy-middleware": "^2.0.6", + "i18next": "^23.8.2", + "i18next-browser-languagedetector": "^7.2.0", + "i18next-http-backend": "^2.4.3", "knex": "^2.4.2", "moment": "^2.29.4", "multer": "^1.4.5-lts.1", @@ -54,6 +57,7 @@ "react-bootstrap": "^2.7.2", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", + "react-i18next": "^14.0.5", "react-router-dom": "^6.8.1", "react-scripts": "5.0.1", "react-toastify": "^9.1.3", diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json new file mode 100644 index 0000000..87922c5 --- /dev/null +++ b/public/locales/en/translation.json @@ -0,0 +1,72 @@ +{ + "JELLYSTAT": "Jellystat", + "MENU_TABS": { + "HOME": "Home", + "LIBRARIES": "Libraries", + "USERS": "Users", + "ACTIVITY": "Activity", + "STATISTICS": "Statistics", + "SETTINGS": "Settings", + "ABOUT": "About", + "LOGOUT": "Logout" + }, + "HOME_PAGE": { + "SESSIONS": "Sessions", + "RECENTLY_ADDED": "Recently Added", + "WATCH_STATISTIC": "Watch Statistics", + "LIBRARY_OVERVIEW": "Library Overview" + }, + "SESSIONS":{ + "NO_SESSIONS": "No Active Sessions Found" + }, + "STAT_CARDS": { + "MOST_VIEWED_MOVIES": "MOST VIEWED MOVIES", + "MOST_POPULAR_MOVIES": "MOST POPULAR MOVIES", + "MOST_VIEWED_SERIES": "MOST VIEWED SERIES", + "MOST_POPULAR_SERIES": "MOST POPULAR SERIES", + "MOST_LISTENED_MUSIC": "MOST LISTENED MUSIC", + "MOST_POPULAR_MUSIC": "MOST POPULAR MUSIC", + "MOST_VIEWED_LIBRARIES": "MOST VIEWED LIBRARIES", + "MOST_USED_CLIENTS": "MOST USED CLIENTS", + "MOST_ACTIVE_USERS": "MOST ACTIVE USERS" + }, + "LIBRARY_OVERVIEW": { + "MOVIE_LIBRARIES": "MOVIE LIBRARIES", + "SHOW_LIBRARIES": "SHOW LIBRARIES", + "MUSIC_LIBRARIES": "MUSIC LIBRARIES", + "MIXED_LIBRARIES": "MIXED LIBRARIES" + }, + "LIBRARY_CARD": { + "LIBRARY": "Library", + "TOTAL_TIME": "Total Time", + "TOTAL_FILES": "Total Files", + "LIBRARY_SIZE": "Library Size", + "TOTAL_PLAYS": "Total Plays", + "TOTAL_PLAYBACK": "Total Playback", + "LAST_PLAYED": "Last Played", + "LAST_ACTIVITY": "Last Activity" + }, + "SHOW_ARCHIVED_LIBRARIES":"Show Archived Libraries", + "HIDE_ARCHIVED_LIBRARIES":"Hide Archived Libraries", + "UNITS":{ + "DAYS": "Days", + "HOURS": "Hours", + "MINUTES": "Minutes", + "SECONDS": "Seconds", + "PLAYS": "Plays", + "ITEMS": "Items" + }, + "TOTAL": "Total", + "LAST": "Last", + "SERIES": "Series", + "SEASONS": "Seasons", + "EPISODES": "Episodes", + "MOVIES": "Movies", + "SONGS": "Songs", + "FILES": "Files", + "LIBRARIES": "Libraries", + "USERS": "Users", + "TYPE": "Type", + "NEW_VERSION_AVAILABLE":"New version available" + + } \ No newline at end of file diff --git a/src/index.jsx b/src/index.jsx index 3566462..e5ed90b 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; @@ -7,8 +7,12 @@ import App from './App.jsx'; import './index.css'; import 'bootstrap/dist/css/bootstrap.min.css'; +import './localization.js'; +import Loading from './pages/components/general/loading.jsx'; + ReactDOM.createRoot(document.getElementById('root')).render( + }/> diff --git a/src/lib/navdata.jsx b/src/lib/navdata.jsx index ef87ef3..52deecb 100644 --- a/src/lib/navdata.jsx +++ b/src/lib/navdata.jsx @@ -1,53 +1,51 @@ import HomeFillIcon from 'remixicon-react/HomeFillIcon'; -// import FileListFillIcon from 'remixicon-react/FileListFillIcon'; import BarChartFillIcon from 'remixicon-react/BarChartFillIcon'; import HistoryFillIcon from 'remixicon-react/HistoryFillIcon'; import SettingsFillIcon from 'remixicon-react/SettingsFillIcon'; import GalleryFillIcon from 'remixicon-react/GalleryFillIcon'; import UserFillIcon from 'remixicon-react/UserFillIcon'; import InformationFillIcon from 'remixicon-react/InformationFillIcon'; +import { Trans } from 'react-i18next'; -// import ReactjsFillIcon from 'remixicon-react/ReactjsFillIcon'; - export const navData = [ { id: 0, icon: , - text: "Home", + text: , link: "" }, { id: 1, icon: , - text: "Libraries", + text: , link: "libraries" }, { id: 2, icon: , - text: "Users", + text: , link: "users" }, { id: 4, icon: , - text: "Activity", + text: , link: "activity" }, { id: 5, icon: , - text: "Statistics", + text: , link: "statistics" }, { id: 6, icon: , - text: "Settings", + text: , link: "settings" } , @@ -55,7 +53,7 @@ export const navData = [ { id: 7, icon: , - text: "About", + text: , link: "about" } diff --git a/src/localization.js b/src/localization.js new file mode 100644 index 0000000..ea389d6 --- /dev/null +++ b/src/localization.js @@ -0,0 +1,18 @@ +import i18n from 'i18next' +import Backend from 'i18next-http-backend' +import LanguageDetector from 'i18next-browser-languagedetector' +import { initReactI18next } from 'react-i18next' + +i18n.use(Backend).use(LanguageDetector).use(initReactI18next).init({ + fallbackLng: 'en', + debug: true, + detection: { + order: ['queryString', 'cookie'], + cache: ['cookie'] + }, + interpolation: { + escapeValue: false + } +}) + +export default i18n \ No newline at end of file diff --git a/src/pages/components/HomeStatisticCards.jsx b/src/pages/components/HomeStatisticCards.jsx index b1422ce..cee2d28 100644 --- a/src/pages/components/HomeStatisticCards.jsx +++ b/src/pages/components/HomeStatisticCards.jsx @@ -1,7 +1,4 @@ -import React, { useState } from "react"; - - - +import { useState } from "react"; import MVLibraries from "./statCards/mv_libraries"; import MVMovies from "./statCards/mv_movies"; @@ -14,6 +11,7 @@ import MVMusic from "./statCards/mv_music"; import MPMusic from "./statCards/mp_music"; import "../css/statCard.css"; +import { Trans } from "react-i18next"; function HomeStatisticCards() { const [days, setDays] = useState(30); @@ -34,9 +32,9 @@ function HomeStatisticCards() { return (
-

Watch Statistics

+

-
Last
+
-
Days
+
diff --git a/src/pages/components/general/navbar.jsx b/src/pages/components/general/navbar.jsx index 4a66954..80bcdaa 100644 --- a/src/pages/components/general/navbar.jsx +++ b/src/pages/components/general/navbar.jsx @@ -5,6 +5,7 @@ import LogoutBoxLineIcon from "remixicon-react/LogoutBoxLineIcon"; import logo_dark from '../../images/icon-b-512.png'; import "../../css/navbar.css"; import VersionCard from "./version-card"; +import { Trans } from "react-i18next"; export default function Navbar() { const handleLogout = () => { @@ -20,7 +21,7 @@ export default function Navbar() { - Jellystat + @@ -42,7 +43,7 @@ export default function Navbar() { })} - Logout + diff --git a/src/pages/components/general/version-card.jsx b/src/pages/components/general/version-card.jsx index 6dfe845..841ccfb 100644 --- a/src/pages/components/general/version-card.jsx +++ b/src/pages/components/general/version-card.jsx @@ -5,6 +5,7 @@ import Col from 'react-bootstrap/Col'; import "../../css/settings/version.css"; import { Card } from "react-bootstrap"; +import { Trans } from "react-i18next"; export default function VersionCard() { @@ -51,13 +52,13 @@ export default function VersionCard() { - Jellystat {data.current_version} + {data.current_version} {data.update_available? - New version available: {data.latest_version} + : {data.latest_version} : <> diff --git a/src/pages/components/library/library-card.jsx b/src/pages/components/library/library-card.jsx index 27845c0..1c29b8c 100644 --- a/src/pages/components/library/library-card.jsx +++ b/src/pages/components/library/library-card.jsx @@ -1,4 +1,4 @@ -import React, {useState} from "react"; +import {useState} from "react"; import { Link } from "react-router-dom"; import "../../css/library/library-card.css"; @@ -10,6 +10,8 @@ import TvLineIcon from "remixicon-react/TvLineIcon"; import FilmLineIcon from "remixicon-react/FilmLineIcon"; import FileMusicLineIcon from "remixicon-react/FileMusicLineIcon"; import CheckboxMultipleBlankLineIcon from "remixicon-react/CheckboxMultipleBlankLineIcon"; +import { Trans } from "react-i18next"; +import i18next from "i18next"; function LibraryCard(props) { const [imageLoaded, setImageLoaded] = useState(true); @@ -143,62 +145,62 @@ function LibraryCard(props) { - Library + {props.data.Name} - Type + {props.data.CollectionType==='tvshows' ? 'Series' : props.data.CollectionType==='movies'? "Movies" : props.data.CollectionType==='music'? "Music" : 'Mixed'} - Total Time + {ticksToTimeString(props.data && props.data.total_play_time ? props.data.total_play_time:0)} - Total Files + {props.metadata && props.metadata.files ? props.metadata.files :0} - Library Size + {formatFileSize(props.metadata && props.metadata.Size ? props.metadata.Size:0)} - Total Plays + {props.data.Plays} - Total Playback + {formatTotalWatchTime(props.data.total_playback_duration)} - Last Played + {props.data.ItemName || 'n/a'} - Last Activity + {props.data.LastActivity ? formatLastActivityTime(props.data.LastActivity) : 'never'} - {props.data.CollectionType==='tvshows' ? 'Series' : props.data.CollectionType==='movies'? "Movies" : props.data.CollectionType==='music'? "Songs" : 'Files'} + {props.data.CollectionType==='tvshows' ? i18next.t("SERIES") : props.data.CollectionType==='movies'? i18next.t("MOVIES") : props.data.CollectionType==='music'? i18next.t("SONGS") : i18next.t("FILES")} {props.data.Library_Count} - Seasons + {props.data.CollectionType==='tvshows' ? props.data.Season_Count : ''} - Episodes + {props.data.CollectionType==='tvshows' ? props.data.Episode_Count : ''} diff --git a/src/pages/components/libraryOverview.jsx b/src/pages/components/libraryOverview.jsx index cef67ca..1262a6e 100644 --- a/src/pages/components/libraryOverview.jsx +++ b/src/pages/components/libraryOverview.jsx @@ -1,5 +1,5 @@ import "../css/libraryOverview.css"; -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Loading from "./general/loading"; @@ -10,6 +10,8 @@ import TvLineIcon from "remixicon-react/TvLineIcon"; import FilmLineIcon from "remixicon-react/FilmLineIcon"; import FileMusicLineIcon from "remixicon-react/FileMusicLineIcon"; import CheckboxMultipleBlankLineIcon from "remixicon-react/CheckboxMultipleBlankLineIcon"; +import { Trans } from "react-i18next"; +import i18next from "i18next"; export default function LibraryOverView() { const token = localStorage.getItem('token'); @@ -45,13 +47,13 @@ export default function LibraryOverView() { return (
-

Library Overview

+

- stat.CollectionType === "movies")} heading={"MOVIE LIBRARIES"} units={"MOVIES"} icon={MovieIcon}/> - stat.CollectionType === "tvshows")} heading={"SHOW LIBRARIES"} units={"SERIES / SEASONS / EPISODES"} icon={SeriesIcon}/> - stat.CollectionType === "music")} heading={"MUSIC LIBRARIES"} units={"SONGS"} icon={MusicIcon}/> - stat.CollectionType === "mixed")} heading={"MIXED LIBRARIES"} units={"ITEMS"} icon={MixedIcon}/> + stat.CollectionType === "movies")} heading={} units={} icon={MovieIcon}/> + stat.CollectionType === "tvshows")} heading={} units={`${i18next.t("SERIES")} / ${i18next.t("SEASONS")} / ${i18next.t("EPISODES")}`} icon={SeriesIcon}/> + stat.CollectionType === "music")} heading={} units={} icon={MusicIcon}/> + stat.CollectionType === "mixed")} heading={} units={} icon={MixedIcon}/>
diff --git a/src/pages/components/libraryStatCard/library-stat-component.jsx b/src/pages/components/libraryStatCard/library-stat-component.jsx index 3e4000b..7d62f9c 100644 --- a/src/pages/components/libraryStatCard/library-stat-component.jsx +++ b/src/pages/components/libraryStatCard/library-stat-component.jsx @@ -1,4 +1,3 @@ -import React from "react"; import { Link } from "react-router-dom"; import { Row, Col, Card } from "react-bootstrap"; diff --git a/src/pages/components/sessions/sessions.jsx b/src/pages/components/sessions/sessions.jsx index 532b275..f5b52cb 100644 --- a/src/pages/components/sessions/sessions.jsx +++ b/src/pages/components/sessions/sessions.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from '../../../lib/axios_instance'; import Config from "../../../lib/config"; // import API from "../../../classes/jellyfin-api"; @@ -8,6 +8,7 @@ import ErrorBoundary from "../general/ErrorBoundary"; import SessionCard from "./session-card"; import Loading from "../general/loading"; +import { Trans } from "react-i18next"; function Sessions() { const [data, setData] = useState(); @@ -104,16 +105,17 @@ function Sessions() { if ((!data && config) || data.length === 0) { return(
-

Sessions

+ +

- No Active Sessions Found +
); } return (
-

Sessions

+

{data && data.length>0 && data diff --git a/src/pages/components/statCards/most_active_users.jsx b/src/pages/components/statCards/most_active_users.jsx index 108c9d5..3a3ff6f 100644 --- a/src/pages/components/statCards/most_active_users.jsx +++ b/src/pages/components/statCards/most_active_users.jsx @@ -1,10 +1,11 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; import AccountCircleFillIcon from "remixicon-react/AccountCircleFillIcon"; +import { Trans } from "react-i18next"; function MostActiveUsers(props) { const [data, setData] = useState(); @@ -81,7 +82,7 @@ function MostActiveUsers(props) { }; return ( - : } data={data} heading={"MOST ACTIVE USERS"} units={"Plays"}/> + : } data={data} heading={} units={}/> ); } diff --git a/src/pages/components/statCards/most_used_client.jsx b/src/pages/components/statCards/most_used_client.jsx index 5855779..bc592f7 100644 --- a/src/pages/components/statCards/most_used_client.jsx +++ b/src/pages/components/statCards/most_used_client.jsx @@ -1,10 +1,11 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import ItemStatComponent from "./ItemStatComponent"; import ComputerLineIcon from "remixicon-react/ComputerLineIcon"; +import { Trans } from "react-i18next"; function MostUsedClient(props) { const [data, setData] = useState(); @@ -52,7 +53,7 @@ function MostUsedClient(props) { return ( - } data={data} heading={"MOST USED CLIENTS"} units={"Plays"}/> + } data={data} heading={} units={}/> ); } diff --git a/src/pages/components/statCards/mp_movies.jsx b/src/pages/components/statCards/mp_movies.jsx index b2515fb..c679be0 100644 --- a/src/pages/components/statCards/mp_movies.jsx +++ b/src/pages/components/statCards/mp_movies.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; @@ -6,6 +6,7 @@ import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; import Loading from "../general/loading"; +import { Trans } from "react-i18next"; function MPMovies(props) { const [data, setData] = useState(); @@ -75,7 +76,7 @@ function MPMovies(props) { } return ( - + } units={}/> ); } diff --git a/src/pages/components/statCards/mp_music.jsx b/src/pages/components/statCards/mp_music.jsx index 95161b0..5ad1630 100644 --- a/src/pages/components/statCards/mp_music.jsx +++ b/src/pages/components/statCards/mp_music.jsx @@ -1,9 +1,10 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; +import { Trans } from "react-i18next"; @@ -69,7 +70,7 @@ function MPMusic(props) { return ( - + } units={} isAudio={true}/> ); } diff --git a/src/pages/components/statCards/mp_series.jsx b/src/pages/components/statCards/mp_series.jsx index b74619f..7d9e3ea 100644 --- a/src/pages/components/statCards/mp_series.jsx +++ b/src/pages/components/statCards/mp_series.jsx @@ -1,7 +1,8 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; +import { Trans } from "react-i18next"; function MPSeries(props) { @@ -66,7 +67,7 @@ function MPSeries(props) { return ( - + } units={}/> ); } diff --git a/src/pages/components/statCards/mv_libraries.jsx b/src/pages/components/statCards/mv_libraries.jsx index 5dfb8d4..0c6ee6b 100644 --- a/src/pages/components/statCards/mv_libraries.jsx +++ b/src/pages/components/statCards/mv_libraries.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; @@ -8,6 +8,7 @@ import TvLineIcon from "remixicon-react/TvLineIcon"; import FilmLineIcon from "remixicon-react/FilmLineIcon"; import FileMusicLineIcon from "remixicon-react/FileMusicLineIcon"; import CheckboxMultipleBlankLineIcon from "remixicon-react/CheckboxMultipleBlankLineIcon"; +import { Trans } from "react-i18next"; function MVLibraries(props) { const [data, setData] = useState(); @@ -60,7 +61,7 @@ function MVLibraries(props) { return ( - + } units={}/> ); } diff --git a/src/pages/components/statCards/mv_movies.jsx b/src/pages/components/statCards/mv_movies.jsx index 2e55c88..5d00ff3 100644 --- a/src/pages/components/statCards/mv_movies.jsx +++ b/src/pages/components/statCards/mv_movies.jsx @@ -1,10 +1,11 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; +import { Trans } from "react-i18next"; function MVMusic(props) { @@ -73,7 +74,7 @@ function MVMusic(props) { return ( - + } units={}/> ); } diff --git a/src/pages/components/statCards/mv_music.jsx b/src/pages/components/statCards/mv_music.jsx index 906be82..e70e173 100644 --- a/src/pages/components/statCards/mv_music.jsx +++ b/src/pages/components/statCards/mv_music.jsx @@ -1,7 +1,8 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; +import { Trans } from "react-i18next"; function MVMovies(props) { const [data, setData] = useState(); @@ -68,7 +69,7 @@ function MVMovies(props) { return ( - + } units={} isAudio={true}/> ); } diff --git a/src/pages/components/statCards/mv_series.jsx b/src/pages/components/statCards/mv_series.jsx index 30c9be8..ddbf721 100644 --- a/src/pages/components/statCards/mv_series.jsx +++ b/src/pages/components/statCards/mv_series.jsx @@ -1,9 +1,10 @@ -import React, { useState, useEffect } from "react"; +import { useState, useEffect } from "react"; import axios from "axios"; import Config from "../../../lib/config"; import ItemStatComponent from "./ItemStatComponent"; +import { Trans } from "react-i18next"; function MVSeries(props) { @@ -69,7 +70,7 @@ function MVSeries(props) { return ( - + } units={}/> ); } diff --git a/src/pages/home.jsx b/src/pages/home.jsx index 31f30b0..7fdb0f8 100644 --- a/src/pages/home.jsx +++ b/src/pages/home.jsx @@ -1,5 +1,3 @@ -import React from 'react' - import './css/home.css' import Sessions from './components/sessions/sessions' diff --git a/src/pages/libraries.jsx b/src/pages/libraries.jsx index 1c81202..298a943 100644 --- a/src/pages/libraries.jsx +++ b/src/pages/libraries.jsx @@ -9,6 +9,8 @@ import ErrorBoundary from "./components/general/ErrorBoundary"; import EyeOffFillIcon from 'remixicon-react/EyeOffFillIcon'; import EyeFillIcon from 'remixicon-react/EyeFillIcon'; import { Tooltip } from "react-bootstrap"; +import { Trans } from "react-i18next"; +import i18next from "i18next"; function Libraries() { @@ -82,16 +84,16 @@ function Libraries() { return (
-

Libraries

+

{ showArchived ? - + : - +