├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── src ├── App.tsx ├── components │ ├── AddTask.tsx │ ├── MenuBar.tsx │ ├── Stats.tsx │ ├── TaskItem.tsx │ └── TaskList.tsx ├── index.css ├── main.tsx ├── store │ └── useStore.ts ├── types.ts ├── utils │ └── cn.ts └── vite-env.d.ts ├── tailwind.config.js ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /README.md: -------------------------------------------------------------------------------- 1 | # ✅ Task Master 2 | 3 | ## 🚀 Overview 4 | The **Task Management App** helps users efficiently manage daily tasks with features like task creation, editing, completion tracking, filtering, sorting, drag-and-drop reordering, dark mode, and local storage persistence. 5 | 6 | ## ✨ Features 7 | - ✍️ **Add, edit, and delete tasks** 8 | - ✅ **Mark tasks as completed** 9 | - 🔍 **Filter and sort tasks** by status, due date, or priority 10 | - 🎯 **Drag-and-drop reordering** (React DnD) 11 | - 🌙 **Dark mode toggle** 12 | - 💾 **Local storage for task persistence** 13 | - 📱 **Responsive UI** (Tailwind CSS) 14 | 15 | ## 🛠 Tech Stack 16 | - ⚛️ **Frontend:** React.js 17 | - 🎨 **Styling:** Tailwind CSS 18 | - 🖱 **Drag & Drop:** React DnD 19 | - 🔄 **State Management:** React Hooks 20 | - 💽 **Storage:** Local Storage 21 | 22 | ## 📦 Installation 23 | 1. Clone the repository: 24 | ```sh 25 | git clone https://github.com/sriram2915/Task-Master.git 26 | cd Task-Master 27 | ``` 28 | 2. Install dependencies: 29 | ```sh 30 | npm install 31 | ``` 32 | 3. Start the development server: 33 | ```sh 34 | npm run dev 35 | ``` 36 | 37 | ## 🌍 Deployment 38 | The application is hosted on **Vercel**. You can access it **[here](https://task-master-gilt-ten.vercel.app/)**. 39 | 40 | 41 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Task Master 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-react-typescript-starter", 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 | "@dnd-kit/core": "^6.1.0", 14 | "@dnd-kit/sortable": "^8.0.0", 15 | "@dnd-kit/utilities": "^3.2.2", 16 | "clsx": "^2.1.0", 17 | "framer-motion": "^11.0.8", 18 | "lucide-react": "^0.344.0", 19 | "react": "^18.3.1", 20 | "react-dom": "^18.3.1", 21 | "tailwind-merge": "^2.2.1", 22 | "zustand": "^4.5.2" 23 | }, 24 | "devDependencies": { 25 | "@eslint/js": "^9.9.1", 26 | "@types/react": "^18.3.5", 27 | "@types/react-dom": "^18.3.0", 28 | "@vitejs/plugin-react": "^4.3.1", 29 | "autoprefixer": "^10.4.21", 30 | "eslint": "^9.9.1", 31 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 32 | "eslint-plugin-react-refresh": "^0.4.11", 33 | "globals": "^15.9.0", 34 | "postcss": "^8.5.3", 35 | "tailwindcss": "^3.4.17", 36 | "typescript": "^5.5.3", 37 | "typescript-eslint": "^8.3.0", 38 | "vite": "^5.4.2" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { Layout } from 'lucide-react'; 3 | import { motion } from 'framer-motion'; 4 | import { AddTask } from './components/AddTask'; 5 | import { TaskList } from './components/TaskList'; 6 | import { Stats } from './components/Stats'; 7 | import { MenuBar } from './components/MenuBar'; 8 | import { useStore } from './store/useStore'; 9 | 10 | function App() { 11 | const { settings } = useStore(); 12 | 13 | useEffect(() => { 14 | const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); 15 | const updateTheme = () => { 16 | if (settings.theme === 'system') { 17 | document.documentElement.setAttribute( 18 | 'data-theme', 19 | mediaQuery.matches ? 'dark' : 'light' 20 | ); 21 | } else { 22 | document.documentElement.setAttribute('data-theme', settings.theme); 23 | } 24 | }; 25 | 26 | mediaQuery.addEventListener('change', updateTheme); 27 | updateTheme(); 28 | 29 | return () => mediaQuery.removeEventListener('change', updateTheme); 30 | }, [settings.theme]); 31 | 32 | return ( 33 |
34 | {settings.backgroundImage && ( 35 | <> 36 |
40 | {/*
*/} 41 |
45 | 46 | 47 | )} 48 | 49 |
50 | 51 |
52 | 57 | 58 |

Task Master

59 |
60 | 61 |
62 |
63 | 64 | 65 |
66 |
67 | 68 |
69 |
70 |
71 |
72 |
73 | ); 74 | } 75 | 76 | export default App; -------------------------------------------------------------------------------- /src/components/AddTask.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Plus } from 'lucide-react'; 3 | import { Priority } from '../types'; 4 | import { useStore } from '../store/useStore'; 5 | 6 | export const AddTask: React.FC = () => { 7 | const [title, setTitle] = useState(''); 8 | const [description, setDescription] = useState(''); 9 | const [priority, setPriority] = useState('medium'); 10 | 11 | const { addTask } = useStore(); 12 | 13 | const handleSubmit = (e: React.FormEvent) => { 14 | e.preventDefault(); 15 | if (title.trim() && description.trim()) { 16 | addTask(title.trim(), description.trim(), priority); 17 | setTitle(''); 18 | setDescription(''); 19 | setPriority('medium'); 20 | } 21 | }; 22 | 23 | return ( 24 |
25 | setTitle(e.target.value)} 29 | placeholder="Task Title" 30 | className="flex-1 rounded-lg border border-gray-300 bg-white px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-white dark:border-gray-600" 31 | /> 32 |