Show login dialog when favoriting without auth
All checks were successful
Build frontend / build (push) Successful in 39s
All checks were successful
Build frontend / build (push) Successful in 39s
This commit is contained in:
@ -97,7 +97,7 @@ function extractCity(address) {
|
|||||||
|
|
||||||
// API-only — no fallback data
|
// API-only — no fallback data
|
||||||
|
|
||||||
const PropertyCard = ({ property, viewMode = 'grid' }) => {
|
const PropertyCard = ({ property, viewMode = 'grid', onLoginRequired }) => {
|
||||||
const { isFavorite: checkFavorite, addFavorite, removeFavorite } = useFavorites();
|
const { isFavorite: checkFavorite, addFavorite, removeFavorite } = useFavorites();
|
||||||
const [favLoading, setFavLoading] = useState(false);
|
const [favLoading, setFavLoading] = useState(false);
|
||||||
const [currentImage, setCurrentImage] = useState(0);
|
const [currentImage, setCurrentImage] = useState(0);
|
||||||
@ -107,7 +107,7 @@ const PropertyCard = ({ property, viewMode = 'grid' }) => {
|
|||||||
const toggleFavorite = async (e) => {
|
const toggleFavorite = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!AuthService.isAuthenticated()) { toast.error('سجل الدخول أولاً'); return; }
|
if (!AuthService.isAuthenticated()) { onLoginRequired?.(); return; }
|
||||||
setFavLoading(true);
|
setFavLoading(true);
|
||||||
if (isFav) {
|
if (isFav) {
|
||||||
await removeFavorite(property.id);
|
await removeFavorite(property.id);
|
||||||
@ -493,6 +493,7 @@ export default function PropertiesPage() {
|
|||||||
const [sortBy, setSortBy] = useState('newest');
|
const [sortBy, setSortBy] = useState('newest');
|
||||||
const [properties, setProperties] = useState([]);
|
const [properties, setProperties] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [showLoginDialog, setShowLoginDialog] = useState(false);
|
||||||
const [filters, setFilters] = useState({
|
const [filters, setFilters] = useState({
|
||||||
search: '',
|
search: '',
|
||||||
propertyType: 'all',
|
propertyType: 'all',
|
||||||
@ -625,7 +626,7 @@ export default function PropertiesPage() {
|
|||||||
: 'space-y-4'
|
: 'space-y-4'
|
||||||
}>
|
}>
|
||||||
{filteredProperties.map((property) => (
|
{filteredProperties.map((property) => (
|
||||||
<PropertyCard key={property.id} property={property} viewMode={viewMode} />
|
<PropertyCard key={property.id} property={property} viewMode={viewMode} onLoginRequired={() => setShowLoginDialog(true)} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -644,6 +645,36 @@ export default function PropertiesPage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Toaster position="top-center" />
|
<Toaster position="top-center" />
|
||||||
|
{showLoginDialog && (
|
||||||
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm" onClick={() => setShowLoginDialog(false)}>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.95 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="bg-white rounded-2xl p-6 max-w-sm w-full mx-4 shadow-xl text-center"
|
||||||
|
>
|
||||||
|
<div className="w-14 h-14 bg-amber-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||||
|
<Heart className="w-7 h-7 text-amber-600" />
|
||||||
|
</div>
|
||||||
|
<h3 className="text-xl font-bold text-gray-900 mb-2">تسجيل الدخول مطلوب</h3>
|
||||||
|
<p className="text-gray-500 mb-6">يجب تسجيل الدخول لإضافة العقارات إلى المفضلة</p>
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowLoginDialog(false)}
|
||||||
|
className="flex-1 py-3 border border-gray-200 rounded-xl font-medium text-gray-600 hover:bg-gray-50 transition-colors"
|
||||||
|
>
|
||||||
|
إلغاء
|
||||||
|
</button>
|
||||||
|
<Link
|
||||||
|
href="/login"
|
||||||
|
className="flex-1 py-3 bg-amber-500 text-white rounded-xl font-medium hover:bg-amber-600 transition-colors text-center"
|
||||||
|
>
|
||||||
|
تسجيل الدخول
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -422,7 +422,7 @@ export default function PropertyDetailsPage() {
|
|||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (!AuthService.isAuthenticated()) { toast.error('سجل الدخول أولاً'); return; }
|
if (!AuthService.isAuthenticated()) { setShowLoginDialog(true); return; }
|
||||||
const propId = property?._raw?.id || parseInt(params.id);
|
const propId = property?._raw?.id || parseInt(params.id);
|
||||||
setFavLoading(true);
|
setFavLoading(true);
|
||||||
if (isFavorite(propId)) {
|
if (isFavorite(propId)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user