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 && (
)}
{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 && (
)}
{/* 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 ? (
Внимание: Эта рецензия содержит спойлеры!
setShowSpoilers(true)}
className="text-status-warning hover:underline text-sm"
>
Показать спойлеры
) : (
)}
{/* Read More Button */}
{review.content && review.content.length > 300 && (
setShowFullReview(!showFullReview)}
className="text-campfire-amber hover:underline text-sm self-start mb-4"
>
{showFullReview ? 'Свернуть' : 'Читать далее'}
)}
{/* Footer: Date, Comment Count (Placeholder) and Progress */}
{new Date(review.created).toLocaleDateString()}
{renderProgress()}
);
}
export default ReviewItem;