Building form component and App.jsx
//CustomForm.jsx
import { PlusIcon } from "@heroicons/react/24/solid";
function CustomForm() {
const handleFormSubmit = (e) => {
e.preventDefault();
console.log("Form submitted");
};
return (
<form className="todo" onSubmit={handleFormSubmit}>
<div className="wrapper">
<input
type="task"
id="task"
className="input"
required
autoFocus
maxLength={60}
placeholder="Enter task"
/>
<label htmlFor="task" className="label">
Enter Task
</label>
</div>
<button className="btn" aria-label="Add Task" type="submit">
<PlusIcon />
</button>
</form>
);
}
export default CustomForm;
//App.jsx
import "./App.css";
import CustomForm from "./components/CustomForm";
function App() {
return (
<div className="container">
<header>
<h1>Todo App</h1>
</header>
<CustomForm />
</div>
);
}
export default App;
Displaying tasks in a list
App.jsx
import { useState } from "react";
import "./App.css";
import CustomForm from "./components/CustomForm";
import TaskList from "./components/TaskList";
function App() {
const [tasks, setTasks] = useState([]);
const addTask = (task) => {
setTasks((prevTask) => [...prevTask, task]);
};
return (
<div className="container">
<header>
<h1>Todo App</h1>
</header>
<CustomForm addTask={addTask} />
<TaskList tasks={tasks} />
</div>
);
}
export default App;
//CustomForm.jsx
import { useState } from "react";
// librabry imports
import { PlusIcon } from "@heroicons/react/24/solid";
function CustomForm({ addTask }) {
const [task, setTask] = useState("");
const handleFormSubmit = (e) => {
e.preventDefault();
addTask({
name: task,
checked: false,
id: Date.now(),
});
console.log("Form submitted");
setTask("");
};
return (
<form className="todo" onSubmit={handleFormSubmit}>
<div className="wrapper">
<input
type="task"
id="task"
className="input"
required
autoFocus
maxLength={60}
placeholder="Enter task"
value={task}
onChange={(e) => setTask(e.target.value)}
/>
<label htmlFor="task" className="label">
Enter Task
</label>
</div>
<button className="btn" aria-label="Add Task" type="submit">
<PlusIcon />
</button>
</form>
);
}
export default CustomForm;
//TaskList.jsx
import TaskItem from "./TaskItem";
import classes from "./TaskList.module.css";
const TaskList = ({ tasks }) => {
return (
<ul className={classes.tasks}>
{tasks
.sort((a, b) => b.id - a.id) // To order task on Stack Order
.map((task) => (
<TaskItem key={task.id} task={task} />
))}
</ul>
);
};
export default TaskList;
//TaskItem
import { useState } from "react";
import classes from "./TaskItem.module.css";
import { CheckIcon } from "@heroicons/react/24/outline";
import { PencilSquareIcon } from "@heroicons/react/24/outline";
import { TrashIcon } from "@heroicons/react/24/outline";
function TaskItem({ task }) {
const [isChecked, setIsChecked] = useState(task.checked);
const handleCheckboxChange = (e) => {
setIsChecked(!isChecked);
};
return (
<li className={classes.task}>
<div className={classes["task-group"]}>
<input
type="checkbox"
className={classes.checkbox}
onChange={handleCheckboxChange}
checked={isChecked}
name={task.name}
id={task.id}
/>
<label htmlFor={task.id} className={classes.label}>
{task.name}
<p className={classes.checkmark}>
<CheckIcon strokeWidth={2} width={24} height={24} />
</p>
</label>
</div>
<div className={classes["task-group"]}>
<button
className="btn"
area-label={`Update ${task.name} Task`}
// onClick={}
>
<PencilSquareIcon width={24} height={24} />
</button>
<button
className={`btn ${classes.delete}`}
area-label={`Delete ${task.name} Task`}
// onClick={}
>
<TrashIcon width={24} height={24} />
</button>
</div>
</li>
);
}
export default TaskItem;