├── .DS_Store
├── 1.redux-core-only
├── .DS_Store
├── 1.redux-counter-project-1
│ ├── counter.js
│ └── package.json
├── 2.redux-posts-project-2
│ ├── package.json
│ └── posts.js
└── 3.redux-only-posts-async-project-3
│ ├── app.js
│ └── package.json
├── 2.react-redux-only
├── .DS_Store
├── react-redux-notes-app-project-4
│ ├── README.md
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── components
│ │ │ ├── AddNotes.js
│ │ │ ├── Form.css
│ │ │ ├── NotesList.css
│ │ │ └── NotesList.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ ├── redux
│ │ │ ├── actions
│ │ │ │ ├── notesAction.js
│ │ │ │ └── notesActionTypes.js
│ │ │ ├── reducer
│ │ │ │ └── noteReducer.js
│ │ │ └── store
│ │ │ │ └── store.js
│ │ ├── reportWebVitals.js
│ │ └── setupTests.js
│ └── yarn.lock
└── react-redux-posts-app-project-5
│ ├── README.md
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ └── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ ├── Form.css
│ ├── Header.css
│ ├── Posts.css
│ ├── PostsList.js
│ └── SearchPost.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ ├── actions
│ │ ├── postActionTypes.js
│ │ └── postActions.js
│ ├── reducers
│ │ └── postReducer.js
│ └── store
│ │ └── store.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ └── utils
│ └── apiURL.js
├── 3.redux-toolkit-core-only
├── .DS_Store
├── 1.rtk-only-counter-project-6
│ ├── .DS_Store
│ ├── app.js
│ └── package.json
└── 2.rtk-only-posts-project-7
│ ├── app.js
│ └── package.json
├── README.md
├── react-redux-notes-app-final
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ ├── AddNotes.js
│ ├── Form.css
│ ├── NotesList.css
│ └── NotesList.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ ├── actions
│ │ ├── notesAction.js
│ │ └── notesActionTypes.js
│ ├── reducer
│ │ └── noteReducer.js
│ └── store
│ │ └── store.js
│ ├── reportWebVitals.js
│ └── setupTests.js
├── react-redux-notes-app-starter
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ ├── AddNotes.js
│ ├── Form.css
│ ├── NotesList.css
│ └── NotesList.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── react-redux-posts-app-final
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ │ ├── Form.css
│ │ ├── Header.css
│ │ ├── Posts.css
│ │ ├── PostsList.js
│ │ └── SearchPost.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── actions
│ │ │ ├── postActionTypes.js
│ │ │ └── postActions.js
│ │ ├── reducers
│ │ │ └── postReducer.js
│ │ └── store
│ │ │ └── store.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ └── utils
│ │ └── apiURL.js
└── yarn.lock
├── react-redux-posts-app-starter
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── components
│ ├── Form.css
│ ├── Header.css
│ ├── Posts.css
│ ├── PostsList.js
│ └── SearchPost.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── rtk-income-expenses-project-final
├── .DS_Store
├── README.md
├── package.json
├── postcss.config.js
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.js
│ ├── App.test.js
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── AuthRoute
│ │ │ └── AuthRoute.js
│ │ ├── Dashboard
│ │ │ ├── AccountDetails.js
│ │ │ ├── AccountList.js
│ │ │ ├── AccountSummary.js
│ │ │ ├── MainDashBoard.js
│ │ │ └── TransactionList.js
│ │ ├── Forms
│ │ │ ├── AddAccount.js
│ │ │ ├── AddTransaction.js
│ │ │ ├── EditAccount.js
│ │ │ ├── EditTransaction.js
│ │ │ ├── Login.js
│ │ │ └── Register.js
│ │ ├── HomePage
│ │ │ └── Home.js
│ │ └── Navbar
│ │ │ └── Navbar.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── redux
│ │ ├── slice
│ │ │ ├── accounts
│ │ │ │ └── accountsSlice.js
│ │ │ ├── transactions
│ │ │ │ └── transactionSlice.js
│ │ │ └── users
│ │ │ │ └── usersSlice.js
│ │ └── store
│ │ │ └── store.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ └── utils
│ │ └── baseURL.js
├── tailwind.config.js
└── yarn-error.log
├── rtk-income-expenses-project-starter
├── .DS_Store
├── README.md
├── package.json
├── postcss.config.js
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.js
│ ├── App.test.js
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── Dashboard
│ │ │ ├── AccountDetails.js
│ │ │ ├── AccountList.js
│ │ │ ├── AccountSummary.js
│ │ │ ├── MainDashBoard.js
│ │ │ └── TransactionList.js
│ │ ├── Forms
│ │ │ ├── AddAccount.js
│ │ │ ├── AddTransaction.js
│ │ │ ├── EditAccount.js
│ │ │ ├── EditTransaction.js
│ │ │ ├── Login.js
│ │ │ └── Register.js
│ │ ├── HomePage
│ │ │ └── Home.js
│ │ └── Navbar
│ │ │ └── Navbar.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── tailwind.config.js
└── yarn-error.log
└── rtk-posts-app-final
├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.js
├── App.test.js
├── components
│ ├── Form.css
│ ├── Header.css
│ ├── Posts.css
│ ├── PostsList.js
│ └── SearchPost.js
├── index.css
├── index.js
├── logo.svg
├── redux
│ ├── slice
│ │ └── postsSlice.js
│ └── store
│ │ └── store.js
├── reportWebVitals.js
├── setupTests.js
└── utils
│ └── apiURL.js
└── yarn.lock
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/.DS_Store
--------------------------------------------------------------------------------
/1.redux-core-only/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/1.redux-core-only/.DS_Store
--------------------------------------------------------------------------------
/1.redux-core-only/1.redux-counter-project-1/counter.js:
--------------------------------------------------------------------------------
1 | const redux = require("redux");
2 | const { createStore } = redux;
3 |
4 | //Counter Action Types
5 | const INCREMENT = "INCREMENT";
6 | const DECREMENT = "DECREMENT";
7 | const RESET = "RESET";
8 | const INCREMENT_BY_AMT = "INCREMENT_BY_AMT";
9 |
10 | //Counter initial state
11 | const initialState = {
12 | count: 0,
13 | };
14 | {
15 | type: "Add";
16 | }
17 | //Counter Action Creators
18 | const incrementAction = () => {
19 | return {
20 | type: INCREMENT,
21 | };
22 | };
23 |
24 | const decrementAction = () => {
25 | return {
26 | type: DECREMENT,
27 | };
28 | };
29 |
30 | const resetAction = () => {
31 | return {
32 | type: RESET,
33 | };
34 | };
35 |
36 | const incrementByAmtAction = (amt) => {
37 | return {
38 | type: INCREMENT_BY_AMT,
39 | payload: amt,
40 | };
41 | };
42 |
43 | //Counter Reducer
44 | const counterReducer = (state = initialState, action) => {
45 | switch (action.type) {
46 | case INCREMENT:
47 | return {
48 | count: state.count + 1,
49 | };
50 | case DECREMENT:
51 | return {
52 | count: state.count - 1,
53 | };
54 | case RESET:
55 | return {
56 | count: 0,
57 | };
58 | case INCREMENT_BY_AMT:
59 | return {
60 | count: state.count + action.payload,
61 | };
62 | default:
63 | return state;
64 | }
65 | };
66 |
67 | //Counter store
68 | const store = createStore(counterReducer);
69 |
70 | //Subscribe: It means that whenever the state changes, the callback function will be called.
71 |
72 | const unSubscribe = store.subscribe(() => {
73 | console.log(store.getState());
74 | });
75 |
76 | //Dispatch
77 | store.dispatch(incrementAction());
78 | store.dispatch(incrementAction());
79 | store.dispatch(incrementByAmtAction(5));
80 |
--------------------------------------------------------------------------------
/1.redux-core-only/1.redux-counter-project-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "redux-counter",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "redux": "^4.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/1.redux-core-only/2.redux-posts-project-2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "redux-counter",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "redux": "^4.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/1.redux-core-only/2.redux-posts-project-2/posts.js:
--------------------------------------------------------------------------------
1 | const redux = require("redux");
2 | const { createStore } = redux;
3 | //Add Post Action Type
4 | const ADD_POST = "ADD_POST";
5 | const REMOVE_POST = "REMOVE_POST";
6 |
7 | //Post initial state
8 | const initialState = {
9 | posts: [],
10 | };
11 |
12 | //Add Post Action Creator
13 | const addPostAction = post => {
14 | return {
15 | type: ADD_POST,
16 | post,
17 | };
18 | };
19 |
20 | //Remove Post Action Creator
21 | const removePostAction = id => {
22 | return {
23 | type: REMOVE_POST,
24 | id,
25 | };
26 | };
27 |
28 | //Post Reducer
29 | postsReducer = (state = initialState, action) => {
30 | switch (action.type) {
31 | case ADD_POST:
32 | return {
33 | posts: [...state.posts, action.post],
34 | };
35 | case REMOVE_POST:
36 | return {
37 | posts: state.posts.filter(post => post.id !== action.id),
38 | };
39 | default:
40 | return state;
41 | }
42 | };
43 |
44 | //Post store
45 | const store = createStore(postsReducer);
46 |
47 | //Subscribe: It means that whenever the state changes, the callback function will be called.
48 | const unSubscribe = store.subscribe(() => {
49 | console.log(store.getState());
50 | });
51 |
52 | //Dispatch
53 | store.dispatch(addPostAction({ id: 1, title: "Post 1" }));
54 | store.dispatch(addPostAction({ id: 2, title: "Post 2" }));
55 |
56 | store.dispatch(removePostAction(1));
57 |
58 | unSubscribe();
59 |
--------------------------------------------------------------------------------
/1.redux-core-only/3.redux-only-posts-async-project-3/app.js:
--------------------------------------------------------------------------------
1 | const { applyMiddleware, createStore } = require("redux");
2 | const axios = require("axios");
3 | const thunkMiddleware = require("redux-thunk").default;
4 |
5 | //Post action types
6 | const FETCH_POSTS_REQUEST = "FETCH_POSTS_REQUEST";
7 | const FETCH_POSTS_SUCCESS = "FETCH_POSTS_SUCCESS";
8 | const FETCH_POSTS_FAILURE = "FETCH_POSTS_FAILURE";
9 |
10 | //Async action creator
11 | const fetchPostRequest = () => {
12 | return {
13 | type: FETCH_POSTS_REQUEST,
14 | };
15 | };
16 |
17 | //success action creator
18 | const fetchPostSuccess = (posts) => {
19 | return {
20 | type: FETCH_POSTS_SUCCESS,
21 | payload: posts,
22 | };
23 | };
24 |
25 | //failure action creator
26 | const fetchPostFailure = (error) => {
27 | return {
28 | type: FETCH_POSTS_FAILURE,
29 | payload: error,
30 | };
31 | };
32 |
33 | //Async action creator
34 | const fetchPosts = () => {
35 | return async (dispatch) => {
36 | dispatch(fetchPostRequest());
37 | try {
38 | const response = await axios.get(
39 | "https://jsonplaceholder.typicode.com/posts"
40 | );
41 | dispatch(fetchPostSuccess(response));
42 | } catch (error) {
43 | dispatch(fetchPostFailure(error.message));
44 | }
45 | };
46 | };
47 |
48 | //Post reducer
49 | const postReducer = (
50 | state = { posts: [], loading: false, error: "" },
51 | action
52 | ) => {
53 | switch (action.type) {
54 | case FETCH_POSTS_REQUEST:
55 | return {
56 | ...state,
57 | loading: true,
58 | };
59 | case FETCH_POSTS_SUCCESS:
60 | return {
61 | ...state,
62 | loading: false,
63 | posts: action.payload,
64 | error: "",
65 | };
66 | case FETCH_POSTS_FAILURE:
67 | return {
68 | ...state,
69 | loading: false,
70 | posts: [],
71 | error: action.payload,
72 | };
73 | default:
74 | return state;
75 | }
76 | };
77 |
78 | //store
79 | const store = createStore(postReducer, applyMiddleware(thunkMiddleware));
80 |
81 | //subscribe
82 | store.subscribe(() => {
83 | console.log(store.getState().posts);
84 | });
85 |
86 | //dispatch
87 | store.dispatch(fetchPosts());
88 |
--------------------------------------------------------------------------------
/1.redux-core-only/3.redux-only-posts-async-project-3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "redux-only",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "axios": "^0.27.2",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2.react-redux-only/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/.DS_Store
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-redux": "^8.0.4",
13 | "react-scripts": "5.0.1",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.1",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "redux-devtools-extension": "^2.13.9"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/react-redux-notes-app-project-4/public/favicon.ico
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/react-redux-notes-app-project-4/public/logo192.png
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/react-redux-notes-app-project-4/public/logo512.png
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import AddNotes from "./components/AddNotes";
3 | import NotesList from "./components/NotesList";
4 |
5 | function App() {
6 | return (
7 |
11 | );
12 | }
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/components/AddNotes.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useDispatch } from "react-redux";
3 | import { addNoteAction } from "../redux/actions/notesAction";
4 | import "./Form.css";
5 |
6 | const AddNotes = () => {
7 | //dispatch
8 | const dispatch = useDispatch();
9 | const [note, setNote] = useState({
10 | title: "",
11 | content: "",
12 | });
13 |
14 | const handleChange = e => {
15 | setNote({
16 | ...note,
17 | [e.target.name]: e.target.value,
18 | });
19 | };
20 |
21 | const handleSubmit = e => {
22 | //prevent empty notes
23 | if (note.title === "" || note.content === "") {
24 | return alert("Please fill in the form");
25 | }
26 | e.preventDefault();
27 | //dispatch action
28 | dispatch(addNoteAction(note));
29 | console.log(note);
30 | //reset form
31 | setNote({
32 | title: "",
33 | content: "",
34 | });
35 | };
36 |
37 | return (
38 |
39 |
40 |
Notes Taking App Built with React Redux
41 |
42 | This is a simple notes taking app built with React Redux. You can add
43 |
44 |
45 |
65 |
Enroll in the course
66 |
67 | );
68 | };
69 |
70 | export default AddNotes;
71 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .formContainer {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | justify-content: center;
6 | width: 100%;
7 | padding: 20px;
8 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
9 | }
10 | h3 {
11 | margin: 0;
12 | padding: 0;
13 | font-size: 2.5rem;
14 | font-weight: bold;
15 | }
16 |
17 | p {
18 | margin: 10px;
19 | padding: 0;
20 | font-size: 1rem;
21 | font-weight: 400;
22 | }
23 | form {
24 | display: flex;
25 | flex-direction: row;
26 | align-items: center;
27 | justify-content: center;
28 | width: auto;
29 | height: 100%;
30 | }
31 |
32 | form input {
33 | width: 80%;
34 | height: 100%;
35 | border: 1px solid #ccc;
36 | outline: none;
37 | padding: 10px;
38 | font-size: 1.1rem;
39 | border-radius: 5px;
40 | margin: 0 10px;
41 | }
42 |
43 | .btn-enroll {
44 | background-color: #4caf50;
45 | color: #fff;
46 | }
47 |
48 | button {
49 | }
50 | .add-btn {
51 | background-color: #4caf50;
52 | color: #fff;
53 | width: 100px;
54 | height: 40px;
55 | border: none;
56 | outline: none;
57 | border-radius: 5px;
58 | font-size: 1.1rem;
59 | cursor: pointer;
60 | width: 70%;
61 | }
62 | a {
63 | text-decoration: none;
64 | color: white;
65 | padding: 5px;
66 | border-radius: 5px;
67 | background-color: red;
68 | padding: 10px;
69 | margin: 10px;
70 | }
71 |
72 | a:hover {
73 | transform: scale(1.1);
74 | transition: all 0.3s ease-in-out;
75 | }
76 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/components/NotesList.css:
--------------------------------------------------------------------------------
1 | .item-container {
2 | display: flex;
3 | flex-direction: row;
4 | justify-content: center;
5 | width: 100%;
6 | align-items: center;
7 | padding: 10px;
8 | }
9 |
10 | .item-content {
11 | width: 800px;
12 | padding: 10px;
13 | background-color: white;
14 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
15 | }
16 |
17 | .item-content button {
18 | width: 100%;
19 | height: 40px;
20 | border: none;
21 | outline: none;
22 | border-radius: 5px;
23 | font-size: 1.1rem;
24 | cursor: pointer;
25 | background-color: #4caf50;
26 | color: #fff;
27 | }
28 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/components/NotesList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import {
4 | deleteNoteAction,
5 | fetchNotesAction,
6 | } from "../redux/actions/notesAction";
7 |
8 | import "./NotesList.css";
9 |
10 | const NotesList = () => {
11 | //dispatch
12 | const dispatch = useDispatch();
13 | useEffect(() => {
14 | dispatch(fetchNotesAction());
15 | }, []);
16 | //get data from store
17 | const notes = useSelector(storeData => {
18 | return storeData.notes;
19 | });
20 |
21 | return (
22 | <>
23 | Notes List
24 |
25 | {notes.map(note => (
26 |
27 |
28 |
{note.title}
29 |
{note.content}
30 |
33 |
34 |
35 | ))}
36 | >
37 | );
38 | };
39 |
40 | export default NotesList;
41 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/index.css:
--------------------------------------------------------------------------------
1 | /* body {
2 | background-color: #f5f5f5;
3 | }
4 |
5 | code {
6 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
7 | monospace;
8 | } */
9 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import { Provider } from "react-redux";
4 | import "./index.css";
5 | import App from "./App";
6 |
7 | import reportWebVitals from "./reportWebVitals";
8 | import store from "./redux/store/store";
9 |
10 | const root = ReactDOM.createRoot(document.getElementById("root"));
11 | root.render(
12 |
13 |
14 |
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/redux/actions/notesAction.js:
--------------------------------------------------------------------------------
1 | import { ADD_NOTE, DELETE_NOTE, FETCH_NOTES } from "./notesActionTypes";
2 |
3 | //actions
4 | //Add note action creator
5 | export const addNoteAction = note => {
6 | return {
7 | type: ADD_NOTE,
8 | payload: note,
9 | };
10 | };
11 | //Delete note action creator
12 | export const deleteNoteAction = id => {
13 | return {
14 | type: DELETE_NOTE,
15 | payload: id,
16 | };
17 | };
18 | //Fetch notes action creator
19 | export const fetchNotesAction = () => {
20 | return {
21 | type: FETCH_NOTES,
22 | };
23 | };
24 | //store
25 | //dispatch
26 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/redux/actions/notesActionTypes.js:
--------------------------------------------------------------------------------
1 | export const ADD_NOTE = "ADD_NOTE";
2 | export const DELETE_NOTE = "DELETE_NOTE";
3 | export const FETCH_NOTES = "FETCH_NOTES";
4 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/redux/reducer/noteReducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | ADD_NOTE,
3 | DELETE_NOTE,
4 | FETCH_NOTES,
5 | } from "../actions/notesActionTypes";
6 |
7 | //Initialstate
8 | const initialstate = {
9 | notes: [],
10 | };
11 |
12 | //note reducer
13 | const notesReducer = (state = initialstate, action) => {
14 | switch (action.type) {
15 | case ADD_NOTE:
16 | //new note
17 | const newNote = {
18 | id: Math.random(),
19 | title: action.payload.title,
20 | content: action.payload.content,
21 | };
22 | //add note into storage
23 | const updatedNotes = [...state.notes, newNote];
24 | localStorage.setItem("notes", JSON.stringify(updatedNotes));
25 | return {
26 | notes: [...state.notes, newNote],
27 | };
28 | //fetch notes
29 | case FETCH_NOTES:
30 | return {
31 | notes: JSON.parse(localStorage.getItem("notes"))
32 | ? JSON.parse(localStorage.getItem("notes"))
33 | : [],
34 | };
35 | //Delete note
36 | case DELETE_NOTE:
37 | const filteredNotes = state.notes.filter(
38 | note => note.id !== action.payload
39 | );
40 | //Resave to localstorage
41 | localStorage.setItem("notes", JSON.stringify(filteredNotes));
42 | return {
43 | ...state,
44 | notes: filteredNotes,
45 | };
46 | default:
47 | return state;
48 | }
49 | };
50 |
51 | export default notesReducer;
52 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/redux/store/store.js:
--------------------------------------------------------------------------------
1 | import { createStore } from "redux";
2 | import { composeWithDevTools } from "redux-devtools-extension";
3 | import notesReducer from "../reducer/noteReducer";
4 |
5 | const store = createStore(notesReducer, composeWithDevTools());
6 |
7 | export default store;
8 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-notes-app-project-4/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-redux": "^8.0.5",
13 | "react-scripts": "5.0.1",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.2",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "redux-devtools-extension": "^2.13.9"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/react-redux-posts-app-project-5/public/favicon.ico
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/react-redux-posts-app-project-5/public/logo192.png
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/2.react-redux-only/react-redux-posts-app-project-5/public/logo512.png
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 |
3 | import NotesList from "./components/PostsList";
4 |
5 | function App() {
6 | return ;
7 | }
8 |
9 | export default App;
10 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .form-header {
2 | background-color: #22577a;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 | form {
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | justify-content: center;
12 | width: 100%;
13 | height: 100%;
14 | margin: 10px;
15 | }
16 |
17 | form input {
18 | border: 1px solid #ccc;
19 | outline: none;
20 | font-size: 1.1rem;
21 | border-radius: 5px;
22 | margin: 5px;
23 | padding: 5px;
24 | }
25 |
26 | form button {
27 | border: 1px solid #ccc;
28 | outline: none;
29 | color: #fff;
30 | cursor: pointer;
31 | padding: 8px;
32 | background-color: #22577a;
33 | width: 100px;
34 | border-radius: 5px;
35 | margin: 5px;
36 | }
37 |
38 | form button:hover {
39 | background-color: #1b435e;
40 | transform: scale(1.1);
41 | transition: all 0.2s ease-in-out;
42 | }
43 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/components/Header.css:
--------------------------------------------------------------------------------
1 | header {
2 | background-color: #333;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/components/Posts.css:
--------------------------------------------------------------------------------
1 | .posts-list {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | width: 100%;
6 | background-color: #f5f5f5;
7 | }
8 |
9 | .post-details {
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | width: 80%;
14 | margin: 10px;
15 | padding: 10px;
16 | border: 1px solid #fff;
17 | border-radius: 5px;
18 | background-color: #fff;
19 | }
20 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/components/PostsList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import SearchPost from "./SearchPost";
4 | import "./Posts.css";
5 | import { fetchPostsAction } from "../redux/actions/postActions";
6 |
7 | const PostsList = () => {
8 | //dispatch
9 | const dispatch = useDispatch();
10 | useEffect(() => {
11 | dispatch(fetchPostsAction());
12 | }, []);
13 |
14 | //get data from store
15 | const { loading, error, posts, post } = useSelector(data => data);
16 |
17 | console.log(loading, error, posts, post);
18 |
19 | return (
20 | <>
21 |
22 |
23 |
Total Posts {posts.length}
24 | {loading ? (
25 |
Loading
26 | ) : error ? (
27 |
28 | {error.response.status && "No Post Found"}
29 |
30 | ) : (
31 | posts.map(post => (
32 |
33 |
{post.title}
34 |
{post.body}
35 |
36 | ))
37 | )}
38 |
39 | >
40 | );
41 | };
42 |
43 | export default PostsList;
44 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/components/SearchPost.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useSelector, useDispatch } from "react-redux";
3 | import { fetchPostAction } from "../redux/actions/postActions";
4 |
5 | import "./Form.css";
6 | const SearchPost = () => {
7 | const dispatch = useDispatch();
8 | //search form state
9 | const [search, setSearch] = React.useState("");
10 | //search form submit handler
11 | const handleSubmit = e => {
12 | e.preventDefault();
13 | if (search === "") {
14 | return alert("Please provide a value");
15 | }
16 | dispatch(fetchPostAction(search));
17 | };
18 |
19 | return (
20 |
21 |
22 |
React Redux Project
23 |
24 | This project is a simple React Redux project that fetches data with
25 | search functionality from an API
26 |
27 |
28 |
37 |
38 | );
39 | };
40 |
41 | export default SearchPost;
42 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import reportWebVitals from "./reportWebVitals";
6 | import { Provider } from "react-redux";
7 | import store from "./redux/store/store";
8 |
9 | const root = ReactDOM.createRoot(document.getElementById("root"));
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/redux/actions/postActionTypes.js:
--------------------------------------------------------------------------------
1 | //notes action types
2 | export const FETCH_POSTS_SUCCESS = "FETCH_POSTS_SUCCESS";
3 | export const FETCH_POSTS_FAILURE = "FETCH_POSTS_FAILURE";
4 | export const FETCH_POSTS_REQUEST = "FETCH_POSTS_REQUEST";
5 |
6 | export const SEARCH_POST_REQUEST = "SEARCH_POST_REQUEST";
7 | export const SEARCH_POST_SUCCESS = "SEARCH_POST_SUCCESS";
8 | export const SEARCH_POST_FAILURE = "SEARCH_POST_FAILURE";
9 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/redux/actions/postActions.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import {
3 | FETCH_POSTS_SUCCESS,
4 | FETCH_POSTS_FAILURE,
5 | FETCH_POSTS_REQUEST,
6 | SEARCH_POST_FAILURE,
7 | SEARCH_POST_REQUEST,
8 | SEARCH_POST_SUCCESS,
9 | } from "./postActionTypes";
10 | const apiURL = "https://jsonplaceholder.typicode.com/posts";
11 | //Actions Creators
12 | //1. fetch posts (request started, success, error)
13 |
14 | //request started
15 | const fetchPostsRequest = () => {
16 | return {
17 | type: FETCH_POSTS_REQUEST,
18 | };
19 | };
20 |
21 | //success
22 | const fetchPostsSuccess = posts => {
23 | return {
24 | type: FETCH_POSTS_SUCCESS,
25 | payload: posts,
26 | };
27 | };
28 |
29 | //error action creator
30 | const fetchPostsErr = error => {
31 | return {
32 | type: FETCH_POSTS_FAILURE,
33 | payload: error,
34 | };
35 | };
36 |
37 | //fetch posts action
38 | export const fetchPostsAction = () => {
39 | return async dispatch => {
40 | //request action
41 | dispatch(fetchPostsRequest());
42 | try {
43 | //make http request
44 | const res = await axios.get(apiURL);
45 | //success action
46 | dispatch(fetchPostsSuccess(res.data));
47 | } catch (error) {
48 | //error action
49 | dispatch(fetchPostsErr(error));
50 | }
51 | };
52 | };
53 |
54 | //2. fetch post (request started, success, error)
55 | //request action
56 | const fetchPostRequest = () => {
57 | return {
58 | type: SEARCH_POST_REQUEST,
59 | };
60 | };
61 | //success
62 | const fetchPostSuccess = post => {
63 | return {
64 | type: SEARCH_POST_SUCCESS,
65 | payload: post,
66 | };
67 | };
68 |
69 | //error action creator
70 | const fetchPostErr = error => {
71 | return {
72 | type: SEARCH_POST_FAILURE,
73 | payload: error,
74 | };
75 | };
76 |
77 | //single post action
78 | export const fetchPostAction = id => {
79 | return async dispatch => {
80 | dispatch(fetchPostRequest());
81 | try {
82 | //make http request
83 | const res = await axios.get(`${apiURL}/${id}`);
84 | //success
85 | dispatch(fetchPostSuccess(res.data));
86 | } catch (error) {
87 | dispatch(fetchPostErr(error));
88 | }
89 | };
90 | };
91 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/redux/reducers/postReducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | FETCH_POSTS_SUCCESS,
3 | FETCH_POSTS_FAILURE,
4 | FETCH_POSTS_REQUEST,
5 | SEARCH_POST_FAILURE,
6 | SEARCH_POST_REQUEST,
7 | SEARCH_POST_SUCCESS,
8 | } from "../actions/postActionTypes";
9 |
10 | //initial state
11 | const initialState = {
12 | loading: false,
13 | error: "",
14 | posts: [],
15 | post: {},
16 | };
17 |
18 | //reducers
19 | export const postsReducer = (state = initialState, action) => {
20 | switch (action.type) {
21 | case FETCH_POSTS_REQUEST:
22 | return {
23 | ...state,
24 | loading: true,
25 | };
26 | //success
27 | case FETCH_POSTS_SUCCESS:
28 | return {
29 | ...state,
30 | posts: action.payload,
31 | loading: false,
32 | };
33 | //error
34 | case FETCH_POSTS_FAILURE:
35 | return {
36 | ...state,
37 | posts: [],
38 | error: action.payload,
39 | loading: false,
40 | };
41 | //========SEARCH SINGLE POST =======
42 | case SEARCH_POST_REQUEST:
43 | return {
44 | ...state,
45 | loading: true,
46 | };
47 | case SEARCH_POST_SUCCESS:
48 | return {
49 | ...state,
50 | posts: [action.payload],
51 | loading: false,
52 | };
53 | case SEARCH_POST_FAILURE:
54 | return {
55 | ...state,
56 | posts: [],
57 | error: action.payload,
58 | loading: false,
59 | };
60 | //return default state
61 | default:
62 | return state;
63 | }
64 | };
65 | //store
66 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/redux/store/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from "redux";
2 | import { composeWithDevTools } from "redux-devtools-extension";
3 | import reduxThunk from "redux-thunk";
4 | import { postsReducer } from "../reducers/postReducer";
5 |
6 | //combine all middlewares
7 | const middlewares = [reduxThunk];
8 | const middlewareEnhancers = applyMiddleware(...middlewares);
9 | const store = createStore(
10 | postsReducer,
11 | composeWithDevTools(middlewareEnhancers)
12 | );
13 |
14 | export default store;
15 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/2.react-redux-only/react-redux-posts-app-project-5/src/utils/apiURL.js:
--------------------------------------------------------------------------------
1 | const apiURL = "https://jsonplaceholder.typicode.com/posts";
2 | export default apiURL;
3 |
--------------------------------------------------------------------------------
/3.redux-toolkit-core-only/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/3.redux-toolkit-core-only/.DS_Store
--------------------------------------------------------------------------------
/3.redux-toolkit-core-only/1.rtk-only-counter-project-6/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/3.redux-toolkit-core-only/1.rtk-only-counter-project-6/.DS_Store
--------------------------------------------------------------------------------
/3.redux-toolkit-core-only/1.rtk-only-counter-project-6/app.js:
--------------------------------------------------------------------------------
1 | //configure store
2 | const { configureStore, createSlice } = require("@reduxjs/toolkit");
3 |
4 | //state for counter
5 | const initialState = {
6 | counter: 0,
7 | };
8 |
9 | //Slice
10 | const counterSlice = createSlice({
11 | name: "counter", //name of the slice
12 | initialState,
13 | reducers: {
14 | increment: state => {
15 | state.counter += 1;
16 | },
17 | decrement: state => {
18 | state.counter -= 1;
19 | },
20 |
21 | incrementByAmount: (state, action) => {
22 | state.counter += action.payload;
23 | },
24 | reset: state => {
25 | state.counter = 0;
26 | },
27 | },
28 | //extra reducers method 1
29 | // extraReducers: {
30 | // "notes/addNote": (state, action) => {
31 | // state.counter += 1;
32 | // },
33 | // },
34 | //The key we specify in the extraReducers object is the action name and the value in a differeent createSlice that we want to listen to
35 |
36 | //extra reducers method 2 (Most recommended)
37 | extraReducers: builder => {
38 | builder.addCase("notes/addNote", (state, action) => {
39 | state.counter += 1;
40 | });
41 | },
42 | });
43 |
44 | //Export actions
45 | const { increment, decrement, incrementByAmount, reset } = counterSlice.actions;
46 |
47 | //reducers
48 | const counterReducer = counterSlice.reducer;
49 |
50 | const store = configureStore({
51 | reducer: {
52 | counter: counterReducer,
53 | },
54 | });
55 |
56 | //subscribe to store
57 | const unSubscribe = store.subscribe(() => {
58 | console.log(store.getState());
59 | });
60 |
61 | //dispatch actions
62 | store.dispatch(increment());
63 | store.dispatch(increment());
64 | store.dispatch(incrementByAmount(10));
65 |
66 | //unsubscribe
67 | unSubscribe();
68 |
--------------------------------------------------------------------------------
/3.redux-toolkit-core-only/1.rtk-only-counter-project-6/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rtk-only",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "@reduxjs/toolkit": "^1.8.5",
14 | "axios": "^0.27.2",
15 | "redux-logger": "^3.0.6"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/3.redux-toolkit-core-only/2.rtk-only-posts-project-7/app.js:
--------------------------------------------------------------------------------
1 | const {
2 | createAsyncThunk,
3 | createSlice,
4 | configureStore,
5 | } = require("@reduxjs/toolkit");
6 | const axios = require("axios");
7 |
8 | const API = "https://jsonplaceholder.typicode.com/posts";
9 |
10 | //Initial state
11 | const initialState = {
12 | posts: [],
13 | loading: false,
14 | error: null,
15 | };
16 | //create Async Thunk
17 | const fetchPosts = createAsyncThunk("posts/fetchPosts", async () => {
18 | const res = await axios.get(API);
19 | return res.data; //grabbing the data only
20 | });
21 | //slice
22 |
23 | const postsSlice = createSlice({
24 | name: "posts",
25 | initialState,
26 | extraReducers: (builder) => {
27 | //Handle lifecycle - pending-success, rejected
28 | //pending
29 | builder.addCase(fetchPosts.pending, (state, action) => {
30 | state.loading = true;
31 | });
32 | //fulfilled
33 | builder.addCase(fetchPosts.fulfilled, (state, action) => {
34 | state.posts = action.payload;
35 | state.loading = false;
36 | });
37 | //rejected
38 | builder.addCase(fetchPosts.rejected, (state, action) => {
39 | state.posts = [];
40 | state.loading = false;
41 | state.error = action.payload;
42 | });
43 | },
44 | });
45 |
46 | //generate reducer
47 | const postsReducer = postsSlice.reducer;
48 |
49 | //store
50 | const store = configureStore({
51 | reducer: postsReducer,
52 | });
53 |
54 | //dispatch
55 | store.subscribe(() => {
56 | console.log(store.getState());
57 | });
58 | store.dispatch(fetchPosts());
59 |
--------------------------------------------------------------------------------
/3.redux-toolkit-core-only/2.rtk-only-posts-project-7/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rtk-only",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "@reduxjs/toolkit": "^1.8.5",
14 | "axios": "^0.27.2"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-redux": "^8.0.4",
13 | "react-scripts": "5.0.1",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.1",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "redux-devtools-extension": "^2.13.9"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-notes-app-final/public/favicon.ico
--------------------------------------------------------------------------------
/react-redux-notes-app-final/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-notes-app-final/public/logo192.png
--------------------------------------------------------------------------------
/react-redux-notes-app-final/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-notes-app-final/public/logo512.png
--------------------------------------------------------------------------------
/react-redux-notes-app-final/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import AddNotes from "./components/AddNotes";
3 | import NotesList from "./components/NotesList";
4 |
5 | function App() {
6 | return (
7 |
11 | );
12 | }
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/components/AddNotes.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useDispatch } from "react-redux";
3 | import { addNoteAction } from "../redux/actions/notesAction";
4 | import "./Form.css";
5 |
6 | const AddNotes = () => {
7 | //dispatch
8 | const dispatch = useDispatch();
9 | const [note, setNote] = useState({
10 | title: "",
11 | content: "",
12 | });
13 |
14 | const handleChange = e => {
15 | setNote({
16 | ...note,
17 | [e.target.name]: e.target.value,
18 | });
19 | };
20 |
21 | const handleSubmit = e => {
22 | //prevent empty notes
23 | if (note.title === "" || note.content === "") {
24 | return alert("Please fill in the form");
25 | }
26 | e.preventDefault();
27 | //dispatch action
28 | dispatch(addNoteAction(note));
29 | console.log(note);
30 | //reset form
31 | setNote({
32 | title: "",
33 | content: "",
34 | });
35 | };
36 |
37 | return (
38 |
39 |
40 |
Notes Taking App Built with React Redux
41 |
42 | This is a simple notes taking app built with React Redux. You can add
43 |
44 |
45 |
65 |
Enroll in the course
66 |
67 | );
68 | };
69 |
70 | export default AddNotes;
71 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .formContainer {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | justify-content: center;
6 | width: 100%;
7 | padding: 20px;
8 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
9 | }
10 | h3 {
11 | margin: 0;
12 | padding: 0;
13 | font-size: 2.5rem;
14 | font-weight: bold;
15 | }
16 |
17 | p {
18 | margin: 10px;
19 | padding: 0;
20 | font-size: 1rem;
21 | font-weight: 400;
22 | }
23 | form {
24 | display: flex;
25 | flex-direction: row;
26 | align-items: center;
27 | justify-content: center;
28 | width: auto;
29 | height: 100%;
30 | }
31 |
32 | form input {
33 | width: 80%;
34 | height: 100%;
35 | border: 1px solid #ccc;
36 | outline: none;
37 | padding: 10px;
38 | font-size: 1.1rem;
39 | border-radius: 5px;
40 | margin: 0 10px;
41 | }
42 |
43 | .btn-enroll {
44 | background-color: #4caf50;
45 | color: #fff;
46 | }
47 |
48 | button {
49 | }
50 | .add-btn {
51 | background-color: #4caf50;
52 | color: #fff;
53 | width: 100px;
54 | height: 40px;
55 | border: none;
56 | outline: none;
57 | border-radius: 5px;
58 | font-size: 1.1rem;
59 | cursor: pointer;
60 | width: 70%;
61 | }
62 | a {
63 | text-decoration: none;
64 | color: white;
65 | padding: 5px;
66 | border-radius: 5px;
67 | background-color: red;
68 | padding: 10px;
69 | margin: 10px;
70 | }
71 |
72 | a:hover {
73 | transform: scale(1.1);
74 | transition: all 0.3s ease-in-out;
75 | }
76 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/components/NotesList.css:
--------------------------------------------------------------------------------
1 | .item-container {
2 | display: flex;
3 | flex-direction: row;
4 | justify-content: center;
5 | width: 100%;
6 | align-items: center;
7 | padding: 10px;
8 | }
9 |
10 | .item-content {
11 | width: 800px;
12 | padding: 10px;
13 | background-color: white;
14 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
15 | }
16 |
17 | .item-content button {
18 | width: 100%;
19 | height: 40px;
20 | border: none;
21 | outline: none;
22 | border-radius: 5px;
23 | font-size: 1.1rem;
24 | cursor: pointer;
25 | background-color: #4caf50;
26 | color: #fff;
27 | }
28 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/components/NotesList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import {
4 | deleteNoteAction,
5 | fetchNotesAction,
6 | } from "../redux/actions/notesAction";
7 |
8 | import "./NotesList.css";
9 |
10 | const NotesList = () => {
11 | //dispatch
12 | const dispatch = useDispatch();
13 | useEffect(() => {
14 | dispatch(fetchNotesAction());
15 | }, []);
16 | //get data from store
17 | const notes = useSelector(storeData => {
18 | return storeData.notes;
19 | });
20 |
21 | return (
22 | <>
23 | Notes List
24 |
25 | {notes.map(note => (
26 |
27 |
28 |
{note.title}
29 |
{note.content}
30 |
33 |
34 |
35 | ))}
36 | >
37 | );
38 | };
39 |
40 | export default NotesList;
41 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/index.css:
--------------------------------------------------------------------------------
1 | /* body {
2 | background-color: #f5f5f5;
3 | }
4 |
5 | code {
6 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
7 | monospace;
8 | } */
9 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import { Provider } from "react-redux";
4 | import "./index.css";
5 | import App from "./App";
6 |
7 | import reportWebVitals from "./reportWebVitals";
8 | import store from "./redux/store/store";
9 |
10 | const root = ReactDOM.createRoot(document.getElementById("root"));
11 | root.render(
12 |
13 |
14 |
15 | );
16 |
17 | // If you want to start measuring performance in your app, pass a function
18 | // to log results (for example: reportWebVitals(console.log))
19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
20 | reportWebVitals();
21 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/redux/actions/notesAction.js:
--------------------------------------------------------------------------------
1 | import { ADD_NOTE, DELETE_NOTE, FETCH_NOTES } from "./notesActionTypes";
2 |
3 | //actions
4 | //Add note action creator
5 | export const addNoteAction = note => {
6 | return {
7 | type: ADD_NOTE,
8 | payload: note,
9 | };
10 | };
11 | //Delete note action creator
12 | export const deleteNoteAction = id => {
13 | return {
14 | type: DELETE_NOTE,
15 | payload: id,
16 | };
17 | };
18 | //Fetch notes action creator
19 | export const fetchNotesAction = () => {
20 | return {
21 | type: FETCH_NOTES,
22 | };
23 | };
24 | //store
25 | //dispatch
26 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/redux/actions/notesActionTypes.js:
--------------------------------------------------------------------------------
1 | export const ADD_NOTE = "ADD_NOTE";
2 | export const DELETE_NOTE = "DELETE_NOTE";
3 | export const FETCH_NOTES = "FETCH_NOTES";
4 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/redux/reducer/noteReducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | ADD_NOTE,
3 | DELETE_NOTE,
4 | FETCH_NOTES,
5 | } from "../actions/notesActionTypes";
6 |
7 | //Initialstate
8 | const initialstate = {
9 | notes: [],
10 | };
11 |
12 | //note reducer
13 | const notesReducer = (state = initialstate, action) => {
14 | switch (action.type) {
15 | case ADD_NOTE:
16 | //new note
17 | const newNote = {
18 | id: Math.random(),
19 | title: action.payload.title,
20 | content: action.payload.content,
21 | };
22 | //add note into storage
23 | const updatedNotes = [...state.notes, newNote];
24 | localStorage.setItem("notes", JSON.stringify(updatedNotes));
25 | return {
26 | notes: [...state.notes, newNote],
27 | };
28 | //fetch notes
29 | case FETCH_NOTES:
30 | return {
31 | notes: JSON.parse(localStorage.getItem("notes"))
32 | ? JSON.parse(localStorage.getItem("notes"))
33 | : [],
34 | };
35 | //Delete note
36 | case DELETE_NOTE:
37 | const filteredNotes = state.notes.filter(
38 | note => note.id !== action.payload
39 | );
40 | //Resave to localstorage
41 | localStorage.setItem("notes", JSON.stringify(filteredNotes));
42 | return {
43 | ...state,
44 | notes: filteredNotes,
45 | };
46 | default:
47 | return state;
48 | }
49 | };
50 |
51 | export default notesReducer;
52 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/redux/store/store.js:
--------------------------------------------------------------------------------
1 | import { createStore } from "redux";
2 | import { composeWithDevTools } from "redux-devtools-extension";
3 | import notesReducer from "../reducer/noteReducer";
4 |
5 | const store = createStore(notesReducer, composeWithDevTools());
6 |
7 | export default store;
8 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-redux-notes-app-final/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-redux": "^8.0.4",
13 | "react-scripts": "5.0.1",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.1",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "redux-devtools-extension": "^2.13.9"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-notes-app-starter/public/favicon.ico
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-notes-app-starter/public/logo192.png
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-notes-app-starter/public/logo512.png
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 | import AddNotes from "./components/AddNotes";
3 | import NotesList from "./components/NotesList";
4 |
5 | function App() {
6 | return (
7 |
11 | );
12 | }
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/components/AddNotes.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { useDispatch } from "react-redux";
3 | import "./Form.css";
4 |
5 | const AddNotes = () => {
6 | //dispatch
7 | const dispatch = useDispatch();
8 | const [note, setNote] = useState({
9 | title: "",
10 | content: "",
11 | });
12 |
13 | const handleChange = (e) => {
14 | setNote({
15 | ...note,
16 | [e.target.name]: e.target.value,
17 | });
18 | };
19 |
20 | const handleSubmit = (e) => {
21 | //prevent empty notes
22 | if (note.title === "" || note.content === "") {
23 | return alert("Please fill in the form");
24 | }
25 | e.preventDefault();
26 | };
27 |
28 | return (
29 |
30 |
31 |
Notes Taking App Built with React Redux
32 |
33 | This is a simple notes taking app built with React Redux. You can add
34 |
35 |
36 |
56 |
Enroll in the course
57 |
58 | );
59 | };
60 |
61 | export default AddNotes;
62 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .formContainer {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | justify-content: center;
6 | width: 100%;
7 | padding: 20px;
8 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
9 | }
10 | h3 {
11 | margin: 0;
12 | padding: 0;
13 | font-size: 2.5rem;
14 | font-weight: bold;
15 | }
16 |
17 | p {
18 | margin: 10px;
19 | padding: 0;
20 | font-size: 1rem;
21 | font-weight: 400;
22 | }
23 | form {
24 | display: flex;
25 | flex-direction: row;
26 | align-items: center;
27 | justify-content: center;
28 | width: auto;
29 | height: 100%;
30 | }
31 |
32 | form input {
33 | width: 80%;
34 | height: 100%;
35 | border: 1px solid #ccc;
36 | outline: none;
37 | padding: 10px;
38 | font-size: 1.1rem;
39 | border-radius: 5px;
40 | margin: 0 10px;
41 | }
42 |
43 | .btn-enroll {
44 | background-color: #4caf50;
45 | color: #fff;
46 | }
47 |
48 | button {
49 | }
50 | .add-btn {
51 | background-color: #4caf50;
52 | color: #fff;
53 | width: 100px;
54 | height: 40px;
55 | border: none;
56 | outline: none;
57 | border-radius: 5px;
58 | font-size: 1.1rem;
59 | cursor: pointer;
60 | width: 70%;
61 | }
62 | a {
63 | text-decoration: none;
64 | color: white;
65 | padding: 5px;
66 | border-radius: 5px;
67 | background-color: red;
68 | padding: 10px;
69 | margin: 10px;
70 | }
71 |
72 | a:hover {
73 | transform: scale(1.1);
74 | transition: all 0.3s ease-in-out;
75 | }
76 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/components/NotesList.css:
--------------------------------------------------------------------------------
1 | .item-container {
2 | display: flex;
3 | flex-direction: row;
4 | justify-content: center;
5 | width: 100%;
6 | align-items: center;
7 | padding: 10px;
8 | }
9 |
10 | .item-content {
11 | width: 800px;
12 | padding: 10px;
13 | background-color: white;
14 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
15 | }
16 |
17 | .item-content button {
18 | width: 100%;
19 | height: 40px;
20 | border: none;
21 | outline: none;
22 | border-radius: 5px;
23 | font-size: 1.1rem;
24 | cursor: pointer;
25 | background-color: #4caf50;
26 | color: #fff;
27 | }
28 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/components/NotesList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 |
3 | import "./NotesList.css";
4 |
5 | const NotesList = () => {
6 | return (
7 | <>
8 | Notes List
9 |
10 |
11 |
12 |
some title
13 |
some content
14 |
15 |
16 |
17 | >
18 | );
19 | };
20 |
21 | export default NotesList;
22 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/index.css:
--------------------------------------------------------------------------------
1 | /* body {
2 | background-color: #f5f5f5;
3 | }
4 |
5 | code {
6 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
7 | monospace;
8 | } */
9 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 |
6 | import reportWebVitals from "./reportWebVitals";
7 |
8 | const root = ReactDOM.createRoot(document.getElementById("root"));
9 | root.render();
10 |
11 | // If you want to start measuring performance in your app, pass a function
12 | // to log results (for example: reportWebVitals(console.log))
13 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
14 | reportWebVitals();
15 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-redux-notes-app-starter/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-redux": "^8.0.5",
13 | "react-scripts": "5.0.1",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.2",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "redux-devtools-extension": "^2.13.9"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-posts-app-final/public/favicon.ico
--------------------------------------------------------------------------------
/react-redux-posts-app-final/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-posts-app-final/public/logo192.png
--------------------------------------------------------------------------------
/react-redux-posts-app-final/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-posts-app-final/public/logo512.png
--------------------------------------------------------------------------------
/react-redux-posts-app-final/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 |
3 | import NotesList from "./components/PostsList";
4 |
5 | function App() {
6 | return ;
7 | }
8 |
9 | export default App;
10 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .form-header {
2 | background-color: #22577a;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 | form {
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | justify-content: center;
12 | width: 100%;
13 | height: 100%;
14 | margin: 10px;
15 | }
16 |
17 | form input {
18 | border: 1px solid #ccc;
19 | outline: none;
20 | font-size: 1.1rem;
21 | border-radius: 5px;
22 | margin: 5px;
23 | padding: 5px;
24 | }
25 |
26 | form button {
27 | border: 1px solid #ccc;
28 | outline: none;
29 | color: #fff;
30 | cursor: pointer;
31 | padding: 8px;
32 | background-color: #22577a;
33 | width: 100px;
34 | border-radius: 5px;
35 | margin: 5px;
36 | }
37 |
38 | form button:hover {
39 | background-color: #1b435e;
40 | transform: scale(1.1);
41 | transition: all 0.2s ease-in-out;
42 | }
43 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/components/Header.css:
--------------------------------------------------------------------------------
1 | header {
2 | background-color: #333;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/components/Posts.css:
--------------------------------------------------------------------------------
1 | .posts-list {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | width: 100%;
6 | background-color: #f5f5f5;
7 | }
8 |
9 | .post-details {
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | width: 80%;
14 | margin: 10px;
15 | padding: 10px;
16 | border: 1px solid #fff;
17 | border-radius: 5px;
18 | background-color: #fff;
19 | }
20 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/components/PostsList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import SearchPost from "./SearchPost";
4 | import "./Posts.css";
5 | import { fetchPostsAction } from "../redux/actions/postActions";
6 |
7 | const PostsList = () => {
8 | //dispatch
9 | const dispatch = useDispatch();
10 | useEffect(() => {
11 | dispatch(fetchPostsAction());
12 | }, []);
13 |
14 | //get data from store
15 | const { loading, error, posts, post } = useSelector(data => data);
16 |
17 | console.log(loading, error, posts, post);
18 |
19 | return (
20 | <>
21 |
22 |
23 |
Total Posts {posts.length}
24 | {loading ? (
25 |
Loading
26 | ) : error ? (
27 |
28 | {error.response.status && "No Post Found"}
29 |
30 | ) : (
31 | posts.map(post => (
32 |
33 |
{post.title}
34 |
{post.body}
35 |
36 | ))
37 | )}
38 |
39 | >
40 | );
41 | };
42 |
43 | export default PostsList;
44 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/components/SearchPost.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useSelector, useDispatch } from "react-redux";
3 | import { fetchPostAction } from "../redux/actions/postActions";
4 |
5 | import "./Form.css";
6 | const SearchPost = () => {
7 | const dispatch = useDispatch();
8 | //search form state
9 | const [search, setSearch] = React.useState("");
10 | //search form submit handler
11 | const handleSubmit = e => {
12 | e.preventDefault();
13 | if (search === "") {
14 | return alert("Please provide a value");
15 | }
16 | dispatch(fetchPostAction(search));
17 | };
18 |
19 | return (
20 |
21 |
22 |
React Redux Project
23 |
24 | This project is a simple React Redux project that fetches data with
25 | search functionality from an API
26 |
27 |
28 |
37 |
38 | );
39 | };
40 |
41 | export default SearchPost;
42 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import reportWebVitals from "./reportWebVitals";
6 | import { Provider } from "react-redux";
7 | import store from "./redux/store/store";
8 |
9 | const root = ReactDOM.createRoot(document.getElementById("root"));
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/redux/actions/postActionTypes.js:
--------------------------------------------------------------------------------
1 | //notes action types
2 | export const FETCH_POSTS_SUCCESS = "FETCH_POSTS_SUCCESS";
3 | export const FETCH_POSTS_FAILURE = "FETCH_POSTS_FAILURE";
4 | export const FETCH_POSTS_REQUEST = "FETCH_POSTS_REQUEST";
5 |
6 | export const SEARCH_POST_REQUEST = "SEARCH_POST_REQUEST";
7 | export const SEARCH_POST_SUCCESS = "SEARCH_POST_SUCCESS";
8 | export const SEARCH_POST_FAILURE = "SEARCH_POST_FAILURE";
9 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/redux/actions/postActions.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import {
3 | FETCH_POSTS_SUCCESS,
4 | FETCH_POSTS_FAILURE,
5 | FETCH_POSTS_REQUEST,
6 | SEARCH_POST_FAILURE,
7 | SEARCH_POST_REQUEST,
8 | SEARCH_POST_SUCCESS,
9 | } from "./postActionTypes";
10 | const apiURL = "https://jsonplaceholder.typicode.com/posts";
11 | //Actions Creators
12 | //1. fetch posts (request started, success, error)
13 |
14 | //request started
15 | const fetchPostsRequest = () => {
16 | return {
17 | type: FETCH_POSTS_REQUEST,
18 | };
19 | };
20 |
21 | //success
22 | const fetchPostsSuccess = posts => {
23 | return {
24 | type: FETCH_POSTS_SUCCESS,
25 | payload: posts,
26 | };
27 | };
28 |
29 | //error action creator
30 | const fetchPostsErr = error => {
31 | return {
32 | type: FETCH_POSTS_FAILURE,
33 | payload: error,
34 | };
35 | };
36 |
37 | //fetch posts action
38 | export const fetchPostsAction = () => {
39 | return async dispatch => {
40 | //request action
41 | dispatch(fetchPostsRequest());
42 | try {
43 | //make http request
44 | const res = await axios.get(apiURL);
45 | //success action
46 | dispatch(fetchPostsSuccess(res.data));
47 | } catch (error) {
48 | //error action
49 | dispatch(fetchPostsErr(error));
50 | }
51 | };
52 | };
53 |
54 | //2. fetch post (request started, success, error)
55 | //request action
56 | const fetchPostRequest = () => {
57 | return {
58 | type: SEARCH_POST_REQUEST,
59 | };
60 | };
61 | //success
62 | const fetchPostSuccess = post => {
63 | return {
64 | type: SEARCH_POST_SUCCESS,
65 | payload: post,
66 | };
67 | };
68 |
69 | //error action creator
70 | const fetchPostErr = error => {
71 | return {
72 | type: SEARCH_POST_FAILURE,
73 | payload: error,
74 | };
75 | };
76 |
77 | //single post action
78 | export const fetchPostAction = id => {
79 | return async dispatch => {
80 | dispatch(fetchPostRequest());
81 | try {
82 | //make http request
83 | const res = await axios.get(`${apiURL}/${id}`);
84 | //success
85 | dispatch(fetchPostSuccess(res.data));
86 | } catch (error) {
87 | dispatch(fetchPostErr(error));
88 | }
89 | };
90 | };
91 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/redux/reducers/postReducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | FETCH_POSTS_SUCCESS,
3 | FETCH_POSTS_FAILURE,
4 | FETCH_POSTS_REQUEST,
5 | SEARCH_POST_FAILURE,
6 | SEARCH_POST_REQUEST,
7 | SEARCH_POST_SUCCESS,
8 | } from "../actions/postActionTypes";
9 |
10 | //initial state
11 | const initialState = {
12 | loading: false,
13 | error: "",
14 | posts: [],
15 | post: {},
16 | };
17 |
18 | //reducers
19 | export const postsReducer = (state = initialState, action) => {
20 | switch (action.type) {
21 | case FETCH_POSTS_REQUEST:
22 | return {
23 | ...state,
24 | loading: true,
25 | };
26 | //success
27 | case FETCH_POSTS_SUCCESS:
28 | return {
29 | ...state,
30 | posts: action.payload,
31 | loading: false,
32 | };
33 | //error
34 | case FETCH_POSTS_FAILURE:
35 | return {
36 | ...state,
37 | posts: [],
38 | error: action.payload,
39 | loading: false,
40 | };
41 | //========SEARCH SINGLE POST =======
42 | case SEARCH_POST_REQUEST:
43 | return {
44 | ...state,
45 | loading: true,
46 | };
47 | case SEARCH_POST_SUCCESS:
48 | return {
49 | ...state,
50 | posts: [action.payload],
51 | loading: false,
52 | };
53 | case SEARCH_POST_FAILURE:
54 | return {
55 | ...state,
56 | posts: [],
57 | error: action.payload,
58 | loading: false,
59 | };
60 | //return default state
61 | default:
62 | return state;
63 | }
64 | };
65 | //store
66 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/redux/store/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from "redux";
2 | import { composeWithDevTools } from "redux-devtools-extension";
3 | import reduxThunk from "redux-thunk";
4 | import { postsReducer } from "../reducers/postReducer";
5 |
6 | //combine all middlewares
7 | const middlewares = [reduxThunk];
8 | const middlewareEnhancers = applyMiddleware(...middlewares);
9 | const store = createStore(
10 | postsReducer,
11 | composeWithDevTools(middlewareEnhancers)
12 | );
13 |
14 | export default store;
15 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/react-redux-posts-app-final/src/utils/apiURL.js:
--------------------------------------------------------------------------------
1 | const apiURL = "https://jsonplaceholder.typicode.com/posts";
2 | export default apiURL;
3 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.5",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.27.2",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-redux": "^8.0.4",
13 | "react-scripts": "5.0.1",
14 | "redux": "^4.2.0",
15 | "redux-logger": "^3.0.6",
16 | "redux-thunk": "^2.4.1",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | },
43 | "devDependencies": {
44 | "redux-devtools-extension": "^2.13.9"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-posts-app-starter/public/favicon.ico
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-posts-app-starter/public/logo192.png
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/react-redux-posts-app-starter/public/logo512.png
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 |
3 | import NotesList from "./components/PostsList";
4 |
5 | function App() {
6 | return ;
7 | }
8 |
9 | export default App;
10 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .form-header {
2 | background-color: #22577a;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 | form {
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | justify-content: center;
12 | width: 100%;
13 | height: 100%;
14 | margin: 10px;
15 | }
16 |
17 | form input {
18 | border: 1px solid #ccc;
19 | outline: none;
20 | font-size: 1.1rem;
21 | border-radius: 5px;
22 | margin: 5px;
23 | padding: 5px;
24 | }
25 |
26 | form button {
27 | border: 1px solid #ccc;
28 | outline: none;
29 | color: #fff;
30 | cursor: pointer;
31 | padding: 8px;
32 | background-color: #22577a;
33 | width: 100px;
34 | border-radius: 5px;
35 | margin: 5px;
36 | }
37 |
38 | form button:hover {
39 | background-color: #1b435e;
40 | transform: scale(1.1);
41 | transition: all 0.2s ease-in-out;
42 | }
43 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/components/Header.css:
--------------------------------------------------------------------------------
1 | header {
2 | background-color: #333;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/components/Posts.css:
--------------------------------------------------------------------------------
1 | .posts-list {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | width: 100%;
6 | background-color: #f5f5f5;
7 | }
8 |
9 | .post-details {
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | width: 80%;
14 | margin: 10px;
15 | padding: 10px;
16 | border: 1px solid #fff;
17 | border-radius: 5px;
18 | background-color: #fff;
19 | }
20 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/components/PostsList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import SearchPost from "./SearchPost";
3 | import "./Posts.css";
4 |
5 | const PostsList = () => {
6 | return (
7 | <>
8 |
9 |
10 |
Total Posts 100
11 |
12 |
Post Title 1
13 |
Post body 1
14 |
15 |
16 | >
17 | );
18 | };
19 |
20 | export default PostsList;
21 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/components/SearchPost.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./Form.css";
3 | const SearchPost = () => {
4 | //search form state
5 | const [search, setSearch] = React.useState("");
6 | //search form submit handler
7 | const handleSubmit = e => {
8 | e.preventDefault();
9 | };
10 |
11 | return (
12 |
13 |
14 |
React Redux Project
15 |
16 | This project is a simple React Redux project that fetches data with
17 | search functionality from an API
18 |
19 |
20 |
29 |
30 | );
31 | };
32 |
33 | export default SearchPost;
34 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import reportWebVitals from "./reportWebVitals";
6 |
7 | const root = ReactDOM.createRoot(document.getElementById("root"));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/react-redux-posts-app-starter/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-final/.DS_Store
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@headlessui/react": "^1.7.2",
7 | "@heroicons/react": "^2.0.11",
8 | "@reduxjs/toolkit": "^1.8.5",
9 | "@testing-library/jest-dom": "^5.16.5",
10 | "@testing-library/react": "^13.3.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "axios": "^0.27.2",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0",
15 | "react-redux": "^8.0.4",
16 | "react-router-dom": "^6.4.1",
17 | "react-scripts": "5.0.1",
18 | "web-vitals": "^2.1.4"
19 | },
20 | "scripts": {
21 | "start": "react-scripts start",
22 | "build": "react-scripts build",
23 | "test": "react-scripts test",
24 | "eject": "react-scripts eject"
25 | },
26 | "eslintConfig": {
27 | "extends": [
28 | "react-app",
29 | "react-app/jest"
30 | ]
31 | },
32 | "browserslist": {
33 | "production": [
34 | ">0.2%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "last 1 chrome version",
40 | "last 1 firefox version",
41 | "last 1 safari version"
42 | ]
43 | },
44 | "devDependencies": {
45 | "autoprefixer": "^10.4.12",
46 | "postcss": "^8.4.16",
47 | "tailwindcss": "^3.1.8"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-final/public/favicon.ico
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-final/public/logo192.png
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-final/public/logo512.png
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/App.js:
--------------------------------------------------------------------------------
1 | import Home from "./components/HomePage/Home";
2 | import Register from "./components/Forms/Register";
3 | import MainDashBoard from "./components/Dashboard/MainDashBoard";
4 | import AccountDetails from "./components/Dashboard/AccountDetails";
5 | import Navbar from "./components/Navbar/Navbar";
6 | import { BrowserRouter, Routes, Route } from "react-router-dom";
7 | import AddTransaction from "./components/Forms/AddTransaction";
8 | import EditTransaction from "./components/Forms/EditTransaction";
9 | import AddAccount from "./components/Forms/AddAccount";
10 | import EditAccount from "./components/Forms/EditAccount";
11 | import Login from "./components/Forms/Login";
12 | import AuthRoute from "./components/AuthRoute/AuthRoute";
13 |
14 | function App() {
15 | return (
16 |
17 |
18 |
19 | } />
20 | } />
21 |
25 |
26 |
27 | }
28 | />
29 |
30 |
34 |
35 |
36 | }
37 | />
38 |
39 |
43 |
44 |
45 | }
46 | />
47 |
48 |
52 |
53 |
54 | }
55 | />
56 |
60 |
61 |
62 | }
63 | />
64 |
68 |
69 |
70 | }
71 | />
72 | } />
73 |
74 |
75 | );
76 | }
77 |
78 | export default App;
79 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-final/src/assets/logo.png
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/components/AuthRoute/AuthRoute.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useSelector } from "react-redux";
3 |
4 | const AuthRoute = ({ children }) => {
5 | //get token from store
6 | const { userInfo } = useSelector((state) => state?.users?.userAuth);
7 | if (!userInfo?.token) {
8 | window.location.href = "/login";
9 | return null;
10 | }
11 | return {children}
;
12 | };
13 |
14 | export default AuthRoute;
15 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/components/Dashboard/AccountSummary.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const AccountSummary = ({ profile }) => {
4 | //get all accounts
5 | const accounts = profile?.accounts;
6 |
7 | //get all transactions
8 | const transactions = accounts?.map((account) => account?.transactions);
9 | console.log(transactions);
10 | //total income
11 | const totalIncome = transactions?.reduce((acc, transaction) => {
12 | return (
13 | acc +
14 | transaction
15 | ?.filter((transaction) => transaction?.transactionType === "Income")
16 | .reduce((acc, transaction) => acc + transaction?.amount, 0)
17 | );
18 | }, 0);
19 |
20 | //total expenses
21 | const totalExpenses = transactions?.reduce((acc, transaction) => {
22 | return (
23 | acc +
24 | transaction
25 | ?.filter((transaction) => transaction?.transactionType === "Expenses")
26 | .reduce((acc, transaction) => acc + transaction?.amount, 0)
27 | );
28 | }, 0);
29 |
30 | console.log(totalExpenses);
31 | return (
32 | <>
33 | {profile?.accounts?.length <= 0 ? (
34 | No Account Summary Found
35 | ) : (
36 |
37 |
38 | Account Summary - for {profile?.accounts?.length} accounts
39 |
40 |
41 |
42 |
43 |
Total Income
44 |
45 | $ {totalIncome}
46 |
47 |
48 |
49 |
Total Expenses
50 |
51 | $ {totalExpenses}
52 |
53 |
54 |
55 |
Total Balance
56 |
57 | $ {totalIncome - totalExpenses}
58 |
59 |
60 |
61 |
Total Transactions
62 |
63 | {transactions?.length}
64 |
65 |
66 |
67 |
68 |
69 | )}
70 | >
71 | );
72 | };
73 |
74 | export default AccountSummary;
75 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/components/Dashboard/MainDashBoard.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useSelector, useDispatch } from "react-redux";
3 | import { getProfileAction } from "../../redux/slice/users/usersSlice";
4 |
5 | import AccountList from "./AccountList";
6 | import AccountSummary from "./AccountSummary";
7 |
8 | const MainDashBoard = () => {
9 | //dispatch
10 | const dispatch = useDispatch();
11 |
12 | useEffect(() => {
13 | dispatch(getProfileAction());
14 | }, [dispatch]);
15 | //get data from store
16 | const { profile, error, loading } = useSelector((state) => state?.users);
17 |
18 | return (
19 | <>
20 | {loading ? (
21 | Loading...
22 | ) : error ? (
23 | {error}
24 | ) : (
25 | <>
26 |
27 |
28 | >
29 | )}
30 | >
31 | );
32 | };
33 |
34 | export default MainDashBoard;
35 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import { Provider } from "react-redux";
4 |
5 | import "./index.css";
6 | import App from "./App";
7 | import reportWebVitals from "./reportWebVitals";
8 | import store from "./redux/store/store";
9 |
10 | const root = ReactDOM.createRoot(document.getElementById("root"));
11 | root.render(
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
19 | // If you want to start measuring performance in your app, pass a function
20 | // to log results (for example: reportWebVitals(console.log))
21 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
22 | reportWebVitals();
23 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/redux/store/store.js:
--------------------------------------------------------------------------------
1 | import { configureStore } from "@reduxjs/toolkit";
2 | import accountsReducer from "../slice/accounts/accountsSlice";
3 | import transactionsReducer from "../slice/transactions/transactionSlice";
4 | import usersReducer from "../slice/users/usersSlice";
5 |
6 | //store
7 | const store = configureStore({
8 | reducer: {
9 | users: usersReducer,
10 | accounts: accountsReducer,
11 | transactions: transactionsReducer,
12 | },
13 | });
14 |
15 | export default store;
16 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/src/utils/baseURL.js:
--------------------------------------------------------------------------------
1 | const baseURL = "https://income-expenses-tracker-web-dev.onrender.com/api/v1";
2 |
3 | export default baseURL;
4 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-final/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ["./src/**/*.{js,jsx,ts,tsx}"],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-starter/.DS_Store
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@headlessui/react": "^1.7.2",
7 | "@heroicons/react": "^2.0.11",
8 | "@reduxjs/toolkit": "^1.8.5",
9 | "@testing-library/jest-dom": "^5.16.5",
10 | "@testing-library/react": "^13.3.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "axios": "^0.27.2",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0",
15 | "react-redux": "^8.0.4",
16 | "react-router-dom": "^6.4.1",
17 | "react-scripts": "5.0.1",
18 | "web-vitals": "^2.1.4"
19 | },
20 | "scripts": {
21 | "start": "react-scripts start",
22 | "build": "react-scripts build",
23 | "test": "react-scripts test",
24 | "eject": "react-scripts eject"
25 | },
26 | "eslintConfig": {
27 | "extends": [
28 | "react-app",
29 | "react-app/jest"
30 | ]
31 | },
32 | "browserslist": {
33 | "production": [
34 | ">0.2%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "last 1 chrome version",
40 | "last 1 firefox version",
41 | "last 1 safari version"
42 | ]
43 | },
44 | "devDependencies": {
45 | "autoprefixer": "^10.4.12",
46 | "postcss": "^8.4.16",
47 | "tailwindcss": "^3.1.8"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-starter/public/favicon.ico
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-starter/public/logo192.png
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-starter/public/logo512.png
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/App.js:
--------------------------------------------------------------------------------
1 | import Home from "./components/HomePage/Home";
2 | import Register from "./components/Forms/Register";
3 | import MainDashBoard from "./components/Dashboard/MainDashBoard";
4 | import AccountDetails from "./components/Dashboard/AccountDetails";
5 | import Navbar from "./components/Navbar/Navbar";
6 | import { BrowserRouter, Routes, Route } from "react-router-dom";
7 | import AddTransaction from "./components/Forms/AddTransaction";
8 | import EditTransaction from "./components/Forms/EditTransaction";
9 | import AddAccount from "./components/Forms/AddAccount";
10 | import EditAccount from "./components/Forms/EditAccount";
11 | import Login from "./components/Forms/Login";
12 |
13 | function App() {
14 | return (
15 |
16 |
17 |
18 | } />
19 | } />
20 | } />
21 | } />
22 | } />
23 | } />
24 | } />
25 | } />
26 | } />
27 | } />
28 |
29 |
30 | );
31 | }
32 |
33 | export default App;
34 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-income-expenses-project-starter/src/assets/logo.png
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/components/Dashboard/AccountSummary.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const AccountSummary = () => {
4 | return (
5 |
6 | Account Summary
7 |
8 |
9 |
10 |
Total Revenue
11 | $33,261
12 |
13 |
14 |
Subscribers
15 | 481,095
16 |
17 |
18 |
Conversations
19 | 643,533
20 |
21 |
22 |
Modal Sale Rate
23 | 25%
24 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default AccountSummary;
32 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/components/Dashboard/MainDashBoard.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import AccountList from "./AccountList";
3 | import AccountSummary from "./AccountSummary";
4 |
5 | const MainDashBoard = () => {
6 | return (
7 | <>
8 |
9 |
10 | >
11 | );
12 | };
13 |
14 | export default MainDashBoard;
15 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/components/Forms/Login.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | const Login = () => {
5 | const [formData, setFormData] = useState({
6 | email: "",
7 | password: "",
8 | });
9 | //---Destructuring---
10 | const { email, password } = formData;
11 | //---onchange handler----
12 | const onChangeHandler = (e) => {
13 | setFormData({ ...formData, [e.target.name]: e.target.value });
14 | };
15 |
16 | //---onsubmit handler----
17 | const onSubmitHandler = (e) => {
18 | e.preventDefault();
19 | console.log(formData);
20 | };
21 | return (
22 | <>
23 |
24 |
25 |
26 |
27 |
28 |
29 | Login
30 |
31 |
32 |
74 |
75 |
76 |
77 | >
78 | );
79 | };
80 |
81 | export default Login;
82 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/rtk-income-expenses-project-starter/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ["./src/**/*.{js,jsx,ts,tsx}"],
4 | theme: {
5 | extend: {},
6 | },
7 | plugins: [],
8 | };
9 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-manager-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@reduxjs/toolkit": "^1.9.0",
7 | "@testing-library/jest-dom": "^5.16.5",
8 | "@testing-library/react": "^13.3.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "axios": "^0.27.2",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0",
13 | "react-redux": "^8.0.5",
14 | "react-scripts": "5.0.1",
15 | "web-vitals": "^2.1.4"
16 | },
17 | "scripts": {
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject"
22 | },
23 | "eslintConfig": {
24 | "extends": [
25 | "react-app",
26 | "react-app/jest"
27 | ]
28 | },
29 | "browserslist": {
30 | "production": [
31 | ">0.2%",
32 | "not dead",
33 | "not op_mini all"
34 | ],
35 | "development": [
36 | "last 1 chrome version",
37 | "last 1 firefox version",
38 | "last 1 safari version"
39 | ]
40 | },
41 | "devDependencies": {
42 | "redux-devtools-extension": "^2.13.9"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-posts-app-final/public/favicon.ico
--------------------------------------------------------------------------------
/rtk-posts-app-final/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-posts-app-final/public/logo192.png
--------------------------------------------------------------------------------
/rtk-posts-app-final/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tweneboah/redux-core-react-redux-redux-toolkit-course/9d8f98dd3a422d73b2479a9a6a62a73cf9a363c4/rtk-posts-app-final/public/logo512.png
--------------------------------------------------------------------------------
/rtk-posts-app-final/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/App.js:
--------------------------------------------------------------------------------
1 | import "./App.css";
2 |
3 | import NotesList from "./components/PostsList";
4 |
5 | function App() {
6 | return ;
7 | }
8 |
9 | export default App;
10 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .form-header {
2 | background-color: #22577a;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 | form {
8 | display: flex;
9 | flex-direction: column;
10 | align-items: center;
11 | justify-content: center;
12 | width: 100%;
13 | height: 100%;
14 | margin: 10px;
15 | }
16 |
17 | form input {
18 | border: 1px solid #ccc;
19 | outline: none;
20 | font-size: 1.1rem;
21 | border-radius: 5px;
22 | margin: 5px;
23 | padding: 5px;
24 | }
25 |
26 | form button {
27 | border: 1px solid #ccc;
28 | outline: none;
29 | color: #fff;
30 | cursor: pointer;
31 | padding: 8px;
32 | background-color: #22577a;
33 | width: 100px;
34 | border-radius: 5px;
35 | margin: 5px;
36 | }
37 |
38 | form button:hover {
39 | background-color: #1b435e;
40 | transform: scale(1.1);
41 | transition: all 0.2s ease-in-out;
42 | }
43 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/components/Header.css:
--------------------------------------------------------------------------------
1 | header {
2 | background-color: #333;
3 | color: #fff;
4 | padding: 10px;
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/components/Posts.css:
--------------------------------------------------------------------------------
1 | .posts-list {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | width: 100%;
6 | background-color: #f5f5f5;
7 | }
8 |
9 | .post-details {
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | width: 80%;
14 | margin: 10px;
15 | padding: 10px;
16 | border: 1px solid #fff;
17 | border-radius: 5px;
18 | background-color: #fff;
19 | }
20 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/components/PostsList.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import SearchPost from "./SearchPost";
4 | import "./Posts.css";
5 | import { fetchPosts } from "../redux/slice/postsSlice";
6 |
7 | const PostsList = () => {
8 | //dispatch
9 | const dispatch = useDispatch();
10 | useEffect(() => {
11 | dispatch(fetchPosts(100));
12 | }, []);
13 | //Get data from store
14 | const { posts, loading, error } = useSelector((state) => {
15 | return state.posts;
16 | });
17 | return (
18 | <>
19 |
20 |
21 |
Total Posts {posts.length}
22 | {loading ? (
23 |
Loading...
24 | ) : error ? (
25 |
{error}
26 | ) : (
27 | posts.map((post) => {
28 | return (
29 |
30 |
{post.title}
31 |
{post.body}
32 |
33 | );
34 | })
35 | )}
36 |
37 | >
38 | );
39 | };
40 |
41 | export default PostsList;
42 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/components/SearchPost.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import { searchPost } from "../redux/slice/postsSlice";
4 | import "./Form.css";
5 |
6 | const SearchPost = () => {
7 | const dispatch = useDispatch();
8 | //search form state
9 | const [search, setSearch] = React.useState("");
10 | //search form submit handler
11 | const handleSubmit = (e) => {
12 | e.preventDefault();
13 | dispatch(searchPost(search));
14 | };
15 |
16 | return (
17 |
18 |
19 |
React Redux Project
20 |
21 | This project is a simple React Redux project that fetches data with
22 | search functionality from an API
23 |
24 |
25 |
34 |
35 | );
36 | };
37 |
38 | export default SearchPost;
39 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | }
7 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import { Provider } from "react-redux";
4 | import "./index.css";
5 | import App from "./App";
6 | import reportWebVitals from "./reportWebVitals";
7 | import store from "./redux/store/store";
8 |
9 | const root = ReactDOM.createRoot(document.getElementById("root"));
10 | root.render(
11 |
12 |
13 |
14 |
15 |
16 | );
17 |
18 | // If you want to start measuring performance in your app, pass a function
19 | // to log results (for example: reportWebVitals(console.log))
20 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
21 | reportWebVitals();
22 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/redux/slice/postsSlice.js:
--------------------------------------------------------------------------------
1 | import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
2 | import axios from "axios";
3 | import apiURL from "../../utils/apiURL";
4 |
5 | //initialState
6 | const initialState = {
7 | posts: [],
8 | loading: false,
9 | error: "",
10 | };
11 |
12 | //actions for fetch all posts
13 | export const fetchPosts = createAsyncThunk(
14 | "posts/fetch",
15 | async (payload, { rejectWithValue, getState, dispatch }) => {
16 | try {
17 | const res = await axios.get(apiURL);
18 | return res.data;
19 | } catch (error) {
20 | console.log(error);
21 | return rejectWithValue(error.response.status);
22 | }
23 | }
24 | );
25 |
26 | //Search post Action
27 | export const searchPost = createAsyncThunk(
28 | "posts/search",
29 | async (id, { rejectWithValue, getState, dispatch }) => {
30 | try {
31 | const res = await axios.get(`${apiURL}/${id}`);
32 | return res.data;
33 | } catch (error) {
34 | console.log(error);
35 | return rejectWithValue(error.response.status);
36 | }
37 | }
38 | );
39 | //slice
40 | const postsSlice = createSlice({
41 | name: "posts",
42 | initialState,
43 | extraReducers: (builder) => {
44 | //handle actions
45 | //pending
46 | builder.addCase(fetchPosts.pending, (state, action) => {
47 | state.loading = true;
48 | });
49 | //fulfilled
50 | builder.addCase(fetchPosts.fulfilled, (state, action) => {
51 | state.loading = false;
52 | state.posts = action.payload;
53 | });
54 | //Rejected
55 | builder.addCase(fetchPosts.rejected, (state, action) => {
56 | state.loading = false;
57 | state.posts = [];
58 | state.error = action.payload;
59 | });
60 | //search post
61 | builder.addCase(searchPost.pending, (state, action) => {
62 | state.loading = true;
63 | });
64 | builder.addCase(searchPost.fulfilled, (state, action) => {
65 | state.loading = false;
66 | state.posts = [action.payload];
67 | });
68 | builder.addCase(searchPost.rejected, (state, action) => {
69 | state.loading = false;
70 | state.posts = [];
71 | state.error = action.payload;
72 | });
73 | },
74 | });
75 |
76 | //Generate reducer
77 | const postsReducer = postsSlice.reducer;
78 |
79 | export default postsReducer;
80 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/redux/store/store.js:
--------------------------------------------------------------------------------
1 | import { configureStore } from "@reduxjs/toolkit";
2 | import postsReducer from "../slice/postsSlice";
3 |
4 | //store
5 |
6 | const store = configureStore({
7 | reducer: {
8 | posts: postsReducer,
9 | },
10 | });
11 |
12 | export default store;
13 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/rtk-posts-app-final/src/utils/apiURL.js:
--------------------------------------------------------------------------------
1 | const apiUrl = "https://jsonplaceholder.typicode.com/posts";
2 | export default apiUrl;
3 |
--------------------------------------------------------------------------------