- Parte 3 : Viaggi
- Chat
This commit is contained in:
298
src/modules/viaggi/pages/MyRidesPage.ts
Normal file
298
src/modules/viaggi/pages/MyRidesPage.ts
Normal file
@@ -0,0 +1,298 @@
|
||||
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,
|
||||
completeRide: 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({
|
||||
name: 'leave-feedback',
|
||||
params: { rideId: 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
|
||||
};
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user