Rev 36668 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<section class="wrapper"><div class="row"><div class="col-lg-12"><h3 class="page-header"><i class="icon_pin_alt"></i> Auth User Base Location</h3><ol class="breadcrumb"><li><i class="fa fa-home"></i><a href="${rc.contextPath}/dashboard">Home</a></li><li><i class="icon_group"></i> Partner Acquisition</li><li><i class="icon_pin_alt"></i> Base Location</li></ol></div></div><div class="row" style="margin-bottom:10px;"><div class="col-lg-12" style="display:flex; gap:10px; align-items:center; flex-wrap:wrap;"><select id="blCategory" class="form-control input-sm" style="width:140px;"><option value="4">Sales</option><option value="20">BGC</option></select><select id="blLevel" class="form-control input-sm" style="width:140px;"><option value="">Level</option>#foreach($e in $escalationTypes)<option value="$e">$e</option>#end</select><select id="blAuthUser" class="form-control input-sm" style="width:240px;"><option value="">Select User</option></select><span id="blCurrent" style="color:#777; font-size:12px; margin-left:8px;"></span></div></div><div class="row"><div class="col-lg-12" style="margin-bottom:10px;"><input id="blSearch" type="text" class="form-control input-sm"placeholder="Search a place..." style="width:60%; display:inline-block;"autocomplete="off"><span style="font-size:11px; color:#888; margin-left:8px;">or click on the map to drop a pin</span></div></div><div class="row"><div class="col-lg-8"><div id="blMap" style="width:100%; height:520px; border-radius:8px; background:#eee;"></div></div><div class="col-lg-4"><div style="padding:10px; background:#f8f9fa; border-radius:6px; margin-bottom:12px;"><div style="font-weight:600; font-size:13px; margin-bottom:6px;">Add new base location</div><div style="font-size:12px; color:#555;">Selected:</div><div id="blPicked" style="font-weight:600; margin-top:4px;">-</div><div id="blPickedCoords" style="font-size:11px; color:#888; margin-top:4px;"></div><label style="display:block; margin-top:10px; font-size:12px; font-weight:normal;"><input type="checkbox" id="blMakeDefault"> Mark as default location</label><button id="blSave" class="btn btn-primary btn-sm" style="width:100%; margin-top:10px;" disabled>Save Location</button><div id="blMsg" style="margin-top:10px; font-size:12px;"></div></div><div style="background:#fff; border:1px solid #e5e5e5; border-radius:6px;"><div style="padding:8px 12px; font-weight:600; font-size:13px; border-bottom:1px solid #eee; background:#f5f5f5;">Saved locations</div><div id="blList" style="max-height:400px; overflow-y:auto;"><div style="padding:14px; color:#999; font-size:12px; text-align:center;">Select a user to see their base locations</div></div></div></div></div></section><script>function blEnsureMaps(cb) {if (typeof google !== 'undefined' && google.maps && google.maps.places) {cb();return;}var existing = document.getElementById('gmaps-api-loader');if (existing) {var t = setInterval(function () {if (typeof google !== 'undefined' && google.maps && google.maps.places) {clearInterval(t);cb();}}, 100);return;}var s = document.createElement('script');s.id = 'gmaps-api-loader';s.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyAckO0y4Z6WhBOuMjNjioWLSYZDhGEvGBc&libraries=places&v=weekly';s.async = true;s.onload = function () {cb();};document.head.appendChild(s);}blEnsureMaps(function () {var blMap, blAutocomplete;var blMarkers = {}; // id → google.maps.Marker for saved locationsvar pickMarker = null; // the draggable "new" pinvar picked = {lat: null, lng: null, name: '', address: ''};function readServerMsg(xhr, fallback) {try {var err = JSON.parse(xhr.responseText);if (err && err.response) {if (typeof err.response === 'string') return err.response;if (err.response.message) return err.response.message;}} catch (e) {}return fallback || 'Request failed';}function setPicked(lat, lng, name, address) {picked.lat = lat;picked.lng = lng;picked.name = name || '';picked.address = address || name || '';$('#blPicked').text(name || '(unnamed pin)');$('#blPickedCoords').text(lat.toFixed(6) + ', ' + lng.toFixed(6));$('#blSave').prop('disabled', !$('#blAuthUser').val());}function placePickMarker(lat, lng) {var pos = new google.maps.LatLng(lat, lng);if (!pickMarker) {pickMarker = new google.maps.Marker({map: blMap, position: pos, draggable: true,icon: {path: google.maps.SymbolPath.CIRCLE, scale: 10,fillColor: '#3b82f6', fillOpacity: 0.95, strokeColor: '#fff', strokeWeight: 2},zIndex: 9999});pickMarker.addListener('dragend', function (e) {setPicked(e.latLng.lat(), e.latLng.lng(), picked.name, picked.address);});} else {pickMarker.setPosition(pos);}blMap.panTo(pos);if (blMap.getZoom() < 12) blMap.setZoom(14);}function clearSavedMarkers() {Object.keys(blMarkers).forEach(function (id) {blMarkers[id].setMap(null);});blMarkers = {};}function addSavedMarker(loc) {var pos = new google.maps.LatLng(parseFloat(loc.latitude), parseFloat(loc.longitude));var m = new google.maps.Marker({map: blMap, position: pos,title: (loc.isDefault ? '[Default] ' : '') + (loc.locationName || ''),icon: {path: google.maps.SymbolPath.CIRCLE, scale: 8,fillColor: loc.isDefault ? '#16a34a' : '#94a3b8', fillOpacity: 0.95,strokeColor: '#fff', strokeWeight: 2}});blMarkers[loc.id] = m;}blMap = new google.maps.Map(document.getElementById('blMap'), {center: {lat: 22.0, lng: 79.0}, zoom: 5});blMap.addListener('click', function (e) {placePickMarker(e.latLng.lat(), e.latLng.lng());setPicked(e.latLng.lat(), e.latLng.lng(), 'Picked location', '');});blAutocomplete = new google.maps.places.Autocomplete(document.getElementById('blSearch'),{componentRestrictions: {country: 'in'}});blAutocomplete.addListener('place_changed', function () {var p = blAutocomplete.getPlace();if (!p.geometry) return;var lat = p.geometry.location.lat(), lng = p.geometry.location.lng();placePickMarker(lat, lng);setPicked(lat, lng, p.name || p.formatted_address || '', p.formatted_address || '');});$('#blLevel').off('change.bl').on('change.bl', function () {var level = $(this).val();$('#blAuthUser').html('<option value="">Select User</option>');$('#blCurrent').text('');$('#blSave').prop('disabled', true);renderList(null);if (!level) return;$.ajax({url: context + '/beatPlan/getAuthUsers',type: 'GET', dataType: 'json',data: {categoryId: $('#blCategory').val(), escalationType: level},success: function (r) {var data = r.response || r;var h = '<option value="">Select User</option>';if (data && data.length) {data.forEach(function (u) {h += '<option value="' + u.id + '">' + u.name + '</option>';});} else {h = '<option value="">No users at this level</option>';}$('#blAuthUser').html(h);},error: function () {$('#blAuthUser').html('<option value="">Error loading users</option>');}});});$('#blCategory').off('change.bl').on('change.bl', function () {$('#blLevel').val('').trigger('change.bl');});$('#blAuthUser').off('change.bl').on('change.bl', function () {var uid = $(this).val();$('#blCurrent').text('');$('#blSave').prop('disabled', true);if (pickMarker) {pickMarker.setMap(null);pickMarker = null;}picked = {lat: null, lng: null, name: '', address: ''};$('#blPicked').text('-');$('#blPickedCoords').text('');$('#blMakeDefault').prop('checked', false);if (!uid) {renderList(null);return;}loadList(uid);});function loadList(uid) {$.ajax({url: context + '/beatPlan/listBaseLocations',type: 'GET', dataType: 'json',data: {authUserId: uid},success: function (r) {var data = r.response || r;renderList(data.locations || []);},error: function () {renderList([]);}});}function renderList(locations) {clearSavedMarkers();if (locations === null) {$('#blList').html('<div style="padding:14px; color:#999; font-size:12px; text-align:center;">Select a user to see their base locations</div>');$('#blCurrent').text('');return;}if (locations.length === 0) {$('#blList').html('<div style="padding:14px; color:#999; font-size:12px; text-align:center;">No base locations yet. Pick on the map and Save.</div>');$('#blCurrent').html('<em>No base location set yet</em>');return;}var html = '';var defaultLoc = null;var bounds = new google.maps.LatLngBounds();locations.forEach(function (l) {addSavedMarker(l);bounds.extend(new google.maps.LatLng(parseFloat(l.latitude), parseFloat(l.longitude)));if (l.isDefault) defaultLoc = l;var safeName = (l.locationName || '').replace(/</g, '<');var badge = l.isDefault? '<span style="display:inline-block;background:#16a34a;color:#fff;font-size:10px;padding:1px 6px;border-radius:3px;margin-left:4px;">DEFAULT</span>': '';var actions = l.isDefault? '<button class="btn btn-default btn-xs bl-remove-btn" disabled title="Default location cannot be removed">Remove</button>': '<button class="btn btn-success btn-xs bl-set-default-btn" data-id="' + l.id + '">Set Default</button> '+ '<button class="btn btn-danger btn-xs bl-remove-btn" data-id="' + l.id + '">Remove</button>';html += '<div style="padding:10px 12px; border-bottom:1px solid #f0f0f0;">'+ '<div style="font-weight:600; font-size:13px;">' + safeName + badge + '</div>'+ '<div style="font-size:11px; color:#888; margin-top:2px;">' + l.latitude + ', ' + l.longitude + '</div>'+ '<div style="margin-top:6px;">' + actions + '</div>'+ '</div>';});$('#blList').html(html);if (defaultLoc) {$('#blCurrent').html('Default: <strong>' + defaultLoc.locationName + '</strong> ('+ defaultLoc.latitude + ', ' + defaultLoc.longitude + ')');} else {$('#blCurrent').html('<em>No default set (legacy)</em>');}if (locations.length === 1) {blMap.panTo(new google.maps.LatLng(parseFloat(locations[0].latitude), parseFloat(locations[0].longitude)));if (blMap.getZoom() < 12) blMap.setZoom(13);} else {blMap.fitBounds(bounds);}}$('#blSave').off('click.bl').on('click.bl', function () {var uid = $('#blAuthUser').val();if (!uid) {alert('Pick a user');return;}if (picked.lat == null) {alert('Pick a location on the map');return;}var btn = $(this);btn.prop('disabled', true).text('Saving...');$('#blMsg').text('');$.ajax({url: context + '/beatPlan/updateBaseLocation',type: 'POST',data: {authUserId: uid,locationName: picked.name || ('Location ' + picked.lat.toFixed(4) + ',' + picked.lng.toFixed(4)),latitude: String(picked.lat),longitude: String(picked.lng),address: picked.address,isDefault: $('#blMakeDefault').is(':checked')},success: function (r) {var d = r.response || r;$('#blMsg').html('<span style="color:#2e7d32;">' + (d.message || 'Saved.') + '</span>');btn.prop('disabled', false).text('Save Location');if (pickMarker) {pickMarker.setMap(null);pickMarker = null;}picked = {lat: null, lng: null, name: '', address: ''};$('#blPicked').text('-');$('#blPickedCoords').text('');$('#blMakeDefault').prop('checked', false);loadList(uid);},error: function (xhr) {var msg = readServerMsg(xhr, 'Save failed');if (xhr.status === 403 || xhr.status === 401) msg += ' (HTTP ' + xhr.status + ')';$('#blMsg').html('<span style="color:#c62828;">' + msg + '</span>');btn.prop('disabled', false).text('Save Location');}});});$(document).off('click.blset').on('click.blset', '.bl-set-default-btn', function () {var id = $(this).data('id');var uid = $('#blAuthUser').val();if (!confirm('Set this location as the default base location?')) return;$.ajax({url: context + '/beatPlan/setDefaultBaseLocation',type: 'POST',data: {id: id},success: function () {loadList(uid);},error: function (xhr) {alert(readServerMsg(xhr, 'Could not set default'));}});});$(document).off('click.blrm').on('click.blrm', '.bl-remove-btn', function () {if ($(this).prop('disabled')) return;var id = $(this).data('id');var uid = $('#blAuthUser').val();if (!confirm('Remove this base location? This cannot be undone.')) return;$.ajax({url: context + '/beatPlan/deleteBaseLocation',type: 'POST',data: {id: id},success: function () {loadList(uid);},error: function (xhr) {alert(readServerMsg(xhr, 'Could not remove'));}});});});</script>