import React, { useEffect, useState, useMemo } from 'react'; import { ChevronLeft, Image as ImageIcon, Download, Calendar, MapPin, Loader2, Filter, X, Trash2 } from 'lucide-react'; import { useNotification } from '@/hooks/useNotification'; import { useConfirm } from '@/hooks/useConfirm'; export const MyPhotosPage = ({ onBack }: { onBack: () => void }) => { const [photos, setPhotos] = useState([]); const [isLoading, setIsLoading] = useState(true); const [filterTourId, setFilterTourId] = useState(''); const [filterDate, setFilterDate] = useState(''); const [selectedPhoto, setSelectedPhoto] = useState(null); // State cho lightbox const [sortOrder, setSortOrder] = useState<'newest' | 'oldest'>('newest'); // 'newest' by default const notify = useNotification(); const confirm = useConfirm(); useEffect(() => { const fetchPhotos = async () => { try { const response = await fetch('/api/v1/users/me/photos', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (!response.ok) throw new Error('Failed to fetch photos'); const data = await response.json(); setPhotos(data); } catch (error) { notify({ title: 'Lỗi', message: 'Không thể tải danh sách ảnh.', type: 'error' }); } finally { setIsLoading(false); } }; fetchPhotos(); }, []); // Lấy danh sách các Tour duy nhất để hiển thị trong bộ lọc const uniqueTours = useMemo(() => { const tourMap = new Map(); photos.forEach(p => { if (p.tourId && p.tour) { tourMap.set(p.tourId, { id: p.tourId, title: p.tour.title }); } }); return Array.from(tourMap.values()); }, [photos]); // Logic lọc ảnh tại Frontend const filteredPhotos = useMemo(() => { let sortedPhotos = photos.filter(p => { const matchTour = !filterTourId || p.tourId === filterTourId; // So sánh ngày định dạng YYYY-MM-DD const photoDate = p.capturedAt ? p.capturedAt.split('T')[0] : ''; const matchDate = !filterDate || photoDate === filterDate; return matchTour && matchDate; }); // Sắp xếp ảnh if (sortOrder === 'newest') { sortedPhotos.sort((a, b) => new Date(b.capturedAt).getTime() - new Date(a.capturedAt).getTime()); } else { // 'oldest' sortedPhotos.sort((a, b) => new Date(a.capturedAt).getTime() - new Date(b.capturedAt).getTime()); } return sortedPhotos; }, [photos, filterTourId, filterDate, sortOrder]); const handleDeletePhoto = async (photoId: string) => { const isConfirmed = await confirm({ title: 'Xóa ảnh này?', message: 'Bạn có chắc chắn muốn xóa ảnh này không? Hành động này không thể hoàn tác.' }); if (!isConfirmed) return; try { const response = await fetch(`/api/v1/photos/${photoId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (!response.ok) throw new Error('Failed to delete photo'); notify({ title: 'Thành công', message: 'Ảnh đã được xóa.', type: 'success' }); // Cập nhật lại danh sách ảnh sau khi xóa setPhotos(prev => prev.filter(p => p.id !== photoId)); setSelectedPhoto(null); // Đóng lightbox } catch (error) { notify({ title: 'Lỗi', message: 'Không thể xóa ảnh. Vui lòng thử lại.', type: 'error' }); } }; // Đóng lightbox khi nhấn ESC useEffect(() => { const handleEsc = (event: KeyboardEvent) => event.key === 'Escape' && setSelectedPhoto(null); window.addEventListener('keydown', handleEsc); return () => window.removeEventListener('keydown', handleEsc); }, []); return (
{/* Header */}

Ảnh của tôi

Kho lưu trữ ảnh gốc cá nhân

{/* Filter Bar - Thanh công cụ lọc */}
Bộ lọc:
{/* Lọc theo Tour */}
{/* Lọc theo Thời gian */}
setFilterDate(e.target.value)} className="pl-3 pr-3 py-2 bg-gray-50 border border-gray-100 rounded-xl text-xs font-bold outline-none focus:ring-2 focus:ring-blue-500 transition-all text-gray-700 cursor-pointer" />
{/* Lọc theo Sắp xếp */}
{/* Reset Filters - Nút xóa nhanh lọc */} {(filterTourId || filterDate) && ( )}

Kết quả: {filteredPhotos.length} / {photos.length} ảnh

{isLoading ? (

Đang tải kho ảnh...

) : filteredPhotos.length > 0 ? (
{filteredPhotos.map((photo) => (
setSelectedPhoto(photo)} className="group relative bg-white rounded-3xl overflow-hidden shadow-sm border border-gray-100 transition-all hover:shadow-xl hover:-translate-y-1 cursor-pointer" > {/* Image Preview */} {/* Info */}
{photo.tour?.title || 'Không rõ hành trình'}
{new Date(photo.capturedAt).toLocaleDateString('vi-VN')}
))}
) : (

Chưa có ảnh nào

Hãy tham gia các chuyến đi và lưu lại khoảnh khắc nhé!

)}
{/* Lightbox - Xem ảnh toàn màn hình */} {selectedPhoto && (
setSelectedPhoto(null)} > {/* Nút xóa ảnh */}
e.stopPropagation()}> Fullscreen view

{selectedPhoto.tour?.title || 'Không rõ hành trình'}

{new Date(selectedPhoto.capturedAt).toLocaleDateString('vi-VN', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}

{selectedPhoto.originalUrl && ( Tải xuống ảnh gốc )}
)}
); };