No records added yet.
';
return;
}
const ul = document.createElement('ul');
const sortedRecordsForList = [...presidentialRecords].sort((a, b) => a.termStartYear - b.termStartYear || a.presidentName.localeCompare(b.presidentName));
sortedRecordsForList.forEach(record => {
const li = document.createElement('li');
const recordText = document.createElement('span');
recordText.textContent = `${record.presidentName} (${record.termStartYear} - ${record.termEndYear || 'Present'}), ${record.party}`;
const deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.classList.add('uspa-button', 'uspa-button-delete');
deleteButton.addEventListener('click', () => deleteRecord(record.id));
li.appendChild(recordText);
li.appendChild(deleteButton);
ul.appendChild(li);
});
currentRecordsListDiv.appendChild(ul);
}
function handleAddRecordFormSubmit(event) {
event.preventDefault();
const newRecord = {
id: generateId(),
presidentName: presidentNameInput.value.trim(),
termStartYear: parseInt(termStartYearInput.value),
termEndYear: termEndYearInput.value.trim(), // Keep as string for "Present"
party: partyInput.value.trim(),
vicePresident: vicePresidentInput.value.trim(),
keyEvents: keyEventsInput.value.trim(),
notableQuotes: notableQuotesInput.value.trim(),
bioNotes: bioNotesInput.value.trim()
};
if (!newRecord.presidentName || isNaN(newRecord.termStartYear) || !newRecord.termEndYear || !newRecord.party) {
alert("President Name, Term Start/End Years, and Party are required.");
return;
}
presidentialRecords.push(newRecord);
saveRecordsToLocalStorage();
renderCurrentRecordsList();
updatePartySuggestions();
addRecordForm.reset();
presidentNameInput.focus();
if (document.getElementById('archiveViewer').classList.contains('active')) {
renderArchiveView();
}
}
function deleteRecord(recordId) {
presidentialRecords = presidentialRecords.filter(record => record.id !== recordId);
saveRecordsToLocalStorage();
renderCurrentRecordsList();
updatePartySuggestions();
if (document.getElementById('archiveViewer').classList.contains('active')) {
renderArchiveView();
}
}
function getOrganizedRecords() {
let records = [...presidentialRecords];
const partyFilter = filterPartySelect.value;
const keyword = filterKeywordInput.value.toLowerCase();
// Filter
if (partyFilter) {
records = records.filter(r => r.party === partyFilter);
}
if (keyword) {
records = records.filter(r =>
r.presidentName.toLowerCase().includes(keyword) ||
r.keyEvents.toLowerCase().includes(keyword) ||
r.bioNotes.toLowerCase().includes(keyword) ||
r.vicePresident.toLowerCase().includes(keyword) ||
r.notableQuotes.toLowerCase().includes(keyword)
);
}
// Sort
const [sortField, sortOrder] = sortBySelect.value.split('_');
records.sort((a, b) => {
let valA, valB;
if (sortField === 'termStartYear') {
valA = a.termStartYear;
valB = b.termStartYear;
} else { // name
valA = a.presidentName.toLowerCase();
valB = b.presidentName.toLowerCase();
}
if (valA < valB) return sortOrder === 'asc' ? -1 : 1;
if (valA > valB) return sortOrder === 'asc' ? 1 : -1;
// Secondary sort by term start year if names are same, or by name if terms are same
if (sortField === 'name') {
return a.termStartYear - b.termStartYear;
} else {
return a.presidentName.localeCompare(b.presidentName);
}
});
return records;
}
function renderArchiveView() {
updateCssVariables();
archiveViewDiv.innerHTML = '';
const organizedRecords = getOrganizedRecords();
if (organizedRecords.length === 0) {
archiveViewDiv.innerHTML = '
No presidential records match your criteria or none have been added yet.
';
return;
}
organizedRecords.forEach(record => {
const card = document.createElement('div');
card.classList.add('uspa-record-card');
let termDisplay = `${record.termStartYear} – ${record.termEndYear || 'Present'}`;
card.innerHTML = `
${record.presidentName}
Term: ${termDisplay} | Party: ${record.party}
${record.vicePresident ? `
Vice President(s): ${record.vicePresident}
` : ''}
${record.keyEvents ? `
Key Events/Policies:
${record.keyEvents.replace(/\n/g, '
')}
` : ''}
${record.notableQuotes ? `
Notable Quotes:
${record.notableQuotes.replace(/\n/g, '
')}
` : ''}
${record.bioNotes ? `
Biographical Notes:
${record.bioNotes.replace(/\n/g, '
')}
` : ''}
`;
archiveViewDiv.appendChild(card);
});
}
function handlePdfDownload() {
if (!jsPDF_constructor_for_tool) {
alert("PDF library is not available."); return;
}
const recordsToExport = getOrganizedRecords();
const pdfDocTitle = displayTitleInput.value || "US Presidential History";
if (recordsToExport.length === 0) {
alert("No records to export based on current filters/sort."); return;
}
const pdf = new jsPDF_constructor_for_tool({ orientation: 'p', unit: 'mm', format: 'a4' });
const primaryColor = primaryColorInput.value;
const textColor = textColorInput.value;
const pageBgColor = bgColorInput.value;
pdf.setFillColor(pageBgColor);
pdf.rect(0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight(), 'F');
const margin = 15;
const contentWidth = pdf.internal.pageSize.getWidth() - 2 * margin;
let currentY = margin;
pdf.setFont("helvetica", "bold"); // Using a standard font
pdf.setFontSize(20);
pdf.setTextColor(primaryColor);
const titleLines = pdf.splitTextToSize(pdfDocTitle, contentWidth);
pdf.text(titleLines, pdf.internal.pageSize.getWidth() / 2, currentY, { align: 'center' });
currentY += (titleLines.length * 20 * 0.35) + 12; // Adjust spacing based on font size
recordsToExport.forEach(record => {
let estimatedBlockHeight = 0;
pdf.setFont("helvetica", "bold"); pdf.setFontSize(14); estimatedBlockHeight += 6; // Name
pdf.setFont("helvetica", "normal"); pdf.setFontSize(10); estimatedBlockHeight += 5; // Term/Party
if(record.vicePresident) estimatedBlockHeight += (pdf.splitTextToSize(record.vicePresident, contentWidth).length * 10 * 0.35) + 4;
if(record.keyEvents) { pdf.setFontSize(11); estimatedBlockHeight += 5; pdf.setFontSize(10); estimatedBlockHeight += (pdf.splitTextToSize(record.keyEvents, contentWidth).length * 10 * 0.35) + 4; }
if(record.notableQuotes) { pdf.setFontSize(11); estimatedBlockHeight += 5; pdf.setFontSize(10); estimatedBlockHeight += (pdf.splitTextToSize(record.notableQuotes, contentWidth).length * 10 * 0.35) + 4; }
if(record.bioNotes) { pdf.setFontSize(11); estimatedBlockHeight += 5; pdf.setFontSize(10); estimatedBlockHeight += (pdf.splitTextToSize(record.bioNotes, contentWidth).length * 10 * 0.35) + 4; }
estimatedBlockHeight += 10; // Spacing
if (currentY + estimatedBlockHeight > pdf.internal.pageSize.getHeight() - margin) {
pdf.addPage(); currentY = margin;
pdf.setFillColor(pageBgColor); pdf.rect(0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight(), 'F');
}
// President Name
pdf.setFont("helvetica", "bold"); pdf.setFontSize(14); pdf.setTextColor(primaryColor);
const nameLines = pdf.splitTextToSize(record.presidentName, contentWidth);
pdf.text(nameLines, margin, currentY);
currentY += (nameLines.length * 14 * 0.35) + 2;
// Term & Party
pdf.setFont("helvetica", "italic"); pdf.setFontSize(10); pdf.setTextColor(textColor);
const termPartyText = `Term: ${record.termStartYear} – ${record.termEndYear || 'Present'} | Party: ${record.party}`;
pdf.text(termPartyText, margin, currentY);
currentY += (10 * 0.35) + 4;
pdf.setFont("helvetica", "normal"); // Reset font style
// Vice President
if (record.vicePresident) {
pdf.setFontSize(10); pdf.setTextColor(textColor);
pdf.setFont("helvetica", "bold"); pdf.text("Vice President(s):", margin, currentY); currentY += (10 * 0.35) + 1;
pdf.setFont("helvetica", "normal");
const vpLines = pdf.splitTextToSize(record.vicePresident, contentWidth - 5); // Indent slightly
pdf.text(vpLines, margin + 5, currentY);
currentY += (vpLines.length * 10 * 0.35) + 3;
}
// Function to render multi-line text sections
const renderSection = (label, text) => {
if (text) {
pdf.setFontSize(11); pdf.setTextColor(primaryColor); pdf.setFont("helvetica", "bold");
pdf.text(label, margin, currentY); currentY += (11 * 0.35) + 1;
pdf.setFontSize(10); pdf.setTextColor(textColor); pdf.setFont("helvetica", "normal");
const lines = pdf.splitTextToSize(text, contentWidth -5);
pdf.text(lines, margin + 5, currentY);
currentY += (lines.length * 10 * 0.35) + 4;
}
};
renderSection("Key Events/Policies:", record.keyEvents);
renderSection("Notable Quotes:", record.notableQuotes);
renderSection("Biographical Notes:", record.bioNotes);
currentY += 6; // Extra space between records
});
let safePdfTitle = pdfDocTitle.replace(/[^a-z0-9]/gi, '_').toLowerCase() || "us_presidential_history";
if (safePdfTitle.length > 50) safePdfTitle = safePdfTitle.substring(0, 50);
pdf.save(safePdfTitle + '.pdf');
}
// Event Listeners
tabs.forEach(tab => {
tab.addEventListener('click', (e) => switchTab(e.currentTarget.dataset.tab));
});
document.querySelectorAll('.uspa-next-tab, .uspa-prev-tab').forEach(button => {
button.addEventListener('click', (e) => {
const targetTabId = e.currentTarget.dataset.nexttab || e.currentTarget.dataset.prevtab;
if (targetTabId) switchTab(targetTabId);
});
});
if (addRecordForm) addRecordForm.addEventListener('submit', handleAddRecordFormSubmit);
if (clearFormButton) clearFormButton.addEventListener('click', () => addRecordForm.reset());
// Tab 2 Listeners
if(applyOrganizationButton) applyOrganizationButton.addEventListener('click', renderArchiveView);
if(clearOrganizationButton) clearOrganizationButton.addEventListener('click', () => {
sortBySelect.value = 'termStartYear_asc';
filterPartySelect.value = '';
filterKeywordInput.value = '';
renderArchiveView();
});
// Live update for keyword as user types
if(filterKeywordInput) filterKeywordInput.addEventListener('input', renderArchiveView);
[displayTitleInput, primaryColorInput, textColorInput, bgColorInput, cardBgColorInput].forEach(input => {
if (input) {
input.addEventListener('input', renderArchiveView);
if (input.type === 'color') input.addEventListener('change', renderArchiveView);
}
});
if (downloadPdfButton && !downloadPdfButton.disabled) {
downloadPdfButton.addEventListener('click', handlePdfDownload);
}
// Initialization
loadRecordsFromLocalStorage();
updatePartySuggestions();
renderCurrentRecordsList();
switchTab('recordsManager');
renderArchiveView(); // Prepare archive view content
updateCssVariables();
});