import { ref, computed } from 'vue'; import { Api } from '@api'; import type { DriverProfile, Vehicle, UserPreferences, DriverPublicProfile } from '../types/viaggi.types'; // ============================================================ // STATE // ============================================================ const driverProfile = ref(null); const myDriverProfile = ref(null); const myVehicles = ref([]); const myPreferences = ref(null); const loading = ref(false); const error = ref(null); // ============================================================ // COMPOSABLE // ============================================================ export function useDriverProfile() { // ------------------------------------------------------------ // COMPUTED // ------------------------------------------------------------ const isDriver = computed(() => myDriverProfile.value?.isDriver ?? false); const hasVehicles = computed(() => myVehicles.value.length > 0); const defaultVehicle = computed(() => myVehicles.value.find(v => v.isDefault) || myVehicles.value[0] ); const averageRating = computed(() => myDriverProfile.value?.averageRating ?? 0); const totalRides = computed(() => (myDriverProfile.value?.ridesCompletedAsDriver ?? 0) + (myDriverProfile.value?.ridesCompletedAsPassenger ?? 0) ); // ------------------------------------------------------------ // API CALLS // ------------------------------------------------------------ /** * Ottieni profilo pubblico di un conducente */ const fetchDriverProfile = async (userId: string) => { try { loading.value = true; error.value = null; const response = await Api.SendReqWithData( `/api/viaggi/driver/user/${userId}`, 'GET' ); if (response.success && response.data) { driverProfile.value = response.data; } return response; } catch (err: any) { error.value = err.message || 'Errore nel recupero del profilo'; throw err; } finally { loading.value = false; } }; /** * Aggiorna il mio profilo conducente e/o preferenze */ const updateDriverProfile = async (data: { driverProfile?: Partial; preferences?: Partial; }) => { try { loading.value = true; error.value = null; const response = await Api.SendReqWithData( '/api/viaggi/driver/profile', 'PUT', { ...data } ); if (response.success && response.data) { // Il backend ritorna user.profile che contiene driverProfile e preferences if (response.data.driverProfile) { myDriverProfile.value = response.data.driverProfile; } if (response.data.preferences) { myPreferences.value = response.data.preferences; } } return response; } catch (err: any) { error.value = err.message || 'Errore nell\'aggiornamento del profilo'; throw err; } finally { loading.value = false; } }; /** * Aggiorna solo le preferenze */ const updatePreferences = async (preferences: Partial) => { return await updateDriverProfile({ preferences }); }; /** * Aggiungi veicolo */ const addVehicle = async (vehicleData: Omit) => { try { loading.value = true; error.value = null; const response = await Api.SendReqWithData( '/api/viaggi/driver/vehicles', 'POST', { vehicle: vehicleData } ); if (response.success && response.data) { myVehicles.value = response.data; } return response; } catch (err: any) { error.value = err.message || 'Errore nell\'aggiunta del veicolo'; throw err; } finally { loading.value = false; } }; /** * Aggiorna veicolo */ const updateVehicle = async (vehicleId: string, vehicleData: Partial) => { try { loading.value = true; error.value = null; const response = await Api.SendReqWithData( `/api/viaggi/driver/vehicles/${vehicleId}`, 'PUT', { vehicle: vehicleData } ); if (response.success && response.data) { myVehicles.value = response.data; } return response; } catch (err: any) { error.value = err.message || 'Errore nell\'aggiornamento del veicolo'; throw err; } finally { loading.value = false; } }; /** * Rimuovi veicolo */ const removeVehicle = async (vehicleId: string) => { try { loading.value = true; error.value = null; const response = await Api.SendReqWithData( `/api/viaggi/driver/vehicles/${vehicleId}`, 'DELETE' ); if (response.success) { myVehicles.value = myVehicles.value.filter(v => v._id !== vehicleId); } return response; } catch (err: any) { error.value = err.message || 'Errore nella rimozione del veicolo'; throw err; } finally { loading.value = false; } }; /** * Imposta veicolo predefinito */ const setDefaultVehicle = async (vehicleId: string) => { try { loading.value = true; error.value = null; const response = await Api.SendReqWithData( `/api/viaggi/driver/vehicles/${vehicleId}/default`, 'POST' ); if (response.success) { // Aggiorna localmente myVehicles.value = myVehicles.value.map(v => ({ ...v, isDefault: v._id === vehicleId })); } return response; } catch (err: any) { error.value = err.message || 'Errore nell\'impostazione del veicolo predefinito'; throw err; } finally { loading.value = false; } }; // ------------------------------------------------------------ // UTILITIES // ------------------------------------------------------------ /** * Formatta tipo veicolo */ const formatVehicleType = (type: string): string => { const types: Record = { auto: '🚗 Auto', moto: '🏍️ Moto', furgone: '🚐 Furgone', minibus: '🚌 Minibus', altro: '🚙 Altro' }; return types[type] || type; }; /** * Formatta veicolo completo */ const formatVehicle = (vehicle: Vehicle): string => { const parts = []; if (vehicle.brand) parts.push(vehicle.brand); if (vehicle.model) parts.push(vehicle.model); if (vehicle.color) parts.push(`(${vehicle.color})`); return parts.join(' ') || 'Veicolo'; }; /** * Formatta response time */ const formatResponseTime = (time?: string): string => { const times: Record = { within_hour: 'Entro un\'ora', within_day: 'Entro un giorno', within_days: 'Entro qualche giorno' }; return times[time || 'within_day'] || 'N/D'; }; /** * Formatta member since */ const formatMemberSince = (date?: Date | string): string => { if (!date) return 'N/D'; const d = new Date(date); return d.toLocaleDateString('it-IT', { month: 'long', year: 'numeric' }); }; /** * Calcola livello utente */ const calculateLevel = (points: number): { level: number; progress: number; nextLevel: number } => { const levels = [0, 100, 300, 600, 1000, 1500, 2500, 4000, 6000, 10000]; let level = 1; for (let i = 1; i < levels.length; i++) { if (points >= levels[i]) { level = i + 1; } else { break; } } const currentLevelPoints = levels[level - 1] || 0; const nextLevelPoints = levels[level] || levels[levels.length - 1]; const progress = ((points - currentLevelPoints) / (nextLevelPoints - currentLevelPoints)) * 100; return { level, progress: Math.min(100, Math.max(0, progress)), nextLevel: nextLevelPoints }; }; /** * Ottieni badge icon */ const getBadgeIcon = (badgeName: string): string => { const badges: Record = { first_ride: '🎉', five_rides: '🚗', ten_rides: '🏆', fifty_rides: '⭐', hundred_rides: '👑', eco_warrior: '🌱', super_driver: '🦸', top_rated: '💯', fast_responder: '⚡', friendly: '😊' }; return badges[badgeName] || '🏅'; }; /** * Inizializza profilo dal user corrente (userStore) */ const initFromUser = (user: any) => { if (user?.profile?.driverProfile) { myDriverProfile.value = user.profile.driverProfile; myVehicles.value = user.profile.driverProfile.vehicles || []; } if (user?.profile?.preferences) { myPreferences.value = user.profile.preferences; } }; /** * Pulisci stato */ const clearState = () => { driverProfile.value = null; myDriverProfile.value = null; myVehicles.value = []; myPreferences.value = null; error.value = null; }; // ------------------------------------------------------------ // RETURN // ------------------------------------------------------------ return { // State driverProfile, myDriverProfile, myVehicles, myPreferences, loading, error, // Computed isDriver, hasVehicles, defaultVehicle, averageRating, totalRides, // API Methods fetchDriverProfile, updateDriverProfile, updatePreferences, addVehicle, updateVehicle, removeVehicle, setDefaultVehicle, // Utilities formatVehicleType, formatVehicle, formatResponseTime, formatMemberSince, calculateLevel, getBadgeIcon, initFromUser, clearState }; }