Files
myprojplanet_vite/src/modules/viaggi/pages/MyRidesPage.ts
2025-12-24 19:46:49 +01:00

296 lines
8.4 KiB
TypeScript

import { ref, computed, onMounted, watch, defineComponent } from 'vue';
import { useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { useRides } from '../composables/useRides';
import { useRideRequests } from '../composables/useRideRequests';
import MyRideCard from '../components/ride/MyRideCard.vue';
import RequestCard from '../components/ride/RequestCard.vue';
import type { Ride, RideRequest } from '../types';
import { useUserStore } from 'app/src/store';
export default defineComponent({
name: 'MyRidesPage',
components: {
MyRideCard,
RequestCard
},
setup() {
const router = useRouter();
const $q = useQuasar();
const userStore = useUserStore()
const {
myRides,
loading,
fetchMyRides,
deleteRide,
completeRideApi,
} = useRides();
const {
receivedRequests,
sentRequests,
loading: loadingRequests,
requestCounts,
fetchReceivedRequests,
fetchSentRequests,
acceptRequest: acceptRequestApi,
rejectRequest: rejectRequestApi,
cancelRequest: cancelRequestApi
} = useRideRequests();
// State
const activeTab = ref('upcoming');
const requestsSubTab = ref('received');
const roleFilter = ref<'all' | 'driver' | 'passenger'>('all');
const showRequestsDialog = ref(false);
const selectedRide = ref<Ride | null>(null);
const selectedRideRequests = ref<RideRequest[]>([]);
const currentUserId = ref<string>(userStore.my._id);
// Filters
const roleFilters = [
{ label: 'Tutti', value: 'all' },
{ label: '🚗 Come conducente', value: 'driver' },
{ label: '👤 Come passeggero', value: 'passenger' }
];
// Computed
const upcomingCount = computed(() => myRides.upcoming.length);
const pendingRequestsCount = computed(() => requestCounts.value.pending);
const filteredUpcoming = computed(() => {
if (roleFilter.value === 'all') return myRides.upcoming;
if (roleFilter.value === 'driver') {
return myRides.upcoming.filter(r => isDriver(r));
}
return myRides.upcoming.filter(r => !isDriver(r));
});
const filteredPast = computed(() => {
if (roleFilter.value === 'all') return myRides.past;
if (roleFilter.value === 'driver') {
return myRides.past.filter(r => isDriver(r));
}
return myRides.past.filter(r => !isDriver(r));
});
// Methods
const isDriver = (ride: Ride): boolean => {
const userId = typeof ride.userId === 'string' ? ride.userId : ride.userId._id;
return userId === currentUserId.value;
};
const getPendingRequests = (rideId: string): number => {
return receivedRequests.value.filter(r => {
const reqRideId = typeof r.rideId === 'string' ? r.rideId : r.rideId._id;
return reqRideId === rideId && r.status === 'pending';
}).length;
};
const canLeaveFeedback = (ride: Ride): boolean => {
// TODO: Implement logic to check if user can leave feedback
return ride.status === 'completed';
};
const goToCreate = () => {
router.push({ path: '/viaggi/richiedi' });
};
const goToRide = (rideId: string) => {
router.push(`/viaggi/ride/${rideId}`);
};
const goToProfile = (userId: string) => {
router.push(`/viaggi/profilo/${userId}`);
};
const editRide = (rideId: string) => {
router.push(`/viaggi/ride/${rideId}/modifica`);
};
const cancelRide = async (ride: Ride) => {
$q.dialog({
title: 'Cancella Viaggio',
message: 'Sei sicuro di voler cancellare questo viaggio?',
prompt: {
model: '',
type: 'text',
label: 'Motivo (opzionale)'
},
cancel: true
}).onOk(async (reason: string) => {
try {
await deleteRide(ride._id, reason);
$q.notify({ type: 'positive', message: 'Viaggio cancellato' });
await fetchMyRides();
} catch (error: any) {
$q.notify({ type: 'negative', message: error.data?.message || error.message });
}
});
};
const completeRide = async (ride: Ride) => {
$q.dialog({
title: 'Completa Viaggio',
message: 'Confermi che il viaggio è stato completato?',
cancel: true
}).onOk(async () => {
try {
await completeRideApi(ride._id);
$q.notify({ type: 'positive', message: 'Viaggio completato!' });
await fetchMyRides();
} catch (error: any) {
$q.notify({ type: 'negative', message: error.data?.message || error.message });
}
});
};
const openRequestsDialog = async (ride: Ride) => {
selectedRide.value = ride;
selectedRideRequests.value = receivedRequests.value.filter(r => {
const reqRideId = typeof r.rideId === 'string' ? r.rideId : r.rideId._id;
return reqRideId === ride._id;
});
showRequestsDialog.value = true;
};
const openFeedbackDialog = (ride: Ride) => {
router.push(`/viaggi/feedback/viaggio/${ride._id}`);
};
const acceptRequest = async (request: RideRequest) => {
$q.dialog({
title: 'Accetta Richiesta',
message: `Vuoi accettare la richiesta di ${getUserName(request.passengerId)}?`,
prompt: {
model: '',
type: 'text',
label: 'Messaggio (opzionale)'
},
cancel: true
}).onOk(async (message: string) => {
try {
await acceptRequestApi(request._id, message);
$q.notify({ type: 'positive', message: 'Richiesta accettata!' });
await fetchReceivedRequests();
await fetchMyRides();
} catch (error: any) {
$q.notify({ type: 'negative', message: error.data?.message || error.message });
}
});
};
const rejectRequest = async (request: RideRequest) => {
$q.dialog({
title: 'Rifiuta Richiesta',
message: 'Vuoi rifiutare questa richiesta?',
prompt: {
model: '',
type: 'text',
label: 'Motivo (opzionale)'
},
cancel: true
}).onOk(async (message: string) => {
try {
await rejectRequestApi(request._id, message);
$q.notify({ type: 'info', message: 'Richiesta rifiutata' });
await fetchReceivedRequests();
} catch (error: any) {
$q.notify({ type: 'negative', message: error.data?.message || error.message });
}
});
};
const cancelRequest = async (request: RideRequest) => {
$q.dialog({
title: 'Annulla Richiesta',
message: 'Vuoi annullare questa richiesta?',
cancel: true
}).onOk(async () => {
try {
await cancelRequestApi(request._id);
$q.notify({ type: 'info', message: 'Richiesta annullata' });
await fetchSentRequests();
} catch (error: any) {
$q.notify({ type: 'negative', message: error.data?.message || error.message });
}
});
};
const getUserName = (user: any): string => {
if (typeof user === 'string') return 'Utente';
if (user.name) return `${user.name} ${user.surname || ''}`.trim();
return user.username || 'Utente';
};
// Watch tab changes
watch(activeTab, async (tab) => {
if (tab === 'requests') {
if (requestsSubTab.value === 'received') {
await fetchReceivedRequests();
} else {
await fetchSentRequests();
}
}
});
watch(requestsSubTab, async (subTab) => {
if (subTab === 'received') {
await fetchReceivedRequests();
} else {
await fetchSentRequests();
}
});
// Lifecycle
onMounted(async () => {
await fetchMyRides();
await fetchReceivedRequests();
});
return {
// State
activeTab,
requestsSubTab,
roleFilter,
showRequestsDialog,
selectedRideRequests,
loading,
loadingRequests,
myRides,
receivedRequests,
sentRequests,
currentUserId,
// Filters
roleFilters,
// Computed
upcomingCount,
pendingRequestsCount,
filteredUpcoming,
filteredPast,
// Methods
isDriver,
getPendingRequests,
canLeaveFeedback,
goToCreate,
goToRide,
goToProfile,
editRide,
cancelRide,
completeRide,
openRequestsDialog,
openFeedbackDialog,
acceptRequest,
rejectRequest,
cancelRequest
};
}
});