├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── index.html
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.js
├── asstes
│ └── space.jpg
├── index.css
├── index.js
├── redux
│ ├── store.js
│ └── todoSlice.js
├── reportWebVitals.js
└── setupTests.js
└── tailwind.config.js
/.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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todolist-app-redux",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@headlessui/react": "^2.1.8",
7 | "@heroicons/react": "^2.1.5",
8 | "@reduxjs/toolkit": "^2.2.6",
9 | "@testing-library/jest-dom": "^5.17.0",
10 | "@testing-library/react": "^13.4.0",
11 | "@testing-library/user-event": "^13.5.0",
12 | "react": "^18.3.1",
13 | "react-dom": "^18.3.1",
14 | "react-icons": "^5.3.0",
15 | "react-redux": "^9.1.2",
16 | "react-scripts": "5.0.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 | "tailwindcss": "^3.4.11"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from 'react';
2 | import { useDispatch, useSelector } from 'react-redux';
3 | import { addTodo, deleteTodo, edittodo } from './redux/todoSlice';
4 | import { FaEdit, FaTrash, FaPlus, FaSave } from 'react-icons/fa';
5 | import bgimg from './asstes/space.jpg';
6 |
7 | function App() {
8 | const [inputValue, setInputValue] = useState('');
9 | const [editid, seteditiid] = useState();
10 | const [edittext, setedittext] = useState('');
11 | const inputref=useRef()
12 | const todos = useSelector((state) => state.todos.todos);
13 | const dispatch = useDispatch();
14 | useEffect(()=>{
15 | inputref.current.focus()
16 | },[])
17 | const handleAddTodo = () => {
18 | if (inputValue) {
19 | dispatch(addTodo(inputValue));
20 | setInputValue('');
21 | }
22 | };
23 |
24 | const editc = (index) => {
25 | seteditiid(index);
26 | };
27 |
28 | const handleInput = (e) => {
29 | e.preventDefault();
30 | setInputValue(e.target.value);
31 | };
32 |
33 | return (
34 |
35 |
36 |
Todo List
37 |
38 |
45 |
48 |
49 |
50 | {todos.map((todo) => (
51 |
52 | {editid === todo.id ? (
53 | <>
54 |
setedittext(e.target.value)}
58 | className="flex-1 p-2 rounded-md border border-gray-300 text-black"
59 | />
60 |
69 | >
70 | ) : (
71 | <>
72 |
{todo.text}
73 |
74 |
77 |
80 |
81 | >
82 | )}
83 |
84 | ))}
85 |
86 |
87 | );
88 | }
89 |
90 | export default App;
91 |
--------------------------------------------------------------------------------
/src/asstes/space.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/m-h-d-salih/task-manager-using-redux/cd0c2dc5d970bebdd681888b3f3b04e50f305875/src/asstes/space.jpg
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/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';
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 |
--------------------------------------------------------------------------------
/src/redux/store.js:
--------------------------------------------------------------------------------
1 |
2 | import { configureStore } from '@reduxjs/toolkit';
3 | import todoSlice from './todoSlice';
4 |
5 |
6 |
7 | const store = configureStore({
8 | reducer: {
9 | todos: todoSlice,
10 | },
11 | });
12 |
13 | export default store;
14 |
--------------------------------------------------------------------------------
/src/redux/todoSlice.js:
--------------------------------------------------------------------------------
1 |
2 | import { createSlice } from '@reduxjs/toolkit';
3 |
4 |
5 |
6 | const initialState = {
7 | todos: [],
8 |
9 | };
10 |
11 | const todoSlice = createSlice({
12 | name: 'todos',
13 | initialState,
14 | reducers: {
15 | addTodo: (state, action) => {
16 | const todo = state.todos;
17 | state.todos.push({ id: todo.length, text: action.payload ,color:state.color});
18 | },
19 | deleteTodo: (state, action) => {
20 | state.todos = state.todos.filter(todo => todo.id !== action.payload);
21 | },
22 | edittodo:(state,{payload})=>{
23 | const {edittext,editid}=payload
24 | state.todos[editid].text=edittext
25 |
26 |
27 | }
28 |
29 |
30 |
31 | },
32 | });
33 |
34 | export const { addTodo, deleteTodo,edittodo} = todoSlice.actions;
35 | export default todoSlice.reducer;
36 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./src/**/*.{js,jsx,ts,tsx}",
5 | ],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [],
10 | }
11 |
12 |
--------------------------------------------------------------------------------