Files
427e7578-d7bf-49c8-aee9-2dd…/frontend/src/components/OptionList.tsx
2026-04-14 18:31:48 +01:00

61 lines
2.2 KiB
TypeScript

import { PollOption } from '../types/poll.types';
import { VoteButton } from './VoteButton';
interface OptionListProps {
options: PollOption[];
onVote: (optionId: string) => void;
hasVoted?: (option: PollOption) => boolean;
}
export function OptionList({ options, onVote, hasVoted }: OptionListProps) {
const totalVotes = options.reduce((sum, opt) => sum + opt.votes, 0);
const sortedOptions = [...options].sort((a, b) => b.votes - a.votes);
return (
<div className="space-y-3">
{sortedOptions.length === 0 ? (
<div className="text-center py-8 text-white/60">
No options yet. Add one to get started!
</div>
) : (
sortedOptions.map((option) => {
const percentage = totalVotes > 0 ? (option.votes / totalVotes) * 100 : 0;
const userHasVoted = hasVoted ? hasVoted(option) : false;
return (
<div
key={option.id}
className={`bg-white/10 backdrop-blur-sm rounded-lg p-4 border transition-all duration-200 ${
userHasVoted
? 'border-green-400/50 bg-green-400/10'
: 'border-white/20 hover:border-white/30'
}`}
>
<div className="flex items-center justify-between mb-2">
<span className="text-white font-medium text-lg">
{option.text}
{userHasVoted && <span className="ml-2 text-green-400 text-sm"> Voted</span>}
</span>
<VoteButton optionId={option.id} votes={option.votes} onVote={onVote} disabled={userHasVoted} />
</div>
<div className="w-full bg-white/10 rounded-full h-2 overflow-hidden">
<div
className="bg-gradient-to-r from-green-400 to-blue-500 h-full transition-all duration-500 ease-out"
style={{ width: `${percentage}%` }}
/>
</div>
<div className="mt-2 flex justify-between text-xs text-white/60">
<span>by {option.createdBy}</span>
<span>{percentage.toFixed(1)}%</span>
</div>
</div>
);
})
)}
</div>
);
}