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

191 lines
4.9 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 { useChat } from '../composables/useChat';
import RideCard from '../components/ride/RideCard.vue';
import RideFilters from '../components/ride/RideFilters.vue';
import type { Ride, RideSearchFilters, RideType } from '../types';
import { useUserStore } from 'app/src/store';
export default defineComponent({
name: 'RidesListPage',
components: {
RideCard,
RideFilters
},
setup() {
const router = useRouter();
const $q = useQuasar();
const {
rides,
loading,
pagination,
filters,
hasMorePages,
fetchRides,
searchRides,
loadMore: loadMoreRides,
resetFilters
} = useRides();
const { createRequest } = useRideRequests();
const { getOrCreateDirectChat } = useChat();
// State
const userStore = useUserStore()
const activeTab = ref<'all' | 'offers' | 'requests'>('all');
const currentUserId = ref<string>(userStore.my._id);
// Computed
const filteredRides = computed(() => {
if (activeTab.value === 'all') return rides.value;
const type: RideType = activeTab.value === 'offers' ? 'offer' : 'request';
return rides.value.filter(r => r.type === type);
});
const offersCount = computed(() =>
rides.value.filter(r => r.type === 'offer').length
);
const requestsCount = computed(() =>
rides.value.filter(r => r.type === 'request').length
);
const hasActiveFilters = computed(() => {
return !!(filters.from || filters.to || filters.date || filters.type);
});
// Methods
const handleSearch = async (searchFilters: RideSearchFilters) => {
await searchRides(searchFilters);
};
const handleReset = async () => {
resetFilters();
await fetchRides({ reset: true });
};
const loadMore = async () => {
await loadMoreRides();
};
const goToCreate = () => {
const type = activeTab.value === 'requests' ? 'request' : 'offer';
router.push({ path: '/viaggi/richiedi', query: { type } });
};
const goToDetail = (rideId: string) => {
router.push(`/viaggi/ride/${rideId}`);
};
const goToDriverProfile = (userId: string) => {
router.push(`/viaggi/profilo/${userId}`);
};
const handleBook = async (ride: Ride) => {
// Apri dialog per prenotazione
$q.dialog({
title: 'Richiedi Passaggio',
message: `Vuoi richiedere un passaggio per il viaggio ${ride.departure.city}${ride.destination.city}?`,
prompt: {
model: '',
type: 'textarea',
label: 'Messaggio (opzionale)',
placeholder: 'Scrivi un messaggio al conducente...'
},
cancel: true,
persistent: true
}).onOk(async (message: string) => {
try {
$q.loading.show({ message: 'Invio richiesta...' });
await createRequest({
rideId: ride._id,
message,
seatsRequested: 1,
useOriginalRoute: true
});
$q.notify({
type: 'positive',
message: 'Richiesta inviata con successo!',
caption: 'Il conducente riceverà la tua richiesta'
});
} catch (error: any) {
$q.notify({
type: 'negative',
message: 'Errore nell\'invio della richiesta',
caption: error.data?.message || error.message
});
} finally {
$q.loading.hide();
}
});
};
const handleContact = async (ride: Ride) => {
try {
const userId = typeof ride.userId === 'string' ? ride.userId : ride.userId._id;
const response = await getOrCreateDirectChat(userId, ride._id);
if (response?.data) {
router.push(`/viaggi/chat/${response.data._id}`);
}
} catch (error: any) {
$q.notify({
type: 'negative',
message: 'Errore nell\'apertura della chat',
caption: error.data?.message || error.message
});
}
};
// Watch tab changes
watch(activeTab, (newTab) => {
if (newTab === 'all') {
filters.type = undefined;
} else {
filters.type = newTab === 'offers' ? 'offer' : 'request';
}
});
// Lifecycle
onMounted(async () => {
await fetchRides({ reset: true });
});
return {
// State
rides,
loading,
filters,
activeTab,
currentUserId,
hasMorePages,
// Computed
filteredRides,
offersCount,
requestsCount,
hasActiveFilters,
// Methods
handleSearch,
handleReset,
loadMore,
goToCreate,
goToDetail,
goToDriverProfile,
handleBook,
handleContact
};
}
});