81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import reactLogo from './assets/react.svg'
|
|
import dockerLogo from './assets/docker.svg'
|
|
import './App.css'
|
|
|
|
function App() {
|
|
const [users, setUsers] = useState([])
|
|
const [page, setPage] = useState(1)
|
|
const [pagination, setPagination] = useState({
|
|
currentPage: 1,
|
|
lastPage: 1,
|
|
total: 0,
|
|
})
|
|
|
|
useEffect(() => {
|
|
fetch(`/api/users?page=${page}`)
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
setUsers(data.data || [])
|
|
setPagination({
|
|
currentPage: data.meta.currentPage,
|
|
lastPage: data.meta.lastPage,
|
|
total: data.meta.total,
|
|
})
|
|
})
|
|
.catch(err => console.error('Failed to fetch users:', err))
|
|
}, [page])
|
|
|
|
const handlePrevious = () => {
|
|
if (page > 1) setPage(page - 1)
|
|
}
|
|
|
|
const handleNext = () => {
|
|
if (page < pagination.lastPage) setPage(page + 1)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div>
|
|
<a href="https://react.dev" target="_blank" rel="noreferrer">
|
|
<img src={reactLogo} className="logo react" alt="React logo" />
|
|
</a>
|
|
<a href="https://docker.com" target="_blank" rel="noreferrer">
|
|
<img src={dockerLogo} className="logo docker" alt="Docker logo" />
|
|
</a>
|
|
</div>
|
|
|
|
<h1>React + Docker + Traefik</h1>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Email</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{users.length > 0 ? users.map((user) => (
|
|
<tr key={user.id}>
|
|
<td>{user.fullName}</td>
|
|
<td>{user.email}</td>
|
|
</tr>
|
|
)) : (
|
|
<tr>
|
|
<td colSpan="2">No users found</td>
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
</table>
|
|
|
|
<div className="pagination">
|
|
<button onClick={handlePrevious} disabled={page === 1}>Previous</button>
|
|
<span>Page {pagination.currentPage} of {pagination.lastPage}</span>
|
|
<button onClick={handleNext} disabled={page === pagination.lastPage}>Next</button>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default App
|