mirror of
https://github.com/Freika/dawarich.git
synced 2026-05-07 21:19:23 -05:00
Imlement visits deletion API
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
|
||||
|
||||
import "@rails/ujs"
|
||||
import "@rails/actioncable"
|
||||
import "controllers"
|
||||
import "@hotwired/turbo-rails"
|
||||
|
||||
@@ -72,22 +72,21 @@ export default class extends Controller {
|
||||
// Create the Add Visit control
|
||||
const AddVisitControl = L.Control.extend({
|
||||
onAdd: (map) => {
|
||||
const button = L.DomUtil.create('button', 'add-visit-button');
|
||||
button.innerHTML = '📍 Add a Visit';
|
||||
button.title = 'Click to add a visit to the map';
|
||||
const button = L.DomUtil.create('button', 'leaflet-control-button add-visit-button');
|
||||
button.innerHTML = '➕';
|
||||
button.title = 'Add a visit';
|
||||
|
||||
// Style the button
|
||||
button.style.backgroundColor = 'white';
|
||||
button.style.padding = '8px 12px';
|
||||
button.style.border = '2px solid #ccc';
|
||||
button.style.borderRadius = '4px';
|
||||
// Style the button to match other map controls
|
||||
button.style.width = '48px';
|
||||
button.style.height = '48px';
|
||||
button.style.border = 'none';
|
||||
button.style.cursor = 'pointer';
|
||||
button.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)';
|
||||
button.style.fontSize = '14px';
|
||||
button.style.fontWeight = 'bold';
|
||||
button.style.marginBottom = '5px';
|
||||
button.style.display = 'block';
|
||||
button.style.width = '100%';
|
||||
button.style.backgroundColor = 'white';
|
||||
button.style.borderRadius = '4px';
|
||||
button.style.padding = '0';
|
||||
button.style.lineHeight = '48px';
|
||||
button.style.fontSize = '18px';
|
||||
button.style.textAlign = 'center';
|
||||
button.style.transition = 'all 0.2s ease';
|
||||
|
||||
@@ -135,10 +134,9 @@ export default class extends Controller {
|
||||
this.isAddingVisit = true;
|
||||
|
||||
// Update button style to show active state
|
||||
button.style.backgroundColor = '#007bff';
|
||||
button.style.backgroundColor = '#dc3545';
|
||||
button.style.color = 'white';
|
||||
button.style.borderColor = '#0056b3';
|
||||
button.innerHTML = '✕ Cancel';
|
||||
button.innerHTML = '✕';
|
||||
|
||||
// Change cursor to crosshair
|
||||
this.map.getContainer().style.cursor = 'crosshair';
|
||||
@@ -155,8 +153,7 @@ export default class extends Controller {
|
||||
// Reset button style
|
||||
button.style.backgroundColor = 'white';
|
||||
button.style.color = 'black';
|
||||
button.style.borderColor = '#ccc';
|
||||
button.innerHTML = '📍 Add Visit';
|
||||
button.innerHTML = '➕';
|
||||
|
||||
// Reset cursor
|
||||
this.map.getContainer().style.cursor = '';
|
||||
@@ -370,7 +367,7 @@ export default class extends Controller {
|
||||
|
||||
if (stimulusController && stimulusController.visitsManager) {
|
||||
console.log('Found maps controller with visits manager');
|
||||
|
||||
|
||||
// Clear existing visits and fetch fresh data
|
||||
if (stimulusController.visitsManager.visitCircles) {
|
||||
stimulusController.visitsManager.visitCircles.clearLayers();
|
||||
@@ -386,7 +383,7 @@ export default class extends Controller {
|
||||
}
|
||||
} else {
|
||||
console.log('Could not find maps controller or visits manager');
|
||||
|
||||
|
||||
// Fallback: Try to dispatch a custom event
|
||||
const refreshEvent = new CustomEvent('visits:refresh', { bubbles: true });
|
||||
mapsController.dispatchEvent(refreshEvent);
|
||||
@@ -414,7 +411,7 @@ export default class extends Controller {
|
||||
if (confirmedVisitsLayer && !map.hasLayer(confirmedVisitsLayer)) {
|
||||
console.log('Adding confirmed visits layer to map');
|
||||
map.addLayer(confirmedVisitsLayer);
|
||||
|
||||
|
||||
// Update the layer control checkbox to reflect the layer is now active
|
||||
this.updateLayerControlCheckbox('Confirmed Visits', true);
|
||||
}
|
||||
@@ -442,7 +439,7 @@ export default class extends Controller {
|
||||
if (label && label.textContent.trim() === layerName) {
|
||||
console.log(`Updating ${layerName} checkbox to ${isEnabled}`);
|
||||
input.checked = isEnabled;
|
||||
|
||||
|
||||
// Trigger change event to ensure proper state management
|
||||
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
}
|
||||
|
||||
@@ -1357,7 +1357,7 @@ export class VisitsManager {
|
||||
<label class="label">
|
||||
<span class="label-text text-sm font-medium">Location</span>
|
||||
</label>
|
||||
<select class="select select-bordered select-sm w-full bg-base-200 text-base-content" name="place">
|
||||
<select class="select select-bordered select-sm text-xs w-full bg-base-200 text-base-content" name="place">
|
||||
${possiblePlaces.length > 0 ? possiblePlaces.map(place => `
|
||||
<option value="${place.id}" ${place.id === visit.place.id ? 'selected' : ''}>
|
||||
${place.name}
|
||||
@@ -1391,6 +1391,14 @@ export class VisitsManager {
|
||||
</button>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button type="button" class="btn btn-sm btn-outline btn-error w-full delete-visit" data-id="${visit.id}">
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
|
||||
</svg>
|
||||
Delete Visit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
@@ -1507,9 +1515,11 @@ export class VisitsManager {
|
||||
// Add event listeners for confirm and decline buttons
|
||||
const confirmBtn = form.querySelector('.confirm-visit');
|
||||
const declineBtn = form.querySelector('.decline-visit');
|
||||
const deleteBtn = form.querySelector('.delete-visit');
|
||||
|
||||
confirmBtn?.addEventListener('click', (event) => this.handleStatusChange(event, visit.id, 'confirmed'));
|
||||
declineBtn?.addEventListener('click', (event) => this.handleStatusChange(event, visit.id, 'declined'));
|
||||
deleteBtn?.addEventListener('click', (event) => this.handleDeleteVisit(event, visit.id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1551,6 +1561,51 @@ export class VisitsManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles deletion of a visit with confirmation
|
||||
* @param {Event} event - The click event
|
||||
* @param {string} visitId - The visit ID to delete
|
||||
*/
|
||||
async handleDeleteVisit(event, visitId) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
// Show confirmation dialog
|
||||
const confirmDelete = confirm('Are you sure you want to delete this visit? This action cannot be undone.');
|
||||
|
||||
if (!confirmDelete) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/v1/visits/${visitId}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.apiKey}`,
|
||||
}
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// Close the popup
|
||||
if (this.currentPopup) {
|
||||
this.map.closePopup(this.currentPopup);
|
||||
this.currentPopup = null;
|
||||
}
|
||||
|
||||
// Refresh the visits list
|
||||
this.fetchAndDisplayVisits();
|
||||
showFlashMessage('notice', 'Visit deleted successfully');
|
||||
} else {
|
||||
const errorData = await response.json();
|
||||
const errorMessage = errorData.error || 'Failed to delete visit';
|
||||
showFlashMessage('error', errorMessage);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting visit:', error);
|
||||
showFlashMessage('error', 'Failed to delete visit');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates text to a specified length and adds ellipsis if needed
|
||||
* @param {string} text - The text to truncate
|
||||
|
||||
Reference in New Issue
Block a user