parent
ad2597f610
commit
314eb5d7d2
3 changed files with 138 additions and 105 deletions
@ -0,0 +1,111 @@ |
|||||||
|
import { ThumbsDown, ThumbsUp } from 'lucide-react'; |
||||||
|
import { getRelativeTimeString } from '../../lib/date'; |
||||||
|
import { VoteButton } from './VoteButton'; |
||||||
|
import { GitHubIcon } from '../ReactIcons/GitHubIcon'; |
||||||
|
import type { |
||||||
|
AllowedVoteType, |
||||||
|
ProjectStatusDocument, |
||||||
|
} from './ListProjectSolutions'; |
||||||
|
|
||||||
|
export const submittedAlternatives = [ |
||||||
|
'submitted their solution', |
||||||
|
'got it done', |
||||||
|
'submitted their take', |
||||||
|
'finished the project', |
||||||
|
'submitted their work', |
||||||
|
'completed the project', |
||||||
|
'got it done', |
||||||
|
'delivered their project', |
||||||
|
'handed in their solution', |
||||||
|
'provided their deliverables', |
||||||
|
'submitted their approach', |
||||||
|
'sent in their project', |
||||||
|
'presented their take', |
||||||
|
'shared their completed task', |
||||||
|
'submitted their approach', |
||||||
|
'completed it', |
||||||
|
'finalized their solution', |
||||||
|
'delivered their approach', |
||||||
|
'turned in their project', |
||||||
|
'submitted their final draft', |
||||||
|
'delivered their solution', |
||||||
|
]; |
||||||
|
|
||||||
|
type ProjectSolutionRowProps = { |
||||||
|
solution: ProjectStatusDocument & { |
||||||
|
user: { |
||||||
|
id: string; |
||||||
|
name: string; |
||||||
|
avatar: string; |
||||||
|
}; |
||||||
|
voteType?: AllowedVoteType | 'none'; |
||||||
|
}; |
||||||
|
counter: number; |
||||||
|
onVote: (solutionId: string, voteType: AllowedVoteType) => void; |
||||||
|
onVisitSolution: (solution: ProjectSolutionRowProps['solution']) => void; |
||||||
|
}; |
||||||
|
|
||||||
|
export function ProjectSolutionRow(props: ProjectSolutionRowProps) { |
||||||
|
const { solution, counter, onVote, onVisitSolution } = props; |
||||||
|
|
||||||
|
const avatar = solution.user.avatar || ''; |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="flex flex-col gap-2 py-2 text-sm text-gray-500"> |
||||||
|
<div className="flex flex-col justify-between gap-2 text-sm text-gray-500 sm:flex-row sm:items-center sm:gap-0"> |
||||||
|
<div className="flex items-center gap-1.5"> |
||||||
|
<img |
||||||
|
src={ |
||||||
|
avatar |
||||||
|
? `${import.meta.env.PUBLIC_AVATAR_BASE_URL}/${avatar}` |
||||||
|
: '/images/default-avatar.png' |
||||||
|
} |
||||||
|
alt={solution.user.name} |
||||||
|
className="mr-0.5 h-7 w-7 rounded-full" |
||||||
|
/> |
||||||
|
<span className="font-medium text-black">{solution.user.name}</span> |
||||||
|
<span className="hidden sm:inline"> |
||||||
|
{submittedAlternatives[counter % submittedAlternatives.length] || |
||||||
|
'submitted their solution'} |
||||||
|
</span>{' '} |
||||||
|
<span className="flex-grow text-right text-gray-400 sm:flex-grow-0 sm:text-left sm:font-medium sm:text-black"> |
||||||
|
{getRelativeTimeString(solution?.submittedAt!)} |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div className="flex items-center justify-end gap-1"> |
||||||
|
<span className="flex shrink-0 overflow-hidden rounded-full border"> |
||||||
|
<VoteButton |
||||||
|
icon={ThumbsUp} |
||||||
|
isActive={solution?.voteType === 'upvote'} |
||||||
|
count={solution.upvotes || 0} |
||||||
|
onClick={() => { |
||||||
|
onVote(solution._id!, 'upvote'); |
||||||
|
}} |
||||||
|
/> |
||||||
|
|
||||||
|
<VoteButton |
||||||
|
icon={ThumbsDown} |
||||||
|
isActive={solution?.voteType === 'downvote'} |
||||||
|
count={solution.downvotes || 0} |
||||||
|
hideCount={true} |
||||||
|
onClick={() => { |
||||||
|
onVote(solution._id!, 'downvote'); |
||||||
|
}} |
||||||
|
/> |
||||||
|
</span> |
||||||
|
|
||||||
|
<button |
||||||
|
className="ml-1 flex items-center gap-1 rounded-full border px-2 py-1 text-xs text-black transition-colors hover:border-black hover:bg-black hover:text-white" |
||||||
|
onClick={() => { |
||||||
|
onVisitSolution(solution); |
||||||
|
}} |
||||||
|
> |
||||||
|
<GitHubIcon className="h-4 w-4 text-current" /> |
||||||
|
Visit Solution |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
Loading…
Reference in new issue