// /Volumes/Data/Code/FHGR/Frontend/js/main.js document.addEventListener('DOMContentLoaded', function() { // Journey Management let currentJourney = { name: "", description: "", markers: [] }; function saveJourney() { const journeyData = { name: document.getElementById('journey-name').value, description: document.getElementById('journey-desc').value, markers: currentJourney.markers.map(marker => ({ lat: marker.getLatLng().lat, lng: marker.getLatLng().lng })) }; // Save to backend fetch('/api/journeys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(journeyData) }) .then(response => response.json()) .then(data => { console.log('Journey saved:', data); alert('Journey saved successfully!'); currentJourney = { name: "", description: "", markers: [] }; document.getElementById('journey-name').value = ''; document.getElementById('journey-desc').value = ''; }) .catch(error => console.error('Error saving journey:', error)); } function updateMarkersList() { const container = document.getElementById('markers-list'); container.innerHTML = ''; currentJourney.markers.forEach((marker, index) => { const markerElement = document.createElement('div'); markerElement.className = 'marker-item'; markerElement.innerHTML = ` ${index + 1} ${marker.getLatLng().lat.toFixed(4)}, ${marker.getLngLat().lng.toFixed(4)} `; // Add click handler to focus on marker markerElement.addEventListener('click', () => { map.flyTo(marker.getLatLng(), 10); }); container.appendChild(markerElement); }); } // Event Listeners document.getElementById('save-journey').addEventListener('click', saveJourney); // Initialize current journey when page loads window.currentJourney = { id: Date.now(), name: "", description: "", markers: [], path: null }; // Function to prepare and save the journey function prepareAndSaveJourney() { const journeyData = { name: document.getElementById('journey-title').value, description: document.getElementById('journey-description').value, markers: window.currentJourney.markers.map(marker => ({ id: marker.id, lngLat: [marker.getLatLng().lat, marker.getLatLng().lng], content: marker.content })) }; // Save to backend fetch('http://localhost:5000/api/journeys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(journeyData) }) .then(response => response.json()) .then(data => { alert('Journey saved successfully!'); window.currentJourney = { id: Date.now(), name: "", description: "", markers: [], path: null }; document.getElementById('journey-title').value = ''; document.getElementById('journey-description').value = ''; }) .catch(error => { console.error('Error:', error); alert('Failed to save journey. Please try again.'); }); } // Event listeners for the buttons document.getElementById('add-marker-btn').addEventListener('click', function() { map.on('click', function(e) { const marker = L.marker(e.latlng, {draggable: true}).addTo(map); // Add popup with input field marker.bindPopup(''); window.currentJourney.markers.push(marker); updateMarkersList(); }); }); document.getElementById('save-journey-btn').addEventListener('click', prepareAndSaveJourney); document.getElementById('clear-markers-btn').addEventListener('click', function() { map.eachLayer(function(layer) { if (layer instanceof L.Marker) { map.removeLayer(layer); } }); window.currentJourney.markers = []; updateMarkersList(); }); function updateMarkersList() { const markersContainer = document.getElementById('markers-container'); markersContainer.innerHTML = ''; if (window.currentJourney.markers.length === 0) { markersContainer.innerHTML = '

No markers yet. Click on the map to add markers.

'; return; } window.currentJourney.markers.forEach((marker, index) => { const markerElement = document.createElement('div'); markerElement.className = 'marker-item'; markerElement.innerHTML = ` ${index + 1} ${marker.getLatLng().lat.toFixed(4)}, ${marker.getLngLat().lng.toFixed(4)} `; // Add click event to edit marker markerElement.addEventListener('click', () => { marker.openPopup(); }); markersContainer.appendChild(markerElement); }); } window.journeys = []; window.isCreatingJourney = true; // Initialize the map const map = L.map('map').setView([8.5, 47.3], 10); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); // Add navigation controls L.control.scale().addTo(map); // Add geolocate control map.addControl(new maplibregl.GeolocateControl({ positionOptions: { enableHighAccuracy: true }, trackUserLocation: true })); // Add fullscreen control map.addControl(L.control.fullscreen()); // Mode switching const modeCreateBtn = document.getElementById('mode-create'); const modeViewBtn = document.getElementById('mode-view'); const createPanel = document.getElementById('create-panel'); const viewPanel = document.getElementById('view-panel'); const markersContainer = document.getElementById('markers-container'); const emptyMarkers = document.getElementById('empty-markers'); function switchMode(mode) { if (mode === 'create') { modeCreateBtn.classList.add('active'); modeViewBtn.classList.remove('active'); createPanel.classList.add('active-panel'); viewPanel.classList.remove('active-panel'); // Enable marker adding window.isCreatingJourney = true; } else { // view mode modeCreateBtn.classList.remove('active'); modeViewBtn.classList.add('active'); createPanel.classList.remove('active-panel'); viewPanel.classList.add('active-panel'); // Disable marker adding window.isCreatingJourney = false; } } modeCreateBtn.addEventListener('click', () => switchMode('create')); modeViewBtn.addEventListener('click', () => switchMode('view')); async function loadJourneysFromBackend() { try { const response = await fetch('http://localhost:5000/api/journeys'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const journeysData = await response.json(); // Ensure we always have an array if (!Array.isArray(journeysData)) { console.warn('Expected array of journeys, got:', journeysData); window.journeys = []; return []; } window.journeys = journeysData; populateJourneySelect(journeysData); return journeysData; } catch (err) { console.error('Error loading journeys from backend:', err); // Fallback to local storage const savedJourneys = localStorage.getItem('journeys'); if (savedJourneys) { try { const parsedJourneys = JSON.parse(savedJourneys); if (Array.isArray(parsedJourneys)) { window.journeys = parsedJourneys; populateJourneySelect(window.journeys); return window.journeys; } else { console.warn('Saved journeys are not an array:', parsedJourneys); window.journeys = []; populateJourneySelect([]); return []; } } catch (parseError) { console.error('Error parsing saved journeys:', parseError); window.journeys = []; populateJourneySelect([]); return []; } } // If no data available, initialize empty array window.journeys = []; populateJourneySelect([]); return []; } } async function saveJourneyToBackend(journey) { try { const response = await fetch('http://localhost:5000/api/journeys', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: journey.id, name: journey.name, description: journey.description, markers: journey.markers.map(marker => ({ lngLat: marker.getLngLat().toArray(), content: marker.content })) }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const journeyData = await response.json(); console.log('Journey saved:', journeyData); return journeyData; } catch (err) { console.error('Error saving journey to backend:', err); // Fallback to local storage const savedJourneys = localStorage.getItem('journeys') || '[]'; const journeys = JSON.parse(savedJourneys); // Update or add the journey const existingIndex = journeys.findIndex(j => j.id === journey.id); if (existingIndex !== -1) { journeys[existingIndex] = { id: journey.id, name: journey.name, description: journey.description, markers: journey.markers.map(marker => ({ id: marker.id, lngLat: marker.getLngLat(), content: marker.content })) }; } else { journeys.push({ id: journey.id, name: journey.name, description: journey.description, markers: journey.markers.map(marker => ({ id: marker.id, lngLat: marker.getLngLat(), content: marker.content })) }); } localStorage.setItem('journeys', JSON.stringify(journeys)); console.log('Journey saved to local storage'); return journey; } } async function loadCurrentJourneyFromBackend(journeyId) { try { const response = await fetch(`http://localhost:5000/api/journeys/${journeyId}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const journeyData = await response.json(); // Update the current journey object window.currentJourney = { id: journeyData.id, name: journeyData.name, description: journeyData.description, markers: [], path: null }; // Create markers from the journey data if (Array.isArray(journeyData.markers)) { journeyData.markers.forEach(markerData => { const lngLat = maplibregl.LngLat.fromArray(markerData.lngLat); const marker = window.createMarker(lngLat, markerData.content); window.currentJourney.markers.push(marker); }); } // Update the journey path updateJourneyPath(); return journeyData; } catch (err) { console.error('Error loading journey from backend:', err); // Fallback to local storage const savedJourneys = localStorage.getItem('journeys'); if (savedJourneys) { try { const journeys = JSON.parse(savedJourneys); if (Array.isArray(journeys)) { const journey = journeys.find(j => j.id === journeyId); if (journey) { // Update the current journey object window.currentJourney = { id: journey.id, name: journey.name, description: journey.description, markers: [], path: null }; // Create markers from the journey data if (Array.isArray(journey.markers)) { journey.markers.forEach(markerData => { const lngLat = maplibregl.LngLat.fromArray(markerData.lngLat); const marker = window.createMarker(lngLat, markerData.content); window.currentJourney.markers.push(marker); }); } // Update the journey path updateJourneyPath(); console.log('Journey loaded from local storage'); return journey; } } else { console.warn('Saved journeys are not an array:', journeys); } } catch (parseError) { console.error('Error parsing saved journeys:', parseError); } } // If no data available, return null return null; } } // Update the journey select dropdown function populateJourneySelect(journeys) { const select = document.getElementById('journey-select'); select.innerHTML = ''; select.innerHTML += ''; // Sort journeys by name for consistent ordering const sortedJourneys = [...journeys].sort((a, b) => a.name.localeCompare(b.name)); sortedJourneys.forEach(journey => { const option = document.createElement('option'); option.value = journey.id; option.textContent = journey.name; select.appendChild(option); }); } // Toggle sidebar document.getElementById('toggle-sidebar').addEventListener('click', function() { document.querySelector('.sidebar').classList.toggle('collapsed'); }); // Initialize in create mode switchMode('create'); // Load journeys from backend when the page loads loadJourneysFromBackend().then(() => { // If there are journeys, set the first one as the current journey if (window.journeys.length > 0) { // Set the first journey as current const firstJourney = window.journeys[0]; loadCurrentJourneyFromBackend(firstJourney.id).then(() => { // Update the journey title and description document.getElementById('journey-title').value = currentJourney.name; document.getElementById('journey-description').value = currentJourney.description; }); } }); // Add journey selection functionality document.getElementById('journey-select').addEventListener('change', function() { const selectedId = this.value; if (selectedId === 'all') { // Show all journeys // Implementation depends on how you want to display multiple journeys return; } if (selectedId) { // Load the selected journey loadCurrentJourneyFromBackend(selectedId).then(() => { // Update the journey title and description document.getElementById('journey-title').value = currentJourney.name; document.getElementById('journey-description').value = currentJourney.description; // Update the journey info panel document.getElementById('info-title').textContent = currentJourney.name; document.getElementById('info-description').textContent = currentJourney.description; document.getElementById('info-marker-count').textContent = currentJourney.markers.length; document.getElementById('info-date').textContent = new Date().toLocaleDateString(); }); } }); // View blog post button document.getElementById('view-blog').addEventListener('click', function() { // Implementation depends on your blog system alert('Viewing blog post for this journey...'); }); // Edit journey button document.getElementById('edit-journey').addEventListener('click', function() { // Switch to create mode switchMode('create'); // Update the journey title and description document.getElementById('journey-title').value = currentJourney.name; document.getElementById('journey-description').value = currentJourney.description; }); // Delete journey button document.getElementById('delete-journey').addEventListener('click', async function() { if (confirm('Are you sure you want to delete this journey?')) { try { const response = await fetch(`http://localhost:5000/api/journeys/${currentJourney.id}`, { method: 'DELETE' }); if (response.ok) { // Remove from the journeys array const index = window.journeys.findIndex(j => j.id === currentJourney.id); if (index !== -1) { window.journeys.splice(index, 1); } // Update the journey select dropdown populateJourneySelect(window.journeys); // Clear the current journey currentJourney = { id: Date.now(), name: "Untitled Journey", description: "", markers: [], path: null }; // Clear the map map.getSource('journey-path').setData({ type: 'Feature', properties: {}, geometry: { type: 'LineString', coordinates: [] } }); // Clear the form document.getElementById('journey-title').value = ''; document.getElementById('journey-description').value = ''; alert('Journey deleted successfully!'); } else { alert('Failed to delete journey.'); } } catch (err) { console.error('Error deleting journey:', err); // Fallback to local storage const savedJourneys = localStorage.getItem('journeys'); if (savedJourneys) { try { const journeys = JSON.parse(savedJourneys); if (Array.isArray(journeys)) { const index = journeys.findIndex(j => j.id === currentJourney.id); if (index !== -1) { journeys.splice(index, 1); localStorage.setItem('journeys', JSON.stringify(journeys)); } } } catch (parseError) { console.error('Error parsing saved journeys:', parseError); } } alert('Journey deleted successfully (local storage)'); } } }); });