├── 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 |
--------------------------------------------------------------------------------