This commit is contained in:
@ -1,90 +1,134 @@
|
||||
// import { useState } from 'react';
|
||||
// import { motion } from 'framer-motion';
|
||||
// import { Star } from 'lucide-react';
|
||||
|
||||
// const StarRating = ({
|
||||
// rating,
|
||||
// onRatingChange,
|
||||
// maxStars = 5,
|
||||
// size = 24,
|
||||
// color = '#ffc107',
|
||||
// readOnly = false,
|
||||
// className = ''
|
||||
// }) => {
|
||||
// const [hoverRating, setHoverRating] = useState(null);
|
||||
|
||||
// const handleClick = (value) => {
|
||||
// if (!readOnly && onRatingChange) {
|
||||
// onRatingChange(value);
|
||||
// }
|
||||
// };
|
||||
|
||||
// const handleMouseEnter = (value) => {
|
||||
// if (!readOnly) {
|
||||
// setHoverRating(value);
|
||||
// }
|
||||
// };
|
||||
|
||||
// const handleMouseLeave = () => {
|
||||
// if (!readOnly) {
|
||||
// setHoverRating(null);
|
||||
// }
|
||||
// };
|
||||
|
||||
// const getStarIcon = (index) => {
|
||||
// const currentRating = hoverRating !== null ? hoverRating : rating;
|
||||
|
||||
// if (currentRating > index) {
|
||||
// const hasHalfStar = currentRating % 1 > 0.5 && index + 0.5 <= currentRating;
|
||||
// if (hasHalfStar) {
|
||||
// // For half star, we'll use a combination approach or just show full star
|
||||
// // Since we don't have StarOutline, we'll approximate with full stars
|
||||
// return <Star className={`w-${size} h-${size} text-${color}`} />;
|
||||
// }
|
||||
// return <Star className={`w-${size} h-${size} text-${color}`} />;
|
||||
// }
|
||||
// return <Star className={`w-${size} h-${size} text-gray-400`} />;
|
||||
// };
|
||||
|
||||
// return (
|
||||
// <div className={`flex gap-1 ${className}`} onMouseLeave={handleMouseLeave}>
|
||||
// {[...Array(maxStars)].map((_, index) => (
|
||||
// <motion.div
|
||||
// key={index}
|
||||
// whileHover={{ scale: readOnly ? 1 : 1.1 }}
|
||||
// onClick={() => handleClick(index + 1)}
|
||||
// onMouseEnter={() => handleMouseEnter(index + 1)}
|
||||
// >
|
||||
// {getStarIcon(index)}
|
||||
// </motion.div>
|
||||
// ))}
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default StarRating;
|
||||
|
||||
// // Helper functions
|
||||
// export function getStarCount(rating, maxStars = 5) {
|
||||
// return Math.round(rating * maxStars) / maxStars;
|
||||
// }
|
||||
|
||||
// export function formatRating(rating) {
|
||||
// if (rating === 0) return 'لا يوجد تقييم';
|
||||
// return `${rating.toFixed(1)}`; // Show 1 decimal place
|
||||
// }
|
||||
|
||||
// export function getRatingColor(rating) {
|
||||
// if (rating >= 4.5) return 'text-green-600';
|
||||
// if (rating >= 3.5) return 'text-yellow-600';
|
||||
// if (rating >= 2.5) return 'text-orange-600';
|
||||
// return 'text-red-600';
|
||||
// }
|
||||
|
||||
// export function getRatingText(rating) {
|
||||
// if (rating >= 4.5) return 'ممتاز';
|
||||
// if (rating >= 3.5) return 'جيد جداً';
|
||||
// if (rating >= 2.5) return 'جيد';
|
||||
// if (rating >= 1.5) return 'مقبول';
|
||||
// return 'ضعيف';
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Star } from 'lucide-react';
|
||||
|
||||
const StarRating = ({
|
||||
rating,
|
||||
onRatingChange,
|
||||
maxStars = 5,
|
||||
size = 24,
|
||||
color = '#ffc107',
|
||||
readOnly = false,
|
||||
className = ''
|
||||
}) => {
|
||||
const [hoverRating, setHoverRating] = useState(null);
|
||||
const StarRating = ({ rating = 0, onRatingChange, size = 28, readOnly = false }) => {
|
||||
const [hoverRating, setHoverRating] = useState(0);
|
||||
|
||||
const handleClick = (value) => {
|
||||
if (!readOnly && onRatingChange) {
|
||||
onRatingChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseEnter = (value) => {
|
||||
if (!readOnly) {
|
||||
setHoverRating(value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
if (!readOnly) {
|
||||
setHoverRating(null);
|
||||
}
|
||||
};
|
||||
|
||||
const getStarIcon = (index) => {
|
||||
const currentRating = hoverRating !== null ? hoverRating : rating;
|
||||
|
||||
if (currentRating > index) {
|
||||
const hasHalfStar = currentRating % 1 > 0.5 && index + 0.5 <= currentRating;
|
||||
if (hasHalfStar) {
|
||||
// For half star, we'll use a combination approach or just show full star
|
||||
// Since we don't have StarOutline, we'll approximate with full stars
|
||||
return <Star className={`w-${size} h-${size} text-${color}`} />;
|
||||
}
|
||||
return <Star className={`w-${size} h-${size} text-${color}`} />;
|
||||
}
|
||||
return <Star className={`w-${size} h-${size} text-gray-400`} />;
|
||||
if (!readOnly && onRatingChange) onRatingChange(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`flex gap-1 ${className}`} onMouseLeave={handleMouseLeave}>
|
||||
{[...Array(maxStars)].map((_, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
whileHover={{ scale: readOnly ? 1 : 1.1 }}
|
||||
onClick={() => handleClick(index + 1)}
|
||||
onMouseEnter={() => handleMouseEnter(index + 1)}
|
||||
>
|
||||
{getStarIcon(index)}
|
||||
</motion.div>
|
||||
))}
|
||||
<div
|
||||
className="flex gap-1"
|
||||
onMouseLeave={() => !readOnly && setHoverRating(0)}
|
||||
>
|
||||
{[1, 2, 3, 4, 5].map((star) => {
|
||||
const filled = (hoverRating || rating) >= star;
|
||||
return (
|
||||
<button
|
||||
key={star}
|
||||
type="button"
|
||||
onClick={() => handleClick(star)}
|
||||
onMouseEnter={() => !readOnly && setHoverRating(star)}
|
||||
className="focus:outline-none transition-transform hover:scale-110"
|
||||
disabled={readOnly}
|
||||
>
|
||||
<Star
|
||||
size={size}
|
||||
className={`${filled ? 'fill-amber-500 text-amber-500' : 'text-gray-300 fill-transparent'}`}
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StarRating;
|
||||
|
||||
// Helper functions
|
||||
export function getStarCount(rating, maxStars = 5) {
|
||||
return Math.round(rating * maxStars) / maxStars;
|
||||
}
|
||||
|
||||
export function formatRating(rating) {
|
||||
if (rating === 0) return 'لا يوجد تقييم';
|
||||
return `${rating.toFixed(1)}`; // Show 1 decimal place
|
||||
}
|
||||
|
||||
export function getRatingColor(rating) {
|
||||
if (rating >= 4.5) return 'text-green-600';
|
||||
if (rating >= 3.5) return 'text-yellow-600';
|
||||
if (rating >= 2.5) return 'text-orange-600';
|
||||
return 'text-red-600';
|
||||
}
|
||||
|
||||
export function getRatingText(rating) {
|
||||
if (rating >= 4.5) return 'ممتاز';
|
||||
if (rating >= 3.5) return 'جيد جداً';
|
||||
if (rating >= 2.5) return 'جيد';
|
||||
if (rating >= 1.5) return 'مقبول';
|
||||
return 'ضعيف';
|
||||
}
|
||||
export default StarRating;
|
||||
Reference in New Issue
Block a user