Skip to content

Commit 75b3f69

Browse files
committed
Add bounty review period frontend support
1 parent 412d3ea commit 75b3f69

File tree

9 files changed

+229
-340
lines changed

9 files changed

+229
-340
lines changed

components/Bounty/BountyMetadataLine.tsx

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { formatDeadline } from '@/utils/date';
22
import { CurrencyBadge } from '@/components/ui/CurrencyBadge';
33
import { RadiatingDot } from '@/components/ui/RadiatingDot';
44
import { ContentTypeBadge } from '@/components/ui/ContentTypeBadge';
5-
import { Check } from 'lucide-react';
5+
import { Check, Clock, XCircle } from 'lucide-react';
66
import { useCurrencyPreference } from '@/contexts/CurrencyPreferenceContext';
7-
7+
import { Tooltip } from '@/components/ui/Tooltip';
88
interface BountyMetadataLineProps {
99
amount: number;
1010
expirationDate?: string;
11-
isOpen: boolean;
11+
reviewPeriodEndDate?: string;
12+
status: 'OPEN' | 'CLOSED' | 'REVIEW_PERIOD' | 'EXPIRED' | 'CANCELLED';
1213
expiringSoon: boolean;
1314
className?: string;
1415
solutionsCount?: number;
@@ -18,19 +19,61 @@ interface BountyMetadataLineProps {
1819
export const BountyMetadataLine = ({
1920
amount,
2021
expirationDate,
21-
isOpen,
22+
reviewPeriodEndDate,
23+
status,
2224
expiringSoon,
2325
className = '',
2426
showDeadline = true,
2527
}: BountyMetadataLineProps) => {
2628
const { showUSD } = useCurrencyPreference();
2729

28-
// Format the deadline text
29-
const deadlineText = isOpen
30-
? expirationDate
31-
? formatDeadline(expirationDate)
32-
: 'No deadline'
33-
: 'Completed';
30+
const isOpen = status === 'OPEN';
31+
const isActive = status === 'OPEN' || status === 'REVIEW_PERIOD';
32+
33+
const getDeadlineText = () => {
34+
switch (status) {
35+
case 'OPEN':
36+
return expirationDate ? formatDeadline(expirationDate) : 'No deadline';
37+
case 'REVIEW_PERIOD':
38+
if (reviewPeriodEndDate) {
39+
const deadline = formatDeadline(reviewPeriodEndDate);
40+
// Transform deadline text for review period
41+
if (deadline === 'Ended') {
42+
return 'Review ended';
43+
} else if (deadline === 'Ended today') {
44+
return 'Review ended today';
45+
} else if (deadline === 'Ends today') {
46+
return 'Review ends today';
47+
} else if (deadline === 'Ends tomorrow') {
48+
return 'Review ends tomorrow';
49+
} else if (deadline.includes('days left')) {
50+
// "10 days left" → "Review ends in 10 days"
51+
const days = deadline.match(/(\d+) days left/)?.[1];
52+
return `Review ends in ${days} days`;
53+
} else if (deadline.startsWith('Ends in')) {
54+
// "Ends in 5 hours" → "Review ends in 5 hours"
55+
return deadline.replace('Ends in', 'Review ends in');
56+
} else if (deadline === 'Ends in less than an hour') {
57+
return 'Review ends in less than an hour';
58+
} else if (deadline.startsWith('Ends ')) {
59+
// "Ends Dec 15, 2024" → "Review ends Dec 15, 2024"
60+
return deadline.replace('Ends', 'Review ends');
61+
}
62+
return `Review ${deadline.toLowerCase()}`;
63+
}
64+
return 'Under Review';
65+
case 'CLOSED':
66+
return 'Completed';
67+
case 'EXPIRED':
68+
return 'Bounty Ended';
69+
case 'CANCELLED':
70+
return 'Cancelled';
71+
default:
72+
return 'Completed';
73+
}
74+
};
75+
76+
const deadlineText = getDeadlineText();
3477

3578
return (
3679
<div className={`space-y-3 ${className}`}>
@@ -49,16 +92,47 @@ export const BountyMetadataLine = ({
4992

5093
{showDeadline && (
5194
<div className="flex items-center gap-2 text-sm">
52-
{isOpen ? (
53-
<RadiatingDot size={12} dotSize={6} isRadiating={isOpen} className="flex-shrink-0" />
95+
{isActive ? (
96+
<RadiatingDot
97+
size={12}
98+
dotSize={6}
99+
isRadiating={isActive}
100+
className="flex-shrink-0"
101+
/>
102+
) : status === 'EXPIRED' ? (
103+
<XCircle size={14} className="text-gray-500 flex-shrink-0" />
54104
) : (
55105
<Check size={14} className="text-green-600 flex-shrink-0" />
56106
)}
57-
<span
58-
className={`${isOpen ? (expiringSoon ? 'text-orange-600 font-medium' : 'text-gray-700') : 'text-green-700 font-medium'}`}
59-
>
60-
{deadlineText}
61-
</span>
107+
{status === 'REVIEW_PERIOD' ? (
108+
<Tooltip
109+
content={
110+
<div className="flex items-start gap-3 text-left">
111+
<div className="bg-orange-100 p-2 rounded-md flex items-center justify-center">
112+
<Clock className="h-5 w-5 text-orange-600" />
113+
</div>
114+
<div>
115+
Bounty creators get extra time after the deadline to review submissions and
116+
award funds.
117+
</div>
118+
</div>
119+
}
120+
position="top"
121+
width="w-[360px]"
122+
>
123+
<span
124+
className={`${isActive ? (expiringSoon ? 'text-orange-600 font-medium' : 'text-gray-700') : status === 'EXPIRED' ? 'text-gray-500' : 'text-green-700 font-medium'} cursor-help underline decoration-dotted underline-offset-2`}
125+
>
126+
{deadlineText}
127+
</span>
128+
</Tooltip>
129+
) : (
130+
<span
131+
className={`${isActive ? (expiringSoon ? 'text-orange-600 font-medium' : 'text-gray-700') : status === 'EXPIRED' ? 'text-gray-500' : 'text-green-700 font-medium'}`}
132+
>
133+
{deadlineText}
134+
</span>
135+
)}
62136
</div>
63137
)}
64138
</div>

0 commit comments

Comments
 (0)