# Hình Ảnh - Thẻ Tham Khảo Nhanh ## 🎯 Tổng Quan | Mục | Trạng Thái | Chi Tiết | |-----|------------|----------| | **Thẻ HTML ``** | ✅ Tìm thấy 0 | Tất cả đã được thay thế bằng next/image | | **next/image Đã Dùng** | ✅ 8 tệp | Triển khai đúng cách trên toàn ứng dụng | | **Thành Phần Hình Ảnh** | ✅ 3 chuyên biệt | Gallery, Lightbox, Upload | | **Cấu Hình** | ✅ Đã cấu hình | remotePatterns + tiêu đề CSP | | **Khả Năng Tiếp Cận** | ✅ Hỗ trợ đầy đủ | Văn bản thay thế, điều hướng bàn phím, ARIA | | **Bảo Mật** | ✅ Chỉ HTTPS | CSP đã cấu hình, blob URL cho xem trước | --- ## 📁 Vị Trí Sử Dụng Hình Ảnh ### **Thành Phần Hình Ảnh Cốt Lõi** ``` components/listings/image-gallery.tsx ← Trình xem thư viện chính components/listings/image-lightbox.tsx ← Xem toàn màn hình components/listings/image-upload.tsx ← Tải lên với xem trước ``` ### **Các Thành Phần Hiển Thị Hình Ảnh** ``` components/search/property-card.tsx → Hình thu nhỏ trong kết quả tìm kiếm components/agents/agent-profile-client.tsx → Ảnh đại diện + danh sách của môi giới components/comparison/comparison-table.tsx → Hình ảnh so sánh components/listings/listing-detail-client.tsx → Tích hợp ImageGallery ``` ### **Thành Phần Trang** ``` app/[locale]/(public)/listings/[id]/page.tsx → Chi tiết tin đăng (dùng ImageGallery) app/[locale]/(public)/search/page.tsx → Kết quả tìm kiếm (dùng PropertyCard) app/[locale]/(public)/agents/[id]/page.tsx → Hồ sơ môi giới app/[locale]/(dashboard)/listings/page.tsx → Danh sách bảng điều khiển app/[locale]/(dashboard)/listings/new/page.tsx → Tải lên tin đăng mới ``` --- ## 🔧 Cấu Hình ### **next.config.js** ```javascript images: { remotePatterns: [ { protocol: 'https', hostname: '**', }, ], } ``` ### **Tiêu Đề CSP** ``` img-src 'self' data: blob: https://*.mapbox.com https://*.tiles.mapbox.com https: ``` - ✅ Cho phép blob: (xem trước tệp) - ✅ Cho phép data: (hình ảnh nội tuyến) - ✅ Cho phép tất cả HTTPS --- ## 📊 Chi Tiết Thành Phần Hình Ảnh ### ImageGallery ```typescript ``` **Tính năng:** Ảnh chính + hình thu nhỏ, điều hướng, bộ đếm, tích hợp lightbox ### ImageLightbox ```typescript setIsOpen(false)} /> ``` **Tính năng:** Điều hướng bàn phím, vuốt, tải trước, bẫy tiêu điểm ### ImageUpload ```typescript ``` **Tính năng:** Kéo-thả, xác thực (JPEG/PNG/WebP), xem trước, dọn dẹp --- ## 🎨 Kiểu Dữ Liệu Hình Ảnh ```typescript interface PropertyMedia { id: string; url: string; // URL hình ảnh type: 'image' | 'video'; // Loại phương tiện order: number; // Thứ tự hiển thị caption?: string; // Chú thích tùy chọn } interface ImageFile { file: File; // Tệp trình duyệt preview: string; // blob: URL } ``` --- ## ⚡ Tính Năng Hiệu Suất | Tính Năng | Trạng Thái | |-----------|------------| | Kích thước thích ứng (thuộc tính `sizes`) | ✅ Đã triển khai | | Tải ưu tiên cho nội dung phía trên nếp gấp | ✅ Đã triển khai | | Tải trước hình ảnh trong lightbox | ✅ Đã triển khai | | Dọn dẹp blob URL (bộ nhớ) | ✅ Đã triển khai | | Placeholder xương | ⚠️ Chưa triển khai | | Nén hình ảnh khi tải lên | ⚠️ Chưa triển khai | --- ## ♿ Tính Năng Khả Năng Tiếp Cận | Tính Năng | Trạng Thái | |-----------|------------| | Văn bản thay thế trên hình ảnh | ✅ Tiếng Việt | | Nhãn ARIA | ✅ Đã triển khai | | Điều hướng bàn phím | ✅ Phím mũi tên + Escape | | Bẫy tiêu điểm trong hộp thoại | ✅ Đã triển khai | | Bẫy tab | ✅ Đã triển khai | --- ## 🔒 Danh Sách Kiểm Tra Bảo Mật - ✅ Mẫu remote chỉ dùng HTTPS - ✅ Tiêu đề CSP đã cấu hình - ✅ blob: URL chỉ dùng cho xem trước phía máy khách - ⚠️ Xác thực URL hình ảnh tại API - **CẦN LÀM** - ⚠️ Quét tệp tải lên của người dùng - **CẦN LÀM** --- ## 📝 Các Tác Vụ Thông Dụng ### Thêm Hình Ảnh vào Thành Phần ```tsx import Image from 'next/image'; Văn bản mô tả bằng tiếng Việt ``` ### Hiển Thị Thư Viện Hình Ảnh ```tsx import { ImageGallery } from '@/components/listings/image-gallery'; ``` ### Tải Lên Tệp ```tsx import { ImageUpload } from '@/components/listings/image-upload'; const [images, setImages] = useState([]); ``` --- ## 🚨 Lưu Ý Quan Trọng 1. **Không bao giờ dùng thẻ HTML ``** - Sử dụng `next/image` thay thế 2. **Ngoại lệ:** Xem trước blob URL trong image-upload là chấp nhận được 3. **Luôn cung cấp văn bản thay thế** - Dùng văn bản tiếng Việt 4. **Dùng thuộc tính `sizes`** - Cho hình ảnh thích ứng 5. **Đặt `priority`** - Cho hình ảnh phía trên nếp gấp 6. **Thu hồi blob URL** - Khi huỷ gắn kết để ngăn rò rỉ bộ nhớ 7. **Xác thực URL hình ảnh** - Tại lớp API trước khi trả về --- ## 📞 Câu Hỏi? Xem `IMAGE_AUDIT_REPORT.md` để biết chi tiết đầy đủ và các khuyến nghị.