feat(mobile): implement property photo swipe and refine lightbox UI

This commit is contained in:
Satyam
2026-02-13 14:14:21 +05:30
parent fae968a541
commit 33384d8b7f
+33 -10
View File
@@ -33,6 +33,8 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
// Lightbox State
const [lightboxIndex, setLightboxIndex] = useState(null); // null = closed, number = open at index
const [touchStart, setTouchStart] = useState(null);
const [touchEnd, setTouchEnd] = useState(null);
const panelRef = useRef(null);
const closeButtonRef = useRef(null);
@@ -206,6 +208,29 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
if (data) setIsEditing(false);
};
// Swipe Logic for Lightbox
const handleTouchStart = (e) => {
setTouchEnd(null);
setTouchStart(e.targetTouches[0].clientX);
};
const handleTouchMove = (e) => {
setTouchEnd(e.targetTouches[0].clientX);
};
const handleTouchEnd = () => {
if (!touchStart || !touchEnd) return;
const distance = touchStart - touchEnd;
const isLeftSwipe = distance > 50;
const isRightSwipe = distance < -50;
if (isLeftSwipe) {
setLightboxIndex((prev) => (prev + 1) % photos.length);
} else if (isRightSwipe) {
setLightboxIndex((prev) => (prev - 1 + photos.length) % photos.length);
}
};
// Photo Logic
const handleUploadPhoto = (e) => {
const file = e.target.files[0];
@@ -624,11 +649,14 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
{/* LIGHTBOX OVERLAY */}
{lightboxIndex !== null && photos[lightboxIndex] && (
<div
className="fixed inset-0 z-[2000] bg-black/95 backdrop-blur-sm flex items-center justify-center p-4 animate-in fade-in duration-200 focus:outline-none"
className="fixed inset-0 z-[2000] bg-black/95 backdrop-blur-sm flex items-center justify-center p-4 animate-in fade-in duration-200 focus:outline-none touch-none"
tabIndex={-1}
ref={lightboxRef}
role="dialog"
aria-label="Photo Lightbox"
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>
{/* Close Button */}
<button
@@ -642,10 +670,10 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
{/* Navigation Left */}
<button
onClick={(e) => { e.stopPropagation(); setLightboxIndex((prev) => (prev - 1 + photos.length) % photos.length); }}
className="absolute left-4 text-white/70 hover:text-white p-3 rounded-full hover:bg-white/10 transition-colors z-50 focus:ring-2 focus:ring-white hidden md:block"
className="absolute left-2 md:left-4 text-white/70 hover:text-white p-2 md:p-3 rounded-full hover:bg-white/10 transition-colors z-50 focus:ring-2 focus:ring-white"
aria-label="Previous photo"
>
<ChevronLeft size={32} />
<ChevronLeft size={28} className="md:w-8 md:h-8" />
</button>
{/* Main Image */}
@@ -664,17 +692,12 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
{/* Navigation Right */}
<button
onClick={(e) => { e.stopPropagation(); setLightboxIndex((prev) => (prev + 1) % photos.length); }}
className="absolute right-4 text-white/70 hover:text-white p-3 rounded-full hover:bg-white/10 transition-colors z-50 focus:ring-2 focus:ring-white hidden md:block"
className="absolute right-2 md:right-4 text-white/70 hover:text-white p-2 md:p-3 rounded-full hover:bg-white/10 transition-colors z-50 focus:ring-2 focus:ring-white"
aria-label="Next photo"
>
<ChevronRight size={32} />
<ChevronRight size={28} className="md:w-8 md:h-8" />
</button>
{/* Mobile Navigation Hints (Optional) */}
<div className="md:hidden absolute bottom-8 flex space-x-8 text-white/30 text-xs pointer-events-none">
<span> Swipe Left</span>
<span>Swipe Right </span>
</div>
</div>
)}
</div>