// Main JavaScript for Homepage
// DOM Elements
const browseEventsBtn = document.getElementById("browse-events");
const eventCardsContainer = document.getElementById("event-cards-container");
// Event Listeners
document.addEventListener("DOMContentLoaded", init);
if (browseEventsBtn) {
browseEventsBtn.addEventListener("click", () => {
window.location.href = "./pages/events.html";
});
}
async function init() {
// Initialize the app
console.log("Initializing homepage...");
// Load upcoming events for the homepage
await loadUpcomingEvents();
}
async function loadUpcomingEvents() {
// Check if contract is available
if (typeof window.contract === "undefined" || !window.contract) {
console.log("Contract not initialized yet, waiting...");
// Check if MetaMask is connected
if (typeof window.ethereum !== "undefined") {
try {
// Get accounts
const accounts = await window.ethereum.request({ method:
'eth_accounts' });
if (accounts.length > 0) {
// If connected, wait for contract to be initialized
setTimeout(loadUpcomingEvents, 500);
return;
}
} catch (error) {
console.error("Error checking accounts:", error);
}
}
// Show placeholder content if not connected
showPlaceholderEvents();
return;
}
try {
// Get event count from contract
const eventCount = await contract.eventCount();
// If no events, show placeholder
if (eventCount.toNumber() === 0) {
showNoEventsMessage();
return;
}
// Clear loading indicator
eventCardsContainer.innerHTML = "";
// Load a maximum of 3 most recent events for homepage
const maxEvents = Math.min(eventCount.toNumber(), 3);
const eventPromises = [];
// Fetch event details in parallel
for (let i = eventCount.toNumber() - 1; i >= Math.max(0,
eventCount.toNumber() - maxEvents); i--) {
eventPromises.push(loadEventCard(i));
}
// Wait for all events to load
await Promise.all(eventPromises);
} catch (error) {
console.error("Error loading upcoming events:", error);
showErrorMessage();
}
}
async function loadEventCard(eventId) {
try {
// Get event details from contract
const eventDetails = await contract.getEventDetails(eventId);
// Create event card element
const eventCard = document.createElement("div");
eventCard.className = "event-card";
// Current time for status calculation
const now = new Date();
const startTime = new Date(eventDetails[3].toNumber() * 1000);
const endTime = new Date(eventDetails[4].toNumber() * 1000);
// Determine event status
let statusClass = "";
let statusText = "";
if (!eventDetails[5]) { // Not active
statusClass = "status-ended";
statusText = "Ended";
} else if (now < startTime) {
statusClass = "status-upcoming";
statusText = "Upcoming";
} else if (now > endTime) {
statusClass = "status-ended";
statusText = "Expired";
} else {
statusClass = "status-active";
statusText = "Active";
}
// Build event card HTML
eventCard.innerHTML = `
<div class="event-image">
<img src="#" alt="${eventDetails[0]}" id="img-event-${eventId}">
<div class="event-status ${statusClass}">${statusText}</div>
</div>
<div class="event-details">
<h3 class="event-title">${eventDetails[0]}</h3>
<p class="event-description">${eventDetails[1]}</p>
<div class="event-meta">
<span class="event-timing"><i class="fas fa-clock"></i> $
{formatDate(startTime)}</span>
<span class="event-candidates"><i class="fas fa-users"></i> $
{eventDetails[6].toNumber()} Candidates</span>
</div>
<div class="event-actions">
<a href="./pages/event-details.html?id=${eventId}" class="btn
primary-btn">View Details</a>
</div>
</div>
`;
// Add to container
eventCardsContainer.appendChild(eventCard);
// Load image from IPFS
const imgElement = document.getElementById(`img-event-${eventId}`);
if (imgElement) {
loadImageFromIPFS(eventDetails[2], imgElement);
}
} catch (error) {
console.error(`Error loading event ${eventId}:`, error);
}
}
function showPlaceholderEvents() {
eventCardsContainer.innerHTML = `
<div class="event-card">
<div class="event-image">
<img src="./assets/images/event-placeholder.png" alt="Connect
wallet to see events">
<div class="event-status status-upcoming">Example</div>
</div>
<div class="event-details">
<h3 class="event-title">Connect Wallet to See Events</h3>
<p class="event-description">Connect your MetaMask wallet to see
actual voting events. This is just a placeholder example.</p>
<div class="event-meta">
<span class="event-timing"><i class="fas fa-clock"></i> Example
date</span>
<span class="event-candidates"><i class="fas fa-users"></i> 0
Candidates</span>
</div>
<div class="event-actions">
<button onclick="connectWallet()" class="btn primary-
btn">Connect Wallet</button>
</div>
</div>
</div>
`;
}
function showNoEventsMessage() {
eventCardsContainer.innerHTML = `
<div class="event-card">
<div class="event-image">
<img src="./assets/images/no-events.png" alt="No events">
</div>
<div class="event-details">
<h3 class="event-title">No Events Yet</h3>
<p class="event-description">There are no voting events created
yet. If you're an admin, you can create a new event from the admin panel.</p>
<div class="event-actions" id="admin-create-action" style="display:
none;">
<a href="./pages/admin.html" class="btn primary-btn">Create
Event</a>
</div>
</div>
</div>
`;
// Show create button if user is admin
if (window.isAdmin) {
document.getElementById("admin-create-action").style.display = "flex";
}
}
function showErrorMessage() {
eventCardsContainer.innerHTML = `
<div class="event-card">
<div class="event-details">
<h3 class="event-title">Error Loading Events</h3>
<p class="event-description">There was an error loading the events.
Please try again later or check the console for more information.</p>
</div>
</div>
`;
}
// Helper function to format date
function formatDate(date) {
return new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
}).format(date);
}