diff --git a/src/components/VoteForm.jsx b/src/components/VoteForm.jsx index 6cb17588..791d4174 100644 --- a/src/components/VoteForm.jsx +++ b/src/components/VoteForm.jsx @@ -1,55 +1,126 @@ import axios from "axios"; -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, use } from "react"; import { API_URL } from "../shared"; const VoteForm = ({ poll, readOnly = false }) => { const [rankings, setRankings] = useState({}); - console.log("this is rankins---->", rankings) + console.log("this is rankins---->", rankings); const [submitting, setSubmitting] = useState(false); const [orderedOptions, setOrderedOptions] = useState([]); - console.log("this is ordered options", orderedOptions) + console.log("this is ordered options", orderedOptions); const [draggedItem, setDraggedItem] = useState(null); - console.log("dragged--->", draggedItem) + console.log("dragged--->", draggedItem); const [deletedOptions, setDeletedOptions] = useState(new Set()); const [submitted, setSubmitted] = useState(false); const [error, setError] = useState(null); + const [voteId, setVoteId] = useState(null); + const [movedOptionIds, setMovedOptionIds] = useState(new Set()); + const [moveWarning, setMoveWarning] = useState(""); console.log("VoteForm rendered with poll:", poll); console.log("Poll options:", poll?.pollOptions); + const allDeleted = + orderedOptions.length > 0 && + orderedOptions.every((opt) => deletedOptions.has(opt.id)); // Check if all options are deleted + // Initialize ordered options when poll changes useEffect(() => { - if (poll?.pollOptions) { + if (poll?.pollOptions && orderedOptions.length === 0) { setOrderedOptions([...poll.pollOptions]); } }, [poll?.pollOptions]); // Update rankings whenever the order changes useEffect(() => { - let newRankings = []; - orderedOptions.forEach((option, index) => { + const newRankings = {}; + let currentRank = 1; + + orderedOptions.forEach((option) => { if (deletedOptions.has(option.id)) { - // Keep deleted options as null for algorrithm newRankings[option.id] = null; } else { - // Find the position among non-deleted options - const nonDeletedBefore = orderedOptions - .slice(0, index) - .filter((opt) => !deletedOptions.has(opt.id)).length; - - newRankings.push({ - optionId: option.id, - rank: nonDeletedBefore + 1 - }) - - // newRankings.optionId = option.id, - // newRankings.ranking = index - // newRankings.optionId = option.id + newRankings[option.id] = currentRank++; } }); + setRankings(newRankings); }, [orderedOptions, deletedOptions]); + useEffect(() => { + const fetchOrCreateVote = async () => { + if (!poll?.id || readOnly) return; + + try { + // Try to fetch vote + const res = await axios.get(`${API_URL}/api/polls/${poll.id}/vote`, { + withCredentials: true, + }); + + const voteData = res.data; + setVoteId(voteData.id); + + // Restore saved rankings if they exist + if (voteData.votingRanks) { + const restored = voteData.votingRanks.map((rank) => ({ + optionId: rank.pollOptionId, + rank: rank.rank, + })); + + const restoredMap = {}; + restored.forEach((r) => { + restoredMap[r.optionId] = r.rank; + }); + + setRankings(restoredMap); + + // Set ordered options based on restored rankings + + if (poll?.pollOptions) { + const sortedOptions = [...poll.pollOptions] + .filter( + (opt) => + restoredMap[opt.id] !== undefined && + restoredMap[opt.id] !== null + ) + .sort((a, b) => restoredMap[a.id] - restoredMap[b.id]); + + const unranked = poll.pollOptions.filter( + (opt) => restoredMap[opt.id] === undefined + ); + + setOrderedOptions([...sortedOptions, ...unranked]); + + const deleted = new Set( + poll.pollOptions + .filter((opt) => restoredMap[opt.id] === null) + .map((opt) => opt.id) + ); + setDeletedOptions(deleted); + } + } + } catch (err) { + // Vote doesn't exist, so create it + try { + const createRes = await axios.post( + `${API_URL}/api/polls/${poll.id}/vote`, + { + submitted: false, + rankings: [], + }, + { withCredentials: true } + ); + + setVoteId(createRes.data.id); + } catch (createErr) { + console.error("Failed to create vote:", createErr); + } + } + }; + + fetchOrCreateVote(); + }, [poll?.id, readOnly]); + if (!poll) { return