From 23ec2b05ab39fc283669b43b9c72ed98e6f70ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mod=C3=A9e?= <bjomo323@student.liu.se> Date: Sat, 6 Mar 2021 10:19:15 +0000 Subject: [PATCH] Resolve "Add redux" --- .vs/ProjectSettings.json | 3 + .vs/VSWorkspaceState.json | 6 ++ .vs/slnx.sqlite | Bin 0 -> 90112 bytes .vs/teknikattan-scoring-system/v16/.suo | Bin 0 -> 15360 bytes client/.eslintrc | 47 ++++----- client/Redux-readme.txt | 71 +++++++++++++ client/package-lock.json | 94 ++++++++++++++++-- client/package.json | 6 ++ client/src/actions/Action_Explanation.txt | 8 ++ client/src/actions/communication.js | 62 ++++++++++++ client/src/actions/login.js | 29 ++++++ client/src/actions/types.js | 11 ++ client/src/index.tsx | 33 +++++- .../src/middleware/Middleware_Explanation.txt | 6 ++ client/src/reducers/Reducer_Explanation.txt | 7 ++ client/src/reducers/allReducers.js | 11 ++ client/src/reducers/isLoggedIn.js | 9 ++ 17 files changed, 367 insertions(+), 36 deletions(-) create mode 100644 .vs/ProjectSettings.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 .vs/slnx.sqlite create mode 100644 .vs/teknikattan-scoring-system/v16/.suo create mode 100644 client/Redux-readme.txt create mode 100644 client/src/actions/Action_Explanation.txt create mode 100644 client/src/actions/communication.js create mode 100644 client/src/actions/login.js create mode 100644 client/src/actions/types.js create mode 100644 client/src/middleware/Middleware_Explanation.txt create mode 100644 client/src/reducers/Reducer_Explanation.txt create mode 100644 client/src/reducers/allReducers.js create mode 100644 client/src/reducers/isLoggedIn.js diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 00000000..f8b48885 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 00000000..6b611411 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..2fd9f25a43f737391cedd7aaffa61ebf778acf2a GIT binary patch literal 90112 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 literal 0 HcmV?d00001 diff --git a/.vs/teknikattan-scoring-system/v16/.suo b/.vs/teknikattan-scoring-system/v16/.suo new file mode 100644 index 0000000000000000000000000000000000000000..39e2dc63c325f04b906b01016e830aa1112dcaab GIT binary patch literal 15360 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 HkL>8b@TiC; literal 0 HcmV?d00001 diff --git a/client/.eslintrc b/client/.eslintrc index 7e2cadb0..9234ebf1 100644 --- a/client/.eslintrc +++ b/client/.eslintrc @@ -1,26 +1,27 @@ { - "parser": "@typescript-eslint/parser", - "parserOptions": { - "sourceType": "module", - "project": [ - "tsconfig.json" - ] - }, - "ecmaFeatures": { - "jsx": true - }, - "settings": { - "react": { - "version": "detect" + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module", + "project": [ + "tsconfig.json" + ] + }, + "ecmaFeatures": { + "jsx": true + }, + "settings": { + "react": { + "version": "detect" + } + }, + "extends": [ + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "prettier/@typescript-eslint", + "plugin:prettier/recommended" + ], + "rules": { + "prettier/prettier": ["warn"] } - }, - "extends": [ - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended", - "prettier/@typescript-eslint", - "plugin:prettier/recommended" - ], - "rules": { - "prettier/prettier": ["warn"] } -} \ No newline at end of file + \ No newline at end of file diff --git a/client/Redux-readme.txt b/client/Redux-readme.txt new file mode 100644 index 00000000..7a20ee65 --- /dev/null +++ b/client/Redux-readme.txt @@ -0,0 +1,71 @@ + +This file is a short description of what Redux is, +to learn more about redux, visit https://redux.js.org/ + + +====Install=============================================== +To install Redux type the following in the terminal: + +npm install redux react-redux +npm install @reduxjs/toolkit + +If you have not done so already install axios: + +npm install react-axios +npm install axios + +Also, a good tool to use is the browser plugin. This allows you to se the state in real time. +It even has a useful playback feature. install it here: + +Chrome: +https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd + +Firefox: +https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/ +========================================================= + +What is Redux? + +Redux is a pattern and library for managing and updating +application state, using events called "actions". It serves +as a centralized store for state that needs to be used +across your entire application, with rules ensuring that +the state can only be updated in a predictable fashion. + +The center of every Redux application is the store. +A "store" is a container that holds your application's +global state. + +A store is a JavaScript object with a few special functions +and abilities that make it different than a plain global object: + +- You must never directly modify or change the state that is +kept inside the Redux store + +- Instead, the only way to cause an update to the state is to +create a plain action object that describes "something that +happened in the application", and then dispatch the action to +the store to tell it what happened. + +- When an action is dispatched, the store runs the root reducer +function, and lets it calculate the new state based on the old +state and the action +Finally, the store notifies subscribers that the state has been +updated so the UI can be updated with the new data. + + +Redux uses several types of code: +- Actions are plain objects with a type field, and describe +"what happened" in the app + +- Reducers are functions that calculate a new state value +based on previous state + an action + +- A Redux store runs the root reducer whenever an action +is dispatched + +Cite: https://redux.js.org/tutorials/fundamentals/part-1-overview + + +More useful links on the subject: +https://www.youtube.com/watch?v=CVpUuw9XSjY \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index d6c2bd5b..ca2a06eb 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1895,6 +1895,17 @@ } } }, + "@reduxjs/toolkit": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.5.0.tgz", + "integrity": "sha512-E/FUraRx+8guw9Hlg/Ja8jI/hwCrmIKed8Annt9YsZw3BQp+F24t5I5b2OWR6pkEHY4hn1BgP08FrTZFRKsdaQ==", + "requires": { + "immer": "^8.0.0", + "redux": "^4.0.0", + "redux-thunk": "^2.3.0", + "reselect": "^4.0.0" + } + }, "@rollup/plugin-node-resolve": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", @@ -2312,6 +2323,16 @@ "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==", "dev": true }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dev": true, + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -2414,6 +2435,18 @@ "@types/react": "*" } }, + "@types/react-redux": { + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", + "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", + "dev": true, + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "@types/react-router": { "version": "5.1.11", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.11.tgz", @@ -7844,9 +7877,9 @@ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "immer": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/immer/-/immer-7.0.9.tgz", - "integrity": "sha512-Vs/gxoM4DqNAYR7pugIxi0Xc8XAun/uy7AQu4fLLqaTBHxjOP9pJ266Q9MWA/ly4z6rAFZbvViOtihxUZ7O28A==" + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", + "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==" }, "import-cwd": { "version": "2.1.0", @@ -11033,9 +11066,9 @@ } }, "open": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.0.tgz", - "integrity": "sha512-PGoBCX/lclIWlpS/R2PQuIR4NJoXh6X5AwVzE7WXnWRGvHg7+4TBCgsujUgiPpm0K1y4qvQeWnCWVTpTKZBtvA==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "requires": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -12771,10 +12804,15 @@ "whatwg-fetch": "^3.4.1" } }, + "react-axios": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-axios/-/react-axios-2.0.4.tgz", + "integrity": "sha512-QsTq7C/NwsjfrSmFVxPo29BdX6DtLpRF0fZTJv5/R4BanOm+c4639B3Xb4lF83ZfAOX5IW8XG7htz4V+WNF+WA==" + }, "react-dev-utils": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.2.tgz", - "integrity": "sha512-xG7GlMoYkrgc2M1kDCHKRywXMDbFnjOB+/VzpytQyYBusEzR8NlGTMmUbvN86k94yyKu5XReHB8eZC2JZrNchQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.3.tgz", + "integrity": "sha512-4lEA5gF4OHrcJLMUV1t+4XbNDiJbsAWCH5Z2uqlTqW6dD7Cf5nEASkeXrCI/Mz83sI2o527oBIFKVMXtRf1Vtg==", "requires": { "@babel/code-frame": "7.10.4", "address": "1.1.2", @@ -12789,7 +12827,7 @@ "global-modules": "2.0.0", "globby": "11.0.1", "gzip-size": "5.1.1", - "immer": "7.0.9", + "immer": "8.0.1", "is-root": "2.1.0", "loader-utils": "2.0.0", "open": "^7.0.2", @@ -12902,6 +12940,18 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-redux": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.2.tgz", + "integrity": "sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA==", + "requires": { + "@babel/runtime": "^7.12.1", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.13.1" + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -13223,6 +13273,25 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", + "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "redux-devtools-extension": { + "version": "2.13.8", + "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz", + "integrity": "sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg==" + }, + "redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -13449,6 +13518,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "reselect": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" + }, "resolve": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", diff --git a/client/package.json b/client/package.json index 4d2df9fc..58910bbf 100644 --- a/client/package.json +++ b/client/package.json @@ -6,6 +6,7 @@ "@material-ui/core": "^4.11.3", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.57", + "@reduxjs/toolkit": "^1.5.0", "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.6.3", @@ -16,14 +17,19 @@ "axios": "^0.21.1", "formik": "^2.2.6", "react": "^17.0.1", + "react-axios": "^2.0.4", "react-dom": "^17.0.1", + "react-redux": "^7.2.2", "react-router-dom": "^5.2.0", "react-scripts": "4.0.2", + "redux": "^4.0.5", + "redux-devtools-extension": "^2.13.8", "typescript": "^4.1.3", "web-vitals": "^1.1.0", "yup": "^0.32.9" }, "devDependencies": { + "@types/react-redux": "^7.1.16", "@types/react-router-dom": "^5.1.7", "@typescript-eslint/eslint-plugin": "4.2.0", "@typescript-eslint/parser": "4.2.0", diff --git a/client/src/actions/Action_Explanation.txt b/client/src/actions/Action_Explanation.txt new file mode 100644 index 00000000..dec743a1 --- /dev/null +++ b/client/src/actions/Action_Explanation.txt @@ -0,0 +1,8 @@ +An action is a plain JavaScript object that has a type field. +The actions, the events that occur in the app based on user input, +and trigger updates in the state + +You can think of an action as an event that describes something +that happened in the application. + +https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow \ No newline at end of file diff --git a/client/src/actions/communication.js b/client/src/actions/communication.js new file mode 100644 index 00000000..587f431e --- /dev/null +++ b/client/src/actions/communication.js @@ -0,0 +1,62 @@ +import Types from "./types.js"; + +export function axiosPost(path, data, config = undefined, + startCB = undefined, successCB = undefined, errorCB = undefined){ + return { + type: Types.AXIOS_POST, + path, + data, + config, + startCB, + successCB, + errorCB + } +} + +export function axiosPostSuccess(path, data, previousAction){ + return { + type: Types.AXIOS_POST_SUCCESS, + path, + data, + previousAction + } +} + +export function axiosPostError(path, data, previousAction){ + return { + type: Types.AXIOS_POST_ERROR, + path, + data, + previousAction + } +} + +export function axiosGet(path, data, config = undefined, startCB = undefined, successCB = undefined, errorCB = undefined) { + return { + type: Types.AXIOS_GET, + path, + data, + config, + startCB, + successCB, + errorCB + } +} + +export function axiosGetSuccess(path, data, previousAction){ + return { + type: Types.AXIOS_GET_SUCCESS, + path, + data, + previousAction + } +} + +export function axiosGetError(path, data, previousAction){ + return { + type: Types.AXIOS_GET_ERROR, + path, + data, + previousAction + } +} diff --git a/client/src/actions/login.js b/client/src/actions/login.js new file mode 100644 index 00000000..3ad925a1 --- /dev/null +++ b/client/src/actions/login.js @@ -0,0 +1,29 @@ + +export const login = () => { + return{ + type: 'SIGN_IN' + }; +}; + + + + +/* +// Old code that can be used for comparison + +export function login(name, email, id, token) { + return { + type: Types.USER_LOGIN, + name, + email, + id, + token + } +} + +export function logout() { + return { + type: Types.USER_LOGOUT, + } +} +*/ \ No newline at end of file diff --git a/client/src/actions/types.js b/client/src/actions/types.js new file mode 100644 index 00000000..3d640d40 --- /dev/null +++ b/client/src/actions/types.js @@ -0,0 +1,11 @@ +export default { + AXIOS_GET: "AXIOS_GET", + AXIOS_GET_SUCCESS: "AXIOS_GET_SUCCESS", + AXIOS_GET_ERROR: "AXIOS_GET_ERROR", + + AXIOS_POST: "AXIOS_POST", + AXIOS_POST_SUCCESS: "AXIOS_POST_SUCCESS", + AXIOS_POST_ERROR: "AXIOS_POST_ERROR", + + +} diff --git a/client/src/index.tsx b/client/src/index.tsx index e7b11a23..e6048321 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -1,13 +1,40 @@ import React from 'react' import ReactDOM from 'react-dom' +import { Provider } from 'react-redux' +import { compose, createStore } from 'redux' import App from './App' import './index.css' +import allReducers from './reducers/allReducers' import reportWebVitals from './reportWebVitals' +/* + TypeScript does not know the type of the property. + Therefore, you will get the error; Property ‘__REDUX_DEVTOOLS_EXTENSION_COMPOSE__’ + does not exist on type ‘Window’. Hence, you need to add the property to the global window as below. +*/ +declare global { + interface Window { + __REDUX_DEVTOOLS_EXTENSION__: typeof compose + } +} + +// Create an Advanced global store with the name "store" +// const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose // allows Mozilla plugin to view state in a GUI, https://github.com/zalmoxisus/redux-devtools-extension#13-use-redux-devtools-extension-package-from-npm +// const store = createStore(allReducers, composeEnhancers(applyMiddleware())) + +// simple store with plugin +const store = createStore( + allReducers, + window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() +) + +// Provider wraps the app component so that it can access store ReactDOM.render( - <React.StrictMode> - <App /> - </React.StrictMode>, + <Provider store={store}> + <React.StrictMode> + <App /> + </React.StrictMode> + </Provider>, document.getElementById('root') ) diff --git a/client/src/middleware/Middleware_Explanation.txt b/client/src/middleware/Middleware_Explanation.txt new file mode 100644 index 00000000..dc4e91ab --- /dev/null +++ b/client/src/middleware/Middleware_Explanation.txt @@ -0,0 +1,6 @@ +Redux middleware provides a third-party extension point between dispatching an action, +and the moment it reaches the reducer. People use Redux middleware for logging, +crash reporting, talking to an asynchronous API, routing, and more. + + +https://redux.js.org/tutorials/fundamentals/part-4-store \ No newline at end of file diff --git a/client/src/reducers/Reducer_Explanation.txt b/client/src/reducers/Reducer_Explanation.txt new file mode 100644 index 00000000..dea1357b --- /dev/null +++ b/client/src/reducers/Reducer_Explanation.txt @@ -0,0 +1,7 @@ +A reducer is a function that receives the current state and an action object, +decides how to update the state if necessary, and returns the new state: +(state, action) => newState. +You can think of a reducer as an event listener which handles events based +on the received action (event) type. + +https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow \ No newline at end of file diff --git a/client/src/reducers/allReducers.js b/client/src/reducers/allReducers.js new file mode 100644 index 00000000..2bfcd5ea --- /dev/null +++ b/client/src/reducers/allReducers.js @@ -0,0 +1,11 @@ +// Combines all the reducers so that we only have to pass "one" reducer to the store in src/index.tsx + + +import { combineReducers } from 'redux'; +import loggedInReducer from './isLoggedIn'; + +const allReducers = combineReducers({ + // name: state + isLoggedIn: loggedInReducer // You can write "loggedInReducer" because its the same as "loggedInReducer: loggedInReducer" +}); +export default allReducers; \ No newline at end of file diff --git a/client/src/reducers/isLoggedIn.js b/client/src/reducers/isLoggedIn.js new file mode 100644 index 00000000..b665894a --- /dev/null +++ b/client/src/reducers/isLoggedIn.js @@ -0,0 +1,9 @@ +const loggedInReducer = (state = false, action) => { // isLoggedIn has an initial state of false + switch (action.type) { + case 'SIGN_IN': + return !state; + default: + return state; + } +} +export default loggedInReducer -- GitLab