diff --git a/webapps/sugar_mill_locator/app.js b/webapps/sugar_mill_locator/app.js
index 1542b24..1e6ef67 100644
--- a/webapps/sugar_mill_locator/app.js
+++ b/webapps/sugar_mill_locator/app.js
@@ -2,7 +2,7 @@
const countryColors = {
'South Africa': '#FF6B6B',
'Zimbabwe': '#4ECDC4',
- 'Eswatini': '#45B7D1',
+ 'eSwatini': '#45B7D1',
'Mozambique': '#96CEB4',
'Malawi': '#FFEAA7',
'Zambia': '#DDA15E',
@@ -10,7 +10,8 @@ const countryColors = {
'Kenya': '#F1A208',
'Tanzania': '#A23B72',
'Rwanda': '#8E7DBE',
- 'Burundi': '#C9ADA7'
+ 'Burundi': '#C9ADA7',
+ 'Mexico': '#006846',
};
let map;
@@ -318,12 +319,15 @@ function parseCSV(csvText) {
const lines = csvText.trim().split('\n');
const headers = lines[0].split(',').map(h => h.trim());
- mills = lines.slice(1).map(line => {
+ mills = lines.slice(1).map((line, index) => {
const values = parseCSVLine(line);
const row = {};
headers.forEach((header, idx) => {
row[header] = values[idx] ? values[idx].trim() : '';
});
+
+ row._id = index; // Internal unique ID
+
return row;
}).filter(row => row.Latitude && row.Longitude);
}
@@ -358,12 +362,17 @@ function parseCSVLine(line) {
// Render mills on map
function renderMills() {
+ Object.values(millMarkers).forEach(marker => {
+ if (map.hasLayer(marker)) map.removeLayer(marker);
+ });
+ millMarkers = {};
+
mills.forEach(mill => {
const lat = parseFloat(mill.Latitude);
const lng = parseFloat(mill.Longitude);
if (!isNaN(lat) && !isNaN(lng)) {
- const production = parseFloat(mill['Annual Sugar Production (tons)']) || 0;
+ const production = cleanNumber(mill['Annual Sugar Production (tons)']);
const size = getCircleSize(production);
const color = countryColors[mill.Country] || '#999';
@@ -379,7 +388,7 @@ function renderMills() {
const popup = createPopup(mill);
marker.bindPopup(popup);
- millMarkers[`${lat},${lng}`] = marker;
+ millMarkers[mill._id] = marker;
}
});
@@ -429,7 +438,7 @@ function createPopup(mill) {
${mill.Notes ? `
| "${mill.Notes}" |
` : ''}
`;
@@ -467,6 +476,13 @@ function updateLegend() {
countryFilter.value = currentValue;
}
+// Helper to clean numbers (remove commas and spaces)
+function cleanNumber(val) {
+ if (!val) return 0;
+ const cleanStr = String(val).replace(/[, ]/g, '');
+ return parseFloat(cleanStr) || 0;
+}
+
// Apply filters to mills
function applyFilters() {
const search = document.getElementById('searchInput').value.toLowerCase();
@@ -485,7 +501,7 @@ function applyFilters() {
const matchesCountry = !country || mill.Country === country;
- const production = parseFloat(mill['Annual Sugar Production (tons)']) || 0;
+ const production = cleanNumber(mill['Annual Sugar Production (tons)']);
const matchesProduction = production >= minProduction;
return matchesSearch && matchesCountry && matchesProduction;
@@ -499,13 +515,25 @@ function applyFilters() {
// Update visibility of mill markers based on filters
function updateMillsVisibility() {
- mills.forEach((mill, index) => {
- const key = `${parseFloat(mill.Latitude)},${parseFloat(mill.Longitude)}`;
- const marker = millMarkers[key];
+ mills.forEach(mill => {
+ const marker = millMarkers[mill._id];
+
if (marker) {
const isVisible = filteredMills.includes(mill);
- marker.setOpacity(isVisible ? 1 : 0.3);
- marker.setRadius(isVisible ? getCircleSize(parseFloat(mill['Annual Sugar Production (tons)']) || 0) : getCircleSize(parseFloat(mill['Annual Sugar Production (tons)']) || 0));
+
+ if (isVisible) {
+ if (!map.hasLayer(marker)) {
+ marker.addTo(map);
+ }
+ marker.setStyle({
+ opacity: 0.8,
+ fillOpacity: 0.7
+ });
+ } else {
+ if (map.hasLayer(marker)) {
+ map.removeLayer(marker);
+ }
+ }
}
});
}
@@ -632,55 +660,6 @@ function closeModal(modalId) {
document.getElementById(modalId).classList.remove('active');
}
-// Show feedback modal for existing mill
-function showFeedbackModal(mill, country, lat, lng) {
- document.getElementById('feedbackMill').value = mill;
- document.getElementById('feedbackCountry').value = country;
- document.getElementById('feedbackLocation').value = `${lat}, ${lng}`;
- document.getElementById('feedbackType').value = '';
- document.getElementById('feedbackMessage').value = '';
- document.getElementById('feedbackName').value = '';
- document.getElementById('feedbackEmail').value = '';
-
- const feedbackModal = document.getElementById('feedbackModal');
- feedbackModal.classList.add('active');
-}
-
-// Handle feedback form submission via Formspree
-document.addEventListener('DOMContentLoaded', () => {
- const feedbackForm = document.getElementById('feedbackForm');
- if (feedbackForm) {
- feedbackForm.addEventListener('submit', function(e) {
- e.preventDefault();
-
- // Fetch will handle the form submission to Formspree
- const formData = new FormData(this);
-
- fetch(this.action, {
- method: 'POST',
- body: formData,
- headers: {
- 'Accept': 'application/json'
- }
- })
- .then(response => {
- if (response.ok) {
- // Show success message
- alert('β
Feedback sent successfully! Thank you for your input.');
- closeModal('feedbackModal');
- feedbackForm.reset();
- } else {
- alert('β Error sending feedback. Please try again.');
- }
- })
- .catch(error => {
- console.error('Error:', error);
- alert('β Error sending feedback. Please check your internet connection.');
- });
- });
- }
-});
-
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
document.querySelectorAll('.modal').forEach(m => m.classList.remove('active'));
diff --git a/webapps/sugar_mill_locator/index.html b/webapps/sugar_mill_locator/index.html
index b3b3286..4f9c168 100644
--- a/webapps/sugar_mill_locator/index.html
+++ b/webapps/sugar_mill_locator/index.html
@@ -3,7 +3,7 @@
- Sugar Cane Mills - East & Southern Africa
+ Sugar Cane Mills - East & South Africa & Mexico
@@ -418,7 +418,7 @@
- πΊοΈ Sugar Cane Mills - East & Southern Africa
+ πΊοΈ Sugar Cane Mills - East & South Africa & Mexico
-
-
-