Skip to content
Merged
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
20 changes: 20 additions & 0 deletions components/bounties/statusClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,23 @@ const STATUS_CLASS: Record<string, string> = {
export function bountyStatusClass(status: string): string {
return STATUS_CLASS[status] ?? 'border-zinc-700 bg-zinc-800/60 text-zinc-300';
}

/**
* Badge styling for the submission review status (pending/accepted/rejected/
* disputed). Kept next to bountyStatusClass so the two vocabularies stay
* deliberately aligned; disputed is amber here (not the bounty-level red) so
* a disputed submission reads differently from a rejected one in the list.
*/
const SUBMISSION_STATUS_CLASS: Record<string, string> = {
pending: 'border-blue-500/30 bg-blue-500/10 text-blue-400',
accepted: 'border-emerald-500/30 bg-emerald-500/10 text-emerald-400',
rejected: 'border-red-500/30 bg-red-500/10 text-red-400',
disputed: 'border-amber-500/30 bg-amber-500/10 text-amber-400',
};

export function submissionStatusClass(status: string): string {
return (
SUBMISSION_STATUS_CLASS[status] ??
'border-zinc-700 bg-zinc-800/60 text-zinc-300'
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { useState } from 'react';
import { useParams } from 'next/navigation';
import Link from 'next/link';
import { ArrowLeft, Info, Loader2, Lock } from 'lucide-react';
Expand All @@ -23,12 +24,27 @@ import {
type BountyOperateOverview,
} from '@/features/bounties';
import { ordinal } from '@/lib/utils';
import BountySubmissionsPanel from './BountySubmissionsPanel';

export default function BountyManagementDashboard() {
const params = useParams<{ id: string; bountyId: string }>();
const organizationId = params?.id ?? '';
const bountyId = params?.bountyId ?? '';

// Winner staging lives here (above the tab boundary) so it survives tab
// switches and is reachable by the Payout tab (#633).
const [stagedWinners, setStagedWinners] = useState<Set<string>>(new Set());
const toggleStagedWinner = (id: string) =>
setStagedWinners(prev => {
const next = new Set(prev);
if (next.has(id)) {
next.delete(id);
} else {
next.add(id);
}
return next;
});

const {
data: overview,
isLoading,
Expand Down Expand Up @@ -144,7 +160,15 @@ export default function BountyManagementDashboard() {
</TabsContent>
)}
<TabsContent value='submissions'>
<TabPlaceholder title='Submissions review' issue='#632' />
<BountySubmissionsPanel
organizationId={organizationId}
bountyId={bountyId}
submissionVisibility={overview.submissionVisibility}
submissionDeadline={overview.submissionDeadline ?? null}
rewardCurrency={overview.rewardCurrency}
staged={stagedWinners}
onToggleStage={toggleStagedWinner}
/>
</TabsContent>
<TabsContent value='payout'>
<TabPlaceholder title='Winner selection & payout' issue='#633' />
Expand Down
Loading
Loading