Skip to content

feat(projects): add ProjectsResults grid component with loading, empt… - #361

Open
TheFaith-Code wants to merge 1 commit into
boundlessfi:mainfrom
TheFaith-Code:feat/350-projects-grid-results
Open

feat(projects): add ProjectsResults grid component with loading, empt…#361
TheFaith-Code wants to merge 1 commit into
boundlessfi:mainfrom
TheFaith-Code:feat/350-projects-grid-results

Conversation

@TheFaith-Code

@TheFaith-Code TheFaith-Code commented Jul 29, 2026

Copy link
Copy Markdown
  • Create ProjectsResults in components/discover/projects-results.tsx
  • Map project data to OpportunityCardView using shared toProjectCard mapper
  • Render responsive grid (1 / 2 / 3 columns) of OpportunityCards
  • Handle loading skeleton state with OpportunityCardSkeleton
  • Handle empty and error states with centered muted messages
  • Integrate pagination component showing page controls and item range summary
  • Update ProjectsGrid and ProjectsView to leverage ProjectsResults

closes #350

Summary by CodeRabbit

  • New Features
    • Added a responsive project results grid with project and opportunity cards.
    • Added pagination controls for result sets with multiple pages.
    • Improved empty-state messaging for both broad searches and narrowed results.
  • Bug Fixes
    • Improved handling and display of loading and error states when project results are unavailable.
  • Refactor
    • Consolidated project results rendering to provide more consistent behavior across the projects view.

…y, error, and pagination states (boundlessfi#350)

- Create ProjectsResults in components/discover/projects-results.tsx
- Map project data to OpportunityCardView using shared toProjectCard mapper
- Render responsive grid (1 / 2 / 3 columns) of OpportunityCards
- Handle loading skeleton state with OpportunityCardSkeleton
- Handle empty and error states with centered muted messages
- Integrate pagination component showing page controls and item range summary
- Update ProjectsGrid and ProjectsView to leverage ProjectsResults
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

@TheFaith-Code is attempting to deploy a commit to the Threadflow Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@TheFaith-Code Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d82e002-ed8e-49a6-859a-5b81a9374aae

📥 Commits

Reviewing files that changed from the base of the PR and between 3e28446 and 0257a1a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • components/discover/projects-grid.tsx
  • components/discover/projects-results.tsx
  • components/discover/projects-view.tsx
 _____________________________________________
< Preventing Skynet from becoming self-aware. >
 ---------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/discover/projects-results.tsx`:
- Around line 53-57: Prevent projects-results from invoking useProjects when
external state is supplied, since ProjectsView owns that fetch. Update the query
setup around useProjects and the externalData/externalIsPending/externalIsError
selection so externally managed mode uses only the provided state, while
standalone mode continues fetching with params and preserves the existing result
behavior.
- Around line 49-60: The destructuring default in ProjectsResults must not force
externalPageSize to 12, because it prevents the pageSize calculation from using
params.limit. Remove that default while preserving the fallback to 12 in the
existing pageSize assignment, so direct-fetch calls honor params.limit when no
external page size is provided.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d82e002-ed8e-49a6-859a-5b81a9374aae

📥 Commits

Reviewing files that changed from the base of the PR and between 3e28446 and 0257a1a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • components/discover/projects-grid.tsx
  • components/discover/projects-results.tsx
  • components/discover/projects-view.tsx

Comment on lines +49 to +60
pageSize: externalPageSize = 12,
onPageChange,
className,
}: ProjectsResultsProps) {
// If params is provided and no external data is supplied, fetch using useProjects
const query = useProjects(params ?? {});
const data = externalData ?? (params ? query.data : undefined);
const isPending = externalIsPending ?? (params ? query.isPending : false);
const isError = externalIsError ?? (params ? query.isError : false);

const page = externalPage ?? params?.page ?? 1;
const pageSize = externalPageSize ?? params?.limit ?? 12;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Honor params.limit when pageSize is omitted.

The destructuring default makes externalPageSize always 12, so params?.limit is never used. A direct-fetch caller with { page: 2, limit: 24 } gets incorrect card offsets and pagination ranges.

Proposed fix
-  pageSize: externalPageSize = 12,
+  pageSize: externalPageSize,
@@
-  const pageSize = externalPageSize ?? params?.limit ?? 12;
+  const pageSize = externalPageSize ?? params?.limit ?? 12;
📝 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
pageSize: externalPageSize = 12,
onPageChange,
className,
}: ProjectsResultsProps) {
// If params is provided and no external data is supplied, fetch using useProjects
const query = useProjects(params ?? {});
const data = externalData ?? (params ? query.data : undefined);
const isPending = externalIsPending ?? (params ? query.isPending : false);
const isError = externalIsError ?? (params ? query.isError : false);
const page = externalPage ?? params?.page ?? 1;
const pageSize = externalPageSize ?? params?.limit ?? 12;
pageSize: externalPageSize,
onPageChange,
className,
}: ProjectsResultsProps) {
// If params is provided and no external data is supplied, fetch using useProjects
const query = useProjects(params ?? {});
const data = externalData ?? (params ? query.data : undefined);
const isPending = externalIsPending ?? (params ? query.isPending : false);
const isError = externalIsError ?? (params ? query.isError : false);
const page = externalPage ?? params?.page ?? 1;
const pageSize = externalPageSize ?? params?.limit ?? 12;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/discover/projects-results.tsx` around lines 49 - 60, The
destructuring default in ProjectsResults must not force externalPageSize to 12,
because it prevents the pageSize calculation from using params.limit. Remove
that default while preserving the fallback to 12 in the existing pageSize
assignment, so direct-fetch calls honor params.limit when no external page size
is provided.

Comment on lines +53 to +57
// If params is provided and no external data is supplied, fetch using useProjects
const query = useProjects(params ?? {});
const data = externalData ?? (params ? query.data : undefined);
const isPending = externalIsPending ?? (params ? query.isPending : false);
const isError = externalIsError ?? (params ? query.isError : false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Do not fetch in externally managed mode.

useProjects(params ?? {}) always runs. ProjectsView already fetches at components/discover/projects-view.tsx Line 72 and passes that state here, so this component issues a second, differently keyed unfiltered /projects request whose result is discarded. Split the fetch-owning and presentational components, or add an explicit disabled-query path for external state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/discover/projects-results.tsx` around lines 53 - 57, Prevent
projects-results from invoking useProjects when external state is supplied,
since ProjectsView owns that fetch. Update the query setup around useProjects
and the externalData/externalIsPending/externalIsError selection so externally
managed mode uses only the provided state, while standalone mode continues
fetching with params and preserves the existing result behavior.

@Benjtalkshow Benjtalkshow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, and sorry for the mix-up. The results grid already landed in #358 (components/discover/projects-grid.tsx), so this one duplicates it. I do not want to close your PR, so let us reshape it:

  1. Remove pnpm-lock.yaml and run npm install (this repo uses npm).
  2. Revert projects-results.tsx, projects-grid.tsx, and projects-view.tsx to main (the grid already exists there).
  3. Add one small win to the existing projects-grid.tsx: hide the pagination when pagination.total is 0.

That keeps it small and mergeable. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[projects-page][Grid] Results grid + pagination + states

2 participants