|
|
@@ -74,7 +74,7 @@
|
|
|
<td class="py-3 px-4 border-b border-gray-200 text-gray-600 w-15">
|
|
|
<div class="driver-photo w-10 h-10 rounded-full bg-gray-100" :style="{ backgroundImage: `url(${driver.photo || '/assets/images/default-avatar.png'})` }"></div>
|
|
|
</td>
|
|
|
- <td class="py-3 px-4 border-b border-gray-200 text-gray-600">{{ driver.firstName }} {{ driver.lastName }}</td>
|
|
|
+ <td class="py-3 px-4 border-b border-gray-200 text-gray-600">{{ driver.name }} {{ driver.ortherName }}</td>
|
|
|
<td class="py-3 px-4 border-b border-gray-200 text-gray-600">{{ driver.phone }}</td>
|
|
|
<td class="py-3 px-4 border-b border-gray-200 text-gray-600">{{ getCompanyName(driver.companyId) }}</td>
|
|
|
<td class="py-3 px-4 border-b border-gray-200 text-gray-600">{{ driver.licenseNumber }}</td>
|
|
|
@@ -122,11 +122,11 @@
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
|
<div>
|
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Prénom *</label>
|
|
|
- <input type="text" v-model="formData.firstName" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
+ <input type="text" v-model="formData.name" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
</div>
|
|
|
<div>
|
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Nom *</label>
|
|
|
- <input type="text" v-model="formData.lastName" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
+ <input type="text" v-model="formData.ortherName" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
|
@@ -192,11 +192,11 @@
|
|
|
<div class="w-32 h-32 rounded-full bg-gray-100 bg-cover bg-center" :style="{ backgroundImage: `url(${viewingDriver.photo || '/assets/images/default-avatar.png'})` }"></div>
|
|
|
</div>
|
|
|
<div class="flex-1">
|
|
|
- <h3 class="text-xl font-semibold text-gray-800 mb-4">{{ viewingDriver.firstName }} {{ viewingDriver.lastName }}</h3>
|
|
|
+ <h3 class="text-xl font-semibold text-gray-800 mb-4">{{ viewingDriver.name }} {{ viewingDriver.ortherName }}</h3>
|
|
|
<div class="space-y-3">
|
|
|
<div class="flex">
|
|
|
<span class="w-32 text-sm font-medium text-gray-600">Téléphone:</span>
|
|
|
- <span class="text-sm text-gray-800">{{ viewingDriver.phone }}</span>
|
|
|
+ <span class="text-sm text-gray-800">{{ viewingDriver.telephone }}</span>
|
|
|
</div>
|
|
|
<div class="flex">
|
|
|
<span class="w-32 text-sm font-medium text-gray-600">Email:</span>
|
|
|
@@ -245,7 +245,7 @@
|
|
|
</button>
|
|
|
</div>
|
|
|
<div class="p-5">
|
|
|
- <p class="text-gray-600 mb-2">Êtes-vous sûr de vouloir supprimer le chauffeur <strong class="text-gray-800">{{ driverToDelete?.firstName }} {{ driverToDelete?.lastName }}</strong> ?</p>
|
|
|
+ <p class="text-gray-600 mb-2">Êtes-vous sûr de vouloir supprimer le chauffeur <strong class="text-gray-800">{{ driverToDelete?.name }} {{ driverToDelete?.ortherName }}</strong> ?</p>
|
|
|
<p class="text-red-600 text-sm">Cette action est irréversible.</p>
|
|
|
</div>
|
|
|
<div class="py-4 px-5 border-t border-gray-200 flex justify-end gap-2.5">
|
|
|
@@ -264,35 +264,19 @@ import { ref, computed, onMounted } from 'vue'
|
|
|
import Sidebar from '@/components/Sidebar.vue'
|
|
|
import TopBar from '@/components/TopBar.vue'
|
|
|
import { useUserStore } from '@/stores/useUserStore'
|
|
|
+import { useDriverStore } from '@/stores/useDriverStore'
|
|
|
import { useToast } from '@/composables/useToast'
|
|
|
+import type { Driver, Company } from '@/types'
|
|
|
+import { useCompanies } from '@/composables/useCompanies'
|
|
|
|
|
|
-interface Company {
|
|
|
- id: number
|
|
|
- name: string
|
|
|
-}
|
|
|
-
|
|
|
-interface Driver {
|
|
|
- id: number
|
|
|
- firstName: string
|
|
|
- lastName: string
|
|
|
- phone: string
|
|
|
- email?: string
|
|
|
- address?: string
|
|
|
- companyId: number
|
|
|
- licenseNumber: string
|
|
|
- photo?: string
|
|
|
- notes?: string
|
|
|
- active: boolean
|
|
|
-}
|
|
|
-
|
|
|
-const drivers = ref<Driver[]>([])
|
|
|
-const companies = ref<Company[]>([])
|
|
|
+const driverStore = useDriverStore()
|
|
|
+const { companies, loadCompanies, canAccessCompanies } = useCompanies()
|
|
|
const showAddForm = ref(false)
|
|
|
|
|
|
// Toast notifications
|
|
|
const { success, error } = useToast()
|
|
|
const editingDriver = ref<Driver | null>(null)
|
|
|
-const viewingDriver = ref<Driver | null>(null)
|
|
|
+const viewingDriver = ref<any | null>(null)
|
|
|
const showDeleteConfirm = ref(false)
|
|
|
const driverToDelete = ref<Driver | null>(null)
|
|
|
const searchQuery = ref('')
|
|
|
@@ -300,12 +284,13 @@ const companyFilter = ref('')
|
|
|
const statusFilter = ref('')
|
|
|
|
|
|
const formData = ref({
|
|
|
- firstName: '',
|
|
|
- lastName: '',
|
|
|
+ name: '',
|
|
|
+ ortherName: '',
|
|
|
phone: '',
|
|
|
email: '',
|
|
|
address: '',
|
|
|
companyId: 0,
|
|
|
+ userId: null,
|
|
|
licenseNumber: '',
|
|
|
photo: '',
|
|
|
notes: '',
|
|
|
@@ -333,22 +318,22 @@ const handleUserMenu = () => {
|
|
|
// Implémentez votre logique d'affichage du menu utilisateur ici
|
|
|
}
|
|
|
const isFormValid = computed(() => {
|
|
|
- return formData.value.firstName &&
|
|
|
- formData.value.lastName &&
|
|
|
+ return formData.value.name &&
|
|
|
+ formData.value.ortherName &&
|
|
|
formData.value.phone &&
|
|
|
formData.value.companyId &&
|
|
|
formData.value.licenseNumber
|
|
|
})
|
|
|
|
|
|
const filteredDrivers = computed(() => {
|
|
|
- return drivers.value.filter(driver => {
|
|
|
+ return driverStore.drivers.filter(driver => {
|
|
|
// Filtre de recherche
|
|
|
const searchLower = searchQuery.value.toLowerCase()
|
|
|
- const nameMatch = `${driver.firstName} ${driver.lastName}`.toLowerCase().includes(searchLower)
|
|
|
- const phoneMatch = driver.phone.toLowerCase().includes(searchLower)
|
|
|
- const licenseMatch = driver.licenseNumber.toLowerCase().includes(searchLower)
|
|
|
+ const nameMatch = `${driver.name}`.toLowerCase().includes(searchLower)
|
|
|
+ const phoneMatch = driver.telephone.toLowerCase().includes(searchLower)
|
|
|
+ //const licenseMatch = driver.licenseNumber.toLowerCase().includes(searchLower)
|
|
|
|
|
|
- if (searchQuery.value && !nameMatch && !phoneMatch && !licenseMatch) {
|
|
|
+ if (searchQuery.value && !nameMatch && !phoneMatch /*&& !licenseMatch*/) {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
@@ -358,12 +343,12 @@ const filteredDrivers = computed(() => {
|
|
|
}
|
|
|
|
|
|
// Filtre par statut
|
|
|
- if (statusFilter.value === 'active' && !driver.active) {
|
|
|
- return false
|
|
|
- }
|
|
|
- if (statusFilter.value === 'inactive' && driver.active) {
|
|
|
- return false
|
|
|
- }
|
|
|
+ // if (statusFilter.value === 'active' && !driver.active) {
|
|
|
+ // return false
|
|
|
+ // }
|
|
|
+ // if (statusFilter.value === 'inactive' && driver.active) {
|
|
|
+ // return false
|
|
|
+ // }
|
|
|
|
|
|
return true
|
|
|
})
|
|
|
@@ -398,21 +383,18 @@ const deleteDriver = async () => {
|
|
|
if (!driverToDelete.value) return
|
|
|
|
|
|
try {
|
|
|
- // Simuler une requête API
|
|
|
- // Dans un environnement réel, vous feriez un appel API ici
|
|
|
- // await fetch(`http://localhost:3001/api/drivers/${driverToDelete.value.id}`, {
|
|
|
- // method: 'DELETE'
|
|
|
- // })
|
|
|
-
|
|
|
- // Supprimer le chauffeur de la liste locale
|
|
|
- drivers.value = drivers.value.filter(d => d.id !== driverToDelete.value?.id)
|
|
|
-
|
|
|
- // Fermer la modal de confirmation
|
|
|
- showDeleteConfirm.value = false
|
|
|
- driverToDelete.value = null
|
|
|
+ const result = await driverStore.deleteDriver(driverToDelete.value.id)
|
|
|
|
|
|
- // Afficher une notification de succès
|
|
|
- success('Chauffeur supprimé avec succès')
|
|
|
+ if (result.success) {
|
|
|
+ // Fermer la modal de confirmation
|
|
|
+ showDeleteConfirm.value = false
|
|
|
+ driverToDelete.value = null
|
|
|
+
|
|
|
+ // Afficher une notification de succès
|
|
|
+ success('Chauffeur supprimé avec succès')
|
|
|
+ } else {
|
|
|
+ error(result.message || 'Erreur lors de la suppression du chauffeur')
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
console.error('Erreur lors de la suppression:', error)
|
|
|
error('Erreur lors de la suppression du chauffeur')
|
|
|
@@ -429,8 +411,8 @@ const closeForm = () => {
|
|
|
// Réinitialiser le formulaire
|
|
|
const resetForm = () => {
|
|
|
formData.value = {
|
|
|
- firstName: '',
|
|
|
- lastName: '',
|
|
|
+ name: '',
|
|
|
+ ortherName: '',
|
|
|
phone: '',
|
|
|
email: '',
|
|
|
address: '',
|
|
|
@@ -447,52 +429,35 @@ const saveDriver = async () => {
|
|
|
if (!isFormValid.value) return
|
|
|
|
|
|
try {
|
|
|
+ let result
|
|
|
+
|
|
|
if (editingDriver.value) {
|
|
|
- // Mise à jour d'un chauffeur existant
|
|
|
- // Dans un environnement réel, vous feriez un appel API ici
|
|
|
- // await fetch(`http://localhost:3001/api/drivers/${editingDriver.value.id}`, {
|
|
|
- // method: 'PUT',
|
|
|
- // headers: {
|
|
|
- // 'Content-Type': 'application/json'
|
|
|
- // },
|
|
|
- // body: JSON.stringify(formData.value)
|
|
|
- // })
|
|
|
+ // Modification d'un chauffeur existant
|
|
|
+ result = await driverStore.updateDriver(editingDriver.value.id, formData.value)
|
|
|
|
|
|
- // Mettre à jour le chauffeur dans la liste locale
|
|
|
- const index = drivers.value.findIndex(d => d.id === editingDriver.value?.id)
|
|
|
- if (index !== -1) {
|
|
|
- drivers.value[index] = {
|
|
|
- ...drivers.value[index],
|
|
|
- ...formData.value,
|
|
|
- id: editingDriver.value.id
|
|
|
- }
|
|
|
+ if (result.success) {
|
|
|
+ success('Chauffeur modifié avec succès')
|
|
|
+ } else {
|
|
|
+ error(result.message || 'Erreur lors de la modification du chauffeur')
|
|
|
+ return
|
|
|
}
|
|
|
-
|
|
|
- // Afficher une notification de succès
|
|
|
- success('Chauffeur mis à jour avec succès')
|
|
|
} else {
|
|
|
// Ajout d'un nouveau chauffeur
|
|
|
- // Dans un environnement réel, vous feriez un appel API ici
|
|
|
- // const response = await fetch('http://localhost:3001/api/drivers', {
|
|
|
- // method: 'POST',
|
|
|
- // headers: {
|
|
|
- // 'Content-Type': 'application/json'
|
|
|
- // },
|
|
|
- // body: JSON.stringify(formData.value)
|
|
|
- // })
|
|
|
- // const data = await response.json()
|
|
|
+ const formatterDataToBlack = {
|
|
|
+ name: formData.value.name + ' ' + formData.value.ortherName ,
|
|
|
+ telephone: formData.value.phone,
|
|
|
+ address: formData.value.address,
|
|
|
+ companyId: formData.value.companyId,
|
|
|
+ userId: formData.value.userId,
|
|
|
+ } as Driver
|
|
|
+ result = await driverStore.createDriver(formatterDataToBlack)
|
|
|
|
|
|
- // Simuler l'ajout d'un nouveau chauffeur avec un ID généré
|
|
|
- const newDriver: Driver = {
|
|
|
- ...formData.value,
|
|
|
- id: Math.max(0, ...drivers.value.map(d => d.id)) + 1
|
|
|
+ if (result.success) {
|
|
|
+ success('Chauffeur ajouté avec succès')
|
|
|
+ } else {
|
|
|
+ error(result.message || 'Erreur lors de l\'ajout du chauffeur')
|
|
|
+ return
|
|
|
}
|
|
|
-
|
|
|
- // Ajouter le chauffeur à la liste locale
|
|
|
- drivers.value.push(newDriver)
|
|
|
-
|
|
|
- // Afficher une notification de succès
|
|
|
- success('Chauffeur ajouté avec succès')
|
|
|
}
|
|
|
|
|
|
// Fermer le formulaire
|
|
|
@@ -505,71 +470,14 @@ const saveDriver = async () => {
|
|
|
|
|
|
// Charger les données
|
|
|
onMounted(async () => {
|
|
|
- // Simuler le chargement des entreprises
|
|
|
- companies.value = [
|
|
|
- { id: 1, name: 'Transport Express' },
|
|
|
- { id: 2, name: 'Voyages Confort' },
|
|
|
- { id: 3, name: 'Trans-Afrique' }
|
|
|
- ]
|
|
|
-
|
|
|
- // Simuler le chargement des chauffeurs
|
|
|
- setTimeout(() => {
|
|
|
- drivers.value = [
|
|
|
- {
|
|
|
- id: 1,
|
|
|
- firstName: 'Jean',
|
|
|
- lastName: 'Dupont',
|
|
|
- phone: '+33 6 12 34 56 78',
|
|
|
- email: 'jean.dupont@example.com',
|
|
|
- address: '123 Rue de Paris, 75001 Paris',
|
|
|
- companyId: 1,
|
|
|
- licenseNumber: 'DRV-12345',
|
|
|
- photo: 'https://randomuser.me/api/portraits/men/1.jpg',
|
|
|
- notes: 'Chauffeur expérimenté, plus de 10 ans d\'expérience',
|
|
|
- active: true
|
|
|
- },
|
|
|
- {
|
|
|
- id: 2,
|
|
|
- firstName: 'Marie',
|
|
|
- lastName: 'Laurent',
|
|
|
- phone: '+33 6 23 45 67 89',
|
|
|
- email: 'marie.laurent@example.com',
|
|
|
- companyId: 1,
|
|
|
- licenseNumber: 'DRV-23456',
|
|
|
- photo: 'https://randomuser.me/api/portraits/women/1.jpg',
|
|
|
- active: true
|
|
|
- },
|
|
|
- {
|
|
|
- id: 3,
|
|
|
- firstName: 'Ahmed',
|
|
|
- lastName: 'Bamba',
|
|
|
- phone: '+33 6 34 56 78 90',
|
|
|
- companyId: 2,
|
|
|
- licenseNumber: 'DRV-34567',
|
|
|
- active: true
|
|
|
- },
|
|
|
- {
|
|
|
- id: 4,
|
|
|
- firstName: 'Sophie',
|
|
|
- lastName: 'Martin',
|
|
|
- phone: '+33 6 45 67 89 01',
|
|
|
- email: 'sophie.martin@example.com',
|
|
|
- companyId: 3,
|
|
|
- licenseNumber: 'DRV-45678',
|
|
|
- photo: 'https://randomuser.me/api/portraits/women/2.jpg',
|
|
|
- active: false
|
|
|
- },
|
|
|
- {
|
|
|
- id: 5,
|
|
|
- firstName: 'Pierre',
|
|
|
- lastName: 'Dubois',
|
|
|
- phone: '+33 6 56 78 90 12',
|
|
|
- companyId: 2,
|
|
|
- licenseNumber: 'DRV-56789',
|
|
|
- active: false
|
|
|
- }
|
|
|
- ]
|
|
|
- }, 500) // Simuler un délai de chargement
|
|
|
+ try {
|
|
|
+ // Charger les chauffeurs via le store
|
|
|
+ await driverStore.fetchDrivers()
|
|
|
+ // Charger les entreprises
|
|
|
+ await loadCompanies()
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Erreur lors du chargement des données:', error)
|
|
|
+ }
|
|
|
})
|
|
|
</script>
|
|
|
|