let currentYear; //Adding new element in the array creates new tab const years = ['pre-2009', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016','2017','2018','2019','2020','2021','2022','2023', '2024', 're-watch', 'manga']; function loadYearTabs() { const yearTabs = document.getElementById('year-tabs'); // Populate the tabs years.forEach(year => { const li = document.createElement('li'); li.textContent = year; li.classList.add('tab'); li.dataset.year = year; // Set data-year attribute for each tab // Add a click event listener to each tab li.addEventListener('click', () => { loadYearContent(year); }); yearTabs.appendChild(li); // Now check if all entries are completed for this year fetch(`php/check_completed_year.php?year=${encodeURIComponent(year)}`) .then(response => response.json()) .then(data => { if (data.all_completed) { // Strike through the tab if all are completed li.style.textDecoration = 'line-through'; } }) .catch(error => console.error('Error checking completed status:', error)); }); // Load the last active tab or default to 'pre-2009' const activeYear = localStorage.getItem('activeYear') || 'pre-2009'; loadYearContent(activeYear); } function loadYearContent(year) { currentYear = year; // Save the current year in localStorage for persistence localStorage.setItem('activeYear', year); // Highlight the active tab const tabs = document.querySelectorAll('#year-tabs .tab'); tabs.forEach(tab => { // Add or remove the active class based on the tab's data-year if (tab.dataset.year === year) { tab.classList.add('active'); } else { tab.classList.remove('active'); } }); // Fetch and display content for the selected year fetch(`php/fetch_data.php?year=${encodeURIComponent(year)}`) .then(response => response.text()) .then(html => { document.getElementById('content').innerHTML = html; setupFormSubmission(); setupEditButtons(); setupDeleteButtons(); setupSuggestButton(); setupSetCompleteButtons(); setupSetCurrentlyWatchingButtons(); }) .catch(error => console.error('Error loading content:', error)); } function setupFormSubmission() { const form = document.getElementById('add-form'); function handleFormSubmit(event) { event.preventDefault(); const formData = new FormData(form); fetch('php/add_record.php', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { return response.json().then(errorData => { if (response.status === 403) { alert(errorData.message || 'Access denied: You are not authorized to perform this action.'); } throw new Error(errorData.message || 'An error occurred.'); }); } return response.text(); }) .then(() => { loadYearContent(currentYear); }) .catch(error => { console.error('Error:', error); }); } form.addEventListener('submit', handleFormSubmit); form.addEventListener('keydown', event => { if (event.ctrlKey && event.key === 'Enter') { event.preventDefault(); handleFormSubmit(event); } }); } function setupEditButtons() { const editButtons = document.querySelectorAll('.edit-button'); editButtons.forEach(button => { button.addEventListener('click', () => { const recordId = button.dataset.id; openEditModal(recordId); }); }); } function setupDeleteButtons() { const deleteButtons = document.querySelectorAll('.delete-button'); deleteButtons.forEach(button => { button.addEventListener('click', () => { const recordId = button.dataset.id; if (confirm('Are you sure you want to delete this record?')) { fetch(`php/delete_record.php?id=${recordId}`, { method: 'DELETE' }) .then(response => { if (!response.ok) { return response.json().then(errorData => { if (response.status === 403) { alert(errorData.message || 'Access denied: You are not authorized to delete this record.'); } throw new Error(errorData.message || 'An error occurred while deleting the record.'); }); } return response.text(); }) .then(() => { loadYearContent(currentYear); }) .catch(error => { console.error('Error:', error); }); } }); }); } function openEditModal(id) { // Fetch record data fetch(`php/fetch_record.php?id=${id}`) .then(response => response.json()) .then(data => { const modal = document.getElementById('edit-modal'); const form = document.getElementById('edit-form'); form.innerHTML = generateEditForm(data); modal.style.display = 'block'; setupEditFormSubmission(); }); } function setupModal() { const modal = document.getElementById('edit-modal'); const closeModal = document.getElementById('close-modal'); closeModal.addEventListener('click', () => modal.style.display = 'none'); window.addEventListener('keydown', event => { if (event.key === 'Escape') { modal.style.display = 'none'; } }); // Close modal when clicking outside the modal content modal.addEventListener('click', event => { if (event.target === modal) { modal.style.display = 'none'; } }); } function mapLabelToYear(label) { if (label === 'pre-2009') return -1; if (label === 're-watch') return -2; return parseInt(label, 10); } function setupEditFormSubmission() { const form = document.getElementById('edit-form'); function handleEditFormSubmit(event) { event.preventDefault(); const yearLabelSelect = form.querySelector('#year_label'); const numericYearInput = form.querySelector('#year_numeric'); const selectedLabel = yearLabelSelect.value; // Use the mapLabelToYear function numericYearInput.value = mapLabelToYear(selectedLabel); const formData = new FormData(form); fetch('php/edit_record.php', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { return response.json().then(errorData => { if (response.status === 403) { alert(errorData.message || 'Access denied: You are not authorized to edit this record.'); } throw new Error(errorData.message || 'An error occurred while editing the record.'); }); } return response.text(); }) .then(() => { const modal = document.getElementById('edit-modal'); modal.style.display = 'none'; loadYearContent(currentYear); }) .catch(error => { console.error('Error:', error); }); } form.addEventListener('submit', handleEditFormSubmit); form.addEventListener('keydown', event => { if (event.ctrlKey && event.key === 'Enter') { event.preventDefault(); handleEditFormSubmit(event); } }); } function generateEditForm(data) { function mapYearToLabel(yearValue) { if (yearValue == -1) return 'pre-2009'; if (yearValue == -2) return 're-watch'; if (yearValue == -3) return 'manga'; return yearValue.toString(); } const selectedYearLabel = mapYearToLabel(data.year); return `

Edit Record

`; } function setupSuggestButton() { const suggestButton = document.getElementById('suggest-button'); if (suggestButton) { suggestButton.addEventListener('click', () => { makeSuggestion(); }); } } function makeSuggestion() { // Clear any previous suggestions const previousSuggestion = document.getElementById('suggestion-display'); if (previousSuggestion) { previousSuggestion.remove(); } // Get all table rows that are not completed const rows = Array.from(document.querySelectorAll('table tbody tr')).filter(row => { return !row.classList.contains('completed'); }); // Exclude header rows and ensure there are at least two entries if (rows.length < 1) { alert('Not enough uncompleted entries to make a suggestion.'); return; } // Randomly select two different rows const indices = []; while (indices.length < 1) { const index = Math.floor(Math.random() * rows.length); if (!indices.includes(index)) { indices.push(index); } } const selectedRows = [rows[indices[0]]]; const names = selectedRows.map(row => row.getAttribute('data-name')); // Display the names at the top of the content const content = document.getElementById('content'); const suggestionDisplayDiv = document.createElement('div'); suggestionDisplayDiv.id = 'suggestion-display'; suggestionDisplayDiv.innerHTML = `

${names.join('
')}

`; content.insertBefore(suggestionDisplayDiv, content.querySelector('button')); // Insert before the add form } function setupStickyTabs() { const tabsContainer = document.querySelector('.tabs-container'); const observer = new IntersectionObserver( ([e]) => e.target.classList.toggle('is-sticky', e.intersectionRatio < 1), { threshold: [1] } ); observer.observe(tabsContainer); } function setupSetCompleteButtons() { const setCompleteButtons = document.querySelectorAll('.set-complete-button'); setCompleteButtons.forEach(button => { button.addEventListener('click', () => { const recordId = button.dataset.id; const formData = new FormData(); formData.append('id', recordId); fetch('php/set_complete.php', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { return response.json().then(errorData => { if (response.status === 403) { alert(errorData.message || 'Access denied: You are not authorized to perform this action.'); } throw new Error(errorData.message || 'An error occurred while setting the record as complete.'); }); } return response.json(); }) .then(() => { // Reload the table to reflect the changes loadYearContent(currentYear); }) .catch(error => { console.error('Error:', error); }); }); }); } function setupSetCurrentlyWatchingButtons() { const setCurrentlyWatchingButtons = document.querySelectorAll('.set-currently-watching-button'); setCurrentlyWatchingButtons.forEach(button => { button.addEventListener('click', () => { const recordId = button.dataset.id; const formData = new FormData(); formData.append('id', recordId); fetch('php/set_currently_watching.php', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { return response.json().then(errorData => { if (response.status === 403) { alert(errorData.message || 'Access denied: You are not authorized to perform this action.'); } throw new Error(errorData.message || 'An error occurred while setting the record as currently watching.'); }); } return response.json(); }) .then(() => { // Reload the table to reflect the changes loadYearContent(currentYear); }) .catch(error => { console.error('Error:', error); }); }); }); } document.addEventListener('DOMContentLoaded', () => { console.log('DOM fully loaded and parsed'); loadYearTabs(); setupModal(); var imageCache = {}; var currentHoverTarget = null; function showImageTooltip(event, imageUrl) { var tooltip = document.getElementById('image-tooltip'); if (!tooltip) { tooltip = document.createElement('div'); tooltip.id = 'image-tooltip'; tooltip.style.position = 'absolute'; tooltip.style.border = '1px solid #ccc'; tooltip.style.background = '#fff'; tooltip.style.padding = '5px'; tooltip.style.zIndex = 1000; tooltip.style.maxWidth = '200px'; tooltip.style.maxHeight = '300px'; tooltip.style.overflow = 'hidden'; tooltip.style.display = 'none'; document.body.appendChild(tooltip); } tooltip.innerHTML = ''; tooltip.style.left = (event.pageX + 15) + 'px'; tooltip.style.top = (event.pageY + 15) + 'px'; tooltip.style.display = 'block'; } function hideImageTooltip() { var tooltip = document.getElementById('image-tooltip'); if (tooltip) { tooltip.style.display = 'none'; } } var contentDiv = document.getElementById('content'); contentDiv.addEventListener('mouseover', function (event) { var target = event.target; if (target.tagName.toLowerCase() === 'a' && target.hasAttribute('data-url')) { var url = target.getAttribute('data-url'); currentHoverTarget = target; // Set the current hover target if (imageCache[url]) { showImageTooltip(event, imageCache[url]); } else { var xhr = new XMLHttpRequest(); xhr.open('GET', './php/get_image.php?url=' + encodeURIComponent(url), true); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { var response = JSON.parse(xhr.responseText); if (response.image_url) { imageCache[url] = response.image_url; if (currentHoverTarget === target) { showImageTooltip(event, response.image_url); } } else if (response.error) { console.error(response.error); } } }; xhr.send(); } } }); contentDiv.addEventListener('mouseout', function (event) { var target = event.target; if (target.tagName.toLowerCase() === 'a' && target.hasAttribute('data-url')) { hideImageTooltip(); if (currentHoverTarget === target) { currentHoverTarget = null; // Clear the current hover target } } }); contentDiv.addEventListener('mousemove', function (event) { var tooltip = document.getElementById('image-tooltip'); if (tooltip && tooltip.style.display === 'block') { tooltip.style.left = (event.pageX + 15) + 'px'; tooltip.style.top = (event.pageY + 15) + 'px'; } }); });