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 // Lightbox State
const [lightboxIndex, setLightboxIndex] = useState(null); // null = closed, number = open at index 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 panelRef = useRef(null);
const closeButtonRef = useRef(null); const closeButtonRef = useRef(null);
@@ -206,6 +208,29 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
if (data) setIsEditing(false); 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 // Photo Logic
const handleUploadPhoto = (e) => { const handleUploadPhoto = (e) => {
const file = e.target.files[0]; const file = e.target.files[0];
@@ -624,11 +649,14 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
{/* LIGHTBOX OVERLAY */} {/* LIGHTBOX OVERLAY */}
{lightboxIndex !== null && photos[lightboxIndex] && ( {lightboxIndex !== null && photos[lightboxIndex] && (
<div <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} tabIndex={-1}
ref={lightboxRef} ref={lightboxRef}
role="dialog" role="dialog"
aria-label="Photo Lightbox" aria-label="Photo Lightbox"
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
> >
{/* Close Button */} {/* Close Button */}
<button <button
@@ -642,10 +670,10 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
{/* Navigation Left */} {/* Navigation Left */}
<button <button
onClick={(e) => { e.stopPropagation(); setLightboxIndex((prev) => (prev - 1 + photos.length) % photos.length); }} 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" aria-label="Previous photo"
> >
<ChevronLeft size={32} /> <ChevronLeft size={28} className="md:w-8 md:h-8" />
</button> </button>
{/* Main Image */} {/* Main Image */}
@@ -664,17 +692,12 @@ const PropertyDetailDrawer = ({ isOpen, onClose, data, newLocation, onSave, load
{/* Navigation Right */} {/* Navigation Right */}
<button <button
onClick={(e) => { e.stopPropagation(); setLightboxIndex((prev) => (prev + 1) % photos.length); }} 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" aria-label="Next photo"
> >
<ChevronRight size={32} /> <ChevronRight size={28} className="md:w-8 md:h-8" />
</button> </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>
)} )}
</div> </div>