oramap/frontend/public/script.js
dvirlabs 02074aa4a6
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Add MongoDB integration with CRUD UI
- Integrated MongoDB 7.0 with Mongoose ODM
- Added CRUD API endpoints (GET, POST, PUT, DELETE)
- Created Family model with validation
- Added database seeding script with initial data
- Implemented Add Family modal form in frontend
- Updated docker-compose with MongoDB service
- Updated Helm chart to v0.3.0 with MongoDB StatefulSet
- Updated documentation with MongoDB setup instructions
2026-03-25 01:51:46 +02:00

209 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

let map = L.map('map').setView([15.5527, 48.5164], 6);
// Define the two tile layers
const voyager = L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
attribution: '© OpenStreetMap contributors © CARTO',
subdomains: 'abcd',
maxZoom: 19
});
const openStreetMap = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors',
maxZoom: 19
});
// Add the default layer (Voyager)
voyager.addTo(map);
// Group the layers for switching
const baseMaps = {
"English Map (CartoDB Voyager)": voyager,
"Original Map (OpenStreetMap)": openStreetMap
};
// Add the layer control to the map
L.control.layers(baseMaps).addTo(map);
async function searchFamily() {
const familyName = document.getElementById('searchInput').value.trim();
if (!familyName) {
alert('Please enter a family name.');
return;
}
try {
const response = await fetch(`/api/search?family=${encodeURIComponent(familyName)}`);
const familyResult = await response.json();
if (!familyResult.length) {
alert('No matching family found.');
return;
}
clearMarkers();
familyResult.forEach(record => {
L.marker([record.lat, record.lng]).addTo(map)
.bindPopup(`<strong>${record.family}</strong><br>City: ${record.city}`)
.openPopup();
});
const first = familyResult[0];
map.setView([first.lat, first.lng], 7);
} catch (error) {
console.error('Search error:', error);
alert('Something went wrong while searching. Please try again later.');
}
}
function clearMarkers() {
map.eachLayer(layer => {
if (layer instanceof L.Marker) {
map.removeLayer(layer);
}
});
}
const familyNames = [
"Kafe (קאפח)", "Shiheb (שחב-שבח)", "Eraki (עראקי)", "Salumi (סלומי-שלומי)",
"Afgin (עפג'ין)", "Uzeyri (עזירי-עוזרי)"
// Add more families here if you like
];
// Initialize Fuse.js
const fuse = new Fuse(familyNames, {
includeScore: true,
threshold: 0.4 // Lower = stricter matching
});
const searchInput = document.getElementById('searchInput');
const suggestionsBox = document.createElement('div');
suggestionsBox.classList.add('suggestions');
searchInput.parentNode.style.position = 'relative'; // Make parent relative
searchInput.parentNode.appendChild(suggestionsBox);
searchInput.addEventListener('input', () => {
const value = searchInput.value.trim();
suggestionsBox.innerHTML = '';
if (!value) return;
const results = fuse.search(value);
results.forEach(result => {
const option = document.createElement('div');
option.textContent = result.item;
option.onclick = () => {
searchInput.value = result.item;
suggestionsBox.innerHTML = '';
};
suggestionsBox.appendChild(option);
});
});
L.control.logo = function (opts) {
return new L.Control.Logo(opts);
};
L.Control.Logo = L.Control.extend({
onAdd: function () {
const div = L.DomUtil.create('div', 'custom-logo');
div.innerHTML = `
<img src="logo.png" alt="Logo" style="height: 40px; vertical-align: middle;">
<span style="margin-left: 8px; font-weight: bold; color: #333;">Shevach</span>
`;
return div;
},
onRemove: function () {
// Nothing to clean up
}
});
L.control.logo({ position: 'bottomleft' }).addTo(map);
// Add Family Form Functions
function toggleAddFamilyForm() {
const modal = document.getElementById('addFamilyModal');
const form = document.getElementById('addFamilyForm');
const message = document.getElementById('formMessage');
if (modal.style.display === 'block') {
modal.style.display = 'none';
form.reset();
message.textContent = '';
message.className = 'form-message';
} else {
modal.style.display = 'block';
}
}
async function addFamily(event) {
event.preventDefault();
const familyName = document.getElementById('familyName').value.trim();
const cityName = document.getElementById('cityName').value.trim();
const latitude = parseFloat(document.getElementById('latitude').value);
const longitude = parseFloat(document.getElementById('longitude').value);
const messageEl = document.getElementById('formMessage');
messageEl.textContent = 'Adding family...';
messageEl.className = 'form-message info';
try {
const response = await fetch('/api/families', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
family: familyName,
city: cityName,
lat: latitude,
lng: longitude
})
});
const data = await response.json();
if (response.ok) {
messageEl.textContent = '✅ Family added successfully!';
messageEl.className = 'form-message success';
// Add marker to map
L.marker([latitude, longitude]).addTo(map)
.bindPopup(`<strong>${familyName}</strong><br>City: ${cityName}`)
.openPopup();
map.setView([latitude, longitude], 10);
// Reset form after 2 seconds
setTimeout(() => {
toggleAddFamilyForm();
}, 2000);
} else {
messageEl.textContent = `❌ Error: ${data.error || data.message}`;
messageEl.className = 'form-message error';
}
} catch (error) {
console.error('Add family error:', error);
messageEl.textContent = '❌ Failed to add family. Please try again.';
messageEl.className = 'form-message error';
}
}
// Close modal when clicking outside
window.onclick = function(event) {
const modal = document.getElementById('addFamilyModal');
if (event.target === modal) {
toggleAddFamilyForm();
}
}
// Allow Enter key to trigger search
document.getElementById('searchInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
searchFamily();
}
});