├── README.md ├── src ├── App.css ├── index.css ├── main.jsx ├── components │ └── Navbar.jsx ├── assets │ └── react.svg └── App.jsx ├── postcss.config.js ├── vite.config.js ├── tailwind.config.js ├── .gitignore ├── index.html ├── .github └── workflows │ ├── jekyll-docker.yml │ └── static.yml ├── .eslintrc.cjs ├── package.json └── public └── vite.svg /README.md: -------------------------------------------------------------------------------- 1 | 2 | #Todo-list -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .flex-wrap { 2 | flex-wrap: wrap; 3 | } 4 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } 12 | 13 | -------------------------------------------------------------------------------- /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 | 8 | iNote - your note planner 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/jekyll-docker.yml: -------------------------------------------------------------------------------- 1 | name: Jekyll site CI 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: Build the site in the jekyll/builder container 17 | run: | 18 | docker run \ 19 | -v ${{ github.workspace }}:/srv/jekyll -v ${{ github.workspace }}/_site:/srv/jekyll/_site \ 20 | jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && jekyll build --future" 21 | -------------------------------------------------------------------------------- /src/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Navbar = () => { 4 | return ( 5 | 14 | ) 15 | } 16 | 17 | export default Navbar 18 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react/jsx-no-target-blank': 'off', 16 | 'react-refresh/only-export-components': [ 17 | 'warn', 18 | { allowConstantExport: true }, 19 | ], 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todolist-on-react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --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 | "react-icons": "^5.0.1", 16 | "uuid": "^9.0.1" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.2.64", 20 | "@types/react-dom": "^18.2.21", 21 | "@vitejs/plugin-react": "^4.2.1", 22 | "autoprefixer": "^10.4.18", 23 | "eslint": "^8.57.0", 24 | "eslint-plugin-react": "^7.34.0", 25 | "eslint-plugin-react-hooks": "^4.6.0", 26 | "eslint-plugin-react-refresh": "^0.4.5", 27 | "postcss": "^8.4.36", 28 | "tailwindcss": "^3.4.1", 29 | "vite": "^5.1.6" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v4 36 | - name: Upload artifact 37 | uses: actions/upload-pages-artifact@v3 38 | with: 39 | # Upload entire repository 40 | path: '.' 41 | - name: Deploy to GitHub Pages 42 | id: deployment 43 | uses: actions/deploy-pages@v4 44 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, useRef } from 'react'; 2 | import Navbar from './components/Navbar'; 3 | import { FaEdit } from "react-icons/fa"; 4 | import { MdDelete } from "react-icons/md"; 5 | import { v4 as uuidv4 } from 'uuid'; 6 | 7 | function App() { 8 | const [todo, setTodo] = useState(''); 9 | const [todos, setTodos] = useState([]); 10 | const [showFinshed, setshowFinshed] = useState(true) 11 | const inputRef = useRef(null); 12 | 13 | useEffect(() => { 14 | const storedTodos = JSON.parse(localStorage.getItem("todos")); 15 | if (storedTodos) { 16 | setTodos(storedTodos); 17 | } 18 | }, []); 19 | 20 | useEffect(() => { 21 | if (inputRef.current) { 22 | inputRef.current.focus(); 23 | } 24 | }, []); 25 | 26 | const saveTodos = () => { 27 | localStorage.setItem("todos", JSON.stringify(todos)); 28 | }; 29 | 30 | const toggleFinshed = (e) => { 31 | setshowFinshed(!showFinshed) 32 | } 33 | 34 | 35 | const handleEdit = (id) => { 36 | const editedTodo = todos.find(todo => todo.id === id); 37 | setTodo(editedTodo.todo); 38 | const updatedTodos = todos.filter(todo => todo.id !== id); 39 | setTodos(updatedTodos); 40 | }; 41 | 42 | const handleDelete = (id) => { 43 | const updatedTodos = todos.filter(todo => todo.id !== id); 44 | setTodos(updatedTodos); 45 | saveTodos(); 46 | }; 47 | 48 | const handleAdd = () => { 49 | if (todo.trim() !== '') { 50 | setTodos([...todos, { id: uuidv4(), todo, isCompleted: false }]); 51 | setTodo(''); 52 | saveTodos(); 53 | } 54 | }; 55 | 56 | const handleChange = (e) => { 57 | setTodo(e.target.value); 58 | }; 59 | 60 | const handleKeyPress = (e) => { 61 | if (e.key === 'Enter' && todo.trim() !== '') { 62 | handleAdd() 63 | ; 64 | } 65 | }; 66 | 67 | const handleCheckbox = (id) => { 68 | const updatedTodos = todos.map(todo => 69 | todo.id === id ? { ...todo, isCompleted: !todo.isCompleted } : todo 70 | ); 71 | setTodos(updatedTodos); 72 | saveTodos(); 73 | }; 74 | 75 | return ( 76 | <> 77 | 78 |
79 |

INote - manage your todos at one place

80 |
81 |

Add a Todo

82 | 89 | 90 |
91 | show Finshed 92 |

Your Todo

93 |
94 | {todos.length === 0 &&
No todos to display
} 95 | 96 | {todos.map(item => { 97 | return (showFinshed || !item.isCompleted) &&
98 |
99 | handleCheckbox(item.id)} 102 | type="checkbox" 103 | checked={item.isCompleted} 104 | className="mr-2" 105 | /> 106 |
107 |

{item.todo}

108 | 109 |
110 |
111 |
112 | 113 | 114 |
115 |
116 | })} 117 |
118 |
119 | 120 | ); 121 | } 122 | 123 | export default App; 124 | --------------------------------------------------------------------------------