diff --git a/src/static/js/mainapp/venues.js b/src/static/js/mainapp/venues.js index a57cf50..92e4ac9 100644 --- a/src/static/js/mainapp/venues.js +++ b/src/static/js/mainapp/venues.js @@ -1,21 +1,141 @@ -// function getWaters(venueID) { -// $.ajax({ -// url: `/venues/get-waters/${venueID}`, -// type: "GET", -// "dataType": "json", -// success: function (data) { -// alert(JSON.stringify(data)); -// }, -// error: function (error) { -// alert("error: " + error); -// } -// }); -// } +var marker = null; + map = null; + originalMapCoords = [51.509865, -0.118092]; + isGeocodingInProgress = false; + scriptData = document.currentScript.dataset; -var scriptData = document.currentScript.dataset; +const formControls = [ + // Details Tab + { + id: "venueName", + validation: function (element) { + const value = element.val(); + const minlength = element.attr("minlength") || 0; // FIELD IS VALID IF: + return (!element.attr("required") || value.trim() !== ""); // - element is not required OR not empty + }, + errorMessage: function (element) { + const minlength = element.attr("minlength"); + return `Enter a venue name longer than ${minlength} characters`; + } + }, + // Address Tab +]; + +$(document).ready(function() { + // $("#newVenueAddressTab input").each(function() { //debuging remove later + // $(this).addClass("is-valid"); + // }); +}); + +$("#newVenueAddressTabBtn").on("shown.bs.tab", function() { + + if (!map) { + var tileLayer = L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', { + attribution: false, + }) + + map = L.map("locationMap", { + center: originalMapCoords, + zoom:8, + layers: [tileLayer] + }); + } + + venueCoords = { + lat: $("#venueLatitude").val(), + lng: $("#venueLongitude").val() + }; + if (venueCoords.lat && venueCoords.lng) { + map.setView(new L.LatLng(venueCoords.lat, venueCoords.lng), 15); + marker = L.marker(venueCoords).addTo(map); + } + + map.on('click', function (e) { + if (isGeocodingInProgress) { + return; + } + + toggleLoadingMap(true); + var coordinates = e.latlng; + + // Create a point feature from the clicked coordinates + var clickedPoint = turf.point([coordinates.lng, coordinates.lat]); + + // Define the UK boundary polygon coordinates (simplified for illustration) + var ukBoundary = turf.polygon([ + [ + [-8.647, 59.688], // Northwest corner + [-8.647, 49.784], // Southwest corner + [1.768, 49.784], // Southeast corner + [1.768, 59.688], // Northeast corner + [-8.647, 59.688] // Close the polygon + ] + ]); + + if (marker) { + map.removeLayer(marker); + } + + marker = L.marker(coordinates).addTo(map); + var isInsideUK = turf.booleanPointInPolygon(clickedPoint, ukBoundary); + + if (!isInsideUK) { + alert("Please select a point within the UK"); + map.removeLayer(marker); + toggleLoadingMap(false); + return false; + } + + fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${coordinates.lat}&lon=${coordinates.lng}`) + .then(response => response.json()) + .then(data => { + data.address; // check promise first + + toggleLoadingMap(false); + $("#venueStreetAddress").val(data.address.road || ''); + $("#venueCity").val(data.address.village || data.address.town || data.address.city); + $("#venueProvence").val(data.address.county || data.address.state_district); + $("#venuePostCode").val(data.address.postcode || ''); + $("#venueCountry").val(data.address.country || ''); + $("#venueLatitude").val(coordinates.lat); + $("#venueLongitude").val(coordinates.lng); + }); + }); + + setTimeout(function() {map.invalidateSize(false)}, 200) +}); + +function toggleLoadingMap(isLoading) { + isGeocodingInProgress = isLoading; + $("#saveVenue").prop("disabled", isLoading); + $("#venueStreetAddress").prop("disabled", isLoading) + $("#venueCity").prop("disabled", isLoading) + $("#venueProvence").prop("disabled", isLoading) + $("#venuePostCode").prop("disabled", isLoading) + $("#venueCountry").prop("disabled", isLoading) + if (isLoading) { + $("#locationMapOverlay").show(); + } + else { + $("#locationMapOverlay").hide(); + } +} + +$("#venueModal").on("hidden.bs.modal", function() { + // Reset the map if we are done + if (map) { + map.setView(originalMapCoords, 8); + + if (marker) { + map.removeLayer(marker); + } + } +}); function openVenueModal(venue_id) { $("#venueModal").data("venue-id", venue_id); + const detailsTab = new bootstrap.Tab("#newVenueDetailsTabBtn"); + detailsTab.show(); // back to the first tab if (venue_id == -1) { @@ -24,13 +144,15 @@ function openVenueModal(venue_id) { $("#venueName").val(""); $("#venueDescription").val(""); - $("#venueType").val("FISHERY").change(); + $("#venueType").val("").change(); $("#venueStreetAddress").val(""); $("#venueCity").val(""); $("#venueProvence").val(""); - $("#venuePostCode").val("") - $("#venueCountry").val("") + $("#venuePostCode").val(""); + $("#venueCountry").val(""); + $("#venueLatitude").val(""); + $("#venueLongitude").val(""); $("#venuePhone").val(""); $("#venueEmail").val(""); @@ -60,6 +182,8 @@ function openVenueModal(venue_id) { $("#venueProvence").val(venue.provence); $("#venuePostCode").val(venue.postal_code); $("#venueCountry").val(venue.country); + $("#venueLatitude").val(venue.latitude); + $("#venueLongitude").val(venue.longitude); $("#venuePhone").val(venue.phone_number); $("#venueEmail").val(venue.email_address); @@ -78,6 +202,35 @@ function openVenueModal(venue_id) { new bootstrap.Modal("#venueModal").show(); } +$("#venueForm").on("submit", function(event) { + event.preventDefault(); + const valid = validateVenue(); + if (valid) saveVenue(); +}); + +function validateVenue() { + + // Reset the validation indicators and messages + $("#venueForm .form-control").removeClass("is-valid is-invalid"); + $("#venueForm .invalid-feedback").text(""); + + var valid = true; + + formControls.forEach(function(control) { + var element = $("#" + control.id); + if (!control.validation(element)) { + element.addClass("is-invalid"); + element.siblings(".invalid-feedback").text(control.errorMessage(element)); + valid = false; + } + else { + element.addClass("is-valid"); + } + }); + + return valid; +} + function saveVenue() { var data = { name: $("#venueName").val(), @@ -90,6 +243,8 @@ function saveVenue() { provence: $("#venueProvence").val(), postal_code: $("#venuePostCode").val(), country: $("#venueCountry").val(), + longitude: $("#venueLongitude").val(), + latitude: $("#venueLatitude").val(), phone_number: $("#venuePhone").val(), email_address: $("#venueEmail").val(), @@ -111,7 +266,7 @@ function saveVenue() { dataType: 'json', data: data, success: function(response) { - alert("created, reload page please"); + window.location.reload(); }, error: function(error) { alert("error: " + JSON.stringify(error));