Skip to content

Bounty: Operate → Decide → Payout → Wrap → Disputes UI#639

Closed
darrenyoungblood12345-a11y wants to merge 2 commits into
boundlessfi:mainfrom
darrenyoungblood12345-a11y:feat/fix-issue
Closed

Bounty: Operate → Decide → Payout → Wrap → Disputes UI#639
darrenyoungblood12345-a11y wants to merge 2 commits into
boundlessfi:mainfrom
darrenyoungblood12345-a11y:feat/fix-issue

Conversation

@darrenyoungblood12345-a11y

@darrenyoungblood12345-a11y darrenyoungblood12345-a11y commented Jun 24, 2026

Copy link
Copy Markdown

Fixes #638. Implements bounty management UI covering the full lifecycle.

Summary by CodeRabbit

  • New Features

    • Added bounty detail pages for overview, applications, submissions, settings, disputes, payout, cancel, and wrap-up actions.
    • Added a bounty sidebar for quick navigation across all bounty sections.
    • Added search, filtering, status counts, and action controls across bounty management screens.
    • Added support for viewing winners, disputes, escrow status, and payout history.
  • Bug Fixes

    • Improved loading, empty, and error states for bounty-related screens.
    • Added success/error feedback for status updates, cancellations, dispute resolutions, payouts, and archiving.

… Disputes)

Implements the organizer completion UI for bounties (boundlessfi#638):

- lib/api/bounties.ts — typed API stubs for all bounty lifecycle endpoints
  (getBounty, applications CRUD, submissions, select-winners, cancel,
  disputes, escrow, archive)
- hooks/use-bounty.ts — data hooks (useBounty, useBountyApplications,
  useBountySubmissions, useBountyPayout)
- components/organization/bounties/details/BountySidebar.tsx — per-bounty
  nav sidebar mirroring HackathonSidebar (desktop + mobile sheet)
- app/…/bounties/[bountyId]/page.tsx — overview: stats + lifecycle timeline
- app/…/bounties/[bountyId]/applications/page.tsx — Applications (Decide):
  review, shortlist, select, decline with tab-filtered counts
- app/…/bounties/[bountyId]/submissions/page.tsx — Submissions: list with
  repo/demo links and rank badge
- app/…/bounties/[bountyId]/payout/page.tsx — Payout: rank assignment grid +
  select-winners on-chain flow with confirmation dialog
- app/…/bounties/[bountyId]/cancel/page.tsx — Cancel/Refund: guarded cancel
  with irreversibility warning
- app/…/bounties/[bountyId]/wrap/page.tsx — Wrap: winners podium + share link +
  archive action
- app/…/bounties/[bountyId]/disputes/page.tsx — Disputes: list with resolution
  dialog
- app/…/bounties/[bountyId]/settings/page.tsx — Settings: read-only config view
- app/…/organizations/layout.tsx — wire BountySidebar for /bounties/* paths

Closes boundlessfi#630 boundlessfi#631 boundlessfi#632 boundlessfi#633 boundlessfi#634 boundlessfi#635 boundlessfi#636 boundlessfi#637

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@darrenyoungblood12345-a11y, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 57 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 93324bd7-ae8b-49df-9d34-b8ff0bfce2bc

📥 Commits

Reviewing files that changed from the base of the PR and between 2dfd605 and 80382e9.

📒 Files selected for processing (5)
  • app/(landing)/organizations/[id]/bounties/[bountyId]/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/payout/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/submissions/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx
  • hooks/use-bounty.ts
📝 Walkthrough

Walkthrough

Adds shared bounty API/types and reusable fetch hooks, then wires a bounty sidebar into the organizations layout. New bounty pages cover overview, settings, submissions, applications, payout, wrap, disputes, and cancel flows with loading, error, and mutation states.

Changes

Bounty management and completion

Layer / File(s) Summary
Bounty API contracts and endpoints
lib/api/bounties.ts
Adds bounty status/entity types and REST wrappers for bounty details, lists, applications, submissions, winners, disputes, escrow, and bounty actions.
Shared bounty data hooks
hooks/use-bounty.ts
Adds hooks for loading a bounty, applications, submissions, and payout data with local loading/error state and refetch support.
Bounty sidebar and organizations layout
components/organization/bounties/details/BountySidebar.tsx, app/(landing)/organizations/layout.tsx
Adds a bounty sidebar and switches organization layout rendering so bounty routes use it instead of the default organization sidebar.
Overview, settings, and submissions pages
app/(landing)/organizations/[id]/bounties/[bountyId]/page.tsx, app/(landing)/organizations/[id]/bounties/[bountyId]/settings/page.tsx, app/(landing)/organizations/[id]/bounties/[bountyId]/submissions/page.tsx
Adds authenticated bounty overview, settings, and submissions pages that render fetched bounty data, counts, search, and detail cards.
Applications, payout, and cancel flows
app/(landing)/organizations/[id]/bounties/[bountyId]/applications/page.tsx, app/(landing)/organizations/[id]/bounties/[bountyId]/payout/page.tsx, app/(landing)/organizations/[id]/bounties/[bountyId]/cancel/page.tsx
Adds application status updates, winner selection and payout confirmation, and bounty cancellation with toasts, dialogs, and local state updates.
Wrap and disputes pages
app/(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx, app/(landing)/organizations/[id]/bounties/[bountyId]/disputes/page.tsx
Adds the wrap page for results/archive actions and the disputes page for listing disputes and submitting resolutions.

Sequence Diagram(s)

Shared bounty load

sequenceDiagram
  participant Organizer
  participant BountyOverviewPage
  participant useBounty
  participant getBounty
  participant api
  Organizer->>BountyOverviewPage: open a bounty route
  BountyOverviewPage->>useBounty: request bounty data
  useBounty->>getBounty: fetch organizationId and bountyId
  getBounty->>api: GET bounty details
  api-->>getBounty: ApiResponse<Bounty>
  getBounty-->>useBounty: bounty
  useBounty-->>BountyOverviewPage: loading false
Loading

Application status update

sequenceDiagram
  participant Organizer
  participant ApplicationsPage
  participant updateApplicationStatus
  participant api
  Organizer->>ApplicationsPage: choose SHORTLISTED, SELECTED, or DECLINED
  ApplicationsPage->>updateApplicationStatus: submit status change
  updateApplicationStatus->>api: PATCH application status
  api-->>updateApplicationStatus: updated application
  updateApplicationStatus-->>ApplicationsPage: updated data
  ApplicationsPage->>ApplicationsPage: update local state and toast
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • 623: Updates the bounty detail path and shared bounty hooks used by the detail experience.
  • 630: Adds the bounty management dashboard shell and the related bounty tabs/pages.

Suggested reviewers

  • 0xdevcollins

Poem

A bunny hopped through tabs so bright,
with winners, wraps, and disputes in sight.
One carrot toast for hooks that sing,
one twitching nose for every link.
🐰 Hop, hop—bounty pages gleam tonight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% 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 clearly summarizes the bounty lifecycle UI additions and matches the main scope.
Linked Issues check ✅ Passed The PR adds the bounty overview, decide, payout, wrap, disputes, nav, and supporting hooks/API needed for #638.
Out of Scope Changes check ✅ Passed All changed pages, sidebar, hooks, and API wrappers align with the bounty lifecycle management scope.

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

✨ 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: 5

♻️ Duplicate comments (1)
app/(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx (1)

195-204: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Same wrong-explorer issue as the payout page.

The winner txHash is linked to etherscan.io, but settlement happens on Stellar/Soroban via the escrow runner, so the link won't resolve. Fix alongside the payout page (preferably via a shared explorer-URL helper).

🤖 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/`(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx around
lines 195 - 204, The winner transaction link in the wrap page is pointing to the
wrong explorer, since settlement is on Stellar/Soroban rather than Ethereum.
Update the link generation in the txHash rendering block to use the correct
explorer URL for the network, and align this with the payout page by extracting
or reusing a shared explorer-URL helper so both places resolve the same way.
🤖 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/`(landing)/organizations/[id]/bounties/[bountyId]/page.tsx:
- Around line 72-101: AuthGuard is wrapping too late in the bounty page, so the
loading and error branches can render before auth protection runs. Move the
entire return flow in the bounty page component so AuthGuard wraps the loading,
error, and success states just like the sibling settings/page.tsx and
submissions/page.tsx patterns, using the AuthGuard and Loading symbols to locate
the component body.

In `@app/`(landing)/organizations/[id]/bounties/[bountyId]/payout/page.tsx:
- Around line 251-260: The transaction link in the payout row is hardcoded to
Ethereum and won’t work for Stellar/Soroban tx hashes. Update the link rendering
in the payout page’s transaction anchor to use getTransactionExplorerUrl(...)
from lib/wallet-utils.ts, passing w.txHash so the correct network-specific
explorer URL is generated. Keep the existing conditional rendering and anchor
styling, but replace the etherscan.io href with the shared helper.

In `@app/`(landing)/organizations/[id]/bounties/[bountyId]/submissions/page.tsx:
- Around line 32-36: Update the rank rendering logic in the submissions page so
it checks for `submission.rank !== null` instead of relying on a truthy guard,
because `submission.rank && (...)` will treat `0` as falsy and can render the
literal `0` or exclude rank-0 items from the ranked count. Apply the same
explicit null check wherever the rank badge and the “With Rank Assigned” count
are derived, using the existing `submission.rank` and the associated count logic
in the submissions page.

In `@app/`(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx:
- Around line 62-78: The archive flow in handleArchive updates the server but
never refreshes the bounty data, so the UI keeps using stale state and does not
show completion. Update the useBounty hook usage in wrap/page.tsx to expose a
refetch or otherwise invalidate the bounty query, then call that refresh right
after archiveBounty succeeds before closing the dialog; this will let
isCompleted and the completion banner update and hide the Archive button.

In `@hooks/use-bounty.ts`:
- Around line 143-175: The `useBountyPayout` fetch logic is swallowing failures
because `Promise.allSettled` won’t trigger the `catch` in `fetch`, so no
user-facing error is set when both `getBountyWinners` and `getBountyEscrow`
fail. Update `fetch` in `use-bounty.ts` to inspect the settled results from both
calls, and when neither returns a successful `data` payload, call `setError`
with a fallback message and `reportError` using the existing `useBountyPayout`
context. Keep the current success paths for `setWinners` and `setEscrow`, but
ensure the hook surfaces an error instead of silently completing when both
requests fail.

---

Duplicate comments:
In `@app/`(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx:
- Around line 195-204: The winner transaction link in the wrap page is pointing
to the wrong explorer, since settlement is on Stellar/Soroban rather than
Ethereum. Update the link generation in the txHash rendering block to use the
correct explorer URL for the network, and align this with the payout page by
extracting or reusing a shared explorer-URL helper so both places resolve the
same way.
🪄 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: c7496f1a-240d-4037-a019-039f1e5c1de3

📥 Commits

Reviewing files that changed from the base of the PR and between fd2b990 and 2dfd605.

📒 Files selected for processing (12)
  • app/(landing)/organizations/[id]/bounties/[bountyId]/applications/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/cancel/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/disputes/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/payout/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/settings/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/submissions/page.tsx
  • app/(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx
  • app/(landing)/organizations/layout.tsx
  • components/organization/bounties/details/BountySidebar.tsx
  • hooks/use-bounty.ts
  • lib/api/bounties.ts

Comment thread app/(landing)/organizations/[id]/bounties/[bountyId]/page.tsx Outdated
Comment thread app/(landing)/organizations/[id]/bounties/[bountyId]/submissions/page.tsx Outdated
Comment on lines +62 to +78
const handleArchive = async () => {
setArchiving(true);
try {
const res = await archiveBounty(organizationId, bountyId);
if (res.success) {
toast.success('Bounty archived successfully');
} else {
toast.error(res.message || 'Failed to archive bounty');
}
} catch (err) {
reportError(err, { context: 'wrap-archive', bountyId });
toast.error('Failed to archive bounty');
} finally {
setArchiving(false);
setArchiveOpen(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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Refresh bounty state after archiving so the UI reflects completion.

On success, bounty is never refetched, so isCompleted stays false: the completion banner won't appear and the Archive button remains visible/clickable even after a successful archive. useBountyPayout exposes a refetch, but useBounty here does not; pull a refetch from useBounty (or re-route/invalidate) and call it after a successful archive.

🤖 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/`(landing)/organizations/[id]/bounties/[bountyId]/wrap/page.tsx around
lines 62 - 78, The archive flow in handleArchive updates the server but never
refreshes the bounty data, so the UI keeps using stale state and does not show
completion. Update the useBounty hook usage in wrap/page.tsx to expose a refetch
or otherwise invalidate the bounty query, then call that refresh right after
archiveBounty succeeds before closing the dialog; this will let isCompleted and
the completion banner update and hide the Archive button.

Comment thread hooks/use-bounty.ts
- Move AuthGuard to wrap loading/error states (page.tsx)
- Replace etherscan.io with getTransactionExplorerUrl (payout, wrap)
- Fix rank 0 rendering via explicit null check (submissions)
- Surface errors when both allSettled calls fail (use-bounty)
SKYJAMES777 added a commit to SKYJAMES777/boundless that referenced this pull request Jun 25, 2026
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.

Epic: Bounty completion (Operate -> Decide -> Payout -> Wrap -> Disputes)

2 participants