import { ref, reactive, computed, watch, defineComponent, PropType } from 'vue'; import type { FeedbackFormData, FeedbackRole, FeedbackTag, FeedbackCategories, UserBasic, Ride } from '../../types'; import { FEEDBACK_TAGS_OPTIONS } from '../../types'; interface LocalFeedback { rating: number; categories: FeedbackCategories; comment: string; pros: string[]; cons: string[]; tags: FeedbackTag[]; isPublic: boolean; } export default defineComponent({ name: 'FeedbackForm', props: { rideId: { type: String, required: true }, toUser: { type: Object as PropType, default: null }, role: { type: String as PropType, required: true }, ride: { type: Object as PropType, default: null }, submitting: { type: Boolean, default: false }, showCancel: { type: Boolean, default: true }, showProsCons: { type: Boolean, default: false }, submitLabel: { type: String, default: 'Invia Recensione' } }, emits: ['submit', 'cancel'], setup(props, { emit }) { // State const hoverRating = ref(0); const newPro = ref(''); const newCon = ref(''); const localFeedback = reactive({ rating: 0, categories: { punctuality: 0, cleanliness: 0, communication: 0, driving: 0, respect: 0, reliability: 0 }, comment: '', pros: [], cons: [], tags: [], isPublic: true }); // Categories based on role const allCategories = [ { key: 'punctuality', label: 'Puntualità', icon: '⏰', roles: ['driver', 'passenger'] }, { key: 'communication', label: 'Comunicazione', icon: '💬', roles: ['driver', 'passenger'] }, { key: 'respect', label: 'Rispetto', icon: '🙏', roles: ['driver', 'passenger'] }, { key: 'reliability', label: 'Affidabilità', icon: '💯', roles: ['driver', 'passenger'] }, { key: 'cleanliness', label: 'Pulizia auto', icon: '✨', roles: ['driver'] }, { key: 'driving', label: 'Guida', icon: '🚗', roles: ['driver'] } ]; // Computed const visibleCategories = computed(() => { return allCategories.filter(cat => cat.roles.includes(props.role)); }); const relevantTags = computed(() => { const isPositive = localFeedback.rating >= 4; return FEEDBACK_TAGS_OPTIONS.filter(tag => tag.isPositive === isPositive); }); const userName = computed(() => { if (!props.toUser) return 'Utente'; if (props.toUser.name) { return `${props.toUser.name} ${props.toUser.surname || ''}`.trim(); } return props.toUser.username || 'Utente'; }); const userInitials = computed(() => { return userName.value .split(' ') .map(n => n[0]) .join('') .toUpperCase() .slice(0, 2); }); const userImg = computed(() => { return (props.toUser as any)?.profile?.img; }); const rideInfo = computed(() => { if (!props.ride) return null; return `${props.ride.departure?.city} → ${props.ride.destination?.city}`; }); const ratingLabel = computed(() => { const rating = hoverRating.value || localFeedback.rating; if (rating === 0) return 'Seleziona una valutazione'; if (rating === 1) return '😞 Pessimo'; if (rating === 2) return '😕 Scarso'; if (rating === 3) return '😐 Nella media'; if (rating === 4) return '😊 Buono'; return '🤩 Eccellente!'; }); const commentPlaceholder = computed(() => { if (localFeedback.rating >= 4) { return 'Racconta cosa ti è piaciuto del viaggio...'; } return 'Racconta cosa si potrebbe migliorare...'; }); const canSubmit = computed(() => { return localFeedback.rating > 0; }); // Methods const setRating = (rating: number) => { localFeedback.rating = rating; // Reset tags quando cambia il rating if ((rating >= 4) !== (localFeedback.tags.some(t => FEEDBACK_TAGS_OPTIONS.find(opt => opt.value === t)?.isPositive ))) { localFeedback.tags = []; } }; const toggleTag = (tag: FeedbackTag) => { const index = localFeedback.tags.indexOf(tag); if (index === -1) { localFeedback.tags.push(tag); } else { localFeedback.tags.splice(index, 1); } }; const addPro = () => { if (newPro.value.trim()) { localFeedback.pros.push(newPro.value.trim()); newPro.value = ''; } }; const removePro = (index: number) => { localFeedback.pros.splice(index, 1); }; const addCon = () => { if (newCon.value.trim()) { localFeedback.cons.push(newCon.value.trim()); newCon.value = ''; } }; const removeCon = (index: number) => { localFeedback.cons.splice(index, 1); }; const submit = () => { if (!canSubmit.value) return; const feedbackData: FeedbackFormData = { rideId: props.rideId, toUserId: props.toUser?._id || '', role: props.role, rating: localFeedback.rating, categories: { ...localFeedback.categories }, comment: localFeedback.comment, pros: [...localFeedback.pros], cons: [...localFeedback.cons], tags: [...localFeedback.tags], isPublic: localFeedback.isPublic }; // Rimuovi categorie con valore 0 Object.keys(feedbackData.categories).forEach(key => { if ((feedbackData.categories as any)[key] === 0) { delete (feedbackData.categories as any)[key]; } }); emit('submit', feedbackData); }; return { // State hoverRating, newPro, newCon, localFeedback, // Computed visibleCategories, relevantTags, userName, userInitials, userImg, rideInfo, ratingLabel, commentPlaceholder, canSubmit, // Methods setRating, toggleTag, addPro, removePro, addCon, removeCon, submit }; } });