Merge branch 'fix/image-upload' into feat/image-upload
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import slug from 'slug'
|
||||
|
||||
// Configure slug to match Rails parameterize behavior
|
||||
slug.defaults.mode = 'rfc3986'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["name", "slug", "latitude", "longitude", "address", "mapLinksContainer", "geocodingSpinner", "getCurrentLocationBtn", "getCurrentLocationIcon", "getCurrentLocationText", "previewLocationBtn", "previewLocationIcon", "previewLocationText", "messagesContainer"]
|
||||
static targets = ["name", "slug", "latitude", "longitude", "address", "mapLinksContainer", "geocodingSpinner", "getCurrentLocationBtn", "getCurrentLocationIcon", "getCurrentLocationText", "previewLocationBtn", "previewLocationIcon", "previewLocationText", "messagesContainer", "venueName"]
|
||||
static values = {
|
||||
geocodeDelay: { type: Number, default: 1500 } // Delay before auto-geocoding
|
||||
}
|
||||
@@ -27,15 +30,65 @@ export default class extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// Generate slug from name
|
||||
// Generate slug from name, venue name, and city for better SEO
|
||||
generateSlug() {
|
||||
const name = this.nameTarget.value
|
||||
const venueName = this.hasVenueNameTarget ? this.venueNameTarget.value : ""
|
||||
const address = this.hasAddressTarget ? this.addressTarget.value : ""
|
||||
|
||||
this.slugTarget.value = slug(name)
|
||||
// Extract city from address
|
||||
const city = this.extractCity(address)
|
||||
|
||||
// Build SEO-friendly slug: name-venue-city
|
||||
let slugParts = []
|
||||
|
||||
if (name) slugParts.push(name)
|
||||
if (venueName) slugParts.push(venueName)
|
||||
if (city) slugParts.push(city)
|
||||
|
||||
let slugValue = slugParts.join('-')
|
||||
|
||||
// If no slug parts, generate a fallback slug
|
||||
if (!slugValue) {
|
||||
slugValue = `event-${Date.now()}`
|
||||
}
|
||||
|
||||
// Generate slug with proper character handling (matches Rails parameterize)
|
||||
this.slugTarget.value = slug(slugValue, { lower: true })
|
||||
}
|
||||
|
||||
// Extract city from address
|
||||
extractCity(address) {
|
||||
if (!address) return ""
|
||||
|
||||
// Look for French postal code pattern (5 digits) + city
|
||||
const match = address.match(/(\d{5})\s+([^,]+)/)
|
||||
if (match) {
|
||||
return match[2].trim()
|
||||
}
|
||||
|
||||
// Fallback: extract last part after comma (assume it's city)
|
||||
const parts = address.split(',')
|
||||
if (parts.length > 1) {
|
||||
return parts[parts.length - 1].trim()
|
||||
}
|
||||
|
||||
// Another fallback: look for common French city indicators
|
||||
const cityIndicators = ["Paris", "Lyon", "Marseille", "Toulouse", "Nice", "Nantes", "Strasbourg", "Montpellier", "Bordeaux", "Lille"]
|
||||
for (const city of cityIndicators) {
|
||||
if (address.toLowerCase().includes(city.toLowerCase())) {
|
||||
return city
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Handle address changes with debounced geocoding
|
||||
addressChanged() {
|
||||
// Regenerate slug when address changes
|
||||
this.generateSlug()
|
||||
|
||||
// Clear any existing timeout
|
||||
if (this.geocodeTimeout) {
|
||||
clearTimeout(this.geocodeTimeout)
|
||||
@@ -68,6 +121,11 @@ export default class extends Controller {
|
||||
}, this.geocodeDelayValue)
|
||||
}
|
||||
|
||||
// Handle venue name changes to regenerate slug
|
||||
venueNameChanged() {
|
||||
this.generateSlug()
|
||||
}
|
||||
|
||||
// Get user's current location and reverse geocode to address
|
||||
async getCurrentLocation() {
|
||||
if (!navigator.geolocation) {
|
||||
@@ -516,14 +574,16 @@ export default class extends Controller {
|
||||
showLocationSuccess(message) {
|
||||
this.hideAllLocationMessages()
|
||||
this.showMessage("location-success", message, "success")
|
||||
setTimeout(() => this.hideMessage("location-success"), 4000)
|
||||
// Keep notification visible indefinitely
|
||||
// setTimeout(() => this.hideMessage("location-success"), 4000)
|
||||
}
|
||||
|
||||
// Show error message
|
||||
showLocationError(message) {
|
||||
this.hideAllLocationMessages()
|
||||
this.showMessage("location-error", message, "error")
|
||||
setTimeout(() => this.hideMessage("location-error"), 6000)
|
||||
// Keep notification visible indefinitely
|
||||
// setTimeout(() => this.hideMessage("location-error"), 6000)
|
||||
}
|
||||
|
||||
// Show geocoding warning (less intrusive than error)
|
||||
@@ -531,7 +591,8 @@ export default class extends Controller {
|
||||
this.hideMessage("geocoding-warning")
|
||||
const message = "Les coordonnées n'ont pas pu être déterminées automatiquement. L'événement utilisera une localisation approximative."
|
||||
this.showMessage("geocoding-warning", message, "warning")
|
||||
setTimeout(() => this.hideMessage("geocoding-warning"), 8000)
|
||||
// Keep notification visible indefinitely
|
||||
// setTimeout(() => this.hideMessage("geocoding-warning"), 8000)
|
||||
}
|
||||
|
||||
// Show info about approximate location
|
||||
@@ -539,7 +600,8 @@ export default class extends Controller {
|
||||
this.hideMessage("approximate-location-info")
|
||||
const message = `Localisation approximative trouvée: ${foundLocation}`
|
||||
this.showMessage("approximate-location-info", message, "info")
|
||||
setTimeout(() => this.hideMessage("approximate-location-info"), 6000)
|
||||
// Keep notification visible indefinitely
|
||||
// setTimeout(() => this.hideMessage("approximate-location-info"), 6000)
|
||||
}
|
||||
|
||||
// Show geocoding success with location details
|
||||
@@ -547,7 +609,8 @@ export default class extends Controller {
|
||||
this.hideMessage("geocoding-success")
|
||||
const message = `${title}<br><small class="opacity-75">${location}</small>`
|
||||
this.showMessage("geocoding-success", message, "success")
|
||||
setTimeout(() => this.hideMessage("geocoding-success"), 5000)
|
||||
// Keep notification visible indefinitely
|
||||
// setTimeout(() => this.hideMessage("geocoding-success"), 5000)
|
||||
}
|
||||
|
||||
// Show geocoding progress with strategy info
|
||||
|
||||
Reference in New Issue
Block a user