Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions components/buttons/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ export default function Button({
data-testid='Button-main'
>
{icon && iconPosition === ButtonIconPosition.LEFT && (
<span className='mr-2 inline-block' data-testid='Button-icon-left'>
<span className='inline-block' data-testid='Button-icon-left'>
{icon}
</span>
)}
<span className='inline-block'>{text}</span>
{icon && iconPosition === ButtonIconPosition.RIGHT && (
<span className='ml-2 inline-block' data-testid='Button-icon-right'>
<span className='inline-block' data-testid='Button-icon-right'>
{icon}
</span>
Comment on lines +79 to 87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, find and examine the Button.tsx file
find . -name "Button.tsx" -type f

Repository: asyncapi/website

Length of output: 125


🏁 Script executed:

# Check the content around lines 79-87 to see the actual code
rg -n "inline-block" components/buttons/Button.tsx -A2 -B2 | head -40

Repository: asyncapi/website

Length of output: 859


🏁 Script executed:

# Search for Button usages with both icon and text props to assess impact
rg -n "<Button" --type=tsx --type=jsx -A3 | grep -E "icon=|text=" | head -80

Repository: asyncapi/website

Length of output: 87


🏁 Script executed:

# Specifically look for pagination button usage
rg -n "text=''" --type=tsx --type=jsx -B3 -A3 | grep -E "(Button|Pagination)" | head -40

Repository: asyncapi/website

Length of output: 87


🏁 Script executed:

# Check git log to see if mr-2/ml-2 were removed from Button.tsx
git log -p --oneline -- components/buttons/Button.tsx | grep -E "(mr-2|ml-2)" -B3 -A3 | head -40

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Search for Button component usages more broadly
rg -n "Button" components/ -A4 | grep -E "(icon=|text=)" | head -100

Repository: asyncapi/website

Length of output: 2884


🏁 Script executed:

# Look for imports of Button component to find all usages
rg -n "from.*Button" --type=ts --type=js -A5 2>/dev/null | head -60

Repository: asyncapi/website

Length of output: 4375


🏁 Script executed:

# More direct search: find Button usages in JSX without type restrictions
rg -n "<Button" components/ -A5 | head -120

Repository: asyncapi/website

Length of output: 8033


🏁 Script executed:

# Check pagination component to see how Button is used there
cat -n components/pagination/Pagination.tsx | sed -n '60,75p'

Repository: asyncapi/website

Length of output: 787


🏁 Script executed:

# Check the specific Button usages that have both text and icon
cat -n components/layout/DocsLayout.tsx | sed -n '101,107p'

Repository: asyncapi/website

Length of output: 568


🏁 Script executed:

# Check community Header that uses Button with icon
cat -n components/community/Header.tsx | sed -n '47,53p'

Repository: asyncapi/website

Length of output: 418


🏁 Script executed:

# Let's check git diff to see what actually changed in the Button component
git diff HEAD~1 -- components/buttons/Button.tsx 2>/dev/null | head -80

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Check if there are any recent changes or staging
git status -- components/buttons/Button.tsx

Repository: asyncapi/website

Length of output: 125


🏁 Script executed:

# Try to see the previous version of the file
git show HEAD:components/buttons/Button.tsx 2>/dev/null | grep -n "inline-block" -A1 -B1 | head -40

Repository: asyncapi/website

Length of output: 765


🏁 Script executed:

# Look for any mr-2 or ml-2 in the current file
rg -n "mr-2|ml-2" components/buttons/Button.tsx

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Check all Button usages that have both non-empty text AND icon
rg -n "<Button" components/ -A8 | grep -B8 "icon=" | grep -A8 "text='" | grep -v "text=''" | head -100

Repository: asyncapi/website

Length of output: 1131


🏁 Script executed:

# Let's check the git log for the Button.tsx file to see commit history
git log --oneline components/buttons/Button.tsx | head -20

Repository: asyncapi/website

Length of output: 110


🏁 Script executed:

# Look at a specific commit to see if mr-2/ml-2 was removed
git log -p components/buttons/Button.tsx | grep -E "(mr-2|ml-2)" -B5 -A5 | head -60

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Check the complete Button.tsx file to see full implementation
cat -n components/buttons/Button.tsx | head -120

Repository: asyncapi/website

Length of output: 4400


🏁 Script executed:

# Look at the parent commit to confirm Button.tsx state there
git show HEAD~1:components/buttons/Button.tsx 2>/dev/null | grep -n "inline-block" -A1 -B1 | head -40

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Search across entire codebase for mr-2 or ml-2 in button contexts
rg -n "mr-2|ml-2" components/ --type=tsx --type=jsx

Repository: asyncapi/website

Length of output: 87


🏁 Script executed:

# Check if IconRocket, IconGoogleCalendar, etc. have built-in margins
cat -n components/icons/Rocket.tsx

Repository: asyncapi/website

Length of output: 2364


🏁 Script executed:

# Let's check if there's a master branch or other branches that might have the full history
git branch -a

Repository: asyncapi/website

Length of output: 163


🏁 Script executed:

# Try to get more git history
git log --oneline --all | head -10

Repository: asyncapi/website

Length of output: 209


🏁 Script executed:

# Check if previous version had mr-2/ml-2 by looking at git blame
git blame components/buttons/Button.tsx | grep -E "inline-block"

Repository: asyncapi/website

Length of output: 827


🏁 Script executed:

# Let's verify that buttons with both icon and text actually work by checking rendered tests
find . -name "*.test.tsx" -o -name "*.spec.tsx" | xargs grep -l "Button" | head -3

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Check if there are any snapshot tests or visual tests that would show spacing
find . -name "*.snap" | xargs grep -l "Button" 2>/dev/null | head -3

Repository: asyncapi/website

Length of output: 42


🏁 Script executed:

# Check the master branch to see if it has mr-2/ml-2
git show master:components/buttons/Button.tsx 2>/dev/null | grep -n "inline-block" -A1 -B1

Repository: asyncapi/website

Length of output: 785


🏁 Script executed:

# Let's check if there's a different Button file (dashboard)
cat -n components/dashboard/Button.tsx | head -120

Repository: asyncapi/website

Length of output: 894


🏁 Script executed:

# Search for any margin classes in icon-related spans
rg -n "icon" components/buttons/ -A2 -B2 | grep -E "(className|mr|ml|gap)" | head -40

Repository: asyncapi/website

Length of output: 3215


Removing icon margins breaks every other Button with both icon and text.

Confirmed: the mr-2 / ml-2 classes were removed from the icon spans (lines 79, 85, 101, 103), eliminating spacing between icons and labels globally. This breaks multiple existing Buttons with both icon and text — including GithubButton, YoutubeButton, SlackButton, SubscribeButton, GoogleCalendarButton, ICSFileButton, and others. The pagination buttons with text='' remain unaffected since they have no visible text label.

Apply the conditional margin approach:

Proposed fix — conditionally apply margin when text is present
         {icon && iconPosition === ButtonIconPosition.LEFT && (
-          <span className='inline-block' data-testid='Button-icon-left'>
+          <span className={`inline-block${text ? ' mr-2' : ''}`} data-testid='Button-icon-left'>
             {icon}
           </span>
         )}
         <span className='inline-block'>{text}</span>
         {icon && iconPosition === ButtonIconPosition.RIGHT && (
-          <span className='inline-block' data-testid='Button-icon-right'>
+          <span className={`inline-block${text ? ' ml-2' : ''}`} data-testid='Button-icon-right'>
             {icon}
           </span>
         )}

Apply the same pattern in the <Link> branch (lines 101–103).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<span className='inline-block' data-testid='Button-icon-left'>
{icon}
</span>
)}
<span className='inline-block'>{text}</span>
{icon && iconPosition === ButtonIconPosition.RIGHT && (
<span className='ml-2 inline-block' data-testid='Button-icon-right'>
<span className='inline-block' data-testid='Button-icon-right'>
{icon}
</span>
<span className={`inline-block${text ? ' mr-2' : ''}`} data-testid='Button-icon-left'>
{icon}
</span>
)}
<span className='inline-block'>{text}</span>
{icon && iconPosition === ButtonIconPosition.RIGHT && (
<span className={`inline-block${text ? ' ml-2' : ''}`} data-testid='Button-icon-right'>
{icon}
</span>
🤖 Prompt for AI Agents
In `@components/buttons/Button.tsx` around lines 79 - 87, The icon margin classes
were removed causing icons to collide with text; update the Button component so
the icon spans (the ones with data-testid 'Button-icon-left' and
'Button-icon-right' and the equivalent in the Link branch) conditionally include
the margin class when text is not empty: add "mr-2" to the left-icon span only
when text is present, and "ml-2" to the right-icon span only when text is
present, using the existing ButtonIconPosition and text prop to decide; apply
the same conditional margin logic in both the normal button branch and the Link
branch so components like GithubButton, YoutubeButton, SlackButton,
SubscribeButton, GoogleCalendarButton and ICSFileButton regain spacing.

)}
Expand All @@ -98,9 +98,9 @@ export default function Button({
className={buttonSize === ButtonSize.SMALL ? smallButtonClasses : classNames}
data-testid='Button-link'
>
{icon && iconPosition === ButtonIconPosition.LEFT && <span className='mr-2 inline-block'>{icon}</span>}
{icon && iconPosition === ButtonIconPosition.LEFT && <span className='inline-block'>{icon}</span>}
<span className='inline-block'>{text}</span>
{icon && iconPosition === ButtonIconPosition.RIGHT && <span className='ml-2 inline-block'>{icon}</span>}
{icon && iconPosition === ButtonIconPosition.RIGHT && <span className='inline-block'>{icon}</span>}
</Link>
);
}
52 changes: 52 additions & 0 deletions components/helpers/usePagination.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useCallback, useMemo, useState } from 'react';

/**
* @description Custom hook for managing pagination logic
* @example const { currentPage, setCurrentPage, currentItems, maxPage } = usePagination(items, 10, { currentPage: 2 });
* @param {T[]} items - Array of items to paginate
* @param {number} itemsPerPage - Number of items per page
* @param {object} [options] - Pagination options
* @param {number} [options.currentPage] - Optional current page (controlled)
* @param {(page: number) => void} [options.onPageChange] - Called when setCurrentPage is invoked in controlled mode
* @returns {object}
* @returns {number} currentPage - Current page number
* @returns {function} setCurrentPage - Function to update the current page
* @returns {T[]} currentItems - Items for the current page
* @returns {number} maxPage - Total number of pages
*/
export function usePagination<T>(
items: T[],
itemsPerPage: number,
options: { currentPage?: number; onPageChange?: (page: number) => void } = {}
) {
const [internalPage, setInternalPage] = useState(1);
const { currentPage: controlledPage, onPageChange } = options;
const isControlled = typeof controlledPage === 'number' && !Number.isNaN(controlledPage);
const page = isControlled ? (controlledPage as number) : internalPage;
const maxPage = Math.ceil(items.length / itemsPerPage);
const safePage = maxPage === 0 ? 1 : Math.min(Math.max(page, 1), maxPage);
const setCurrentPage = useCallback(
(nextPage: number) => {
if (isControlled) {
onPageChange?.(nextPage);

return;
}
setInternalPage(nextPage);
},
[isControlled, onPageChange]
);

const currentItems = useMemo(() => {
const start = (safePage - 1) * itemsPerPage;

return items.slice(start, start + itemsPerPage);
}, [items, safePage, itemsPerPage]);

return {
currentPage: safePage,
setCurrentPage,
currentItems,
maxPage
};
}
20 changes: 20 additions & 0 deletions components/icons/Next.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';

/* eslint-disable max-len */
/**
* @description Icons for Next button
*/
export default function IconNext() {
return (
<svg
width='20'
height='20'
viewBox='0 0 24 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
className='stroke-current'
>
<path d='M9 6L15 12L9 18' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' />
</svg>
);
}
20 changes: 20 additions & 0 deletions components/icons/Previous.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';

/* eslint-disable max-len */
/**
* @description Icons for Previous button in pagination
*/
export default function IconPrevious() {
return (
<svg
width='20'
height='20'
viewBox='0 0 24 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
className='stroke-current'
>
<path d='M15 18L9 12L15 6' strokeWidth='2' strokeLinecap='round' strokeLinejoin='round' />
</svg>
);
}
16 changes: 13 additions & 3 deletions components/navigation/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';

import Select from '../form/Select';
import { applyFilterList, type DataObject, type Filter as FilterQuery, onFilterApply } from '../helpers/applyFilter';
Expand All @@ -10,7 +10,7 @@ interface Check {

interface FilterProps<T extends DataObject = DataObject> {
data: T[];
onFilter: (data: T[], query: FilterQuery) => void;
onFilter?: (data: T[], query: FilterQuery) => void;
checks: Check[];
className?: string;
}
Expand All @@ -32,14 +32,24 @@ export default function Filter<T extends DataObject = DataObject>({
const route = useRouter();
const [filters, setFilters] = useState<Record<string, { value: string; text: string }[]>>({});
const [routeQuery, setQuery] = useState<Record<string, string>>({});
const lastFilterKeyRef = useRef<string | null>(null);

useEffect(() => {
setQuery(route.query as Record<string, string>);
applyFilterList(checks, data, setFilters);
}, [route, checks, data]);

useEffect(() => {
onFilterApply(data, onFilter, routeQuery);
if (!onFilter) return;
const filterableQuery = Object.fromEntries(Object.entries(routeQuery).filter(([key]) => key !== 'page'));
const filterKey = Object.entries(filterableQuery)
.sort(([a], [b]) => a.localeCompare(b))
.map(([key, value]) => `${key}:${value}`)
.join('|');

if (filterKey === lastFilterKeyRef.current) return;
lastFilterKeyRef.current = filterKey;
onFilterApply(data, onFilter, filterableQuery);
}, [routeQuery, data, onFilter]);

return checks.map((check) => {
Expand Down
118 changes: 118 additions & 0 deletions components/pagination/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React from 'react';

import { ButtonIconPosition } from '@/types/components/buttons/ButtonPropsType';

import Button from '../buttons/Button';
import IconNext from '../icons/Next';
import IconPrevious from '../icons/Previous';
import PaginationItem from './PaginationItem';

export interface PaginationProps {
// eslint-disable-next-line prettier/prettier

/** Total number of pages */
totalPages: number;

/** Current active page */
currentPage: number;

/** Function to handle page changes */
onPageChange: (page: number) => void;
}

/**
* This is the Pagination component. It displays a list of page numbers that can be clicked to navigate.
*/
export default function Pagination({ totalPages, currentPage, onPageChange }: PaginationProps) {
const handlePageChange = (page: number) => {
if (page >= 1 && page <= totalPages) {
onPageChange(page);
}
};

/**
* @returns number of pages shows in Pagination.
*/
const getPageNumber = (): (number | 'start-ellipsis' | 'end-ellipsis')[] => {
if (totalPages <= 6) {
return Array.from({ length: Math.max(0, totalPages) }, (_, i) => i + 1);
}

const pages: (number | 'start-ellipsis' | 'end-ellipsis')[] = [1];

const left = Math.max(2, currentPage - 1);
const right = Math.min(totalPages - 1, currentPage + 1);

if (left > 2) pages.push('start-ellipsis');
for (let i = left; i <= right; i++) pages.push(i);
if (right < totalPages - 1) pages.push('end-ellipsis');

pages.push(totalPages);

return pages;
};

return (
<nav
role='navigation'
aria-label='Pagination'
className='font-inter flex items-center justify-center gap-2 md:gap-8'
>
{/* Previous button */}
<Button
onClick={() => handlePageChange(currentPage - 1)}
disabled={currentPage === 1}
className={`font-normal flex h-[34px] items-center justify-center rounded bg-white px-3 py-[7px] text-sm
leading-[17px]
tracking-[-0.01em] ${
currentPage === 1
? 'hover:bg-gray-white cursor-not-allowed text-gray-300'
: 'text-[#141717] hover:bg-gray-50'
}`}
Comment on lines +65 to +71
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and display Tailwind configuration files
fd 'tailwind\.config\.(js|ts|cjs|mjs)' --type f -x cat {} \;

# Search for gray-white usage in the codebase
echo "=== Searching for gray-white usage ==="
rg 'gray-white' -n

Repository: asyncapi/website

Length of output: 6052


Replace hover:bg-gray-white with a valid Tailwind color class.

The hover:bg-gray-white class is not defined in the project's Tailwind configuration. The custom gray palette includes shades 50–900, but no "gray-white" variant. Standard Tailwind also doesn't include this shade. The class will be silently ignored, leaving the hover state unstyled. Use hover:bg-white or hover:bg-gray-50 instead.

This applies to lines 69 and 109 in components/pagination/Pagination.tsx.

🤖 Prompt for AI Agents
In `@components/pagination/Pagination.tsx` around lines 65 - 71, The className
strings in the Pagination component use the invalid Tailwind class
"hover:bg-gray-white"; update both occurrences inside the component's className
conditional (where currentPage === 1) to a valid color like "hover:bg-white" or
"hover:bg-gray-50" so the hover state is applied; search for the
"hover:bg-gray-white" token in components/pagination/Pagination.tsx and replace
it in the two places (the currentPage === 1 branch around the first pagination
button and the similar branch later) with the chosen valid Tailwind class.

text=''
icon={<IconPrevious />}
iconPosition={ButtonIconPosition.LEFT}
aria-label='Go to previous page'
/>

{/* Page numbers */}
<div className='flex gap-2' role='list'>
{getPageNumber().map((page) =>
typeof page === 'number' ? (
<PaginationItem
key={page}
pageNumber={page}
isActive={page === currentPage}
onPageChange={handlePageChange}
aria-label={`Go to page ${page}`}
/>
) : (
<span
key={page}
className='font-inter flex size-8 items-center justify-center text-sm font-semibold text-[#6B6B6B] md:size-10'
aria-hidden='true'
>
...
</span>
)
)}
Comment on lines 79 to 98
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

role='list' without role='listitem' children is an ARIA violation.

The <div role='list'> wraps <button> and <span> elements directly. ARIA requires role='list' children to be role='listitem'. Screen readers may ignore or misreport the list structure.

Either wrap each child in <div role='listitem'> or remove role='list' entirely (the page numbers are already self-explanatory with their aria-labels).

Option A — add listitem wrappers
       <div className='flex gap-2' role='list'>
         {getPageNumber().map((page) =>
           typeof page === 'number' ? (
-            <PaginationItem
-              key={page}
-              ...
-            />
+            <div role='listitem' key={page}>
+              <PaginationItem
+                pageNumber={page}
+                isActive={page === currentPage}
+                onPageChange={handlePageChange}
+                aria-label={`Go to page ${page}`}
+              />
+            </div>
           ) : (
-            <span key={page} ...>
-              ...
-            </span>
+            <div role='listitem' key={page}>
+              <span
+                className='font-inter flex size-10 items-center justify-center text-sm font-semibold text-[`#6B6B6B`]'
+                aria-hidden='true'
+              >
+                ...
+              </span>
+            </div>
           )
         )}
       </div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className='flex gap-2' role='list'>
{getPageNumber().map((page) =>
typeof page === 'number' ? (
<PaginationItem
key={page}
pageNumber={page}
isActive={page === currentPage}
onPageChange={handlePageChange}
aria-label={`Go to page ${page}`}
/>
) : (
<span
key={page}
className='font-inter flex size-10 items-center justify-center text-sm font-semibold text-[#6B6B6B]'
aria-hidden='true'
>
...
</span>
)
)}
<div className='flex gap-2' role='list'>
{getPageNumber().map((page) =>
typeof page === 'number' ? (
<div role='listitem' key={page}>
<PaginationItem
pageNumber={page}
isActive={page === currentPage}
onPageChange={handlePageChange}
aria-label={`Go to page ${page}`}
/>
</div>
) : (
<div role='listitem' key={page}>
<span
className='font-inter flex size-10 items-center justify-center text-sm font-semibold text-[`#6B6B6B`]'
aria-hidden='true'
>
...
</span>
</div>
)
)}
</div>
🤖 Prompt for AI Agents
In `@components/pagination/Pagination.tsx` around lines 79 - 98, The container
uses role='list' but its children (rendered by getPageNumber() mapping:
PaginationItem and the ellipsis span) lack role='listitem'; update the mapping
so each mapped item is wrapped in an element with role='listitem' (e.g., wrap
both the PaginationItem branch and the ellipsis span branch in a wrapper with
role='listitem'), ensuring PaginationItem still receives
pageNumber/isActive/onPageChange props and aria-label remains; alternatively
remove role='list' from the container if you prefer not to add wrappers.

</div>

{/* Next button */}
<Button
onClick={() => handlePageChange(currentPage + 1)}
disabled={currentPage === totalPages}
className={`
font-normal flex h-[34px] items-center justify-center rounded bg-white px-3 py-[7px] text-sm leading-[17px]
tracking-[-0.01em] ${
currentPage === totalPages
? 'hover:bg-gray-white cursor-not-allowed text-gray-300'
: 'text-[#141717] hover:bg-gray-50'
}`}
text=''
icon={<IconNext />}
aria-label='Go to next page'
/>
</nav>
);
}
38 changes: 38 additions & 0 deletions components/pagination/PaginationItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

export interface PaginationItemProps {
// eslint-disable-next-line prettier/prettier

Comment on lines +3 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Stray eslint-disable-next-line — applies to a blank line and has no effect.

The directive on line 4 targets the next line, which is empty. Remove it.

Proposed fix
 export interface PaginationItemProps {
-  // eslint-disable-next-line prettier/prettier
-
   /** The page number to display */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface PaginationItemProps {
// eslint-disable-next-line prettier/prettier
export interface PaginationItemProps {
/** The page number to display */
🤖 Prompt for AI Agents
In `@components/pagination/PaginationItem.tsx` around lines 3 - 5, Remove the
stray eslint directive that targets a blank line inside the PaginationItemProps
declaration: delete the "// eslint-disable-next-line prettier/prettier" line so
the interface declaration is clean (inspect the PaginationItemProps interface in
PaginationItem.tsx and remove that unnecessary comment).

/** The page number to display */
pageNumber: number;

/** Whether this page is currently active */
isActive: boolean;

/** Function to handle page change */
onPageChange: (page: number) => void;
}

/**
* This is the PaginationItem component. It displays a single page number that can be clicked.
*/
export default function PaginationItem({
pageNumber,
isActive,
onPageChange,
...buttonProps
}: PaginationItemProps & React.ButtonHTMLAttributes<HTMLButtonElement>) {
return (
<button
onClick={() => onPageChange(pageNumber)}
className={`font-inter font-normal relative flex size-8 items-center
justify-center rounded-full text-xs leading-[26px] md:size-10 md:text-sm
${isActive ? 'bg-[#6200EE] text-white' : 'bg-transparent text-[#141717] hover:bg-gray-50'}
`}
aria-current={isActive ? 'page' : undefined}
{...buttonProps}
>
{pageNumber}
</button>
);
}
Loading
Loading