├── vite.config.js ├── src ├── main.jsx ├── index.css ├── App.jsx └── assets │ └── react.svg ├── .gitignore ├── index.html ├── README.md ├── package.json ├── eslint.config.js └── public └── vite.svg /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App.jsx'; 4 | import './index.css'; 5 | import 'bootstrap/dist/css/bootstrap.min.css'; 6 | 7 | createRoot(document.getElementById('root')).render( 8 | 9 | 10 | , 11 | ) 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Todo App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-todo-app", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@emotion/react": "^11.13.3", 14 | "@emotion/styled": "^11.13.0", 15 | "@mui/icons-material": "^6.1.0", 16 | "@mui/material": "^6.1.0", 17 | "@mui/styled-engine-sc": "^6.1.0", 18 | "bootstrap": "^5.3.3", 19 | "react": "^18.3.1", 20 | "react-dom": "^18.3.1", 21 | "styled-components": "^6.1.13" 22 | }, 23 | "devDependencies": { 24 | "@eslint/js": "^9.9.0", 25 | "@types/react": "^18.3.3", 26 | "@types/react-dom": "^18.3.0", 27 | "@vitejs/plugin-react": "^4.3.1", 28 | "eslint": "^9.9.0", 29 | "eslint-plugin-react": "^7.35.0", 30 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 31 | "eslint-plugin-react-refresh": "^0.4.9", 32 | "globals": "^15.9.0", 33 | "vite": "^5.4.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import react from 'eslint-plugin-react' 4 | import reactHooks from 'eslint-plugin-react-hooks' 5 | import reactRefresh from 'eslint-plugin-react-refresh' 6 | 7 | export default [ 8 | { ignores: ['dist'] }, 9 | { 10 | files: ['**/*.{js,jsx}'], 11 | languageOptions: { 12 | ecmaVersion: 2020, 13 | globals: globals.browser, 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | ecmaFeatures: { jsx: true }, 17 | sourceType: 'module', 18 | }, 19 | }, 20 | settings: { react: { version: '18.3' } }, 21 | plugins: { 22 | react, 23 | 'react-hooks': reactHooks, 24 | 'react-refresh': reactRefresh, 25 | }, 26 | rules: { 27 | ...js.configs.recommended.rules, 28 | ...react.configs.recommended.rules, 29 | ...react.configs['jsx-runtime'].rules, 30 | ...reactHooks.configs.recommended.rules, 31 | 'react/jsx-no-target-blank': 'off', 32 | 'react-refresh/only-export-components': [ 33 | 'warn', 34 | { allowConstantExport: true }, 35 | ], 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #f4f6f9; 3 | } 4 | 5 | .todo-container { 6 | border-radius: 10px; 7 | background-color: white; 8 | padding: 30px; 9 | box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); 10 | } 11 | 12 | .title { 13 | font-weight: 700; 14 | color: #333333; 15 | } 16 | 17 | .custom-input .MuiOutlinedInput-root { 18 | border-radius: 10px; 19 | background-color: #f0f0f0; 20 | box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); 21 | } 22 | 23 | .custom-input .MuiOutlinedInput-root:hover { 24 | background-color: #e9e9e9; 25 | } 26 | 27 | .custom-add-btn { 28 | background-color: #00b894; 29 | color: white; 30 | border-radius: 10px; 31 | box-shadow: 0 3px 8px rgba(0, 184, 148, 0.3); 32 | transition: background-color 0.3s ease, box-shadow 0.3s ease; 33 | } 34 | 35 | .custom-add-btn:hover { 36 | background-color: #019474; 37 | box-shadow: 0 5px 15px rgba(0, 148, 112, 0.4); 38 | } 39 | 40 | .todo-list { 41 | margin-top: 20px; 42 | } 43 | 44 | .todo-item { 45 | background-color: #ffffff; 46 | padding: 10px 15px; 47 | border-radius: 8px; 48 | margin-bottom: 10px; 49 | border: 1px solid #e0e0e0; 50 | transition: background-color 0.3s ease, border 0.3s ease; 51 | } 52 | 53 | .todo-item:hover { 54 | background-color: #f9f9f9; 55 | border: 1px solid #00b894; 56 | } 57 | 58 | .todo-text { 59 | font-size: 1.1rem; 60 | color: #333; 61 | } 62 | 63 | .icon-btn { 64 | margin-left: 10px; 65 | } 66 | 67 | .icon-btn:hover { 68 | background-color: rgba(0, 0, 0, 0.05); 69 | } 70 | 71 | .custom-delete-all-btn { 72 | background-color: #d63031; 73 | color: white; 74 | border-radius: 10px; 75 | box-shadow: 0 3px 8px rgba(214, 48, 49, 0.3); 76 | transition: background-color 0.3s ease, box-shadow 0.3s ease; 77 | } 78 | 79 | .custom-delete-all-btn:hover { 80 | background-color: #b02a27; 81 | box-shadow: 0 5px 15px rgba(176, 42, 39, 0.4); 82 | } -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from "react"; 2 | import { Button, TextField, List, ListItem, IconButton, Typography, Box, Container, Paper } from "@mui/material"; 3 | import DeleteIcon from "@mui/icons-material/Delete"; 4 | import EditIcon from "@mui/icons-material/Edit"; 5 | 6 | function App() { 7 | // Set State For Todos 8 | const [todos, setTodos] = useState([]); 9 | 10 | // Set Ref For Getting Element From Jsx 11 | const inp = useRef(); 12 | 13 | // Function For Add Todos 14 | const addTodos = () => { 15 | if (inp.current.value) { 16 | setTodos([...todos, inp.current.value]); 17 | } else { 18 | alert("Input field cannot be empty"); 19 | } 20 | inp.current.value = ""; 21 | }; 22 | 23 | // Function For Delete Todos 24 | const deleteTodos = (index) => { 25 | todos.splice(index, 1); 26 | setTodos([...todos]); 27 | }; 28 | 29 | // Function For Edit Todos 30 | const editTodo = (index) => { 31 | const newValue = prompt("Enter New Value"); 32 | if (newValue !== todos[index] && newValue) { 33 | todos.splice(index, 1, newValue); 34 | setTodos([...todos]); 35 | } else { 36 | alert("Please Enter a New Value"); 37 | } 38 | }; 39 | 40 | // Function For Delete All Todos 41 | const deleteAll = () => { 42 | setTodos([]); 43 | }; 44 | 45 | return ( 46 | 47 | 48 | 49 | Todo Application 50 | 51 | 52 | 53 | 60 | 61 | 68 | 69 | 70 | {todos.map((item, index) => ( 71 | 75 | {item} 76 |
77 | editTodo(index)} 80 | className="icon-btn" 81 | > 82 | 83 | 84 | deleteTodos(index)} 87 | className="icon-btn" 88 | > 89 | 90 | 91 |
92 |
93 | ))} 94 |
95 | 96 | {todos.length > 0 && ( 97 | 105 | )} 106 |
107 |
108 | ); 109 | } 110 | 111 | export default App; 112 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------