Skip to content

fix(crowdfunding): add error, empty, and skeleton loading states (#521)#609

Open
prem22k wants to merge 1 commit into
boundlessfi:mainfrom
prem22k:fix/issue-521-crowdfunding
Open

fix(crowdfunding): add error, empty, and skeleton loading states (#521)#609
prem22k wants to merge 1 commit into
boundlessfi:mainfrom
prem22k:fix/issue-521-crowdfunding

Conversation

@prem22k

@prem22k prem22k commented Jun 15, 2026

Copy link
Copy Markdown

Description

This PR resolves #521 by properly implementing error handling, loading skeletons, and an empty state for the Crowdfunding dashboard (/me/crowdfunding).

Changes Made:

  • Skeleton Loading: Removed the blocking full-page <LoadingSpinner> from page.tsx that was causing the layout (header) to jump. The table now dynamically renders a robust <Skeleton> grid across all visible columns while fetching.
  • Empty State: Replaced the plain "No campaigns found." table row with the official <EmptyState> component, complete with the illustration and CTA button linking to /projects/create (as per the acceptance criteria).
  • Graceful Error Handling: Replaced the silent catch {} block. If the API fails on the initial load, it now displays a full-page Error UI with a "Try Again" button. If the API fails during pagination (and cached data exists), it displays an inline <Alert> above the table to preserve the user's current view.
  • Auth Hydration Fix: Prevented the component from infinitely spinning its skeletons when a user hits the page unauthenticated.

Screenshots

Before (Buggy State):
Screenshot_2026-06-15_23-35-29

After (New Empty State):
Screenshot_2026-06-15_23-33-45

After (Skeleton Loading State):
Screenshot_2026-06-15_23-45-24

Testing Instructions

  1. Pull the branch locally.
  2. Ensure you have the .env.local configured.
  3. Run npm run dev and navigate to /me/crowdfunding.
  4. To test the error state, load the page unauthenticated or disconnect your internet.
  5. To test the empty state, load the page while authenticated on an account with zero campaigns.

Closes #521

Summary by CodeRabbit

Release Notes

  • Bug Fixes & Improvements
    • Enhanced error handling on the crowdfunding page with inline error banners and dedicated retry screens when campaign loading fails.
    • Improved empty state display when no campaigns are available.
    • Upgraded loading indicators with skeleton placeholders for a smoother visual experience.
    • Better authentication flow messaging for unauthenticated users.

@prem22k prem22k requested a review from 0xdevcollins as a code owner June 15, 2026 18:17
Copilot AI review requested due to automatic review settings June 15, 2026 18:17
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

@prem22k is attempting to deploy a commit to the Threadflow Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

MyCrowdfundingPage adds error and hasFetched state, reworks fetchCampaigns to capture failures and set hasFetched in finally, and expands rendering into four conditional branches (inline error banner, full error+retry panel, EmptyState, or data table). CrowdfundingDataTable replaces its single loading row with five skeleton placeholder rows.

Changes

Crowdfunding Dashboard Error Handling and Empty States

Layer / File(s) Summary
State shape, fetch logic, and auth effects
app/me/crowdfunding/page.tsx
Adds error and hasFetched state, renames auth loading to authLoading, reworks fetchCampaigns to clear errors before fetching and set hasFetched in finally, sets an auth error message when unauthenticated after auth resolves, and derives isTableLoading/hasEmptyState booleans. Imports add AlertCircle and EmptyState, removing LoadingSpinner.
Conditional rendering and skeleton loading
app/me/crowdfunding/page.tsx, components/crowdfunding-data-table.tsx
Page render switches from a single path to four branches: inline destructive banner when error exists with data, full failure panel with "Try Again" button when error exists without data, EmptyState with a "Create your first campaign" CTA, and CrowdfundingDataTable with loading={isTableLoading}. Table loading row is replaced with five rows of per-column Skeleton cells.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hoppity-hop through the campaign page,
No more spinners stuck in an endless cage!
Errors now show with a banner so bright,
Skeletons shimmer while data takes flight.
Empty? No worries — a button appears,
"Create your first campaign!" — hooray, no more tears! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding error handling, empty states, and skeleton loading states to the crowdfunding dashboard.
Linked Issues check ✅ Passed The PR implementation addresses all coding objectives from issue #521: error state with retry logic, empty state with CTA component, and skeleton loading replacing full-page spinner.
Out of Scope Changes check ✅ Passed All changes in both modified files directly implement the required features from issue #521 with no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.


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 and usage tips.

@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: 1

🤖 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 `@app/me/crowdfunding/page.tsx`:
- Around line 42-44: In the catch block, replace the `err: any` type annotation
with `err: unknown`. Then use an `instanceof` check to safely narrow the type
before accessing the `message` property. Check if the caught error is an
instance of `Error` using `instanceof Error`, and only then access
`err.message`; otherwise, provide a fallback error message. This ensures type
safety while maintaining the existing error handling logic in the setError call.
🪄 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

Run ID: 32c294a8-8831-498b-8de4-02d61961b351

📥 Commits

Reviewing files that changed from the base of the PR and between fd2b990 and 43c2f24.

📒 Files selected for processing (2)
  • app/me/crowdfunding/page.tsx
  • components/crowdfunding-data-table.tsx

Comment on lines +42 to +44
} catch (err: any) {
console.error('Failed to fetch crowdfunding campaigns:', err);
setError(err.message || 'Failed to load campaigns. Please try again.');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid any type; use unknown for caught errors.

The coding guidelines prohibit use of any. Narrow the unknown type with an instanceof check to safely extract the error message.

Proposed fix
-    } catch (err: any) {
+    } catch (err: unknown) {
       console.error('Failed to fetch crowdfunding campaigns:', err);
-      setError(err.message || 'Failed to load campaigns. Please try again.');
+      setError(
+        err instanceof Error
+          ? err.message
+          : 'Failed to load campaigns. Please try again.'
+      );
📝 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
} catch (err: any) {
console.error('Failed to fetch crowdfunding campaigns:', err);
setError(err.message || 'Failed to load campaigns. Please try again.');
} catch (err: unknown) {
console.error('Failed to fetch crowdfunding campaigns:', err);
setError(
err instanceof Error
? err.message
: 'Failed to load campaigns. Please try again.'
);
🤖 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 `@app/me/crowdfunding/page.tsx` around lines 42 - 44, In the catch block,
replace the `err: any` type annotation with `err: unknown`. Then use an
`instanceof` check to safely narrow the type before accessing the `message`
property. Check if the caught error is an instance of `Error` using `instanceof
Error`, and only then access `err.message`; otherwise, provide a fallback error
message. This ensures type safety while maintaining the existing error handling
logic in the setError call.

Source: Coding guidelines

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.

Add error handling and empty states to /me/crowdfunding dashboard

2 participants