├── src ├── assets │ ├── tickicon.png │ ├── deleteicon.png │ └── react.svg ├── App.jsx ├── main.jsx ├── todolist │ ├── todoItem.jsx │ ├── addtodo.jsx │ ├── todoList.jsx │ └── todo.css ├── App.css └── index.css ├── vite.config.js ├── .gitignore ├── index.html ├── .eslintrc.cjs ├── package.json └── public └── vite.svg /src/assets/tickicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MubashirAlam89/Todo-App-Using-React-Js/HEAD/src/assets/tickicon.png -------------------------------------------------------------------------------- /src/assets/deleteicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MubashirAlam89/Todo-App-Using-React-Js/HEAD/src/assets/deleteicon.png -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import { TodoList } from "./todolist/todolist"; 3 | function App() { 4 | return ; 5 | } 6 | 7 | export default App; 8 | -------------------------------------------------------------------------------- /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 React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /.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 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { browser: true, es2020: true }, 3 | extends: [ 4 | 'eslint:recommended', 5 | 'plugin:react/recommended', 6 | 'plugin:react/jsx-runtime', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 10 | settings: { react: { version: '18.2' } }, 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': 'warn', 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "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 src --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^18.0.37", 18 | "@types/react-dom": "^18.0.11", 19 | "@vitejs/plugin-react": "^4.0.0", 20 | "eslint": "^8.38.0", 21 | "eslint-plugin-react": "^7.32.2", 22 | "eslint-plugin-react-hooks": "^4.6.0", 23 | "eslint-plugin-react-refresh": "^0.3.4", 24 | "vite": "^4.3.9" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/todolist/todoItem.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import DeleteIcon from "../assets/deleteicon.png"; 3 | import TickIcon from "../assets/tickicon.png"; 4 | import "./todo.css"; 5 | 6 | export const TodoItem = ({ title, deleteTodo }) => { 7 | const taskCompleted = (e) => { 8 | e.target.parentElement.previousSibling.style.textDecoration = 9 | "line-through"; 10 | }; 11 | return ( 12 |
13 |

{title}

14 |
15 | 16 | 17 |
18 |
19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /src/todolist/addtodo.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import { useState } from "react"; 3 | import "./todo.css"; 4 | 5 | export const AddTodo = ({ addTodo }) => { 6 | const [newTask, setNewTask] = useState(""); 7 | 8 | const onChange = (e) => { 9 | setNewTask(e.target.value); 10 | }; 11 | 12 | return ( 13 |
14 | 21 | 30 |
31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0px; 3 | padding: 0px; 4 | box-sizing: border-box; 5 | } 6 | 7 | #root { 8 | max-width: 1280px; 9 | margin: 0 auto; 10 | text-align: center; 11 | } 12 | 13 | .logo { 14 | height: 6em; 15 | padding: 1.5em; 16 | will-change: filter; 17 | transition: filter 300ms; 18 | } 19 | .logo:hover { 20 | filter: drop-shadow(0 0 2em #646cffaa); 21 | } 22 | .logo.react:hover { 23 | filter: drop-shadow(0 0 2em #61dafbaa); 24 | } 25 | 26 | @keyframes logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | 35 | @media (prefers-reduced-motion: no-preference) { 36 | a:nth-of-type(2) .logo { 37 | animation: logo-spin infinite 20s linear; 38 | } 39 | } 40 | 41 | .card { 42 | padding: 2em; 43 | } 44 | 45 | .read-the-docs { 46 | color: #888; 47 | } 48 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | } 6 | 7 | body { 8 | background-color: #e3e9ff; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | height: 100vh; 14 | } 15 | 16 | h1 { 17 | font-size: 3.2em; 18 | line-height: 1.1; 19 | } 20 | 21 | button { 22 | border-radius: 8px; 23 | border: 1px solid transparent; 24 | padding: 8px; 25 | font-size: 3em; 26 | font-weight: 500; 27 | font-family: inherit; 28 | background-color: #1a1a1a; 29 | cursor: pointer; 30 | color: white; 31 | transition: border-color 0.25s; 32 | } 33 | 34 | button:hover { 35 | border-color: #646cff; 36 | } 37 | 38 | button:focus, 39 | button:focus-visible { 40 | outline: 4px auto -webkit-focus-ring-color; 41 | } 42 | 43 | @media (prefers-color-scheme: light) { 44 | :root { 45 | color: #213547; 46 | background-color: #ffffff; 47 | } 48 | 49 | a:hover { 50 | color: #747bff; 51 | } 52 | 53 | button { 54 | background-color: #f9f9f9; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/todolist/todoList.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./todo.css"; 3 | import { TodoItem } from "./todoitem"; 4 | import { AddTodo } from "./addtodo"; 5 | export const TodoList = () => { 6 | const [items, setItems] = useState([ 7 | { 8 | id: 1, 9 | title: "Learn React", 10 | }, 11 | { 12 | id: 2, 13 | title: "Learn Node", 14 | }, 15 | { 16 | id: 3, 17 | title: "Learn Mongo", 18 | }, 19 | { 20 | id: 4, 21 | title: "Learn to be Insan", 22 | }, 23 | ]); 24 | const deleteTodo = (id) => { 25 | const toBeDeletedIndex = items.findIndex((item) => item.id === id); 26 | items.splice(toBeDeletedIndex, 1); 27 | setItems([...items]); 28 | }; 29 | const addTask = (title) => { 30 | if (!title) { 31 | return; 32 | } 33 | const newTask = { id: items.length + 1, title }; 34 | const newItems = [...items, newTask]; 35 | setItems(newItems); 36 | }; 37 | 38 | return ( 39 |
40 |
41 |

Website Todo

42 |
43 |
44 | {items.map((item) => ( 45 | { 49 | deleteTodo(item.id); 50 | }} 51 | /> 52 | ))} 53 |
54 | 55 | {/* */} 58 |
59 | ); 60 | }; 61 | -------------------------------------------------------------------------------- /src/todolist/todo.css: -------------------------------------------------------------------------------- 1 | .bar { 2 | background-color: #af7eeb; 3 | height: 60px; 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | padding: 0 20px; 8 | width: 400px; 9 | border-radius: 5px; 10 | color: white; 11 | font-size: 18px; 12 | } 13 | 14 | .todo-list { 15 | width: 400px; 16 | margin-top: 20px; 17 | border-radius: 5px; 18 | padding: 10px 2px; 19 | background-color: white; 20 | } 21 | .todo-item { 22 | display: flex; 23 | gap: 20px; 24 | justify-content: space-between; 25 | align-items: center; 26 | padding: 8px 20px; 27 | } 28 | .todo-task-title { 29 | word-wrap: break-word; 30 | word-break: break-all; 31 | text-align: start; 32 | } 33 | .icons-container { 34 | display: flex; 35 | justify-content: center; 36 | align-items: center; 37 | column-gap: 5px; 38 | } 39 | .todo-icon { 40 | width: 20px; 41 | height: 20px; 42 | cursor: pointer; 43 | } 44 | 45 | .todo-add-btn { 46 | background-color: #af7eeb; 47 | color: white; 48 | padding: 10px 20px; 49 | margin-top: 12px; 50 | font-size: 16px; 51 | border-radius: 5px; 52 | } 53 | .todo-add-btn:focus { 54 | outline: none; 55 | } 56 | .add-todo { 57 | margin-top: 12px; 58 | display: flex; 59 | justify-content: space-between; 60 | flex-direction: column; 61 | align-items: center; 62 | } 63 | .input-field { 64 | width: 400px; 65 | outline: none; 66 | border: 1px solid #af7eeb; 67 | padding: 10px 20px; 68 | font-size: 16px; 69 | border-radius: 5px; 70 | transition: all 300ms; 71 | } 72 | .input-field:focus { 73 | outline: 1px solid #af7eeb; 74 | } 75 | 76 | @media only screen and (max-width: 600px) { 77 | .bar { 78 | width: 330px; 79 | } 80 | .todo-list { 81 | width: 330px; 82 | } 83 | .input-field { 84 | width: 330px; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------