Merge branch 'main' of http://45.93.137.91:3000/Rahaf/SweetHome
Some checks failed
Build frontend / build (push) Failing after 43s

This commit is contained in:
Rahaf
2026-04-13 00:38:59 +03:00

View File

@ -49,6 +49,9 @@ import { getRentProperty, getSaleProperty, bookReservation, checkAvailability, g
import AuthService from '../../services/AuthService';
import { useFavorites } from '@/app/contexts/FavoritesContext';
import { BuildingTypeKeys, PropertyStatusKeys, extractCity } from '../../enums';
import RatingForm from '../../components/ratings/RatingForm.js';
import RatingList from '../../components/ratings/RatingList.js';
import StarRating from '../../components/ratings/StarRating.js';
// Copy to clipboard that works on HTTP too
async function copyToClipboard(text) {
@ -177,6 +180,11 @@ export default function PropertyDetailsPage() {
const [favLoading, setFavLoading] = useState(false);
const [selectingEnd, setSelectingEnd] = useState(false);
const [showLoginDialog, setShowLoginDialog] = useState(false);
const [showRatingForm, setShowRatingForm] = useState(false);
const [currentRating, setCurrentRating] = useState(0);
const [currentComment, setCurrentComment] = useState('');
const [userRating, setUserRating] = useState(null);
const [canRate, setCanRate] = useState(false);
useEffect(() => {
const id = params.id;
@ -218,20 +226,29 @@ export default function PropertyDetailsPage() {
fetchProperty();
}, [params.id]);
// Fetch available date ranges
// Fetch user rating and check if they can rate
useEffect(() => {
if (!property) return;
const propId = property._raw?.id || params.id;
console.log('[Property] Fetching available dates for:', propId);
getAvailableDateRanges(propId)
.then((data) => {
const ranges = Array.isArray(data) ? data : [];
console.log('[Property] Available date ranges:', ranges);
setAvailableRanges(ranges);
})
.catch((err) => {
console.warn('[Property] Failed to fetch available dates:', err);
});
async function fetchUserRatingAndCheck() {
if (!property || !AuthService.isAuthenticated()) return;
try {
// Check if user has already rated
const rating = await getUserPropertyRating(property._raw?.id || parseInt(params.id), AuthService.getUserId());
if (rating) {
setUserRating(rating);
setCurrentRating(rating.rating);
setCurrentComment(rating.comment || '');
}
// Check if user can rate (e.g., after renting)
const canRateProperty = await canRateProperty(property._raw?.id || parseInt(params.id), AuthService.getUserId());
setCanRate(canRateProperty);
} catch (error) {
console.error('[Property] Failed to fetch user rating:', error);
}
}
fetchUserRatingAndCheck();
}, [property, params.id]);
// Set Open Graph meta tags dynamically for Facebook/Twitter sharing
@ -754,6 +771,10 @@ export default function PropertyDetailsPage() {
{property.reviewList.map((review, idx) => (
<div key={idx} className="border-b border-gray-100 last:border-0 pb-4 last:pb-0">
<div className="flex justify-between items-start mb-2">
<div className="flex items-start gap-2">
<div className="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center flex-shrink-0">
<User className="w-6 h-6 text-gray-600" />
</div>
<div>
<span className="font-bold text-gray-900">{review.user}</span>
<div className="flex items-center gap-1 mt-1">
@ -762,6 +783,7 @@ export default function PropertyDetailsPage() {
))}
</div>
</div>
</div>
<span className="text-sm text-gray-500">{review.date}</span>
</div>
<p className="text-gray-600">{review.comment}</p>
@ -771,24 +793,32 @@ export default function PropertyDetailsPage() {
</motion.div>
)}
{property.rules && property.rules.length > 0 && (
{/* New Rating Components */}
{AuthService.isAuthenticated() && canRate && !userRating && (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.65 }}
className="bg-amber-50 border-2 border-amber-200 rounded-xl p-4 text-center cursor-pointer hover:border-amber-300 transition-all"
onClick={() => setShowRatingForm(true)}
>
<Star className="w-8 h-8 text-amber-500 mx-auto mb-2" />
<h3 className="font-bold text-amber-700 mb-2">قيّم هذا العقار</h3>
<p className="text-sm text-amber-600">شارك تجربتك مع المستأجرين الآخرين</p>
</motion.div>
)}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.7 }}
className="bg-white rounded-2xl p-6 shadow-sm border border-gray-100"
className="bg-white rounded-2xl p-6 shadow-sm border border-gray-200"
>
<h2 className="text-xl font-bold mb-4 text-gray-900">قوانين المنزل</h2>
<ul className="space-y-2">
{property.rules.map((rule, idx) => (
<li key={idx} className="flex items-center gap-2 text-gray-600">
<div className="w-1.5 h-1.5 bg-gray-400 rounded-full" />
{rule}
</li>
))}
</ul>
<RatingList
propertyId={property._raw?.id || parseInt(params.id)}
userId={AuthService.getUserId()}
/>
</motion.div>
)}
</div>
<div className="space-y-6">