"use client" import { useEffect, useState } from "react" import { useRouter } 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 { Vote, Users, Settings, BarChart3, LogOut, Clock, Calendar, Play, StopCircle, Timer, CheckCircle2, AlertCircle, Sparkles } from "lucide-react" import { useAuth } from "@/hooks/use-auth" import apiClient from "@/lib/api-client" import { API_CONFIG } from "@/lib/config" import { DashboardHeader } from "@/components/dashboard-header" interface VoteEvent { id: string title: string description: string start_date: string end_date: string is_active: boolean is_voting_open: boolean status?: string } interface Countdown { days: number hours: number minutes: number seconds: number isActive: boolean isEnded: boolean isUpcoming: boolean } export default function HomePage() { const { user, isAuthenticated, isAdmin, isSuperAdmin, logout, loading } = useAuth() const [voteEvents, setVoteEvents] = useState([]) const [eventsLoading, setEventsLoading] = useState(true) const [countdowns, setCountdowns] = useState>({}) const router = useRouter() // Fetch vote events useEffect(() => { if (isAuthenticated) { fetchVoteEvents() } }, [isAuthenticated]) // Update countdowns every second useEffect(() => { if (voteEvents.length > 0) { const interval = setInterval(() => { updateCountdowns() }, 1000) return () => clearInterval(interval) } }, [voteEvents]) const fetchVoteEvents = async () => { try { setEventsLoading(true) const response = await apiClient.get(API_CONFIG.ENDPOINTS.VOTE_EVENTS) if (response.data.success) { setVoteEvents(response.data.data.vote_events || []) // Initialize countdowns for all events const initialCountdowns: Record = {} response.data.data.vote_events.forEach((event: VoteEvent) => { initialCountdowns[event.id] = calculateCountdown(event.start_date, event.end_date) }) setCountdowns(initialCountdowns) } } catch (error) { console.error('Error fetching vote events:', error) } finally { setEventsLoading(false) } } const calculateCountdown = (startDate: string, endDate: string): Countdown => { const now = new Date().getTime() const start = new Date(startDate).getTime() const end = new Date(endDate).getTime() let targetTime: number let isActive = false let isEnded = false let isUpcoming = false if (now < start) { // Event hasn't started yet targetTime = start isUpcoming = true } else if (now >= start && now <= end) { // Event is active targetTime = end isActive = true } else { // Event has ended targetTime = end isEnded = true } const timeLeft = Math.max(0, targetTime - now) const days = Math.floor(timeLeft / (1000 * 60 * 60 * 24)) const hours = Math.floor((timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60)) const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000) return { days, hours, minutes, seconds, isActive, isEnded, isUpcoming } } const updateCountdowns = () => { const updatedCountdowns: Record = {} voteEvents.forEach((event) => { updatedCountdowns[event.id] = calculateCountdown(event.start_date, event.end_date) }) setCountdowns(updatedCountdowns) } const formatCountdown = (countdown: Countdown) => { if (countdown.isEnded) { return "Event Ended" } if (countdown.days > 0) { return `${countdown.days}d ${countdown.hours}h ${countdown.minutes}m ${countdown.seconds}s` } else if (countdown.hours > 0) { return `${countdown.hours}h ${countdown.minutes}m ${countdown.seconds}s` } else if (countdown.minutes > 0) { return `${countdown.minutes}m ${countdown.seconds}s` } else { return `${countdown.seconds}s` } } const getEventStatus = (countdown: Countdown) => { if (countdown.isEnded) return "ended" if (countdown.isActive) return "active" if (countdown.isUpcoming) return "upcoming" return "unknown" } const getStatusBadge = (status: string, isVotingOpen: boolean) => { if (isVotingOpen && status === "active") { return ( Live Voting ) } switch (status) { case "active": return ( Active (Voting Closed) ) case "upcoming": return ( Coming Soon ) case "ended": return ( Completed ) default: return Unknown } } // Show loading while checking authentication if (loading) { return (

Loading...

) } // Redirect to login if not authenticated if (!isAuthenticated) { router.push("/login") return null } return (
{/* Dashboard Header */} event.is_voting_open).length }} />
{/* Page Title Section */}
Democratic Participation

Available Vote Events

Participate in democratic decisions and make your voice heard

{/* Vote Events Section */}
{eventsLoading ? (

Loading vote events...

Please wait while we fetch the latest information

) : voteEvents.length > 0 ? (
{voteEvents.map((event) => { const countdown = countdowns[event.id] const status = getEventStatus(countdown) return (
{event.title} {getStatusBadge(status, event.is_voting_open)}
{event.description}
{event.is_voting_open ? ( ) : status === "upcoming" ? ( ) : ( )}
{/* Event Dates and Countdown */}
Start: {new Date(event.start_date).toLocaleDateString('id-ID', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })}
End: {new Date(event.end_date).toLocaleDateString('id-ID', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })}
{/* Countdown Display for Active Events */} {!countdown?.isEnded && (event.is_voting_open || status === "upcoming") && (
{event.is_voting_open && status === "active" ? ( ) : ( )} {event.is_voting_open && status === "active" ? "Voting ends in:" : "Starts in:"}
{formatCountdown(countdown)}
)}
) })}
) : (

No Vote Events Available

There are currently no active or upcoming vote events. Check back soon for new voting opportunities.

)}
) }