Mill viewer updates and fixes
This commit is contained in:
parent
40a7d4d691
commit
f231911d7b
|
|
@ -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 ? `<tr><td colspan="2" style="padding-top: 8px; color: #555; font-style: italic;">"${mill.Notes}"</td></tr>` : ''}
|
||||
</table>
|
||||
<div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid #eee;">
|
||||
<button onclick="showFeedbackModal('${mill['Mill/Factory']}', '${mill['Country']}', '${parseFloat(mill.Latitude).toFixed(4)}', '${parseFloat(mill.Longitude).toFixed(4)}')" style="width: 100%; padding: 8px; background: #2596be; color: white; border: none; border-radius: 4px; font-size: 12px; font-weight: 600; cursor: pointer;">💬 Send Feedback</button>
|
||||
<a href="https://docs.google.com/spreadsheets/d/1ZHEIyhupNDHVd1EScBn0DnuiAzMFoZcAPZm3U65abkY/edit?gid=220881066#gid=220881066" target="_blank" style="display: block; width: 100%; padding: 8px; background: #2596be; color: white; text-align: center; text-decoration: none; border-radius: 4px; font-size: 12px; font-weight: 600;">📝 Edit on Google Sheets</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -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'));
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Sugar Cane Mills - East & Southern Africa</title>
|
||||
<title>Sugar Cane Mills - East & South Africa & Mexico</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-measure@3.1.0/dist/leaflet-measure.css" />
|
||||
|
|
@ -418,7 +418,7 @@
|
|||
</script>
|
||||
<header>
|
||||
<button class="back-btn" onclick="window.location.href='../';" title="Back to main tools">← Back</button>
|
||||
<h1>🗺️ Sugar Cane Mills - East & Southern Africa</h1>
|
||||
<h1>🗺️ Sugar Cane Mills - East & South Africa & Mexico</h1>
|
||||
<div class="header-controls">
|
||||
<div class="mode-toggle">
|
||||
<button class="mode-btn active" data-mode="view">View</button>
|
||||
|
|
@ -445,7 +445,7 @@
|
|||
<select id="countryFilter" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 12px; margin-bottom: 8px;">
|
||||
<option value="">All Countries</option>
|
||||
</select>
|
||||
<input type="number" id="minProduction" placeholder="Min production (tons)" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 12px; margin-bottom: 8px;">
|
||||
<input type="number" id="minProduction" placeholder="Min production (tons/year)" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 12px; margin-bottom: 8px;">
|
||||
<button class="btn-secondary" id="resetFiltersBtn" style="width: 100%; padding: 8px;">Reset Filters</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -564,58 +564,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Feedback Modal -->
|
||||
<div id="feedbackModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2>Send Feedback on Mill</h2>
|
||||
<button class="close-btn" onclick="closeModal('feedbackModal')">×</button>
|
||||
</div>
|
||||
<form id="feedbackForm" action="https://formspree.io/f/xgvgybwl" method="POST">
|
||||
<div class="form-group">
|
||||
<label>Mill Name</label>
|
||||
<input type="text" name="mill" id="feedbackMill" readonly style="background: #f5f5f5;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Country</label>
|
||||
<input type="text" name="country" id="feedbackCountry" readonly style="background: #f5f5f5;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Location</label>
|
||||
<input type="text" name="location" id="feedbackLocation" readonly style="background: #f5f5f5;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Feedback Type *</label>
|
||||
<select name="feedbackType" id="feedbackType" required style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 13px;">
|
||||
<option value="">-- Select type --</option>
|
||||
<option value="Correction">Data Correction</option>
|
||||
<option value="Addition">Add Missing Data</option>
|
||||
<option value="Update">Update Information</option>
|
||||
<option value="Verification">Verification/Confirmation</option>
|
||||
<option value="Other">Other Feedback</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Your Message *</label>
|
||||
<textarea name="message" id="feedbackMessage" required style="min-height: 120px;"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Your Name (Optional)</label>
|
||||
<input type="text" name="name" id="feedbackName" placeholder="Your name or organization">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Your Email (Optional)</label>
|
||||
<input type="email" name="email" id="feedbackEmail" placeholder="your@email.com">
|
||||
</div>
|
||||
<input type="hidden" name="_next" value="javascript:void(0)" />
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn-secondary" onclick="closeModal('feedbackModal')">Cancel</button>
|
||||
<button type="submit" class="btn-primary">Send Feedback</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script src="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.js"></script>
|
||||
<script src="https://unpkg.com/leaflet-measure@3.1.0/dist/leaflet-measure.umd.js"></script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue