feat: implement pagination for job listings and enhance UI components#58
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Implements a revised pagination experience for job listings in the frontend (page size + numeric navigation) and adjusts backend Swagger docs initialization to be more fault-tolerant at startup.
Changes:
- Add page-size clamping and a dedicated
setPageSizeAPI inuseJobsPagination. - Update
JobsTableCardUI with results summary, numeric pagination buttons, and page-size number input; update related unit tests. - Add Swagger dependencies and switch backend server Swagger setup to async/dynamic registration.
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
package.json |
Adds Swagger dependencies; minor build config formatting change. |
package-lock.json |
Locks Swagger dependency additions. |
frontend/src/hooks/useJobsPagination.ts |
Adds page-size clamping and updates default page size. |
frontend/src/components/JobsTableCard.tsx |
Reworks pagination controls and adds results summary UI. |
frontend/tests/unit/utils/useJobsPagination.test.ts |
Updates hook tests for act() and page-size clamping behavior. |
frontend/tests/unit/components/JobsTableCard.test.tsx |
Updates component tests for the new pagination UI and summary text. |
backend/src/server.js |
Makes Swagger docs registration async/dynamic and moves startup into an async bootstrap. |
Vagas Full Setup 1.0.0.exe |
Windows installer artifact included in the PR. |
Comments suppressed due to low confidence (1)
frontend/src/components/JobsTableCard.tsx:55
getJobIdfalls back to using the passedindexwhenjob.linkis missing. In this component, the index comes frompaginatedJobs.map, so it resets on each page; that makes the computed ID unstable across pagination and can collide between pages, leading to incorrect React row reuse and incorrect spam/lido mark state when navigating pages. Prefer a stable ID derived from job fields only, or ensure the index used is global (e.g., slice-start + index) rather than page-local.
function getJobId(job: Job, index: number) {
return job.link?.trim() || [job.titulo, job.empresa, job.local, String(index)].filter(Boolean).join("|");
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| app.listen(PORT, () => { | ||
| // eslint-disable-next-line no-console | ||
| console.log(`API de vagas rodando em http://localhost:${PORT}`); | ||
| console.log(`Documentação da API em http://localhost:${PORT}/docs`); | ||
| }); |
There was a problem hiding this comment.
The startup log prints the docs URL unconditionally, even when registerSwaggerDocs() fails and Swagger is disabled (catch path). This makes logs misleading. Consider returning a boolean from registerSwaggerDocs() (or setting a flag) and only logging the docs URL when the route is actually registered.
| currentPage: 1, | ||
| totalPages: 2, | ||
| pageSize: 25, | ||
| totalPages: 5, | ||
| pageSize: 4, | ||
| onPageChange: vi.fn(), | ||
| onPageSizeChange: vi.fn(), | ||
| }; |
There was a problem hiding this comment.
baseProps.onPageChange / onPageSizeChange are shared vi.fn() mocks across all tests in this file, but they aren’t reset between tests. This can produce false positives because calls from earlier tests satisfy later toHaveBeenCalledWith assertions. Create fresh props per test or reset mocks in a beforeEach (e.g., vi.clearAllMocks() or reassign new vi.fn()).
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 10 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <button | ||
| type="button" | ||
| aria-label="Pagina anterior" | ||
| onClick={() => onPageChange(Math.max(1, currentPage - 1))} | ||
| disabled={currentPage === 1} | ||
| className="flex h-9 min-w-9 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:cursor-not-allowed disabled:opacity-40" |
There was a problem hiding this comment.
Os botões de navegação usam aria-label="Pagina anterior" (sem acento). Para manter consistência com o restante do UI em pt-BR e evitar erro de ortografia em leitores de tela, ajuste para "Página anterior" (e alinhe os testes que buscam esse label).
|
|
||
| <button | ||
| type="button" | ||
| aria-label="Pagina seguinte" |
There was a problem hiding this comment.
Mesmo ponto do botão anterior: aria-label="Pagina seguinte" está sem acento. Troque para "Página seguinte" e atualize os testes correspondentes.
| aria-label="Pagina seguinte" | |
| aria-label="Página seguinte" |
| it("aciona paginacao numerica", () => { | ||
| render(<JobsTableCard {...baseProps} />); | ||
| fireEvent.click(screen.getByRole("button", { name: "Proxima" })); | ||
| expect(baseProps.onPageChange).toHaveBeenCalled(); | ||
| fireEvent.click(screen.getByRole("button", { name: "2" })); | ||
| expect(baseProps.onPageChange).toHaveBeenCalledWith(2); | ||
| }); |
There was a problem hiding this comment.
O componente JobsTableCard removeu a prop jobs, mas o teste ainda passa/propaga jobs (via baseProps e também explicitamente em outro teste). Isso pode falhar na checagem de tipos/TSX. Remova jobs do baseProps e das chamadas a <JobsTableCard ...> para manter o contrato de props atualizado.
No description provided.