import React, { useState } from 'react'; import { Link } from 'react-router-dom'; import { FaFire, FaRegCommentDots, FaEye, FaClock, FaCheckCircle, FaGamepad } from 'react-icons/fa'; import { getFileUrl } from '../../services/pocketbaseService'; import DOMPurify from 'dompurify'; import LikeButton from './LikeButton'; // Mapping for watched/completed status values const watchedStatusLabels = { not_watched: 'Не просмотрено', watched: 'Просмотрено', }; const completedStatusLabels = { not_completed: 'Не пройдено', completed: 'Пройдено', }; // ReviewItem now expects review, media, season, reviewCharacteristics, isProfilePage, and isSmallCard props function ReviewItem({ review, media, season, reviewCharacteristics = {}, isProfilePage = false, isSmallCard = false }) { const [showFullReview, setShowFullReview] = useState(false); const [showSpoilers, setShowSpoilers] = useState(false); const reviewMedia = media || review.expand?.media_id; const reviewSeason = season || review.expand?.season_id; const reviewUser = review.expand?.user_id; const characteristics = reviewMedia?.characteristics && typeof reviewMedia.characteristics === 'object' ? reviewMedia.characteristics : reviewCharacteristics; const reviewTitle = reviewMedia ? `${reviewMedia.title}${reviewSeason ? ` - Сезон ${reviewSeason.season_number}${reviewSeason.title ? `: ${reviewSeason.title}` : ''}` : ''}` : 'Неизвестное произведение'; const reviewLink = reviewMedia ? `/media/${reviewMedia.path}` : '#'; // Sanitize HTML content from the rich text editor const sanitizedContent = DOMPurify.sanitize(review.content); // Determine progress display based on media's progress_type const renderProgress = () => { if (!reviewMedia || !reviewMedia.progress_type || review.progress === undefined || review.progress === null) { return null; } const progressType = reviewMedia.progress_type; const progressValue = review.progress; if (progressType === 'hours') { return ( {progressValue} часов ); } else if (progressType === 'watched') { const label = watchedStatusLabels[progressValue] || progressValue; return ( {label} ); } else if (progressType === 'completed') { const label = completedStatusLabels[progressValue] || progressValue; return ( {label} ); } return ( Прогресс: {progressValue} ); }; // Render as a small card for the "All Reviews" section on the profile page if (isSmallCard) { return ( {/* Added relative and overflow-hidden */} {/* Small Poster in corner - Only show on profile page small cards */} {isProfilePage && reviewMedia?.poster && (
{/* Adjusted size and positioning */} {`Постер
)} {/* User Avatar and Title */}
{/* Added right padding conditionally */} {reviewUser && ( {reviewUser.username} )}

{reviewTitle}

{/* Overall Rating */}
{review.overall_rating !== null && review.overall_rating !== undefined ? parseFloat(review.overall_rating).toFixed(1) : 'N/A'} / 10
{/* Progress Display */} {renderProgress() && (
{renderProgress()}
)} {/* Snippet of Review Content */}
{/* Strip HTML for small card snippet */} {sanitizedContent.replace(/<[^>]*>?/gm, '').substring(0, 150)}{sanitizedContent.replace(/<[^>]*>?/gm, '').length > 150 ? '...' : ''}
{/* Date */}
{new Date(review.created).toLocaleDateString()}
); } // Default rendering for larger cards (Showcase, Media Page) return (
{/* Media Poster - Only show on profile page large cards (Showcase) */} {isProfilePage && reviewMedia?.poster && ( {`Постер )} {/* Header: User, Media Title, Overall Rating */}
{/* User Avatar */} {reviewUser && ( {reviewUser.username} )}
{/* User Link */} {reviewUser && ( {reviewUser.username} )} {/* Media Title Link */}

{reviewTitle}

{/* Overall Rating */}
{review.overall_rating !== null && review.overall_rating !== undefined ? parseFloat(review.overall_rating).toFixed(1) : 'N/A'} / 10
{/* Characteristics Ratings */} {Object.keys(characteristics).length > 0 && (

Оценки по характеристикам:

{Object.entries(characteristics).map(([key, label]) => { const ratingValue = review.ratings?.[key]; if (typeof ratingValue === 'number' && ratingValue >= 1 && ratingValue <= 10) { return (
{label}: {ratingValue}
); } return null; })}
)} {/* Review Content and Footer (Flex container) */}
{/* Review Content */}
{review.has_spoilers && !showSpoilers ? (

Внимание: Эта рецензия содержит спойлеры!

) : (
)}
{/* Read More Button */} {review.content && review.content.length > 300 && ( )} {/* Footer: Date, Comment Count (Placeholder) and Progress */}
{new Date(review.created).toLocaleDateString()} {renderProgress()}
); } export default ReviewItem;