/* Reviews */ function ReviewStars({ value, compact = false }) { const rating = Math.max(0, Math.min(5, Number(value) || 0)); return (
{[1, 2, 3, 4, 5].map((star) => ( ))}
); } function RatingInput({ value, onChange }) { return (
{[1, 2, 3, 4, 5].map((star) => ( ))}
); } function ReviewsPanel({ serviceSlug = '', serviceTitle = '' }) { const data = window.__PUBLIC_DATA__ || {}; const services = data.services || []; const allReviews = data.reviews || []; const initialReviews = serviceSlug ? allReviews.filter((review) => review.service_slug === serviceSlug) : allReviews; const defaultService = serviceSlug || services[0]?.slug || ''; const [reviews, setReviews] = React.useState(initialReviews); const [rating, setRating] = React.useState(5); const [selectedService, setSelectedService] = React.useState(defaultService); const [error, setError] = React.useState(''); const [sent, setSent] = React.useState(false); const fileRef = React.useRef(null); React.useEffect(() => { setReviews(serviceSlug ? allReviews.filter((review) => review.service_slug === serviceSlug) : allReviews); setSelectedService(serviceSlug || services[0]?.slug || ''); }, [serviceSlug]); const handleSubmit = async (event) => { event.preventDefault(); setError(''); setSent(false); const form = event.currentTarget; const payload = new FormData(form); payload.set('rating', String(rating)); payload.set('service_slug', serviceSlug || selectedService); try { const response = await fetch('/reviews/', { method: 'POST', body: payload, credentials: 'same-origin', }); const body = await response.json(); if (!response.ok || !body.ok) { const message = Object.values(body.errors || {}).join(' ') || 'Не получилось отправить отзыв.'; throw new Error(message); } if (body.review) { setReviews((current) => [body.review, ...current]); } setSent(true); setRating(5); form.reset(); if (fileRef.current) fileRef.current.value = ''; window.setTimeout(() => setSent(false), 4000); } catch (err) { setError(err.message || 'Не получилось отправить отзыв.'); } }; return (
// отзывы {serviceSlug ? <>Отзывы по услуге : <>Отзывы клиентов} {serviceSlug ? `Здесь показываются только отзывы по услуге «${serviceTitle || serviceSlug}».` : 'Все отзывы по услугам на сайте.'}
{reviews.length || 0}
{serviceSlug ? 'отзывов по услуге' : 'отзывов всего'}
{reviews.length > 0 ? reviews.map((review) => (

{review.author_name}

{review.created_at_label && {review.created_at_label}}
{!serviceSlug && review.service_title && ( {review.service_title} )}

{review.text}

{review.photo_path && {`Фото} {review.admin_reply && (
Ответ администратора

{review.admin_reply}

)}
)) : (

Отзывов пока нет

Можно оставить первый отзыв после выполненной задачи. Он появится в этом блоке с привязкой к услуге.

)}
$ winetlab review ● open
{serviceSlug ? (
Услуга {serviceTitle || serviceSlug}
) : (
)}