-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from AbdusSattar-70/display-todo
Display todo: Add TodoItem and TodoList components
- Loading branch information
Showing
13 changed files
with
379 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { useState } from "react"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
import PrioritySelector from "./PrioritySelector"; | ||
import { Priority } from "../../utils/types"; | ||
import { editTodo } from "../../redux/todoSlice"; | ||
import { RootState } from "../../redux/store"; | ||
|
||
interface EditTodoProps { | ||
todoId: number; | ||
editModalRef: React.RefObject<HTMLDialogElement>; | ||
} | ||
|
||
const EditTodo: React.FC<EditTodoProps> = ({ todoId, editModalRef }) => { | ||
const dispatch = useDispatch(); | ||
const todos = useSelector((state: RootState) => state.todos.todos); | ||
const selectedTodo = todos.find((todo) => todo.id === todoId); | ||
const [updatedText, setUpdatedText] = useState(selectedTodo?.text || ""); | ||
const [priority, setPriority] = useState<Priority>( | ||
selectedTodo?.priority || Priority.Low | ||
); | ||
|
||
const saveEditing = (e: React.FormEvent<HTMLFormElement>) => { | ||
e.preventDefault(); | ||
if (updatedText.trim() !== "") { | ||
const updatedTodo = { | ||
id: todoId, | ||
text: updatedText, | ||
priority, | ||
}; | ||
dispatch(editTodo(updatedTodo)); | ||
editModalRef.current?.close(); | ||
} | ||
}; | ||
|
||
return ( | ||
<dialog ref={editModalRef} className="modal text-slate-200 sm:modal-middle"> | ||
<div className="modal-box bg-slate-600"> | ||
<form | ||
onSubmit={saveEditing} | ||
className="mx-2 mt-2 grid grid-cols-1 gap-2 p-2" | ||
> | ||
<div className="form-control gap-1"> | ||
<label htmlFor="addTodoInput" className="sr-only"> | ||
Update Todo | ||
</label> | ||
<input | ||
id="addTodoInput" | ||
className="input input-bordered bg-slate-800" | ||
type="text" | ||
value={updatedText} | ||
onChange={(e) => setUpdatedText(e.target.value)} | ||
/> | ||
</div> | ||
<PrioritySelector value={priority} onChange={setPriority} /> | ||
<button className="btn btn-success">Update</button> | ||
</form> | ||
<div className="modal-action"> | ||
<button | ||
className="btn btn-sm" | ||
onClick={() => editModalRef.current?.close()} | ||
> | ||
Close | ||
</button> | ||
</div> | ||
</div> | ||
</dialog> | ||
); | ||
}; | ||
|
||
export default EditTodo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { FilterTodos } from "../../utils/types"; | ||
|
||
interface FilterByProps { | ||
filterValue: string; | ||
setFilterValue: (value: string) => void; | ||
} | ||
|
||
const FilterBy: React.FC<FilterByProps> = ({ filterValue, setFilterValue }) => { | ||
const handleTodoFilter = (event: React.ChangeEvent<HTMLSelectElement>) => { | ||
setFilterValue(event.target.value); | ||
}; | ||
|
||
return ( | ||
<div className="form-control gap-1"> | ||
<label htmlFor="filterTodo" className="sr-only"> | ||
Filter Todo | ||
</label> | ||
<select | ||
id="filterTodo" | ||
name="filterTodo" | ||
value={filterValue} | ||
onChange={handleTodoFilter} | ||
className="select select-bordered bg-slate-800" | ||
> | ||
<option value="" disabled> | ||
Filter By | ||
</option> | ||
{Object.values(FilterTodos).map((todo) => ( | ||
<option key={todo} value={todo}> | ||
{todo} | ||
</option> | ||
))} | ||
</select> | ||
</div> | ||
); | ||
}; | ||
|
||
export default FilterBy; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { useRef, useState } from "react"; | ||
import { GrUpdate } from "react-icons/gr"; | ||
import { FaRegTrashCan } from "react-icons/fa6"; | ||
import { getPriorityColorClass } from "../../utils/getPriorityColor"; | ||
import EditTodo from "./EditTodo"; | ||
import { TodoType } from "../../utils/types"; | ||
import { useDispatch } from "react-redux"; | ||
import { removeTodo, toggleTodo } from "../../redux/todoSlice"; | ||
import { DELETE_CONFIRMATION } from "../../utils/constant"; | ||
|
||
interface TodoItemProps { | ||
todo: TodoType; | ||
} | ||
|
||
const TodoItem: React.FC<TodoItemProps> = ({ todo }) => { | ||
const dispatch = useDispatch(); | ||
const { id, text, priority, completed } = todo; | ||
const [isHovered, setIsHovered] = useState(false); | ||
const editModalRef = useRef<HTMLDialogElement | null>(null); | ||
|
||
const handleDeleteTodo = () => { | ||
const confirmation = window.confirm(DELETE_CONFIRMATION); | ||
confirmation && dispatch(removeTodo(id)); | ||
}; | ||
|
||
const handleToggleTodo = () => { | ||
dispatch(toggleTodo(id)); | ||
}; | ||
|
||
return ( | ||
<li | ||
className={`flex flex-col items-start justify-start gap-2 border bg-slate-800 p-2 text-sm hover:bg-slate-600 sm:flex-row sm:items-center ${getPriorityColorClass( | ||
priority | ||
)}`} | ||
onMouseEnter={() => setIsHovered(true)} | ||
onMouseLeave={() => setIsHovered(false)} | ||
> | ||
<div className="flex items-center justify-start gap-2"> | ||
<label className="label cursor-pointer"> | ||
<input | ||
type="checkbox" | ||
checked={completed} | ||
onChange={handleToggleTodo} | ||
className={`checkbox ${ | ||
completed ? "checkbox-success opacity-50" : "checkbox-warning" | ||
}`} | ||
/> | ||
</label> | ||
<kbd className={`kbd bg-slate-600 ${completed ? "opacity-50" : ""}`}> | ||
{priority} | ||
</kbd> | ||
</div> | ||
<span className={completed ? "line-through opacity-50" : ""}>{text}</span> | ||
{/* Actions */} | ||
<div | ||
className={`${ | ||
isHovered ? "flex items-center justify-center gap-2" : "hidden" | ||
}`} | ||
> | ||
<button | ||
className="btn btn-xs" | ||
onClick={() => editModalRef.current?.showModal()} | ||
> | ||
<GrUpdate /> | ||
</button> | ||
<button className="btn btn-xs" onClick={handleDeleteTodo}> | ||
<FaRegTrashCan /> | ||
</button> | ||
</div> | ||
<EditTodo editModalRef={editModalRef} todoId={id} /> | ||
</li> | ||
); | ||
}; | ||
|
||
export default TodoItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// TodoList.tsx | ||
import { useSelector } from "react-redux"; | ||
import { RootState } from "../../redux/store"; | ||
import TodoItem from "./TodoItem"; | ||
|
||
const TodoList = () => { | ||
const todos = useSelector((state: RootState) => state.todos.todos); | ||
|
||
return ( | ||
<> | ||
<div className="mx-auto mt-8 w-full"> | ||
<ul> | ||
{todos.length > 0 ? ( | ||
todos.map((todo) => <TodoItem key={todo.id} todo={todo} />) | ||
) : ( | ||
<li className="border p-4 text-center text-slate-100"> | ||
No Data Found | ||
</li> | ||
)} | ||
</ul> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default TodoList; |
Oops, something went wrong.