From 0fe94c306609fcdcd94760c53df195e3182601c0 Mon Sep 17 00:00:00 2001 From: Daniel Ledda Date: Sun, 24 May 2020 11:37:04 +0200 Subject: [PATCH] Put all user information (including locale) into a user context. Language can be changed, all pages access the user context now. Translated some stuff. --- .idea/{kniffel.iml => kadi_frontendä.iml} | 0 package.json | 2 +- public/index.html | 4 +- public/static/favicon.ico | Bin 3150 -> 0 bytes public/static/manifest.json | 25 -------- public/static/robots.txt | 3 - src/App.tsx | 44 +++++++++----- src/Components/FriendsPage.tsx | 6 +- src/Components/HistoryPage.tsx | 31 +++++++--- src/Components/HomePage.tsx | 6 +- src/Components/KadiPage.tsx | 2 + src/Components/KadiSidebarNav.tsx | 16 +++--- src/Components/KadiTopMenuBar.tsx | 27 ++------- src/Components/ProfilePage.tsx | 8 ++- src/Components/RulesetsPage.tsx | 6 +- src/Components/StatsPage.tsx | 7 ++- src/Contexts/LocaleContext.ts | 19 ------- src/Contexts/UserContext.ts | 8 +++ src/static/images/kadi.svg | 63 ++++++++++++++------- src/static/strings.ts | 54 ++++++++++++++++++ webpack.config.js | 2 +- 21 files changed, 196 insertions(+), 137 deletions(-) rename .idea/{kniffel.iml => kadi_frontendä.iml} (100%) delete mode 100755 public/static/favicon.ico delete mode 100755 public/static/manifest.json delete mode 100755 public/static/robots.txt delete mode 100755 src/Contexts/LocaleContext.ts diff --git a/.idea/kniffel.iml b/.idea/kadi_frontendä.iml similarity index 100% rename from .idea/kniffel.iml rename to .idea/kadi_frontendä.iml diff --git a/package.json b/package.json index dc98925..6d8b65f 100755 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "author": "Daniel Ledda", "scripts": { "build": "webpack --mode development", - "postbuild": "rsync -avu --delete dist/ ../kadi_backend/dist/frontend/static", + "postbuild": "rsync -avu --delete dist/ ../kadi_backend/static/frontend", "start": "webpack-dev-server --mode development", "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/public/index.html b/public/index.html index ab6ceef..3a4647d 100755 --- a/public/index.html +++ b/public/index.html @@ -2,7 +2,7 @@ - + You need to enable JavaScript to run this app. - + \ No newline at end of file diff --git a/public/static/favicon.ico b/public/static/favicon.ico deleted file mode 100755 index bcd5dfd67cd0361b78123e95c2dd96031f27f743..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3150 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 MDeX2GIKR{Qf5okjU;qFB diff --git a/public/static/manifest.json b/public/static/manifest.json deleted file mode 100755 index 080d6c7..0000000 --- a/public/static/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/public/static/robots.txt b/public/static/robots.txt deleted file mode 100755 index e9e57dc..0000000 --- a/public/static/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/src/App.tsx b/src/App.tsx index cf17c61..8ecffcb 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,18 +9,16 @@ import HomePage from "./Components/HomePage"; import {SERVER_BASE_NAME} from "./index"; import axios from "axios"; import UserContext, {IUserContext} from "./Contexts/UserContext"; -import LocaleContext, {ILocaleContext} from "./Contexts/LocaleContext"; interface AppState { userContext: IUserContext; - localeContext: ILocaleContext; } interface AppProps {} class App extends React.Component { private readonly updateUserContext: (username: string, loggedIn: boolean) => void; - private readonly changeLang: (lang: SupportedLang) => void; + private readonly changeLang: (lang: SupportedLang, submit?: boolean) => void; constructor(props: AppProps) { super(props); @@ -28,16 +26,25 @@ class App extends React.Component { this.setState({userContext: { username: username, loggedIn: loggedIn, - updateUserContext: this.updateUserContext + updateUserContext: this.updateUserContext, + currentLang: this.state.userContext.currentLang, + strings: this.state.userContext.strings, + changeLang: this.state.userContext.changeLang, }}); }; - this.changeLang = (lang: SupportedLang) => { - this.setState({localeContext: { + this.changeLang = (lang: SupportedLang, submit=true) => { + this.setState({userContext: { strings: IntlStrings[lang], currentLang: lang, - changeLang: this.changeLang + changeLang: this.changeLang, + username: this.state.userContext.username, + loggedIn: this.state.userContext.loggedIn, + updateUserContext: this.state.userContext.updateUserContext, }}); + if (submit) { + this.submitLanguagePreference(lang); + } }; this.state = { @@ -45,32 +52,40 @@ class App extends React.Component { username: "", loggedIn: false, updateUserContext: this.updateUserContext, - }, - localeContext: { currentLang: SupportedLang.gb, strings: IntlStrings[SupportedLang.gb], changeLang: this.changeLang, } }; + } + componentDidMount(): void { + this.getDefaultVals(); + } + + getDefaultVals(): void { axios.get("/api/user", {baseURL: SERVER_BASE_NAME}) .then((res) => { const data = res.data as any; if (data.loggedIn) { - this.updateUserContext(data.username, true); - } - else { - this.updateUserContext("", false); + this.updateUserContext(data.username, data.loggedIn); + this.changeLang(data.lang, false); } }) .catch(err => console.log(err)); } + submitLanguagePreference(lang: SupportedLang) { + axios.post(SERVER_BASE_NAME + "/api/changeLang", + {lang: lang}, + {headers: {"Content-Type": "application/json"}} + ); + }; + render(): ReactNode { return ( - @@ -90,7 +105,6 @@ class App extends React.Component { /> - ); } diff --git a/src/Components/FriendsPage.tsx b/src/Components/FriendsPage.tsx index b9193f9..1122b3e 100755 --- a/src/Components/FriendsPage.tsx +++ b/src/Components/FriendsPage.tsx @@ -1,6 +1,6 @@ import React, {ReactElement} from "react"; -import KadiPage from "../Components/KadiPage"; import {Header} from "semantic-ui-react"; +import UserContext from "../Contexts/UserContext"; interface FriendsPageProps {} @@ -16,12 +16,14 @@ class FriendsPage extends React.Component { } render(): ReactElement { + const Locale = this.context.strings; return (
- My Friends + {Locale.friendsPage.title}
); } } +FriendsPage.contextType = UserContext; export default FriendsPage; \ No newline at end of file diff --git a/src/Components/HistoryPage.tsx b/src/Components/HistoryPage.tsx index 207db1b..2ddc4ea 100755 --- a/src/Components/HistoryPage.tsx +++ b/src/Components/HistoryPage.tsx @@ -2,6 +2,7 @@ import React, {ReactElement} from "react"; import {Header, List, ListItem} from "semantic-ui-react"; import axios from "axios"; import {SERVER_BASE_NAME} from "../index"; +import UserContext from "../Contexts/UserContext"; interface HistoryPageProps { } @@ -22,10 +23,11 @@ class HistoryPage extends React.Component { } componentDidMount(): void { - axios.get(SERVER_BASE_NAME + "/api/games/") + axios.get(SERVER_BASE_NAME + "/api/games") .then(response => this.setState({gameListings: response.data.games})) .catch(error => this.handleError(error)) .finally(() => this.setState({ loadingGames: false })); + console.log(this.state.gameListings); } handleError = (error: any) => void { @@ -33,21 +35,32 @@ class HistoryPage extends React.Component { }; render(): ReactElement { + const Locale = this.context.strings; return ( <>
- History + {Locale.historyPage.title}
- - { - this.state.gameListings.map(listing => { - return Game played on: {listing.createdAt}; - }) - } - + { + this.state.loadingGames ? ( +

+ Loading games... +

+ ) : + ( + + { + this.state.gameListings.map(listing => { + return Game played on: {listing.createdAt}; + }) + } + + ) + } ); } } +HistoryPage.contextType = UserContext; export default HistoryPage; \ No newline at end of file diff --git a/src/Components/HomePage.tsx b/src/Components/HomePage.tsx index 4a1d6c4..e1d845c 100755 --- a/src/Components/HomePage.tsx +++ b/src/Components/HomePage.tsx @@ -1,6 +1,6 @@ import React, {ReactElement} from "react"; -import KadiPage from "../Components/KadiPage"; import {Header} from "semantic-ui-react"; +import UserContext from "../Contexts/UserContext"; interface HomePageProps {} @@ -16,12 +16,14 @@ class HomePage extends React.Component { } render(): ReactElement { + const Locale = this.context.strings; return (
- Home + {Locale.homePage.title}
); } } +HomePage.contextType = UserContext; export default HomePage; \ No newline at end of file diff --git a/src/Components/KadiPage.tsx b/src/Components/KadiPage.tsx index 25eb161..b722564 100755 --- a/src/Components/KadiPage.tsx +++ b/src/Components/KadiPage.tsx @@ -4,6 +4,7 @@ import "../static/css/site.css"; import KadiSidebarNav from "../Components/KadiSidebarNav"; import MainPageContent from "../Components/MainPageContent"; import {PageId} from "../enums"; +import UserContext from "../Contexts/UserContext"; interface KadiPageProps { activePage: PageId; @@ -32,5 +33,6 @@ class KadiPage extends React.Component { ); } } +KadiPage.contextType = UserContext; export default KadiPage; \ No newline at end of file diff --git a/src/Components/KadiSidebarNav.tsx b/src/Components/KadiSidebarNav.tsx index 72cd0ce..7f9e621 100755 --- a/src/Components/KadiSidebarNav.tsx +++ b/src/Components/KadiSidebarNav.tsx @@ -1,7 +1,7 @@ -import {Header, HeaderContent, Icon, Image, Menu, Segment, Sidebar, SidebarPusher} from "semantic-ui-react"; +import {Header, HeaderContent, Icon, Image, Menu} from "semantic-ui-react"; import logo from "../static/images/kadi.png"; import React from "react"; -import LocaleContext from "../Contexts/LocaleContext"; +import UserContext from "../Contexts/UserContext"; import {Link} from "react-router-dom"; import {PageId} from "../enums"; import {SERVER_BASE_NAME} from "../index"; @@ -11,7 +11,7 @@ interface KadiSidebarNavProps { } const KadiSidebarNav: React.FunctionComponent = (props) => { - const Locale = React.useContext(LocaleContext).strings; + const Locale = React.useContext(UserContext).strings; const {activeItem} = props; return ( = (props) => {Locale.menu.playTab} - + = (props) => {Locale.menu.profileTab} - + = (props) => {Locale.menu.statsTab} - + = (props) => {Locale.menu.rulesetsTab} - + = (props) => {Locale.menu.friendsTab} - + { @@ -21,7 +19,6 @@ class KadiTopMenuBar extends React.Component {}; @@ -33,19 +30,8 @@ class KadiTopMenuBar extends React.Component void = (event, data) => { - const lang = data.value as SupportedLang; - this.setState({currentLangSelection: lang}); - this.changeLanguageGlobally(lang); - }; - render(): ReactElement { - const {loggedIn, username} = this.props.user; - const Locale = this.context.strings; + const {loggedIn, username, strings: Locale, currentLang, changeLang} = this.props.user; return ( - - {LanguageNames[this.state.currentLangSelection]} + + {LanguageNames[currentLang]} )} options={this.languageDropdowns} - onChange={this.handleLanguageChange} + onChange={(e, d) => changeLang(d.value as SupportedLang)} /> @@ -85,6 +71,5 @@ class KadiTopMenuBar extends React.Component { } render(): ReactElement { + const Locale = this.context.strings; return ( -
- My Profile +
+ {Locale.profilePage.title}
); } } +ProfilePage.contextType = UserContext; export default ProfilePage; \ No newline at end of file diff --git a/src/Components/RulesetsPage.tsx b/src/Components/RulesetsPage.tsx index d28d969..317445b 100755 --- a/src/Components/RulesetsPage.tsx +++ b/src/Components/RulesetsPage.tsx @@ -1,6 +1,6 @@ import React, {ReactElement} from "react"; -import KadiPage from "../Components/KadiPage"; import {Header} from "semantic-ui-react"; +import UserContext from "../Contexts/UserContext"; interface RulesetsPageProps {} @@ -16,12 +16,14 @@ class RulesetsPage extends React.Component } render(): ReactElement { + const Locale = this.context.strings; return (
- My Rulesets + {Locale.rulesetsPage.title}
); } } +RulesetsPage.contextType = UserContext; export default RulesetsPage; \ No newline at end of file diff --git a/src/Components/StatsPage.tsx b/src/Components/StatsPage.tsx index 866bc5b..13cf236 100755 --- a/src/Components/StatsPage.tsx +++ b/src/Components/StatsPage.tsx @@ -1,7 +1,6 @@ import React, {ReactNode} from "react"; -import {BrowserRouter as Router, Link, Route} from "react-router-dom"; import {Header} from "semantic-ui-react"; -import KadiPage from "../Components/KadiPage"; +import UserContext from "../Contexts/UserContext"; interface StatsPageProps {} @@ -17,12 +16,14 @@ class StatsPage extends React.Component { } render(): ReactNode { + const Locale = this.context.strings; return (
- My Stats + {Locale.statsPage.title}
); } } +StatsPage.contextType = UserContext; export default StatsPage; \ No newline at end of file diff --git a/src/Contexts/LocaleContext.ts b/src/Contexts/LocaleContext.ts deleted file mode 100755 index 0f9267c..0000000 --- a/src/Contexts/LocaleContext.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {SupportedLang} from "../enums"; -import React from "react"; -import {IntlStrings} from "../static/strings"; - -export interface ILocaleContext { - currentLang: SupportedLang; - strings: any; - changeLang: (lang: SupportedLang) => void; -} - -export const localeDefaultVal: ILocaleContext = { - currentLang: SupportedLang.gb, - strings: IntlStrings[SupportedLang.gb as SupportedLang], - changeLang: () => {}, -}; - -const LocaleContext = React.createContext(localeDefaultVal); - -export default LocaleContext; \ No newline at end of file diff --git a/src/Contexts/UserContext.ts b/src/Contexts/UserContext.ts index a099de1..7ab3c06 100755 --- a/src/Contexts/UserContext.ts +++ b/src/Contexts/UserContext.ts @@ -1,15 +1,23 @@ import React from "react"; +import {SupportedLang} from "../enums"; +import {IntlStrings} from "../static/strings"; export interface IUserContext { username: string; loggedIn: boolean; updateUserContext: (username: string, loggedIn: boolean) => void; + currentLang: SupportedLang; + strings: any; + changeLang: (lang: SupportedLang, submit?: boolean) => void; } const userDefaultVal = { loggedIn: false, username: "", updateUserContext: () => {}, + currentLang: SupportedLang.gb, + strings: IntlStrings[SupportedLang.gb as SupportedLang], + changeLang: () => {}, } as IUserContext; const UserContext = React.createContext(userDefaultVal); diff --git a/src/static/images/kadi.svg b/src/static/images/kadi.svg index a299114..08a823d 100755 --- a/src/static/images/kadi.svg +++ b/src/static/images/kadi.svg @@ -481,7 +481,8 @@ y="30.678488" ry="50.39043" />