- Parte 3 : Viaggi
- Chat
This commit is contained in:
190
src/modules/viaggi/pages/RidesListPage.ts
Normal file
190
src/modules/viaggi/pages/RidesListPage.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
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';
|
||||
|
||||
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 activeTab = ref<'all' | 'offers' | 'requests'>('all');
|
||||
const currentUserId = ref(''); // Da ottenere dal tuo auth store
|
||||
|
||||
// TODO: Ottieni currentUserId dal tuo sistema di autenticazione
|
||||
// Esempio: currentUserId.value = authStore.user?._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
|
||||
};
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user