From 5cceb33c50c99946dc2fcfeedb17e15cdd0b42b7 Mon Sep 17 00:00:00 2001 From: Sina Blattmann Date: Thu, 23 Feb 2023 08:19:42 +0100 Subject: [PATCH] [WIP] added files from fossil to git, added multilanguage --- typescript/Frontend/.gitignore | 23 +++++++ typescript/Frontend/lang/en.json | 50 ++++++++++++++ typescript/Frontend/package-lock.json | 30 ++++++++ typescript/Frontend/package.json | 6 +- typescript/Frontend/src/App.tsx | 69 +++++-------------- typescript/Frontend/src/Login.tsx | 14 ++-- .../Frontend/src/components/CustomerForm.tsx | 34 +++++++-- .../src/components/LanguageSelect.tsx | 27 ++++++++ .../Frontend/src/components/LogoutButton.tsx | 28 ++++++++ .../src/components/NavigationButtons.tsx | 24 +++++++ .../Frontend/src/components/NestedList.tsx | 16 ++--- typescript/Frontend/src/components/Tabs.tsx | 5 +- typescript/Frontend/src/hooks/useToken.tsx | 8 ++- typescript/Frontend/src/lang/de.json | 18 +++++ typescript/Frontend/src/lang/en.json | 18 +++++ typescript/Frontend/src/routes/Home.tsx | 3 +- .../Frontend/src/routes/Installation.tsx | 28 ++++++-- .../Frontend/src/util/installation.util.tsx | 4 +- 18 files changed, 317 insertions(+), 88 deletions(-) create mode 100644 typescript/Frontend/.gitignore create mode 100644 typescript/Frontend/lang/en.json create mode 100644 typescript/Frontend/src/components/LanguageSelect.tsx create mode 100644 typescript/Frontend/src/components/LogoutButton.tsx create mode 100644 typescript/Frontend/src/components/NavigationButtons.tsx create mode 100644 typescript/Frontend/src/lang/de.json create mode 100644 typescript/Frontend/src/lang/en.json diff --git a/typescript/Frontend/.gitignore b/typescript/Frontend/.gitignore new file mode 100644 index 000000000..4d29575de --- /dev/null +++ b/typescript/Frontend/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/typescript/Frontend/lang/en.json b/typescript/Frontend/lang/en.json new file mode 100644 index 000000000..c2937f320 --- /dev/null +++ b/typescript/Frontend/lang/en.json @@ -0,0 +1,50 @@ +{ + "alarms": { + "defaultMessage": "Alarms" + }, + "allInstallations": { + "defaultMessage": "All installations" + }, + "applyChanges": { + "defaultMessage": "Apply changes" + }, + "country": { + "defaultMessage": "Country" + }, + "customerName": { + "defaultMessage": "Customer name" + }, + "english": { + "defaultMessage": "English" + }, + "german": { + "defaultMessage": "German" + }, + "installation": { + "defaultMessage": "Installation" + }, + "location": { + "defaultMessage": "Location" + }, + "log": { + "defaultMessage": "Log" + }, + "logout": { + "defaultMessage": "Logout" + }, + "orderNumbers": { + "defaultMessage": "Order number" + }, + "region": { + "defaultMessage": "Region" + }, + "search": { + "defaultMessage": "Search" + }, + "updatedSuccessfully": { + "defaultMessage": "Updated successfully" + }, + "users": { + "defaultMessage": "Users" + } +} diff --git a/typescript/Frontend/package-lock.json b/typescript/Frontend/package-lock.json index a9afa3d5c..88944aeda 100644 --- a/typescript/Frontend/package-lock.json +++ b/typescript/Frontend/package-lock.json @@ -32,6 +32,9 @@ "reactflow": "^11.5.6", "typescript": "^4.9.5", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@formatjs/cli": "^6.0.3" } }, "node_modules/@adobe/css-tools": { @@ -2306,6 +2309,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@formatjs/cli": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.0.3.tgz", + "integrity": "sha512-YPhDUw5zQwufAZRUlk054Z/J9jeZWH4LEbAVnQFrfJ8NNgOziDqn9SSTEfRB4W0w8JBGgte4x1SwwJjH/HGoRA==", + "dev": true, + "bin": { + "formatjs": "bin/formatjs" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "@vue/compiler-sfc": "^3.2.34" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, "node_modules/@formatjs/ecma402-abstract": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.14.3.tgz", @@ -19710,6 +19733,13 @@ } } }, + "@formatjs/cli": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@formatjs/cli/-/cli-6.0.3.tgz", + "integrity": "sha512-YPhDUw5zQwufAZRUlk054Z/J9jeZWH4LEbAVnQFrfJ8NNgOziDqn9SSTEfRB4W0w8JBGgte4x1SwwJjH/HGoRA==", + "dev": true, + "requires": {} + }, "@formatjs/ecma402-abstract": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.14.3.tgz", diff --git a/typescript/Frontend/package.json b/typescript/Frontend/package.json index e2ab79d93..b0f0b125f 100644 --- a/typescript/Frontend/package.json +++ b/typescript/Frontend/package.json @@ -32,7 +32,8 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "extract": "formatjs extract" }, "eslintConfig": { "extends": [ @@ -51,5 +52,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "@formatjs/cli": "^6.0.3" } } diff --git a/typescript/Frontend/src/App.tsx b/typescript/Frontend/src/App.tsx index c13163b0c..358e4750c 100644 --- a/typescript/Frontend/src/App.tsx +++ b/typescript/Frontend/src/App.tsx @@ -1,15 +1,7 @@ import useToken from "./hooks/useToken"; import Login from "./Login"; import { BrowserRouter, Route, Routes } from "react-router-dom"; -import { - Box, - Grid, - ButtonGroup, - Button, - Divider, - Select, - MenuItem, -} from "@mui/material"; +import { Box, Grid, Divider } from "@mui/material"; import NestedList from "./components/NestedList"; import BasicTable from "./components/Table"; import BasicTabs from "./components/Tabs"; @@ -17,25 +9,18 @@ import Alarms from "./routes/Alarms"; import InstallationDetail from "./routes/Installation"; import Log from "./routes/Log"; import routes from "./routes.json"; -import { FormattedMessage, IntlProvider } from "react-intl"; +import { IntlProvider } from "react-intl"; import { useState } from "react"; +import en from "./lang/en.json"; +import de from "./lang/de.json"; +import NavigationButtons from "./components/NavigationButtons"; +import LanguageSelect from "./components/LanguageSelect"; +import LogoutButton from "./components/LogoutButton"; const App = () => { - const { token, setToken } = useToken(); + const { token, setToken, removeToken } = useToken(); const [language, setLanguage] = useState("en"); - if (!token) { - return ; - } - - const de = { - allInstallations: "Alle Installationen", - }; - - const en = { - allInstallations: "All installations", - }; - const getTranslations = () => { if (language === "de") { return de; @@ -43,6 +28,12 @@ const App = () => { return en; }; + if (!token) { + return ; + } + + console.log("app"); + return ( { - - - - + - + + { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [loading, setLoading] = useState(false); + const [error, setError] = useState(); - const handleSubmit = async (e: any) => { + const handleSubmit = (e: any) => { setLoading(true); - loginUser(username, password).then((res) => { - setToken(res.data); + loginUser(username, password).then(({ data }) => { + if (typeof data === "string") { + setToken(data); + setLoading(false); + } + setError(data); setLoading(false); }); }; @@ -41,6 +46,7 @@ const Login = ({ setToken }: { setToken: any }) => { value={password} handleChange={(e) => setPassword(e.target.value)} /> + {error && Incorrect username or password}
+ + + + + ); }; diff --git a/typescript/Frontend/src/components/LanguageSelect.tsx b/typescript/Frontend/src/components/LanguageSelect.tsx new file mode 100644 index 000000000..6349befc0 --- /dev/null +++ b/typescript/Frontend/src/components/LanguageSelect.tsx @@ -0,0 +1,27 @@ +import { MenuItem, Select } from "@mui/material"; +import { FormattedMessage } from "react-intl"; + +interface LanguageSelectProps { + language: string; + setLanguage: (language: string) => void; +} +const LanguageSelect = (props: LanguageSelectProps) => { + return ( + + ); +}; + +export default LanguageSelect; diff --git a/typescript/Frontend/src/components/LogoutButton.tsx b/typescript/Frontend/src/components/LogoutButton.tsx new file mode 100644 index 000000000..fe773519e --- /dev/null +++ b/typescript/Frontend/src/components/LogoutButton.tsx @@ -0,0 +1,28 @@ +import { Button } from "@mui/material"; +import { FormattedMessage } from "react-intl"; +import axiosConfig from "../config/axiosConfig"; +import { useNavigate } from "react-router-dom"; + +interface LogoutButtonProps { + removeToken: () => void; +} +const LogoutButton = (props: LogoutButtonProps) => { + const navigate = useNavigate(); + + return ( + + ); +}; + +export default LogoutButton; diff --git a/typescript/Frontend/src/components/NavigationButtons.tsx b/typescript/Frontend/src/components/NavigationButtons.tsx new file mode 100644 index 000000000..9175a7410 --- /dev/null +++ b/typescript/Frontend/src/components/NavigationButtons.tsx @@ -0,0 +1,24 @@ +import { Button, ButtonGroup } from "@mui/material"; +import { FormattedMessage } from "react-intl"; + +const NavigationButtons = () => { + return ( + + + + + ); +}; + +export default NavigationButtons; diff --git a/typescript/Frontend/src/components/NestedList.tsx b/typescript/Frontend/src/components/NestedList.tsx index 02759877c..d9d25b62c 100644 --- a/typescript/Frontend/src/components/NestedList.tsx +++ b/typescript/Frontend/src/components/NestedList.tsx @@ -5,7 +5,7 @@ import { Divider, TextField } from "@mui/material"; import { Link } from "react-router-dom"; import useRouteMatch from "../hooks/useRouteMatch"; import routes from "../routes.json"; -import { useEffect, useState } from "react"; +import { Fragment, useEffect, useState } from "react"; import { I_Installation } from "../util/installation.util"; import axiosConfig from "../config/axiosConfig"; import { useIntl } from "react-intl"; @@ -46,11 +46,10 @@ const NestedList = () => { ]); useEffect(() => { - axiosConfig - .get("https://localhost:7087/api/GetAllInstallations", {}) - .then((res) => { - setData(res.data); - }); + console.log("useeffect"); + axiosConfig.get("/GetAllInstallations", {}).then((res) => { + setData(res.data); + }); }, []); return ( @@ -72,9 +71,8 @@ const NestedList = () => { aria-labelledby="nested-list-subheader" > {filteredData?.map((installation) => ( - <> + @@ -87,7 +85,7 @@ const NestedList = () => { - + ))} diff --git a/typescript/Frontend/src/components/Tabs.tsx b/typescript/Frontend/src/components/Tabs.tsx index a1eee2a9d..acb522b8b 100644 --- a/typescript/Frontend/src/components/Tabs.tsx +++ b/typescript/Frontend/src/components/Tabs.tsx @@ -21,7 +21,10 @@ const BasicTabs = () => { return ( - + { const getToken = () => { @@ -11,12 +10,17 @@ const useToken = () => { const saveToken = (userToken: any) => { sessionStorage.setItem("token", JSON.stringify(userToken)); setToken(userToken); - axiosConfig.defaults.headers.common["auth"] = userToken; + }; + + const removeToken = () => { + sessionStorage.removeItem("token"); + setToken(null); }; return { setToken: saveToken, token, + removeToken, }; }; diff --git a/typescript/Frontend/src/lang/de.json b/typescript/Frontend/src/lang/de.json new file mode 100644 index 000000000..21a9804f7 --- /dev/null +++ b/typescript/Frontend/src/lang/de.json @@ -0,0 +1,18 @@ +{ + "alarms": "Alarme", + "allInstallations": "Alle Installationen", + "applyChanges": "Änderungen übernehmen", + "country": "Land", + "customerName": "Kundenname", + "english": "Englisch", + "german": "Deutsch", + "installation": "Installation", + "location": "Ort", + "log": "Log", + "orderNumbers": "Bestellnummern", + "region": "Region", + "search": "Suche", + "users": "Benutzer", + "logout": "Logout", + "updatedSuccessfully": "Erfolgreich aktualisiert" +} diff --git a/typescript/Frontend/src/lang/en.json b/typescript/Frontend/src/lang/en.json new file mode 100644 index 000000000..3197f95b6 --- /dev/null +++ b/typescript/Frontend/src/lang/en.json @@ -0,0 +1,18 @@ +{ + "alarms": "Alarms", + "allInstallations": "All installations", + "applyChanges": "Apply changes", + "country": "country", + "customerName": "Customer name", + "english": "English", + "german": "German", + "installation": "Installation", + "location": "Location", + "log": "Log", + "orderNumbers": "Order numbers", + "region": "Region", + "search": "Search", + "users": "Users", + "logout": "Logout", + "updatedSuccessfully": "Updated successfully" +} \ No newline at end of file diff --git a/typescript/Frontend/src/routes/Home.tsx b/typescript/Frontend/src/routes/Home.tsx index 74ed8bc0b..24127ea56 100644 --- a/typescript/Frontend/src/routes/Home.tsx +++ b/typescript/Frontend/src/routes/Home.tsx @@ -8,7 +8,6 @@ import routes from "../routes.json"; import InstallationDetail from "./Installation"; const Home = () => { - return ( @@ -27,7 +26,7 @@ const Home = () => { type="search" fullWidth /> - + { const { id } = useParams(); const [values, setValues] = useState(); const [loading, setLoading] = useState(false); + const [error, setError] = useState(); useEffect(() => { setLoading(true); - axiosConfig.get("/GetInstallationById?id=" + id).then((res) => { - setValues(res.data); - setLoading(false); - }); + axiosConfig + .get("/GetInstallationById?id=" + id) + .then((res) => { + setValues(res.data); + setLoading(false); + }) + .catch((err: AxiosError) => { + setError(err); + setLoading(false); + }); }, [id]); - if (values && values.id.toString() === id) { + if (error) { + return ( + + {error.message} + + ); + } else if (values && values.id.toString() === id) { return ( ); } else if (loading) { - return ; + return ; } return null; }; diff --git a/typescript/Frontend/src/util/installation.util.tsx b/typescript/Frontend/src/util/installation.util.tsx index 94e106b6f..7f35e1ebd 100644 --- a/typescript/Frontend/src/util/installation.util.tsx +++ b/typescript/Frontend/src/util/installation.util.tsx @@ -8,7 +8,7 @@ export interface I_Installation { location: string; region: string; country: string; - orderNumber: string; + orderNumbers: string; lat: number; long: number; s3Bucket: string; @@ -17,5 +17,3 @@ export interface I_Installation { information: string; parentId: number; } - -