import { useState, useEffect, useRef } from "react"; import { mapOptions } from "../constants"; import { shuffleArray } from "../utils"; import { voteService } from "../services/api"; export function useVoteLogic() { const [cards, setCards] = useState(() => shuffleArray(mapOptions)); const [selectedCard, setSelectedCard] = useState(null); const [showConfirmation, setShowConfirmation] = useState(false); const [isSubmitted, setIsSubmitted] = useState(false); const [voteTimestamp, setVoteTimestamp] = useState(null); const [loading, setLoading] = useState(true); const [pollEnded, setPollEnded] = useState(false); const dragItem = useRef(null); const dragOverItem = useRef(null); useEffect(() => { checkVoteStatus(); }, []); const checkVoteStatus = async () => { try { const data = await voteService.checkVoteStatus(); setPollEnded(data.isPollEnded); if (data.hasVoted && data.vote) { setVoteTimestamp(data.timestamp || null); setCards(data.vote); setIsSubmitted(true); } } catch (error) { console.error("Failed to check vote status:", error); } finally { setLoading(false); } }; const handleDragStart = (index: number) => { if (isSubmitted || pollEnded) return; dragItem.current = index; }; const handleDragEnter = (index: number) => { if (isSubmitted || pollEnded) return; dragOverItem.current = index; }; const handleDragEnd = () => { if (isSubmitted || pollEnded) return; const from = dragItem.current; const to = dragOverItem.current; if (from === null || to === null || from === to) return; const updatedCards = [...cards]; const [removed] = updatedCards.splice(from, 1); updatedCards.splice(to, 0, removed); setCards(updatedCards); dragItem.current = null; dragOverItem.current = null; }; const handleCardTap = (index: number) => { if (isSubmitted || pollEnded) return; if (selectedCard === null) { setSelectedCard(index); } else if (selectedCard === index) { setSelectedCard(null); } else { const updatedCards = [...cards]; const [removed] = updatedCards.splice(selectedCard, 1); updatedCards.splice(index, 0, removed); setCards(updatedCards); setSelectedCard(null); } }; const handleSubmit = () => { setShowConfirmation(true); }; const handleConfirmSubmit = async () => { try { await voteService.submitVote(cards); setIsSubmitted(true); setShowConfirmation(false); setSelectedCard(null); setVoteTimestamp(new Date().toISOString()); } catch (error) { if (error instanceof Error) { alert(`Error submitting vote: ${error.message}`); } else { alert("Failed to submit vote. Please try again."); } } }; const handleCancelSubmit = () => { setShowConfirmation(false); }; const handleTouchStart = (index: number) => { dragItem.current = index; }; const handleTouchMove = (e: React.TouchEvent) => { e.preventDefault(); const touch = e.touches[0]; const elementBelow = document.elementFromPoint( touch.clientX, touch.clientY ); const cardElement = elementBelow?.closest( "[data-card-index]" ) as HTMLElement; if (cardElement) { const index = parseInt(cardElement.dataset.cardIndex || "0"); dragOverItem.current = index; } }; const handleTouchEnd = () => { handleDragEnd(); }; return { cards, selectedCard, showConfirmation, isSubmitted, voteTimestamp, loading, pollEnded, handleDragStart, handleDragEnter, handleDragEnd, handleCardTap, handleSubmit, handleConfirmSubmit, handleCancelSubmit, handleTouchStart, handleTouchMove, handleTouchEnd, }; }