feat: Implement the promoter event creation
Some checks failed
Ruby on Rails Test / rails-test (push) Failing after 1m50s
Some checks failed
Ruby on Rails Test / rails-test (push) Failing after 1m50s
- Promoter can now create an event in draft mode - Place is found based on address and long/lat are automatically deducted from it - Slug is forged using the *slug* npm package instead of custom code
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import slug from 'slug'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["name", "slug", "latitude", "longitude", "address", "mapLinksContainer"]
|
||||
static values = {
|
||||
static values = {
|
||||
geocodeDelay: { type: Number, default: 1500 } // Delay before auto-geocoding
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.geocodeTimeout = null
|
||||
|
||||
|
||||
// Initialize map links if we have an address and coordinates already exist
|
||||
if (this.hasAddressTarget && this.addressTarget.value.trim() &&
|
||||
this.hasLatitudeTarget && this.hasLongitudeTarget &&
|
||||
if (this.hasAddressTarget && this.addressTarget.value.trim() &&
|
||||
this.hasLatitudeTarget && this.hasLongitudeTarget &&
|
||||
this.latitudeTarget.value && this.longitudeTarget.value) {
|
||||
this.updateMapLinks()
|
||||
}
|
||||
@@ -26,14 +27,8 @@ export default class extends Controller {
|
||||
// Generate slug from name
|
||||
generateSlug() {
|
||||
const name = this.nameTarget.value
|
||||
const slug = name
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
|
||||
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
||||
.replace(/-+/g, '-') // Replace multiple hyphens with single
|
||||
.replace(/^-|-$/g, '') // Remove leading/trailing hyphens
|
||||
|
||||
this.slugTarget.value = slug
|
||||
|
||||
this.slugTarget.value = slug(name)
|
||||
}
|
||||
|
||||
// Handle address changes with debounced geocoding
|
||||
@@ -44,7 +39,7 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
const address = this.addressTarget.value.trim()
|
||||
|
||||
|
||||
if (!address) {
|
||||
this.clearCoordinates()
|
||||
this.clearMapLinks()
|
||||
@@ -76,27 +71,27 @@ export default class extends Controller {
|
||||
const position = await this.getCurrentPositionPromise(options)
|
||||
const lat = position.coords.latitude
|
||||
const lng = position.coords.longitude
|
||||
|
||||
|
||||
// Set coordinates first
|
||||
this.latitudeTarget.value = lat.toFixed(6)
|
||||
this.longitudeTarget.value = lng.toFixed(6)
|
||||
|
||||
|
||||
// Then reverse geocode to get address
|
||||
const address = await this.reverseGeocode(lat, lng)
|
||||
|
||||
|
||||
if (address) {
|
||||
this.addressTarget.value = address
|
||||
this.showLocationSuccess("Position actuelle détectée et adresse mise à jour!")
|
||||
} else {
|
||||
this.showLocationSuccess("Position actuelle détectée!")
|
||||
}
|
||||
|
||||
|
||||
this.updateMapLinks()
|
||||
|
||||
|
||||
} catch (error) {
|
||||
this.hideLocationLoading()
|
||||
let message = "Erreur lors de la récupération de la localisation."
|
||||
|
||||
|
||||
switch(error.code) {
|
||||
case error.PERMISSION_DENIED:
|
||||
message = "L'accès à la localisation a été refusé."
|
||||
@@ -108,7 +103,7 @@ export default class extends Controller {
|
||||
message = "La demande de localisation a expiré."
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
this.showLocationError(message)
|
||||
}
|
||||
}
|
||||
@@ -125,11 +120,11 @@ export default class extends Controller {
|
||||
try {
|
||||
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json`)
|
||||
const data = await response.json()
|
||||
|
||||
|
||||
if (data && data.display_name) {
|
||||
return data.display_name
|
||||
}
|
||||
|
||||
|
||||
return null
|
||||
} catch (error) {
|
||||
console.log("Reverse geocoding failed:", error)
|
||||
@@ -145,7 +140,7 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
// If we already have coordinates, just update map links
|
||||
if (this.hasLatitudeTarget && this.hasLongitudeTarget &&
|
||||
if (this.hasLatitudeTarget && this.hasLongitudeTarget &&
|
||||
this.latitudeTarget.value && this.longitudeTarget.value) {
|
||||
this.updateMapLinks()
|
||||
this.showLocationSuccess("Liens de carte mis à jour!")
|
||||
@@ -163,11 +158,11 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
const address = this.addressTarget.value.trim()
|
||||
|
||||
|
||||
try {
|
||||
this.showLocationLoading()
|
||||
const result = await this.performGeocode(address)
|
||||
|
||||
|
||||
if (result) {
|
||||
this.latitudeTarget.value = result.lat
|
||||
this.longitudeTarget.value = result.lng
|
||||
@@ -187,7 +182,7 @@ export default class extends Controller {
|
||||
async geocodeAddressQuiet(address) {
|
||||
try {
|
||||
const result = await this.performGeocode(address)
|
||||
|
||||
|
||||
if (result) {
|
||||
this.latitudeTarget.value = result.lat
|
||||
this.longitudeTarget.value = result.lng
|
||||
@@ -207,7 +202,7 @@ export default class extends Controller {
|
||||
const encodedAddress = encodeURIComponent(address)
|
||||
const response = await fetch(`https://nominatim.openstreetmap.org/search?q=${encodedAddress}&format=json&limit=1`)
|
||||
const data = await response.json()
|
||||
|
||||
|
||||
if (data && data.length > 0) {
|
||||
const result = data[0]
|
||||
return {
|
||||
@@ -215,7 +210,7 @@ export default class extends Controller {
|
||||
lng: parseFloat(result.lon).toFixed(6)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -226,7 +221,7 @@ export default class extends Controller {
|
||||
const lat = parseFloat(this.latitudeTarget.value)
|
||||
const lng = parseFloat(this.longitudeTarget.value)
|
||||
const address = this.hasAddressTarget ? this.addressTarget.value.trim() : ""
|
||||
|
||||
|
||||
if (isNaN(lat) || isNaN(lng) || !address) {
|
||||
this.clearMapLinks()
|
||||
return
|
||||
@@ -239,7 +234,7 @@ export default class extends Controller {
|
||||
// Generate map links HTML
|
||||
generateMapLinks(lat, lng, address) {
|
||||
const encodedAddress = encodeURIComponent(address)
|
||||
|
||||
|
||||
const providers = {
|
||||
openstreetmap: {
|
||||
name: "OpenStreetMap",
|
||||
@@ -247,7 +242,7 @@ export default class extends Controller {
|
||||
icon: "🗺️"
|
||||
},
|
||||
google: {
|
||||
name: "Google Maps",
|
||||
name: "Google Maps",
|
||||
url: `https://www.google.com/maps/search/${encodedAddress}/@${lat},${lng},16z`,
|
||||
icon: "🔍"
|
||||
},
|
||||
@@ -266,7 +261,7 @@ export default class extends Controller {
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${Object.entries(providers).map(([key, provider]) => `
|
||||
<a href="${provider.url}" target="_blank" rel="noopener"
|
||||
<a href="${provider.url}" target="_blank" rel="noopener"
|
||||
class="inline-flex items-center px-3 py-2 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">
|
||||
<span class="mr-2">${provider.icon}</span>
|
||||
${provider.name}
|
||||
@@ -327,7 +322,7 @@ export default class extends Controller {
|
||||
showMessage(id, message, type) {
|
||||
const colors = {
|
||||
info: "bg-blue-50 border-blue-200 text-blue-800",
|
||||
success: "bg-green-50 border-green-200 text-green-800",
|
||||
success: "bg-green-50 border-green-200 text-green-800",
|
||||
error: "bg-red-50 border-red-200 text-red-800",
|
||||
warning: "bg-yellow-50 border-yellow-200 text-yellow-800"
|
||||
}
|
||||
@@ -372,4 +367,4 @@ export default class extends Controller {
|
||||
this.hideMessage("location-error")
|
||||
this.hideMessage("geocoding-warning")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user