|
@@ -1,15 +1,25 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="trip-search-form-container">
|
|
|
|
|
|
|
+ <div class="trip-search-form-container w-full">
|
|
|
<h3>Trouvez votre prochain voyage</h3>
|
|
<h3>Trouvez votre prochain voyage</h3>
|
|
|
<form @submit.prevent="handleSearch" class="search-form">
|
|
<form @submit.prevent="handleSearch" class="search-form">
|
|
|
<div class="form-row">
|
|
<div class="form-row">
|
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
|
<label for="departure">Ville de départ</label>
|
|
<label for="departure">Ville de départ</label>
|
|
|
- <input type="text" id="departure" v-model="searchCriteria.departure" placeholder="Ex: Abidjan" required />
|
|
|
|
|
|
|
+ <select id="departure" class="flex w-full" v-model="searchCriteria.departure" required>
|
|
|
|
|
+ <option value="" disabled>Sélectionner une ville</option>
|
|
|
|
|
+ <option v-for="city in cities" :key="city.name" :value="city.name">
|
|
|
|
|
+ {{ city.name }}
|
|
|
|
|
+ </option>
|
|
|
|
|
+ </select>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="form-group">
|
|
<div class="form-group">
|
|
|
<label for="arrival">Ville d'arrivée</label>
|
|
<label for="arrival">Ville d'arrivée</label>
|
|
|
- <input type="text" id="arrival" v-model="searchCriteria.arrival" placeholder="Ex: Yamoussoukro" required />
|
|
|
|
|
|
|
+ <select id="arrival" class="flex w-full" v-model="searchCriteria.arrival" required>
|
|
|
|
|
+ <option value="" disabled>Sélectionner une ville</option>
|
|
|
|
|
+ <option v-for="city in cities" :key="city.name" :value="city.name">
|
|
|
|
|
+ {{ city.name }}
|
|
|
|
|
+ </option>
|
|
|
|
|
+ </select>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -39,7 +49,15 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { ref } from 'vue';
|
|
|
|
|
|
|
+import { ref, onMounted } from 'vue';
|
|
|
|
|
+
|
|
|
|
|
+interface City {
|
|
|
|
|
+ name: string;
|
|
|
|
|
+ // Vous pouvez ajouter d'autres propriétés ici si elles existent dans votre JSON
|
|
|
|
|
+ // par exemple: id: number;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const cities = ref<City[]>([]);
|
|
|
|
|
|
|
|
const searchCriteria = ref({
|
|
const searchCriteria = ref({
|
|
|
departure: '',
|
|
departure: '',
|
|
@@ -55,6 +73,24 @@ const handleSearch = () => {
|
|
|
// Valider les données ici si nécessaire avant d'émettre
|
|
// Valider les données ici si nécessaire avant d'émettre
|
|
|
emit('search-trips', { ...searchCriteria.value });
|
|
emit('search-trips', { ...searchCriteria.value });
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // Assurez-vous que civ.cities.json est dans le dossier public/datas/
|
|
|
|
|
+ const response = await fetch('/datas/civ.cities.json');
|
|
|
|
|
+ if (!response.ok) {
|
|
|
|
|
+ throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ const data = await response.json();
|
|
|
|
|
+ // Si votre JSON est un tableau d'objets ayant une propriété "name"
|
|
|
|
|
+ // Si la structure est [{"nom": "Abidjan"}, ...] utilisez data.map(c => ({ name: c.nom }))
|
|
|
|
|
+ // Si c'est un tableau de chaînes ["Abidjan", ...], utilisez data.map(name => ({ name }))
|
|
|
|
|
+ cities.value = data;
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("Impossible de charger les villes:", error);
|
|
|
|
|
+ // Gérer l'erreur, par exemple, afficher un message à l'utilisateur
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -63,7 +99,6 @@ const handleSearch = () => {
|
|
|
padding: 25px;
|
|
padding: 25px;
|
|
|
border-radius: 10px;
|
|
border-radius: 10px;
|
|
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
|
|
- max-width: 600px;
|
|
|
|
|
margin: 20px auto;
|
|
margin: 20px auto;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -95,17 +130,20 @@ const handleSearch = () => {
|
|
|
|
|
|
|
|
.search-form input[type="text"],
|
|
.search-form input[type="text"],
|
|
|
.search-form input[type="date"],
|
|
.search-form input[type="date"],
|
|
|
-.search-form input[type="number"] {
|
|
|
|
|
|
|
+.search-form input[type="number"],
|
|
|
|
|
+.search-form select { /* Ajout de select ici */
|
|
|
padding: 10px;
|
|
padding: 10px;
|
|
|
border: 1px solid #ddd;
|
|
border: 1px solid #ddd;
|
|
|
border-radius: 5px;
|
|
border-radius: 5px;
|
|
|
font-size: 1em;
|
|
font-size: 1em;
|
|
|
transition: border-color 0.3s;
|
|
transition: border-color 0.3s;
|
|
|
|
|
+ background-color: white; /* Assurer un fond blanc pour les select */
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.search-form input[type="text"]:focus,
|
|
.search-form input[type="text"]:focus,
|
|
|
.search-form input[type="date"]:focus,
|
|
.search-form input[type="date"]:focus,
|
|
|
-.search-form input[type="number"]:focus {
|
|
|
|
|
|
|
+.search-form input[type="number"]:focus,
|
|
|
|
|
+.search-form select:focus { /* Ajout de select:focus ici */
|
|
|
border-color: #4b8ef1;
|
|
border-color: #4b8ef1;
|
|
|
outline: none;
|
|
outline: none;
|
|
|
}
|
|
}
|