feat(mobile): implement property photo swipe and refine lightbox UI
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user