CampFireCritics/src/components/reviews/ReviewForm.jsx
2025-05-07 10:48:06 +03:00

157 lines
5.1 KiB
JavaScript

import { useState } from 'react';
import { FaStar } from 'react-icons/fa';
import RatingChart from './RatingChart';
function ReviewForm({ mediaId, mediaType, onSubmit }) {
const [ratings, setRatings] = useState({
story: 5,
visuals: 5,
performance: 5,
soundtrack: 5,
enjoyment: 5
});
const [content, setContent] = useState('');
const [hasSpoilers, setHasSpoilers] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const labels = {
story: 'Story & Writing',
visuals: 'Visuals & Effects',
performance: 'Acting/Performance',
soundtrack: 'Sound & Music',
enjoyment: 'Overall Enjoyment'
};
const handleRatingChange = (category, value) => {
setRatings(prev => ({
...prev,
[category]: value
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
setIsSubmitting(true);
try {
// Calculate overall rating
const overallRating = Object.values(ratings).reduce((sum, rating) => sum + rating, 0) / Object.keys(ratings).length;
// Prepare review data
const reviewData = {
mediaId,
mediaType,
content,
ratings,
overallRating,
hasSpoilers,
createdAt: new Date().toISOString()
};
await onSubmit(reviewData);
// Reset form
setContent('');
setRatings({
story: 5,
visuals: 5,
performance: 5,
soundtrack: 5,
enjoyment: 5
});
setHasSpoilers(false);
} catch (error) {
console.error('Error submitting review:', error);
} finally {
setIsSubmitting(false);
}
};
return (
<div className="bg-campfire-charcoal rounded-lg shadow-md p-6">
<h2 className="text-xl font-bold mb-6">Write Your Review</h2>
<form onSubmit={handleSubmit}>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 mb-6">
<div className="md:col-span-2">
{/* Rating Sliders */}
<div className="space-y-6 mb-6">
{Object.keys(ratings).map(category => (
<div key={category} className="space-y-2">
<div className="flex justify-between">
<label className="text-campfire-light">{labels[category]}</label>
<span className="flex items-center text-campfire-amber">
<FaStar className="mr-1" />
{ratings[category]}
</span>
</div>
<input
type="range"
min="1"
max="10"
value={ratings[category]}
onChange={(e) => handleRatingChange(category, parseInt(e.target.value))}
className="w-full h-2 bg-campfire-dark rounded-lg appearance-none cursor-pointer"
style={{
background: `linear-gradient(to right, #FF9D00 0%, #FF9D00 ${(ratings[category] - 1) * 11.1}%, #2D3748 ${(ratings[category] - 1) * 11.1}%, #2D3748 100%)`
}}
/>
</div>
))}
</div>
{/* Review Text */}
<div className="mb-6">
<label htmlFor="review-content" className="block mb-2 text-campfire-light">
Your Review
</label>
<textarea
id="review-content"
rows="8"
placeholder="Share your thoughts on this title..."
value={content}
onChange={(e) => setContent(e.target.value)}
className="w-full p-3 bg-campfire-dark border border-campfire-ash rounded-md text-campfire-light focus:ring-2 focus:ring-campfire-amber focus:border-transparent"
required
/>
</div>
{/* Spoiler Checkbox */}
<div className="mb-6 flex items-center">
<input
type="checkbox"
id="spoiler-check"
checked={hasSpoilers}
onChange={(e) => setHasSpoilers(e.target.checked)}
className="w-4 h-4 text-campfire-amber bg-campfire-dark border-campfire-ash rounded focus:ring-campfire-amber focus:ring-2"
/>
<label htmlFor="spoiler-check" className="ml-2 text-campfire-light">
This review contains spoilers
</label>
</div>
</div>
{/* Rating Chart Preview */}
<div className="md:col-span-1">
<p className="text-center text-campfire-light mb-4">Your Rating Preview</p>
<RatingChart ratings={ratings} size="medium" />
</div>
</div>
{/* Submit Button */}
<div className="flex justify-end">
<button
type="submit"
disabled={isSubmitting}
className="btn-primary"
>
{isSubmitting ? 'Submitting...' : 'Submit Review'}
</button>
</div>
</form>
</div>
);
}
export default ReviewForm;