From db949aaebac2c6df1ed9f73a30e90901909f5609 Mon Sep 17 00:00:00 2001 From: Claw AI Date: Tue, 14 Apr 2026 14:22:39 +0000 Subject: [PATCH] Fix build errors: corrected import paths, added missing RatingList component, fixed syntax errors in rating components --- app/components/ratings/RatingForm.js | 216 +++++++++++++++++++++++++++ app/components/ratings/RatingList.js | 149 ++++++++++++++++++ app/components/ratings/StarRating.js | 90 +++++++++++ app/property/[id]/PropertyDetail.js | 6 +- app/utils/ratings.js | 193 ++++++++++++++++++++++++ 5 files changed, 651 insertions(+), 3 deletions(-) create mode 100644 app/components/ratings/RatingForm.js create mode 100644 app/components/ratings/RatingList.js create mode 100644 app/components/ratings/StarRating.js create mode 100644 app/utils/ratings.js diff --git a/app/components/ratings/RatingForm.js b/app/components/ratings/RatingForm.js new file mode 100644 index 0000000..820ccfa --- /dev/null +++ b/app/components/ratings/RatingForm.js @@ -0,0 +1,216 @@ +import { useState } from 'react'; +import { motion } from 'framer-motion'; +import { Star, Edit2, X, Check, Clock } from 'lucide-react'; +import StarRating from './StarRating.js'; +import toast, { Toaster } from 'react-hot-toast'; +import { rateProperty, rateCustomer, getUserPropertyRating, canRateProperty } from '../../utils/ratings.js'; + +const RatingForm = ({ + propertyId, + userId, + propertyOwner = false, + initialRating = 0, + initialComment = '', + onSubmitSuccess +}) => { + const [rating, setRating] = useState(initialRating); + const [comment, setComment] = useState(initialComment); + const [loading, setLoading] = useState(false); + const [showForm, setShowForm] = useState(false); + const [userRating, setUserRating] = useState(null); + + // Check if user has already rated + useState(() => { + async function fetchUserRating() { + try { + const rating = await getUserPropertyRating(propertyId, userId); + if (rating) { + setUserRating(rating); + setRating(rating.rating); + setComment(rating.comment || ''); + } + } catch (error) { + console.error('[RatingForm] Failed to fetch user rating:', error); + } + } + + if (propertyId && userId) { + fetchUserRating(); + } + }, [propertyId, userId]); + + const handleSubmit = async (e) => { + e.preventDefault(); + + if (!rating) { + toast.error('يرجى إعطاء تقييم من 1 إلى 5 نجوم'); + return; + } + + setLoading(true); + + try { + const ratingData = { + propertyId, + customerId: userId, + rating, + comment: comment.trim() || null + }; + + await rateProperty(ratingData); + + toast.success('تم إرسال التقييم بنجاح!'); + + // Reset form + setRating(0); + setComment(''); + setShowForm(false); + + if (onSubmitSuccess) { + onSubmitSuccess(); + } + } catch (error) { + console.error('[RatingForm] Failed to submit rating:', error); + toast.error('حدث خطأ أثناء إرسال التقييم. يرجى المحاولة مرة أخرى.'); + } finally { + setLoading(false); + } + }; + + const handleEdit = () => { + setShowForm(true); + setRating(userRating?.rating || 0); + setComment(userRating?.comment || ''); + }; + + const handleCancel = () => { + setShowForm(false); + setRating(userRating?.rating || 0); + setComment(userRating?.comment || ''); + }; + + if (!propertyId || !userId) { + return null; + } + + return ( +
+ + + {/* Display existing rating */} + {userRating && !showForm && ( + +
+
+ + {userRating.rating} + من 5 +
+ +
+ + {userRating.comment && ( +
+ "{userRating.comment}" +
+ )} + +
+ + {userRating.createdAt ? new Date(userRating.createdAt).toLocaleDateString('ar-SA') : ''} +
+
+ )} + + {/* Rating form */} + {showForm && ( + +
+
+ +
+ + {rating || '1'} + /5 +
+
+ +
+ +