import { useState } from "react"; import { useMessageStore, type Poll } from "../stores/message.ts"; interface CreatePollModalProps { channelId: string; onClose: () => void; } export function CreatePollModal({ channelId, onClose }: CreatePollModalProps) { const [question, setQuestion] = useState(""); const [options, setOptions] = useState(["", ""]); const [error, setError] = useState(null); const createPoll = useMessageStore((s) => s.createPoll); const addOption = () => { if (options.length < 10) setOptions([...options, ""]); }; const removeOption = (idx: number) => { if (options.length > 2) setOptions(options.filter((_, i) => i !== idx)); }; const updateOption = (idx: number, value: string) => { const next = [...options]; next[idx] = value; setOptions(next); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const filled = options.filter((o) => o.trim()); if (!question.trim() || filled.length < 2) { setError("Need a question and at least 2 options"); return; } try { await createPoll(channelId, question.trim(), filled.map((o) => o.trim())); onClose(); } catch { setError("Failed to create poll"); } }; return (

Create Poll

setQuestion(e.target.value)} placeholder="Question..." maxLength={300} className="terminal-input w-full mb-3" autoFocus />
{options.map((opt, i) => (
updateOption(i, e.target.value)} placeholder={`Option ${i + 1}`} maxLength={150} className="terminal-input flex-1" /> {options.length > 2 && ( )}
))}
{options.length < 10 && ( )} {error &&
{error}
}
); } interface PollDisplayProps { poll: Poll; channelId: string; } export function PollDisplay({ poll, channelId }: PollDisplayProps) { const votePoll = useMessageStore((s) => s.votePoll); const updatePoll = useMessageStore((s) => s.updatePoll); const currentUserId = localStorage.getItem("userId") || ""; const totalVotes = poll.options.reduce((sum, o) => sum + o.votes, 0); const userVotedOption = poll.options.find((o) => o.voters.includes(currentUserId), ); const handleVote = async (optionId: string) => { try { await votePoll(poll.id, optionId); // Optimistic: update local state const updated = { ...poll, options: poll.options.map((o) => { const wasVoted = o.voters.includes(currentUserId); const isTarget = o.id === optionId; let voters = o.voters.filter((v) => v !== currentUserId); let votes = o.votes; if (wasVoted && o.id !== optionId) votes--; if (isTarget) { voters = [...voters, currentUserId]; votes = o.votes + (wasVoted ? 0 : 1); } return { ...o, votes, voters }; }), }; updatePoll(channelId, updated); } catch { // ignore } }; return (
Poll
{poll.question}
{poll.options.map((opt) => { const pct = totalVotes > 0 ? Math.round((opt.votes / totalVotes) * 100) : 0; const isSelected = opt.voters.includes(currentUserId); return ( ); })}
{totalVotes} vote{totalVotes !== 1 ? "s" : ""} {userVotedOption && ( {'('}you voted: {userVotedOption.text}{')'} )}
); }