Votes: ${art.votes}
`;
vac_galleryGrid.appendChild(card);
});
}
/**
* Casts a vote for an entry.
*/
window.vac_vote = function(id) {
if (vac_hasVoted) return;
const entry = vac_entries.find(e => e.id === id);
if (entry) {
entry.votes++;
vac_hasVoted = true;
if (vac_votedMessage) vac_votedMessage.classList.remove('vac-hidden');
vac_renderGallery(); // Re-render gallery to update button states and counts
vac_renderResults(); // Re-render results
vac_renderArtTable(); // Re-render table to show new vote count
}
}
// --- V. TAB 2 (RESULTS) FUNCTIONS ---
/**
* Renders the ranked list of entries.
*/
function vac_renderResults() {
if (!vac_resultsList) return;
vac_resultsList.innerHTML = '';
if (vac_entries.length === 0) {
vac_resultsList.innerHTML = '
No entries in the contest yet.
';
return;
}
// Create a sorted copy
const sortedEntries = [...vac_entries].sort((a, b) => b.votes - a.votes);
sortedEntries.forEach((art, index) => {
const rank = index + 1;
let rankClass = `rank-${rank}`;
if (rank > 3) rankClass = 'rank-other';
const item = document.createElement('div');
item.className = 'vac-result-item';
item.innerHTML = `
${rank}${rank === 1 ? 'st' : rank === 2 ? 'nd' : rank === 3 ? 'rd' : 'th'}
${art.title}
${art.artist}
${art.votes} Votes
`;
vac_resultsList.appendChild(item);
});
}
/**
* Handles the PDF download request.
*/
function vac_downloadPDF() {
const element = vac_container.querySelector('#vac-results-pdf-output');
if (!element || vac_entries.length === 0) {
alert("No results to download. Please add entries to the contest first.");
return;
}
// Clone the element to prepare for PDF
const elementToPrint = element.cloneNode(true);
// Unhide the title that's just for the PDF
const pdfTitle = elementToPrint.querySelector('#vac-pdf-title-clone');
if (pdfTitle) pdfTitle.classList.remove('vac-hidden');
const options = {
margin: 1, // in
filename: 'virtual_art_contest_results.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
if (typeof html2pdf === 'function') {
html2pdf().from(elementToPrint).set(options).save();
} else {
console.error("VAC Tool: html2pdf.js library is not loaded.");
alert("Error: PDF generation library is missing.");
}
}
// --- VI. TAB 3 (CONFIG) FUNCTIONS ---
/**
* Renders the artwork management table.
*/
function vac_renderArtTable() {
if (!vac_artTableBody) return;
vac_artTableBody.innerHTML = '';
if (vac_entries.length === 0) {
vac_artTableBody.innerHTML = '
| No entries added yet. |
';
return;
}
vac_entries.forEach(art => {
const row = document.createElement('tr');
row.innerHTML = `
${art.title} |
${art.artist} |
${art.votes} |
|
`;
vac_artTableBody.appendChild(row);
});
}
/**
* Handles submission of the Add/Edit artwork form.
*/
function vac_handleArtFormSubmit(e) {
e.preventDefault();
if (!vac_artTitle || !vac_artArtist || !vac_artImageUrl || !vac_artDesc || !vac_editIdField) return;
const artData = {
id: vac_editingId ? parseInt(vac_editingId, 10) : Date.now(),
title: vac_artTitle.value.trim(),
artist: vac_artArtist.value.trim(),
url: vac_artImageUrl.value.trim(),
desc: vac_artDesc.value.trim()
};
if (!artData.title || !artData.artist || !artData.url) {
alert("Please fill out Title, Artist, and Image URL.");
return;
}
if (vac_editingId) {
// Update: Find original and merge, preserving vote count
const originalEntry = vac_entries.find(e => e.id === artData.id);
const updatedEntry = { ...originalEntry, ...artData };
vac_entries = vac_entries.map(art => art.id === artData.id ? updatedEntry : art);
} else {
// Add: Add new data with 0 votes
artData.votes = 0;
vac_entries.push(artData);
}
// Re-render everything
vac_renderArtTable();
vac_renderGallery();
vac_renderResults();
vac_resetArtForm();
}
/**
* Resets the art form.
*/
function vac_resetArtForm() {
vac_editingId = null;
if (!vac_editIdField || !vac_artForm || !vac_cancelBtn || !vac_formTitle) return;
vac_editIdField.value = '';
vac_artForm.reset();
vac_cancelBtn.classList.add('vac-hidden');
vac_formTitle.textContent = "Add New Entry";
}
/**
* Populates the form to edit artwork.
*/
window.vac_editEntry = function(id) {
const art = vac_entries.find(a => a.id === id);
if (!art) return;
if (!vac_editIdField || !vac_artTitle || !vac_artArtist || !vac_artImageUrl || !vac_artDesc || !vac_cancelBtn || !vac_formTitle || !vac_artForm) return;
vac_editingId = id;
vac_editIdField.value = id;
vac_artTitle.value = art.title;
vac_artArtist.value = art.artist;
vac_artImageUrl.value = art.url;
vac_artDesc.value = art.desc;
vac_formTitle.textContent = "Edit Entry";
vac_cancelBtn.classList.remove('vac-hidden');
vac_artForm.scrollIntoView({ behavior: 'smooth' });
}
/**
* Deletes an artwork.
*/
window.vac_deleteEntry = function(id) {
if (confirm("Are you sure you want to delete this entry? This will reset all votes for it and cannot be undone.")) {
vac_entries = vac_entries.filter(a => a.id !== id);
vac_renderArtTable();
vac_renderGallery();
vac_renderResults();
if (vac_editingId === id) {
vac_resetArtForm();
}
}
}
// --- VII. INITIALIZE THE TOOL ---
vac_init();
}); // End of DOMContentLoaded