diff --git a/frontend/__tests__/unit/components/Pagination.test.tsx b/frontend/__tests__/unit/components/Pagination.test.tsx
new file mode 100644
index 0000000000..8b80ce1eaf
--- /dev/null
+++ b/frontend/__tests__/unit/components/Pagination.test.tsx
@@ -0,0 +1,136 @@
+import { within, render, fireEvent, screen, cleanup } from '@testing-library/react'
+import '@testing-library/jest-dom'
+import Pagination from 'components/Pagination'
+
+afterEach(cleanup)
+
+describe('', () => {
+ const onPageChange = jest.fn()
+
+ const renderComponent = (
+ overrides: {
+ currentPage?: number
+ totalPages?: number
+ isLoaded?: boolean
+ } = {}
+ ) => {
+ const props = {
+ currentPage: overrides.currentPage ?? 1,
+ totalPages: overrides.totalPages ?? 5,
+ isLoaded: overrides.isLoaded ?? true,
+ onPageChange,
+ }
+ return render()
+ }
+
+ beforeEach(() => {
+ onPageChange.mockClear()
+ })
+
+ it('does not render when isLoaded is false', () => {
+ const { container } = renderComponent({ isLoaded: false })
+ expect(container.firstChild).toBeNull()
+ })
+
+ it('does not render when totalPages ≤ 1', () => {
+ const { container } = renderComponent({ totalPages: 1 })
+ expect(container.firstChild).toBeNull()
+ })
+
+ it('renders Prev and Next buttons and page numbers for small totalPages', () => {
+ renderComponent({ currentPage: 2, totalPages: 4 })
+
+ // Prev / Next
+ const prev = screen.getByRole('button', { name: 'Prev' })
+ const next = screen.getByRole('button', { name: 'Next' })
+
+ expect(prev).toBeEnabled()
+ expect(next).toBeEnabled()
+
+ // Pages 1–4
+ for (let n = 1; n <= 4; n++) {
+ expect(screen.getByRole('button', { name: String(n) })).toBeInTheDocument()
+ }
+ })
+
+ it('disables Prev on first page', () => {
+ const { container } = renderComponent({ currentPage: 1, totalPages: 3 })
+ const prevBtn = within(container).getByRole('button', { name: 'Prev' })
+ expect(prevBtn).toBeDisabled()
+ })
+
+ it('disables Next on last page', () => {
+ const { container } = renderComponent({ currentPage: 3, totalPages: 3 })
+ const nextBtn = within(container).getByRole('button', { name: 'Next' })
+ expect(nextBtn).toBeDisabled()
+ })
+
+ it('calls onPageChange with correct page number on button clicks', () => {
+ renderComponent({ currentPage: 2, totalPages: 5 })
+
+ fireEvent.click(screen.getByRole('button', { name: 'Prev' }))
+ expect(onPageChange).toHaveBeenCalledWith(1)
+
+ fireEvent.click(screen.getByRole('button', { name: 'Next' }))
+ expect(onPageChange).toHaveBeenCalledWith(3)
+
+ fireEvent.click(screen.getByRole('button', { name: '4' }))
+ expect(onPageChange).toHaveBeenCalledWith(4)
+ })
+
+ it('renders ellipses and correct pages for large totalPages', () => {
+ renderComponent({ currentPage: 10, totalPages: 20 })
+
+ // Should show first 3 pages
+ ;[1, 2, 3].forEach((n) => {
+ expect(screen.getByRole('button', { name: String(n) })).toBeInTheDocument()
+ })
+
+ // Should show exactly two “More pages” indicators
+ const ellipses = screen.getAllByLabelText('More pages')
+ expect(ellipses).toHaveLength(2)
+
+ // Should show pages around currentPage: 9, 10, 11
+ ;[9, 10, 11].forEach((n) =>
+ expect(screen.getByRole('button', { name: String(n) })).toBeInTheDocument()
+ )
+
+ // Last page
+ expect(screen.getByRole('button', { name: '20' })).toBeInTheDocument()
+ })
+
+ it('applies active styles and aria-current on the selected page', () => {
+ renderComponent({ currentPage: 3, totalPages: 5 })
+
+ const activeBtn = screen.getByRole('button', { name: '3' })
+ // check for class used in active state
+ expect(activeBtn).toHaveClass('bg-[#83a6cc]')
+ // accessibility: mark current page
+ expect(activeBtn).toHaveAttribute('aria-current', 'page')
+ })
+
+ it('uses default values when props are missing', () => {
+ // No overrides → currentPage=1, totalPages=5, isLoaded=true
+ renderComponent()
+
+ expect(screen.getByRole('button', { name: 'Prev' })).toBeDisabled()
+ expect(screen.getByRole('button', { name: 'Next' })).toBeEnabled()
+ expect(screen.getByRole('button', { name: '5' })).toBeInTheDocument()
+ })
+
+ // Edge-case: currentPage near the start of a large set
+ it('shows correct pages when currentPage = 4 of 10', () => {
+ renderComponent({ currentPage: 4, totalPages: 10 })
+ // Should show 1,2,3,4,5 then ellipsis and 10
+ ;[1, 2, 3, 4, 5].forEach((n) =>
+ expect(screen.getByRole('button', { name: String(n) })).toBeInTheDocument()
+ )
+ expect(screen.getByRole('button', { name: '10' })).toBeInTheDocument()
+ })
+
+ // Edge-case: very small totalPages (2)
+ it('renders exactly pages [1, 2] when totalPages = 2', () => {
+ renderComponent({ totalPages: 2, currentPage: 2 })
+ expect(screen.getAllByRole('button', { name: /^(1|2)$/ })).toHaveLength(2)
+ })
+})
diff --git a/frontend/src/components/Pagination.tsx b/frontend/src/components/Pagination.tsx
index 28050276d4..cbf6695f37 100644
--- a/frontend/src/components/Pagination.tsx
+++ b/frontend/src/components/Pagination.tsx
@@ -61,6 +61,7 @@ const Pagination: React.FC = ({