diff --git a/public/admin.html b/public/admin.html index ac5a24d..60d158e 100644 --- a/public/admin.html +++ b/public/admin.html @@ -170,6 +170,7 @@ } }); + diff --git a/public/images/items/item-1762333137057-290874794.jpg b/public/images/items/item-1762333952965-217359885.jpg similarity index 100% rename from public/images/items/item-1762333137057-290874794.jpg rename to public/images/items/item-1762333952965-217359885.jpg diff --git a/public/js/admin.js b/public/js/admin.js index 4dbb304..983c23a 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -77,11 +77,19 @@ function getFilteredItems() { } return items.filter(item => { - if (window.translationManager) { - const localizedItem = window.translationManager.getLocalizedItem(item); + const translationManager = window.ensureTranslationManager ? window.ensureTranslationManager() : null; + if (translationManager) { + const localizedItem = translationManager.getLocalizedItem(item); return localizedItem.name.toLowerCase().includes(searchTerm) || (localizedItem.description && localizedItem.description.toLowerCase().includes(searchTerm)) || item.location.toLowerCase().includes(searchTerm); + } else if (window.getItemDisplayText) { + const currentLang = localStorage.getItem('language') || 'nl'; + const name = window.getItemDisplayText(item, 'name', currentLang); + const description = window.getItemDisplayText(item, 'description', currentLang); + return name.toLowerCase().includes(searchTerm) || + description.toLowerCase().includes(searchTerm) || + item.location.toLowerCase().includes(searchTerm); } else { // Fallback for when translation manager isn't loaded yet (default to Dutch) const name = item.name?.nl || item.name?.en || item.name || ''; @@ -110,10 +118,28 @@ function displayGridView() { const filteredItems = getFilteredItems(); itemsGrid.innerHTML = filteredItems.map(item => { - const localizedItem = window.translationManager ? window.translationManager.getLocalizedItem(item) : { - name: item.name?.nl || item.name?.en || item.name || 'Onbekend Artikel', - description: item.description?.nl || item.description?.en || item.description || '' - }; + // Use multiple fallback strategies + const translationManager = window.ensureTranslationManager ? window.ensureTranslationManager() : null; + let localizedItem; + + if (translationManager) { + localizedItem = translationManager.getLocalizedItem(item); + } else if (window.getItemDisplayText) { + // Use debug helper fallback + const currentLang = localStorage.getItem('language') || 'nl'; + localizedItem = { + ...item, + name: window.getItemDisplayText(item, 'name', currentLang), + description: window.getItemDisplayText(item, 'description', currentLang) + }; + } else { + // Final fallback + localizedItem = { + ...item, + name: (typeof item.name === 'object') ? (item.name?.nl || item.name?.en || 'Onbekend Artikel') : (item.name || 'Onbekend Artikel'), + description: (typeof item.description === 'object') ? (item.description?.nl || item.description?.en || 'Geen beschrijving beschikbaar') : (item.description || 'Geen beschrijving beschikbaar') + }; + } return `
@@ -146,10 +172,28 @@ function displayListView() { const itemsListBody = document.getElementById('itemsListBody'); const filteredItems = getFilteredItems(); itemsListBody.innerHTML = filteredItems.map(item => { - const localizedItem = window.translationManager ? window.translationManager.getLocalizedItem(item) : { - name: item.name?.nl || item.name?.en || item.name || 'Onbekend Artikel', - description: item.description?.nl || item.description?.en || item.description || '' - }; + // Use multiple fallback strategies + const translationManager = window.ensureTranslationManager ? window.ensureTranslationManager() : null; + let localizedItem; + + if (translationManager) { + localizedItem = translationManager.getLocalizedItem(item); + } else if (window.getItemDisplayText) { + // Use debug helper fallback + const currentLang = localStorage.getItem('language') || 'nl'; + localizedItem = { + ...item, + name: window.getItemDisplayText(item, 'name', currentLang), + description: window.getItemDisplayText(item, 'description', currentLang) + }; + } else { + // Final fallback + localizedItem = { + ...item, + name: (typeof item.name === 'object') ? (item.name?.nl || item.name?.en || 'Onbekend Artikel') : (item.name || 'Onbekend Artikel'), + description: (typeof item.description === 'object') ? (item.description?.nl || item.description?.en || 'Geen beschrijving beschikbaar') : (item.description || 'Geen beschrijving beschikbaar') + }; + } return ` diff --git a/public/js/debug-helper.js b/public/js/debug-helper.js new file mode 100644 index 0000000..faa69fd --- /dev/null +++ b/public/js/debug-helper.js @@ -0,0 +1,50 @@ +// Debug helper for translation issues +console.log('Debug helper loaded'); + +// Function to check item structure +window.debugItem = function(item) { + console.log('Item structure:', item); + console.log('Item name type:', typeof item.name); + console.log('Item name value:', item.name); + console.log('Item description type:', typeof item.description); + console.log('Item description value:', item.description); + + if (window.translationManager) { + console.log('Translation manager exists'); + const localized = window.translationManager.getLocalizedItem(item); + console.log('Localized item:', localized); + } else { + console.log('Translation manager not available'); + } +}; + +// Function to ensure translation manager +window.ensureTranslationManager = function() { + if (!window.translationManager) { + console.log('Creating new translation manager instance'); + if (window.TranslationManager) { + window.translationManager = new window.TranslationManager(); + } else { + console.error('TranslationManager class not available'); + return null; + } + } + return window.translationManager; +}; + +// Enhanced fallback function for items +window.getItemDisplayText = function(item, field, language = 'nl') { + if (!item) return field === 'name' ? 'Onbekend Artikel' : 'Geen beschrijving beschikbaar'; + + const value = item[field]; + + if (typeof value === 'object' && value !== null) { + return value[language] || value.nl || value.en || (field === 'name' ? 'Onbekend Artikel' : 'Geen beschrijving beschikbaar'); + } else if (typeof value === 'string') { + return value; + } else { + return field === 'name' ? 'Onbekend Artikel' : 'Geen beschrijving beschikbaar'; + } +}; + +console.log('Debug helper functions loaded'); \ No newline at end of file diff --git a/public/js/student.js b/public/js/student.js index 7bae553..06b7e83 100644 --- a/public/js/student.js +++ b/public/js/student.js @@ -124,10 +124,16 @@ function displayItems() { // Apply search filter with translation support if (searchTerm.trim() !== '') { filteredItems = filteredItems.filter(item => { - if (window.translationManager) { - const localizedItem = window.translationManager.getLocalizedItem(item); + const translationManager = window.ensureTranslationManager ? window.ensureTranslationManager() : null; + if (translationManager) { + const localizedItem = translationManager.getLocalizedItem(item); return localizedItem.name.toLowerCase().includes(searchTerm) || (localizedItem.description && localizedItem.description.toLowerCase().includes(searchTerm)); + } else if (window.getItemDisplayText) { + const currentLang = localStorage.getItem('language') || 'nl'; + const name = window.getItemDisplayText(item, 'name', currentLang); + const description = window.getItemDisplayText(item, 'description', currentLang); + return name.toLowerCase().includes(searchTerm) || description.toLowerCase().includes(searchTerm); } else { // Fallback for when translation manager isn't loaded yet (default to Dutch) const name = item.name?.nl || item.name?.en || item.name || ''; @@ -151,10 +157,28 @@ function displayItems() { // Display items in grid view const gridContainer = document.getElementById('itemsGrid'); gridContainer.innerHTML = filteredItems.map(item => { - const localizedItem = window.translationManager ? window.translationManager.getLocalizedItem(item) : { - name: item.name?.nl || item.name?.en || item.name || 'Onbekend Artikel', - description: item.description?.nl || item.description?.en || item.description || '' - }; + // Use multiple fallback strategies + const translationManager = window.ensureTranslationManager ? window.ensureTranslationManager() : null; + let localizedItem; + + if (translationManager) { + localizedItem = translationManager.getLocalizedItem(item); + } else if (window.getItemDisplayText) { + // Use debug helper fallback + const currentLang = localStorage.getItem('language') || 'nl'; + localizedItem = { + ...item, + name: window.getItemDisplayText(item, 'name', currentLang), + description: window.getItemDisplayText(item, 'description', currentLang) + }; + } else { + // Final fallback + localizedItem = { + ...item, + name: (typeof item.name === 'object') ? (item.name?.nl || item.name?.en || 'Onbekend Artikel') : (item.name || 'Onbekend Artikel'), + description: (typeof item.description === 'object') ? (item.description?.nl || item.description?.en || 'Geen beschrijving beschikbaar') : (item.description || 'Geen beschrijving beschikbaar') + }; + } return `
@@ -180,10 +204,28 @@ function displayItems() { // Display items in list view const itemsListBody = document.getElementById('itemsListBody'); itemsListBody.innerHTML = filteredItems.map(item => { - const localizedItem = window.translationManager ? window.translationManager.getLocalizedItem(item) : { - name: item.name?.nl || item.name?.en || item.name || 'Onbekend Artikel', - description: item.description?.nl || item.description?.en || item.description || '' - }; + // Use multiple fallback strategies + const translationManager = window.ensureTranslationManager ? window.ensureTranslationManager() : null; + let localizedItem; + + if (translationManager) { + localizedItem = translationManager.getLocalizedItem(item); + } else if (window.getItemDisplayText) { + // Use debug helper fallback + const currentLang = localStorage.getItem('language') || 'nl'; + localizedItem = { + ...item, + name: window.getItemDisplayText(item, 'name', currentLang), + description: window.getItemDisplayText(item, 'description', currentLang) + }; + } else { + // Final fallback + localizedItem = { + ...item, + name: (typeof item.name === 'object') ? (item.name?.nl || item.name?.en || 'Onbekend Artikel') : (item.name || 'Onbekend Artikel'), + description: (typeof item.description === 'object') ? (item.description?.nl || item.description?.en || 'Geen beschrijving beschikbaar') : (item.description || 'Geen beschrijving beschikbaar') + }; + } return ` diff --git a/public/js/translations.js b/public/js/translations.js index 1c94255..ee102d7 100644 --- a/public/js/translations.js +++ b/public/js/translations.js @@ -80,6 +80,10 @@ const translations = { 'confirm-return-request': 'Are you sure you want to request return for this item? An admin will need to approve the return.', 'return-request-success': 'Return requested successfully! An admin will review your request.', + // Item fallbacks + 'unknown-item': 'Unknown Item', + 'no-description': 'No description available', + // Management 'inventory-management': 'Inventory Management', 'reservation-management': 'Reservation Management' @@ -163,6 +167,10 @@ const translations = { 'confirm-return-request': 'Weet je zeker dat je retour wilt aanvragen voor dit artikel? Een admin moet de retour goedkeuren.', 'return-request-success': 'Retour succesvol aangevraagd! Een admin zal je verzoek beoordelen.', + // Item fallbacks + 'unknown-item': 'Onbekend Artikel', + 'no-description': 'Geen beschrijving beschikbaar', + // Management 'inventory-management': 'Voorraadbeheer', 'reservation-management': 'Reserveringsbeheer' @@ -281,10 +289,38 @@ class TranslationManager { // Get translated item data based on current language getLocalizedItem(item) { + // Handle the case where item might be null or undefined + if (!item) { + return { + name: this.translate('unknown-item'), + description: this.translate('no-description') + }; + } + + let name, description; + + // Handle multilingual name + if (typeof item.name === 'object' && item.name !== null) { + name = item.name[this.currentLanguage] || item.name.nl || item.name.en || this.translate('unknown-item'); + } else if (typeof item.name === 'string') { + name = item.name; + } else { + name = this.translate('unknown-item'); + } + + // Handle multilingual description + if (typeof item.description === 'object' && item.description !== null) { + description = item.description[this.currentLanguage] || item.description.nl || item.description.en || this.translate('no-description'); + } else if (typeof item.description === 'string') { + description = item.description || this.translate('no-description'); + } else { + description = this.translate('no-description'); + } + return { ...item, - name: item.name?.[this.currentLanguage] || item.name?.nl || item.name?.en || item.name || 'Unknown Item', - description: item.description?.[this.currentLanguage] || item.description?.nl || item.description?.en || item.description || '' + name: name, + description: description }; } @@ -306,8 +342,16 @@ class TranslationManager { let translationManager; document.addEventListener('DOMContentLoaded', () => { translationManager = new TranslationManager(); + window.translationManager = translationManager; }); // Export for use in other files window.TranslationManager = TranslationManager; -window.translationManager = translationManager; \ No newline at end of file + +// Function to ensure translation manager is available +window.getTranslationManager = function() { + if (!window.translationManager) { + window.translationManager = new TranslationManager(); + } + return window.translationManager; +}; \ No newline at end of file diff --git a/public/student.html b/public/student.html index 8f5f481..f32823b 100644 --- a/public/student.html +++ b/public/student.html @@ -143,6 +143,7 @@
+