diff --git a/package-lock.json b/package-lock.json
index 1027011..43f90a0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12803,6 +12803,16 @@
"workbox-webpack-plugin": "5.1.4"
}
},
+ "react-toastify": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-6.2.0.tgz",
+ "integrity": "sha512-XpjFrcBhQ0/nBOL4syqgP/TywFnOyxmstYLWgSQWcj39qpp+WU4vPt3C/ayIDx7RFyxRWfzWTdR2qOcDGo7G0w==",
+ "requires": {
+ "clsx": "^1.1.1",
+ "prop-types": "^15.7.2",
+ "react-transition-group": "^4.4.1"
+ }
+ },
"react-transition-group": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
diff --git a/package.json b/package.json
index d39d47b..c6f932a 100644
--- a/package.json
+++ b/package.json
@@ -8,17 +8,18 @@
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",
"@testing-library/user-event": "^12.5.0",
- "react": "^17.0.1",
- "react-dom": "^17.0.1",
- "react-router-dom": "^5.2.0",
- "react-scripts": "4.0.1",
+ "axios": "^0.19.2",
"i18next": "^19.4.4",
"i18next-browser-languagedetector": "^4.1.1",
"i18next-http-backend": "^1.0.10",
- "react-i18next": "^11.4.0",
"moment": "^2.25.3",
- "axios": "^0.19.2",
- "react-flags": "^0.1.18"
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1",
+ "react-flags": "^0.1.18",
+ "react-i18next": "^11.4.0",
+ "react-router-dom": "^5.2.0",
+ "react-scripts": "4.0.1",
+ "react-toastify": "^6.2.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/public/locales/en/translations.json b/public/locales/en/translations.json
index 06ed6aa..e84a894 100644
--- a/public/locales/en/translations.json
+++ b/public/locales/en/translations.json
@@ -20,6 +20,7 @@
"Login": {
"Username": "Username",
"Password": "Password",
- "Label": "Login"
+ "Label": "Login",
+ "IncorrectCredentials": "Incorrect credentials."
}
}
diff --git a/public/locales/ro/translations.json b/public/locales/ro/translations.json
index 644e73e..856f529 100644
--- a/public/locales/ro/translations.json
+++ b/public/locales/ro/translations.json
@@ -11,6 +11,7 @@
"Login": {
"Username": "Utilizator",
"Password": "Parolă",
- "Label": "Autentificare"
+ "Label": "Autentificare",
+ "IncorrectCredentials": "Credențiale incorecte."
}
}
diff --git a/src/components/App.js b/src/components/App.js
index 681fd41..9a373a9 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -9,6 +9,8 @@ import {
ApplicationStateContext,
ApplicationDispatchContext
} from "../state/ApplicationContexts";
+import { ToastContainer, Slide } from "react-toastify";
+import "react-toastify/dist/ReactToastify.css";
const App = () => {
//il fac pt test dar e gresit. daca va fi un singur state se va redesena toata aplicatia de fiecare data.
@@ -19,11 +21,26 @@ const App = () => {
]);
return (
-
-
-
-
-
+ <>
+
+
+
+
+
+
+ >
);
};
diff --git a/src/features/login/components/LoginContainer.js b/src/features/login/components/LoginContainer.js
index 60f784b..a23f64c 100644
--- a/src/features/login/components/LoginContainer.js
+++ b/src/features/login/components/LoginContainer.js
@@ -5,10 +5,14 @@ import {
ApplicationStateContext,
ApplicationDispatchContext
} from "../../../state/ApplicationContexts";
+import { useToast } from "../../../hooks";
+import { useTranslation } from "react-i18next";
const LoginContainer = () => {
const state = useContext(ApplicationStateContext);
const dispatchActions = useContext(ApplicationDispatchContext);
+ const { error } = useToast();
+ const { t } = useTranslation();
const handleChange = prop => event => {
dispatchActions.onCredentialsChange(prop, event.target.value);
@@ -16,7 +20,15 @@ const LoginContainer = () => {
const handleLogin = async () => {
const { userName, password } = state.credentials;
- await authenticate(userName, password);
+
+ try {
+ const response = await authenticate(userName, password);
+ if (response.status === "BAD_CREDENTIALS") {
+ error(t("Login.IncorrectCredentials"));
+ }
+ } catch (err) {
+ error(err.message);
+ }
};
return (
diff --git a/src/hooks/index.js b/src/hooks/index.js
new file mode 100644
index 0000000..bc64692
--- /dev/null
+++ b/src/hooks/index.js
@@ -0,0 +1 @@
+export { useToast } from "./useToast";
diff --git a/src/hooks/useAuthorizationToken.js b/src/hooks/useAuthorizationToken.js
deleted file mode 100644
index 92ebf3a..0000000
--- a/src/hooks/useAuthorizationToken.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { useContext } from "react";
-import { ApplicationStateContext } from "../state/ApplicationContexts";
-
-export const useAuthorizationToken = () => {
- const state = useContext(ApplicationStateContext);
- return state.security.authorization.token;
-};
diff --git a/src/hooks/useToast.js b/src/hooks/useToast.js
new file mode 100644
index 0000000..22305c7
--- /dev/null
+++ b/src/hooks/useToast.js
@@ -0,0 +1,11 @@
+import { toast } from "react-toastify";
+
+export const useToast = () => {
+ const info = message => toast.info(message);
+ const success = message => toast.success(message);
+ const warning = message => toast.warning(message);
+ const error = message => toast.error(message);
+ const dark = message => toast.dark(message);
+
+ return { info, success, warning, error, dark };
+};
diff --git a/src/utils/identity.js b/src/utils/identity.js
index 298f25e..f7e105f 100644
--- a/src/utils/identity.js
+++ b/src/utils/identity.js
@@ -14,10 +14,12 @@ const authenticate = async (username, password) => {
method: "post"
};
- const token = await request(url, options);
- setItem(storageKeys.TOKEN, token);
+ const response = await request(url, options);
+ if (response.status === "SUCCESS") {
+ setItem(storageKeys.TOKEN, response.token);
+ }
- return token;
+ return response;
};
export { storageKeys, authenticate };