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 AuthService from '../../services/AuthService';
import { useFavorites } from '@/app/contexts/FavoritesContext'; import { useFavorites } from '@/app/contexts/FavoritesContext';
import { BuildingTypeKeys, PropertyStatusKeys, extractCity } from '../../enums'; 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 // Copy to clipboard that works on HTTP too
async function copyToClipboard(text) { async function copyToClipboard(text) {
@ -177,6 +180,11 @@ export default function PropertyDetailsPage() {
const [favLoading, setFavLoading] = useState(false); const [favLoading, setFavLoading] = useState(false);
const [selectingEnd, setSelectingEnd] = useState(false); const [selectingEnd, setSelectingEnd] = useState(false);
const [showLoginDialog, setShowLoginDialog] = 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(() => { useEffect(() => {
const id = params.id; const id = params.id;
@ -218,20 +226,29 @@ export default function PropertyDetailsPage() {
fetchProperty(); fetchProperty();
}, [params.id]); }, [params.id]);
// Fetch available date ranges // Fetch user rating and check if they can rate
useEffect(() => { useEffect(() => {
if (!property) return; async function fetchUserRatingAndCheck() {
const propId = property._raw?.id || params.id; if (!property || !AuthService.isAuthenticated()) return;
console.log('[Property] Fetching available dates for:', propId);
getAvailableDateRanges(propId) try {
.then((data) => { // Check if user has already rated
const ranges = Array.isArray(data) ? data : []; const rating = await getUserPropertyRating(property._raw?.id || parseInt(params.id), AuthService.getUserId());
console.log('[Property] Available date ranges:', ranges); if (rating) {
setAvailableRanges(ranges); setUserRating(rating);
}) setCurrentRating(rating.rating);
.catch((err) => { setCurrentComment(rating.comment || '');
console.warn('[Property] Failed to fetch available dates:', err); }
});
// 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]); }, [property, params.id]);
// Set Open Graph meta tags dynamically for Facebook/Twitter sharing // Set Open Graph meta tags dynamically for Facebook/Twitter sharing
@ -754,6 +771,10 @@ export default function PropertyDetailsPage() {
{property.reviewList.map((review, idx) => ( {property.reviewList.map((review, idx) => (
<div key={idx} className="border-b border-gray-100 last:border-0 pb-4 last:pb-0"> <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 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> <div>
<span className="font-bold text-gray-900">{review.user}</span> <span className="font-bold text-gray-900">{review.user}</span>
<div className="flex items-center gap-1 mt-1"> <div className="flex items-center gap-1 mt-1">
@ -762,6 +783,7 @@ export default function PropertyDetailsPage() {
))} ))}
</div> </div>
</div> </div>
</div>
<span className="text-sm text-gray-500">{review.date}</span> <span className="text-sm text-gray-500">{review.date}</span>
</div> </div>
<p className="text-gray-600">{review.comment}</p> <p className="text-gray-600">{review.comment}</p>
@ -771,24 +793,32 @@ export default function PropertyDetailsPage() {
</motion.div> </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 <motion.div
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.7 }} 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> <RatingList
<ul className="space-y-2"> propertyId={property._raw?.id || parseInt(params.id)}
{property.rules.map((rule, idx) => ( userId={AuthService.getUserId()}
<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>
</motion.div> </motion.div>
)}
</div> </div>
<div className="space-y-6"> <div className="space-y-6">