Solution:
import './App.css';
import { useState, useEffect } from 'react';
function App() {
const [todos, setTodos] = useState([]);
const [search, setSearch] = useState('');
const [current, setCurrent] = useState(1);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos')
.then((res) => res.json())
.then((data) => setTodos(data.slice(0, 100)))
.catch((err) => console.error(err));
}, []);
const toggleCompleted = (id) => {
console.log('Inside');
const updated = todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
);
console.log(todos);
setTodos(updated);
console.log(updated);
// setTodos(prev =>
// prev.map((todo) =>
// todo.id === id ? { ...todo, completed: !todo.completed } : todo
// )
// );
};
const fetchMatching = todos.filter((todo) =>
todo.title.toLowerCase().includes(search.toLowerCase())
);
// 20 records per page
const total = Math.ceil(fetchMatching.length / 20);
const start = (current - 1) * 20;
const currentTodo = fetchMatching.slice(start, start + 20);
const changePageNo = (page) => {
if (page >= 1 && page <= total) {
setCurrent(page);
}
};
return (
<>
<div>
<h2>Todo List </h2>
<input
type="text"
placeholder="Search any title"
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<table style={{ width: '100%' }}>
<thead>
<tr>
<th style={tStyle}>ID </th>
<th style={tStyle}>Title </th>
<th style={tStyle}>Completed </th>
</tr>
</thead>
<tbody>
{currentTodo.map((todo, index) => (
<tr key={todo.id}>
{/* <td style={tStyle}>{todo.id} </td> */}
<td style={tStyle}>{index + 1} </td>
<td style={tStyle}>{todo.title} </td>
<td
style={{
...tStyle,
cursor: 'pointer',
color: todo.completed ? 'green' : 'red',
}}
onClick={() => toggleCompleted(todo.id)}
>
{todo.completed ? 'True' : 'False'}
</td>
</tr>
))}
</tbody>
</table>
<div>
<button
onClick={() => changePageNo(current - 1)}
disabled={current === 1}
>
Previous
</button>
{[...Array(total)].map((_, index) => (
<button key={index} onClick={() => changePageNo(index + 1)}>
{index + 1}
</button>
))}
<button
onClick={() => changePageNo(current + 1)}
disabled={current === total}
>
Next
</button>
</div>
</div>
</>
);
}
const tStyle = {
border: '2px solid black',
padding: '8px',
textAlign: 'left',
};
export default App;
Output:
