diff --git a/src/App.tsx b/src/App.tsx index 13c44ae..c80317c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,213 @@ -import React from 'react'; +import { + Box, + Typography, + Button, + Stack, + List, + ListItem, + Checkbox, + ToggleButton, + ToggleButtonGroup, + FormControl, + InputLabel, + Select, + MenuItem, + SelectChangeEvent, +} from "@mui/material"; +import { useState, useEffect } from "react"; +import AddTodoDialog from "./components/AddTodoDialog"; +import { Todo } from "./types/todo"; +import { api } from "./services/api"; + +type Filter = "all" | "active" | "completed"; +type SortType = "priority"; + function App() { + const [todos, setTodos] = useState([]); + const [open, setOpen] = useState(false); + const [filter, setFilter] = useState("all"); + const [sortBy, setSortBy] = useState("priority"); + const [newTodo, setNewTodo] = useState({ + id: 0, + text: "", + description: "", + completed: false, + createdAt: new Date().toISOString(), + dueDate: "", + priority: "medium", + }); + + const handleOpen = () => { + setOpen(true); + }; + + const toggleTodoCompletion = (id: number) => { + const todo = todos.find((t) => t.id === id); + if (todo) { + const updatedTodo = { ...todo, completed: !todo.completed }; + api + .updateTodo(id.toString(), updatedTodo) + .then(() => { + setTodos((prevTodos) => + prevTodos.map((t) => (t.id === id ? updatedTodo : t)) + ); + }) + .catch((error) => { + console.error("Error updating todo:", error); + }); + } + }; + + const handleAddTodo = (todo: Omit) => { + console.log("Adding todo:", todo); + api + .createTodo(todo as Todo) // The API will assign the ID + .then(() => { + // Refetch todos to get the updated list with proper IDs + return api.getTodos(); + }) + .then((updatedTodos) => { + setTodos(updatedTodos); + setOpen(false); + // Reset the form + setNewTodo({ + id: 0, + text: "", + description: "", + completed: false, + createdAt: new Date().toISOString(), + dueDate: "", + priority: "medium", + }); + }) + .catch((error) => { + console.error("Error adding todo:", error); + }); + }; + + const handleDelete = (id: number) => { + api + .deleteTodo(id.toString()) + .then(() => { + setTodos((prevTodos) => prevTodos.filter((todo) => todo.id !== id)); + }) + .catch((error) => { + console.error("Error deleting todo:", error); + }); + }; + + const handleFilterChange = ( + event: React.MouseEvent, + newFilter: Filter + ) => { + if (newFilter !== null) { + setFilter(newFilter); + } + }; + + const handleSortChange = (event: SelectChangeEvent) => { + setSortBy(event.target.value as SortType); + }; + + const filteredTodos = todos + .filter((todo) => { + if (filter === "active") return !todo.completed; + if (filter === "completed") return todo.completed; + return true; // "all" filter + }) + .sort((a, b) => { + if (sortBy === "priority") { + const priorityOrder = { high: 0, medium: 1, low: 2 }; + return priorityOrder[a.priority] - priorityOrder[b.priority]; + } else if (sortBy === "dueDate") { + if (!a.dueDate || !b.dueDate) return 0; // If no due date, don't sort + const dateA = new Date(a.dueDate); + const dateB = new Date(b.dueDate); + return dateA.getTime() - dateB.getTime(); + } + return 0; // Default case, no sorting + }); + + useEffect(() => { + const fetchTodos = async () => { + try { + const response = await api.getTodos(); + console.log("Fetched todos:", response); + setTodos(response); + } catch (error) { + console.error("Error fetching todos:", error); + } + }; + + fetchTodos(); + }, []); + return ( -
-

Welcome to my App!

-
+ + + Todo List + + + + + All + Active + Completed + + + Sort By + + + + + {filteredTodos.map((todo) => ( + + toggleTodoCompletion(todo.id)} + sx={{ + color: todo.completed ? "green" : "grey", + "&.Mui-checked": { + color: "success.main", + }, + }} + /> + {todo.text} + + + ))} + + ); } -export default App; \ No newline at end of file +export default App; diff --git a/src/components/AddTodoDialog.tsx b/src/components/AddTodoDialog.tsx new file mode 100644 index 0000000..37117e7 --- /dev/null +++ b/src/components/AddTodoDialog.tsx @@ -0,0 +1,106 @@ +import { + Button, + Dialog, + DialogTitle, + DialogContent, + TextField, + InputLabel, + Select, + MenuItem, + SelectChangeEvent, +} from "@mui/material"; +import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import { Todo } from "../types/todo"; + +type AddTodoDialogProps = { + open: boolean; + setOpen: (open: boolean) => void; + handleAddTodo: (todo: Omit) => void; + newTodo: { + id?: number; + text: string; + description?: string; + completed?: boolean; + createdAt?: string; + dueDate?: string; + priority: "low" | "medium" | "high"; + }; + setNewTodo: (todo: any) => void; +}; + +function AddTodoDialog({ + open, + setOpen, + handleAddTodo, + newTodo, + setNewTodo, +}: AddTodoDialogProps) { + const handlePriorityChange = (event: SelectChangeEvent) => { + setNewTodo({ + ...newTodo, + priority: event.target.value as Todo["priority"], + }); + }; + + return ( + setOpen(false)}> + Add Todo + + setNewTodo({ ...newTodo, text: e.target.value })} + /> + + setNewTodo({ ...newTodo, description: e.target.value }) + } + /> + Priority + + + { + setNewTodo({ + ...newTodo, + dueDate: date ? date.toISOString() : "", + }); + }} + /> + + + + + ); +} + +export default AddTodoDialog; diff --git a/src/services/api.ts b/src/services/api.ts index 5a82863..2f33ce8 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -1,7 +1,80 @@ +import { Todo } from "../types/todo"; + +const baseUrl = "http://localhost:3001"; +const mockTodos: Todo[] = [ + { + id: 1, + text: "Test Todo 1", + description: "This is a test todo", + completed: false, + createdAt: "2025-06-09T04:00:00.000Z", + dueDate: "2025-06-09T04:00:00.000Z", + priority: "medium", + }, + { + id: 2, + text: "Test Todo 2", + description: "This is another test todo", + completed: true, + createdAt: "2025-06-09T04:00:00.000Z", + dueDate: "2025-06-09T04:00:00.000Z", + priority: "high", + }, +]; export const api = { - async createTodo() {}, - async getTodos() {}, - async updateTodo() {}, - async deleteTodo() {}, -}; \ No newline at end of file + getTodos: async () => { + return new Promise((resolve) => { + setTimeout(() => { + const localStorageTodos = localStorage.getItem("todos"); + if (localStorageTodos) { + const todosFromStorage: Todo[] = JSON.parse(localStorageTodos); + resolve(todosFromStorage); + } else { + resolve(mockTodos); + } + }, 1000); // Simulate network delay + }); + }, + createTodo: async (todo: Todo) => { + const localStorageTodos = localStorage.getItem("todos"); + let existingTodos: Todo[] = []; + + if (localStorageTodos) { + existingTodos = JSON.parse(localStorageTodos); + } else { + existingTodos = [...mockTodos]; + } + + // Generate a unique ID + const newId = + existingTodos.length > 0 + ? Math.max(...existingTodos.map((t) => t.id)) + 1 + : 1; + const newTodo = { ...todo, id: newId }; + + const updatedTodos = [...existingTodos, newTodo]; + localStorage.setItem("todos", JSON.stringify(updatedTodos)); + }, + updateTodo: async (id: string, todo: Partial) => { + const localStorageTodos = localStorage.getItem("todos"); + if (localStorageTodos) { + const todosFromStorage: Todo[] = JSON.parse(localStorageTodos); + const updatedTodos = todosFromStorage.map((t) => + t.id.toString() === id ? { ...t, ...todo } : t + ); + localStorage.setItem("todos", JSON.stringify(updatedTodos)); + } + }, + deleteTodo: async (id: string) => { + const localStorageTodos = localStorage.getItem("todos"); + if (localStorageTodos) { + console.log("Deleting todo with id:", id); + const todosFromStorage: Todo[] = JSON.parse(localStorageTodos); + const updatedTodos = todosFromStorage.filter( + (todo) => todo.id.toString() !== id + ); + localStorage.setItem("todos", JSON.stringify(updatedTodos)); + } + }, +}; diff --git a/src/sol.tsx b/src/sol.tsx index 2efb672..70cbfcc 100644 --- a/src/sol.tsx +++ b/src/sol.tsx @@ -1,573 +1,575 @@ -/*import React, { useState, useEffect } from 'react'; -import { Todo } from './types/todo'; -import { api } from './services/api'; -import { - Button, - Dialog, - DialogTitle, - DialogContent, - DialogActions, - TextField, - IconButton, - List, - ListItem, - ListItemText, - ListItemSecondaryAction, - Typography, - Box, - Paper, - Checkbox, - DialogContentText, - Divider, - Chip, - Stack, - ToggleButton, - ToggleButtonGroup, - FormControl, - InputLabel, - Select, - MenuItem, - SelectChangeEvent, -} from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -import AddIcon from '@mui/icons-material/Add'; -import DeleteIcon from '@mui/icons-material/Delete'; -import AccessTimeIcon from '@mui/icons-material/AccessTime'; -import FlagIcon from '@mui/icons-material/Flag'; -import EditIcon from '@mui/icons-material/Edit'; -import './App.css'; - -type FilterType = 'all' | 'active' | 'completed'; -type SortType = 'date' | 'priority' | 'dueDate'; -type PriorityType = 'low' | 'medium' | 'high'; - -function App() { - const [todos, setTodos] = useState([]); - const [newTodo, setNewTodo] = useState({ - title: '', - description: '', - dueDate: null as Date | null, - priority: 'medium' as PriorityType, - }); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [formError, setFormError] = useState(null); - const [open, setOpen] = useState(false); - const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); - const [todoToDelete, setTodoToDelete] = useState(null); - const [filter, setFilter] = useState('all'); - const [sortBy, setSortBy] = useState('date'); - const [editDialogOpen, setEditDialogOpen] = useState(false); - const [todoToEdit, setTodoToEdit] = useState(null); - const [editDescription, setEditDescription] = useState(''); - const [editDueDate, setEditDueDate] = useState(null); - const [editPriority, setEditPriority] = useState('medium'); - - useEffect(() => { - fetchTodos(); - }, []); - - const handleClickOpen = () => { - setOpen(true); - }; - - const handleClose = () => { - setOpen(false); - setNewTodo({ title: '', description: '', dueDate: null, priority: 'medium' }); - setFormError(null); - }; - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setFormError(null); - - if (!newTodo.title.trim()) { - setFormError('Title cannot be empty'); - return; - } - - try { - const todo = await api.createTodo({ - text: newTodo.title.trim(), - description: newTodo.description.trim(), - completed: false, - dueDate: newTodo.dueDate?.toISOString(), - priority: newTodo.priority, - }); - setTodos([...todos, todo]); - handleClose(); - setError(null); - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to create todo'); - } - }; - - const fetchTodos = async () => { - try { - setLoading(true); - const data = await api.getTodos(); - setTodos(data); - setError(null); - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to fetch todos'); - } finally { - setLoading(false); - } - }; - - const toggleTodo = async (id: number) => { - const todo = todos.find(t => t.id === id); - if (!todo) return; - - try { - const updatedTodo = await api.updateTodo(id.toString(), { - completed: !todo.completed, - }); - setTodos(todos.map(t => t.id === id ? updatedTodo : t)); - setError(null); - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to update todo'); - } - }; - - const handleDeleteClick = (todo: Todo) => { - setTodoToDelete(todo); - setDeleteDialogOpen(true); - }; - - const handleDeleteConfirm = async () => { - if (!todoToDelete) return; - - try { - await api.deleteTodo(todoToDelete.id.toString()); - setTodos(todos.filter(t => t.id !== todoToDelete.id)); - setError(null); - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to delete todo'); - } finally { - setDeleteDialogOpen(false); - setTodoToDelete(null); - } - }; - - const handleDeleteCancel = () => { - setDeleteDialogOpen(false); - setTodoToDelete(null); - }; - - const handleFilterChange = ( - event: React.MouseEvent, - newFilter: FilterType, - ) => { - if (newFilter !== null) { - setFilter(newFilter); - } - }; - - const handleSortChange = (event: SelectChangeEvent) => { - setSortBy(event.target.value as SortType); - }; - - const handlePriorityChange = (event: SelectChangeEvent) => { - setNewTodo({ ...newTodo, priority: event.target.value as PriorityType }); - }; - - const getPriorityColor = (priority: string) => { - switch (priority) { - case 'high': - return 'error'; - case 'medium': - return 'warning'; - case 'low': - return 'success'; - default: - return 'default'; - } - }; - - const handleEditClick = (todo: Todo) => { - setTodoToEdit(todo); - setEditDescription(todo.description || ''); - setEditDueDate(todo.dueDate ? new Date(todo.dueDate) : null); - setEditPriority(todo.priority); - setEditDialogOpen(true); - }; - - const handleEditClose = () => { - setEditDialogOpen(false); - setTodoToEdit(null); - setEditDescription(''); - setEditDueDate(null); - setEditPriority('medium'); - }; - - const handleEditSubmit = async () => { - if (!todoToEdit) return; - - try { - const updatedTodo = await api.updateTodo(todoToEdit.id.toString(), { - description: editDescription.trim(), - dueDate: editDueDate?.toISOString(), - priority: editPriority, - }); - setTodos(todos.map(t => t.id === todoToEdit.id ? updatedTodo : t)); - setError(null); - handleEditClose(); - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to update todo'); - } - }; - - const filteredAndSortedTodos = [...todos] - .filter(todo => { - switch (filter) { - case 'active': - return !todo.completed; - case 'completed': - return todo.completed; - default: - return true; - } - }) - .sort((a, b) => { - switch (sortBy) { - case 'priority': { - const priorityOrder = { high: 0, medium: 1, low: 2 }; - return priorityOrder[a.priority] - priorityOrder[b.priority]; - } - case 'dueDate': { - if (!a.dueDate) return 1; - if (!b.dueDate) return -1; - return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime(); - } - default: - return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(); - } - }); - - const formatDate = (dateString: string) => { - return new Date(dateString).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric', - }); - }; - - if (loading) { - return
Loading...
; - } - - return ( - - - Todo List - +// import React, { useState, useEffect } from 'react'; +// import { Todo } from './types/todo'; +// import { api } from './services/api'; +// import { +// Button, +// Dialog, +// DialogTitle, +// DialogContent, +// DialogActions, +// TextField, +// IconButton, +// List, +// ListItem, +// ListItemText, +// ListItemSecondaryAction, +// Typography, +// Box, +// Paper, +// Checkbox, +// DialogContentText, +// Divider, +// Chip, +// Stack, +// ToggleButton, +// ToggleButtonGroup, +// FormControl, +// InputLabel, +// Select, +// MenuItem, +// SelectChangeEvent, +// } from '@mui/material'; +// import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +// import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +// import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; +// import AddIcon from '@mui/icons-material/Add'; +// import DeleteIcon from '@mui/icons-material/Delete'; +// import AccessTimeIcon from '@mui/icons-material/AccessTime'; +// import FlagIcon from '@mui/icons-material/Flag'; +// import EditIcon from '@mui/icons-material/Edit'; +// import './App.css'; + +// type FilterType = 'all' | 'active' | 'completed'; +// type SortType = 'date' | 'priority' | 'dueDate'; +// type PriorityType = 'low' | 'medium' | 'high'; + +// function App() { +// const [todos, setTodos] = useState([]); +// const [newTodo, setNewTodo] = useState({ +// title: '', +// description: '', +// dueDate: null as Date | null, +// priority: 'medium' as PriorityType, +// }); +// const [loading, setLoading] = useState(true); +// const [error, setError] = useState(null); +// const [formError, setFormError] = useState(null); +// const [open, setOpen] = useState(false); +// const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); +// const [todoToDelete, setTodoToDelete] = useState(null); +// const [filter, setFilter] = useState('all'); +// const [sortBy, setSortBy] = useState('date'); +// const [editDialogOpen, setEditDialogOpen] = useState(false); +// const [todoToEdit, setTodoToEdit] = useState(null); +// const [editDescription, setEditDescription] = useState(''); +// const [editDueDate, setEditDueDate] = useState(null); +// const [editPriority, setEditPriority] = useState('medium'); + +// useEffect(() => { +// fetchTodos(); +// }, []); + +// const handleClickOpen = () => { +// setOpen(true); +// }; + +// const handleClose = () => { +// setOpen(false); +// setNewTodo({ title: '', description: '', dueDate: null, priority: 'medium' }); +// setFormError(null); +// }; + +// const handleSubmit = async (e: React.FormEvent) => { +// e.preventDefault(); +// setFormError(null); + +// if (!newTodo.title.trim()) { +// setFormError('Title cannot be empty'); +// return; +// } + +// try { +// const todo = await api.createTodo({ +// text: newTodo.title.trim(), +// description: newTodo.description.trim(), +// completed: false, +// dueDate: newTodo.dueDate?.toISOString(), +// priority: newTodo.priority, +// }); +// setTodos([...todos, todo]); +// handleClose(); +// setError(null); +// } catch (err) { +// setError(err instanceof Error ? err.message : 'Failed to create todo'); +// } +// }; + +// const fetchTodos = async () => { +// try { +// setLoading(true); +// const data = await api.getTodos(); +// setTodos(data); +// setError(null); +// } catch (err) { +// setError(err instanceof Error ? err.message : 'Failed to fetch todos'); +// } finally { +// setLoading(false); +// } +// }; + +// const toggleTodo = async (id: number) => { +// const todo = todos.find(t => t.id === id); +// if (!todo) return; + +// try { +// const updatedTodo = await api.updateTodo(id.toString(), { +// completed: !todo.completed, +// }); +// setTodos(todos.map(t => t.id === id ? updatedTodo : t)); +// setError(null); +// } catch (err) { +// setError(err instanceof Error ? err.message : 'Failed to update todo'); +// } +// }; + +// const handleDeleteClick = (todo: Todo) => { +// setTodoToDelete(todo); +// setDeleteDialogOpen(true); +// }; + +// const handleDeleteConfirm = async () => { +// if (!todoToDelete) return; + +// try { +// await api.deleteTodo(todoToDelete.id.toString()); +// setTodos(todos.filter(t => t.id !== todoToDelete.id)); +// setError(null); +// } catch (err) { +// setError(err instanceof Error ? err.message : 'Failed to delete todo'); +// } finally { +// setDeleteDialogOpen(false); +// setTodoToDelete(null); +// } +// }; + +// const handleDeleteCancel = () => { +// setDeleteDialogOpen(false); +// setTodoToDelete(null); +// }; + +// const handleFilterChange = ( +// event: React.MouseEvent, +// newFilter: FilterType, +// ) => { +// if (newFilter !== null) { +// setFilter(newFilter); +// } +// }; + +// const handleSortChange = (event: SelectChangeEvent) => { +// setSortBy(event.target.value as SortType); +// }; + +// const handlePriorityChange = (event: SelectChangeEvent) => { +// setNewTodo({ ...newTodo, priority: event.target.value as PriorityType }); +// }; + +// const getPriorityColor = (priority: string) => { +// switch (priority) { +// case 'high': +// return 'error'; +// case 'medium': +// return 'warning'; +// case 'low': +// return 'success'; +// default: +// return 'default'; +// } +// }; + +// const handleEditClick = (todo: Todo) => { +// setTodoToEdit(todo); +// setEditDescription(todo.description || ''); +// setEditDueDate(todo.dueDate ? new Date(todo.dueDate) : null); +// setEditPriority(todo.priority); +// setEditDialogOpen(true); +// }; + +// const handleEditClose = () => { +// setEditDialogOpen(false); +// setTodoToEdit(null); +// setEditDescription(''); +// setEditDueDate(null); +// setEditPriority('medium'); +// }; + +// const handleEditSubmit = async () => { +// if (!todoToEdit) return; + +// try { +// const updatedTodo = await api.updateTodo(todoToEdit.id.toString(), { +// description: editDescription.trim(), +// dueDate: editDueDate?.toISOString(), +// priority: editPriority, +// }); +// setTodos(todos.map(t => t.id === todoToEdit.id ? updatedTodo : t)); +// setError(null); +// handleEditClose(); +// } catch (err) { +// setError(err instanceof Error ? err.message : 'Failed to update todo'); +// } +// }; + +// const filteredAndSortedTodos = [...todos] +// .filter(todo => { +// switch (filter) { +// case 'active': +// return !todo.completed; +// case 'completed': +// return todo.completed; +// default: +// return true; +// } +// }) +// .sort((a, b) => { +// switch (sortBy) { +// case 'priority': { +// const priorityOrder = { high: 0, medium: 1, low: 2 }; +// return priorityOrder[a.priority] - priorityOrder[b.priority]; +// } +// case 'dueDate': { +// if (!a.dueDate) return 1; +// if (!b.dueDate) return -1; +// return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime(); +// } +// default: +// return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(); +// } +// }); + +// const formatDate = (dateString: string) => { +// return new Date(dateString).toLocaleDateString('en-US', { +// month: 'short', +// day: 'numeric', +// year: 'numeric', +// }); +// }; + +// if (loading) { +// return
Loading...
; +// } + +// return ( +// +// +// Todo List +// - {error && ( - - {error} - - )} - - - - - All - Active - Completed - - - Sort By - - - - - - Add New Todo -
- - - setNewTodo({ ...newTodo, title: e.target.value })} - error={!!formError} - helperText={formError} - required - /> - setNewTodo({ ...newTodo, description: e.target.value })} - /> - - setNewTodo({ ...newTodo, dueDate: date })} - slotProps={{ textField: { fullWidth: true } }} - /> - - - Priority - - - - - - - - -
-
- - - - Delete Todo - - - - Are you sure you want to delete "{todoToDelete?.text}"? This action cannot be undone. - - - - - - - - - - Edit Todo - - - setEditDescription(e.target.value)} - /> - - setEditDueDate(date)} - slotProps={{ textField: { fullWidth: true } }} - /> - - - Priority - - - - - - - - - - - - - {filteredAndSortedTodos.map((todo, index) => ( - - {index > 0 && } - - toggleTodo(todo.id)} - sx={{ - '&.Mui-checked': { - color: 'success.main', - }, - }} - /> - - - {todo.text} - - } - label={todo.priority} - color={getPriorityColor(todo.priority)} - variant="outlined" - /> - {todo.dueDate && ( - } - label={formatDate(todo.dueDate)} - variant="outlined" - color={new Date(todo.dueDate) < new Date() ? 'error' : 'default'} - /> - )} -
- } - secondary={ - - {todo.description} - - } - onClick={() => toggleTodo(todo.id)} - sx={{ - cursor: 'pointer', - '&:hover': { - '& .MuiTypography-root': { - color: todo.completed ? 'text.secondary' : 'primary.main', - }, - }, - }} - /> - - handleEditClick(todo)} - sx={{ - color: 'primary.main', - mr: 1, - '&:hover': { - bgcolor: 'primary.light', - color: 'primary.contrastText', - }, - }} - > - - - handleDeleteClick(todo)} - sx={{ - color: 'error.main', - '&:hover': { - bgcolor: 'error.light', - color: 'error.contrastText', - }, - }} - > - - - - - - ))} - {todos.length === 0 && ( - - - No todos yet. Add one to get started! - - } - /> - - )} - - -
- ); -} -*/ -export default () => {}; +// {error && ( +// +// {error} +// +// )} + +// +// +// +// All +// Active +// Completed +// +// +// Sort By +// +// +// + +// +// Add New Todo +//
+// +// +// setNewTodo({ ...newTodo, title: e.target.value })} +// error={!!formError} +// helperText={formError} +// required +// /> +// setNewTodo({ ...newTodo, description: e.target.value })} +// /> +// +// setNewTodo({ ...newTodo, dueDate: date })} +// slotProps={{ textField: { fullWidth: true } }} +// /> +// +// +// Priority +// +// +// +// +// +// +// +// +//
+//
+ +// +// +// Delete Todo +// +// +// +// Are you sure you want to delete "{todoToDelete?.text}"? This action cannot be undone. +// +// +// +// +// +// +// + +// +// Edit Todo +// +// +// setEditDescription(e.target.value)} +// /> +// +// setEditDueDate(date)} +// slotProps={{ textField: { fullWidth: true } }} +// /> +// +// +// Priority +// +// +// +// +// +// +// +// +// + +// +// +// {filteredAndSortedTodos.map((todo, index) => ( +// +// {index > 0 && } +// +// toggleTodo(todo.id)} +// sx={{ +// '&.Mui-checked': { +// color: 'success.main', +// }, +// }} +// /> +// +// +// {todo.text} +// +// } +// label={todo.priority} +// color={getPriorityColor(todo.priority)} +// variant="outlined" +// /> +// {todo.dueDate && ( +// } +// label={formatDate(todo.dueDate)} +// variant="outlined" +// color={new Date(todo.dueDate) < new Date() ? 'error' : 'default'} +// /> +// )} +// +// } +// secondary={ +// +// {todo.description} +// +// } +// onClick={() => toggleTodo(todo.id)} +// sx={{ +// cursor: 'pointer', +// '&:hover': { +// '& .MuiTypography-root': { +// color: todo.completed ? 'text.secondary' : 'primary.main', +// }, +// }, +// }} +// /> +// +// handleEditClick(todo)} +// sx={{ +// color: 'primary.main', +// mr: 1, +// '&:hover': { +// bgcolor: 'primary.light', +// color: 'primary.contrastText', +// }, +// }} +// > +// +// +// handleDeleteClick(todo)} +// sx={{ +// color: 'error.main', +// '&:hover': { +// bgcolor: 'error.light', +// color: 'error.contrastText', +// }, +// }} +// > +// +// +// +// +// +// ))} +// {todos.length === 0 && ( +// +// +// No todos yet. Add one to get started! +// +// } +// /> +// +// )} +// +// +// +// ); +// } + +// export default App; + +export { };