'use client' import { useEffect, useState } from 'react' import { coerceToString } from '@/helpers' import { addToast } from '@/lib/toast' import ConsumerInput from '@/components/consumer/ConsumerInput' import ConsumerModal from '@/components/consumer/ConsumerModal' import StarRating from '@/components/reviews/StarRating' import { CREATE_REVIEW, type EventReview } from '@/services/reviews' import { ANALYTICS_EVENTS, trackAnalyticsEventOnce } from '@/lib/analytics' import { texts } from '@/texts' interface ReviewModalProps { isOpen: boolean onOpenChange: (open: boolean) => void eventId: string bookingId: string onSaved?: (review: EventReview) => void } /** Create-only review modal (booking surfaces). Event detail uses inline compose instead. */ const ReviewModal = ({ isOpen, onOpenChange, eventId, bookingId, onSaved }: ReviewModalProps) => { const [rating, setRating] = useState(0) const [body, setBody] = useState('') const [isSaving, setIsSaving] = useState(false) useEffect(() => { if (!isOpen) return setRating(0) setBody('') }, [isOpen]) const handleSave = async () => { if (rating < 1 || rating > 5) { addToast({ title: texts.reviews.selectRating, color: 'warning' }) return } setIsSaving(true) const trimmed = body.trim() const result = await CREATE_REVIEW(eventId, { bookingId, rating, body: trimmed.length > 0 ? trimmed : null, }) setIsSaving(false) if (!result.ok) return trackAnalyticsEventOnce(ANALYTICS_EVENTS.REVIEW_SUBMITTED, result.data.id, { review_id: result.data.id, event_id: eventId, booking_id: bookingId, rating, has_comment: trimmed.length > 0, }) addToast({ title: texts.reviews.submitted, color: 'success', }) onSaved?.(result.data) onOpenChange(false) } return ( void handleSave()} onOpenChange={onOpenChange} onReject={() => { onOpenChange(false) }} >

{texts.reviews.yourRating}

{ setBody(coerceToString(next)) }} />

{texts.reviews.ratingOnlyHint}

) } export default ReviewModal