"use client" import { useEffect, useState, Suspense } from "react" import { useRouter, useSearchParams } from "next/navigation" import Link from "next/link" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Alert, AlertDescription } from "@/components/ui/alert" import { Vote, ArrowLeft, CheckCircle2, Clock, AlertCircle, User, Image as ImageIcon, Loader2, Shield, Timer, CheckCircle } from "lucide-react" import { useAuth } from "@/hooks/use-auth" import apiClient from "@/lib/api-client" import { API_CONFIG } from "@/lib/config" interface Candidate { id: string vote_event_id: string name: string image_url: string description: string created_at: string updated_at: string } interface VoteEvent { id: string title: string description: string start_date: string end_date: string is_active: boolean is_voting_open: boolean created_at: string updated_at: string candidates: Candidate[] } interface VoteStatus { has_voted: boolean } interface VoteRequest { vote_event_id: string candidate_id: string } function VotePageContent() { const { user, isAuthenticated, loading } = useAuth() const router = useRouter() const searchParams = useSearchParams() const eventId = searchParams.get('event_id') const [event, setEvent] = useState(null) const [voteStatus, setVoteStatus] = useState(null) const [selectedCandidate, setSelectedCandidate] = useState(null) const [isLoading, setIsLoading] = useState(true) const [isVoting, setIsVoting] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(null) // Fetch event details and voting status useEffect(() => { if (isAuthenticated && eventId) { fetchEventDetails() fetchVoteStatus() } }, [isAuthenticated, eventId]) const fetchEventDetails = async () => { try { setIsLoading(true) const response = await apiClient.get(`${API_CONFIG.ENDPOINTS.VOTE_EVENTS}/${eventId}`) if (response.data.success) { setEvent(response.data.data) } else { setError("Failed to fetch event details") } } catch (error: any) { console.error('Error fetching event details:', error) setError(error.response?.data?.errors || "Failed to fetch event details") } finally { setIsLoading(false) } } const fetchVoteStatus = async () => { try { const response = await apiClient.get(`${API_CONFIG.ENDPOINTS.VOTE_EVENTS}/${eventId}/vote-status`) if (response.data.success) { setVoteStatus(response.data.data) } else { setError("Failed to fetch voting status") } } catch (error: any) { console.error('Error fetching vote status:', error) setError(error.response?.data?.errors || "Failed to fetch voting status") } } const handleVote = async () => { if (!selectedCandidate || !event) return try { setIsVoting(true) setError(null) setSuccess(null) const voteData: VoteRequest = { vote_event_id: event.id, candidate_id: selectedCandidate } const response = await apiClient.post(API_CONFIG.ENDPOINTS.VOTES, voteData) if (response.data.success) { setSuccess("Your vote has been recorded successfully!") setVoteStatus({ has_voted: true }) // Refresh vote status setTimeout(() => { fetchVoteStatus() }, 1000) } else { setError(response.data.errors || "Failed to submit vote") } } catch (error: any) { console.error('Error submitting vote:', error) setError(error.response?.data?.errors || "Failed to submit vote. Please try again.") } finally { setIsVoting(false) } } const handleCandidateSelect = (candidateId: string) => { setSelectedCandidate(candidateId) setError(null) } // Show loading while checking authentication if (loading) { return (

Loading...

) } // Redirect to login if not authenticated if (!isAuthenticated) { router.push("/login") return null } // Redirect to home if no event ID if (!eventId) { router.push("/") return null } // Check if event is still active and voting is open const isEventActive = event && new Date() >= new Date(event.start_date) && new Date() <= new Date(event.end_date) const canVote = event && event.is_voting_open && isEventActive && !voteStatus?.has_voted return (
{/* Header */}

Voting Interface

{user?.name}
Authenticated
{isLoading ? (

Loading event details...

) : error ? (
{error}
) : event ? (
{/* Event Header */}
{event.is_voting_open && isEventActive ? ( Voting Open ) : !isEventActive ? ( Event Ended ) : ( Coming Soon )}
{event.title} {event.description}
Start: {new Date(event.start_date).toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' })}
End: {new Date(event.end_date).toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' })}
{/* Voting Status - Only show if user hasn't voted */} {voteStatus && !voteStatus.has_voted && (

Ready to vote

Please select your preferred candidate below

)} {/* Success Message */} {success && ( {success} )} {/* Candidates Section - Only show if user hasn't voted */} {!voteStatus?.has_voted && event.candidates && event.candidates.length > 0 ? (

Candidates

Choose your preferred candidate by clicking on their card

{event.candidates.map((candidate) => ( handleCandidateSelect(candidate.id)} >
{candidate.image_url ? ( {candidate.name} ) : ( )}
{candidate.name} {candidate.description && ( {candidate.description} )}
{selectedCandidate === candidate.id && (
Selected
)}
))}
{/* Voting Button */} {canVote && (
{!selectedCandidate && (

Please select a candidate first

)}
)} {/* Cannot Vote Messages */} {!canVote && (
{!event.is_voting_open && ( Voting is currently closed for this event )} {!isEventActive && ( This event has ended )}
)}
) : voteStatus?.has_voted ? ( /* Show message when user has already voted */

Vote Submitted Successfully!

Thank you for participating in this election. Your vote has been recorded.

) : ( /* Show when no candidates available */

No Candidates Available

There are no candidates registered for this voting event yet.

)}
) : (

Event Not Found

The voting event you're looking for could not be found.

)}
) } export default function VotePage() { return (

Loading...

}>
) }