Skip to content
Open
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
29 changes: 25 additions & 4 deletions app/companions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import CompanionCard from "@/components/CompanionCard";
import {getSubjectColor} from "@/lib/utils";
import SearchInput from "@/components/SearchInput";
import SubjectFilter from "@/components/SubjectFilter";
import Link from "next/link";

const CompanionsLibrary = async ({ searchParams }: SearchParams) => {
const filters = await searchParams;
const subject = filters.subject ? filters.subject : '';
const topic = filters.topic ? filters.topic : '';
const subject = filters.subject ?? '';
const topic = filters.topic ?? '';
const page = parseInt(filters.page) || 1;
const limit = 9;
Comment on lines +10 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve page parameter validation and clarify limit choice.

  1. Page validation issue: parseInt(filters.page) can return NaN for invalid inputs, and negative numbers aren't handled.

  2. Limit discrepancy: The PR objectives mention displaying buttons when cards exceed 10, but the limit is set to 9.

Apply this diff to improve page validation:

-    const page = parseInt(filters.page) || 1;
+    const page = Math.max(1, parseInt(filters.page) || 1);

Please clarify if the limit should be 9 or 10 to align with the PR objectives.

📝 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
const subject = filters.subject ?? '';
const topic = filters.topic ?? '';
const page = parseInt(filters.page) || 1;
const limit = 9;
const subject = filters.subject ?? '';
const topic = filters.topic ?? '';
- const page = parseInt(filters.page) || 1;
+ const page = Math.max(1, parseInt(filters.page) || 1);
const limit = 9;
🤖 Prompt for AI Agents
In app/companions/page.tsx around lines 10 to 13, improve the page parameter
validation by explicitly checking if filters.page is a valid positive integer
and defaulting to 1 if not, instead of relying solely on parseInt which can
return NaN or allow negative values. Also, clarify and adjust the limit value to
10 if the PR objectives require showing buttons when cards exceed 10, ensuring
consistency between the limit and the UI behavior.


const companions = await getAllCompanions({ subject, topic });
const companions = await getAllCompanions({ subject, topic, page, limit });

return (
<main>
Expand All @@ -20,6 +23,7 @@ const CompanionsLibrary = async ({ searchParams }: SearchParams) => {
<SubjectFilter />
</div>
</section>

<section className="companions-grid">
{companions.map((companion) => (
<CompanionCard
Expand All @@ -29,8 +33,25 @@ const CompanionsLibrary = async ({ searchParams }: SearchParams) => {
/>
))}
</section>

<section className="flex justify-center gap-4 mb-5">
{page > 1 && (
<Link href={`?page=${page - 1}&subject=${subject}&topic=${topic}`} className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10">
← Previous
</Link>
)}
{companions.length === limit && (
<Link
href={`?page=${page + 1}&subject=${subject}&topic=${topic}`}
className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10"
>
Next →
</Link>
)}
</section>
Comment on lines +37 to +51

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Improve pagination logic and query string handling.

The pagination implementation has several areas for improvement:

  1. Inaccurate "Next" button logic: Using companions.length === limit to determine if more pages exist can show a "Next" button even on the last page if it has exactly 9 companions.

  2. Missing URL encoding: Subject and topic values should be URL encoded to handle special characters safely.

  3. Potential styling contrast issue: The hover effect changes text to orange while background becomes gray, which may not provide adequate contrast.

Consider this improved approach:

-                {companions.length === limit && (
+                {companions.length >= limit && (
                    <Link
-                        href={`?page=${page + 1}&subject=${subject}&topic=${topic}`}
+                        href={`?page=${page + 1}&subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`}
                       className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10"
                    >
                        Next →
                    </Link>
                )}

Also apply URL encoding to the Previous link:

-                   <Link href={`?page=${page - 1}&subject=${subject}&topic=${topic}`} className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10">
+                   <Link href={`?page=${page - 1}&subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`} className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10">

Consider modifying the getAllCompanions function to return additional metadata (like hasNextPage or total count) for more accurate pagination control.


🏁 Script executed:

#!/bin/bash
# Locate and inspect the `getAllCompanions` implementation to verify its return values
rg -n "getAllCompanions" -n .
rg -C3 "getAllCompanions" -n .

Length of output: 2423


🏁 Script executed:

#!/bin/bash
# Display the implementation of getAllCompanions
sed -n '21,100p' lib/actions/companion.actions.ts

# Check for select parameters (to see if count is requested)
rg -n "select" -n lib/actions/companion.actions.ts

# Check for range usage (to see how pagination is applied)
rg -n "range" -n lib/actions/companion.actions.ts

# Check for explicit count usage
rg -n "count" -n lib/actions/companion.actions.ts

Length of output: 3056


Refine pagination logic, encode query parameters, and address hover contrast

To ensure accurate “Next” detection and safe URLs, fetch one extra item (or return a total count) from getAllCompanions, wrap subject/topic in encodeURIComponent, and verify hover color contrast.

• lib/actions/companion.actions.ts
• app/companions/page.tsx

Suggested diff:

--- lib/actions/companion.actions.ts
@@ export const getAllCompanions = async ({ limit = 10, page = 1, subject, topic }: GetAllCompanions) => {
-   query = query.range((page - 1) * limit, page * limit - 1);
-   const { data: companions, error } = await query;
-   if(error) throw new Error(error.message);
-   return companions;
+   // fetch one extra to detect next page
+   query = query.range((page - 1) * limit, page * limit);
+   const { data, error } = await query;
+   if (error) throw new Error(error.message);
+   const hasNextPage = (data?.length ?? 0) > limit;
+   return {
+     companions: (data ?? []).slice(0, limit),
+     hasNextPage,
+   };
--- app/companions/page.tsx
@@
-   const companions = await getAllCompanions({ subject, topic, page, limit });
+   const { companions, hasNextPage } = await getAllCompanions({ subject, topic, page, limit });
@@
-                {companions.length === limit && (
+                {hasNextPage && (
                     <Link
-                        href={`?page=${page + 1}&subject=${subject}&topic=${topic}`}
+                        href={`?page=${page + 1}&subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`}
                         className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10"
                     >
                         Next →
                     </Link>

And update the Previous link similarly:

-<Link href={`?page=${page - 1}&subject=${subject}&topic=${topic}`} …
+<Link href={`?page=${page - 1}&subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`} …

Lastly, confirm your hover colors (background vs. text) meet WCAG contrast requirements.

📝 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
<section className="flex justify-center gap-4 mb-5">
{page > 1 && (
<Link href={`?page=${page - 1}&subject=${subject}&topic=${topic}`} className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10">
Previous
</Link>
)}
{companions.length === limit && (
<Link
href={`?page=${page + 1}&subject=${subject}&topic=${topic}`}
className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10"
>
Next
</Link>
)}
</section>
<section className="flex justify-center gap-4 mb-5">
{page > 1 && (
<Link
href={`?page=${page - 1}&subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`}
className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10"
>
Previous
</Link>
)}
{hasNextPage && (
<Link
href={`?page=${page + 1}&subject=${encodeURIComponent(subject)}&topic=${encodeURIComponent(topic)}`}
className="px-4 py-2 rounded-xl bg-[#fe5933] border border-gray-300 shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-orange-300 transition-all duration-200 relative z-10"
>
Next
</Link>
)}
</section>
🤖 Prompt for AI Agents
In app/companions/page.tsx around lines 37 to 51, improve pagination by
modifying getAllCompanions to return an extra item or total count to accurately
determine if a next page exists instead of relying on companions.length ===
limit. Also, wrap subject and topic query parameters in encodeURIComponent in
both Previous and Next Link hrefs to ensure safe URL encoding. Finally, adjust
the hover text and background colors to ensure sufficient contrast for
accessibility compliance.

</main>
)
);
}


export default CompanionsLibrary