Files
myprojplanet_vite/src/modules/viaggi/composables/useDriverProfile.ts
Surya Paolo 11c17bdd8e - Parte 3 : Viaggi
- Chat
2025-12-24 00:26:29 +01:00

387 lines
9.6 KiB
TypeScript

import { ref, computed } from 'vue';
import { Api } from '@api';
import type {
DriverProfile,
Vehicle,
UserPreferences,
DriverPublicProfile
} from '../types/viaggi.types';
// ============================================================
// STATE
// ============================================================
const driverProfile = ref<DriverPublicProfile | null>(null);
const myDriverProfile = ref<DriverProfile | null>(null);
const myVehicles = ref<Vehicle[]>([]);
const myPreferences = ref<UserPreferences | null>(null);
const loading = ref(false);
const error = ref<string | null>(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<DriverProfile>;
preferences?: Partial<UserPreferences>;
}) => {
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<UserPreferences>) => {
return await updateDriverProfile({ preferences });
};
/**
* Aggiungi veicolo
*/
const addVehicle = async (vehicleData: Omit<Vehicle, '_id'>) => {
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<Vehicle>) => {
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<string, string> = {
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<string, string> = {
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<string, string> = {
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
};
}