# Визуализация новой галереи портфолио ## Структура страницы портфолио (Desktop) ``` ┌─────────────────────────────────────────────────────────────────┐ │ SmartSolTech │ │ Главная > Портфолио > Название проекта │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ [Badge: Web] [Badge: E-commerce] [Badge: Mobile] │ │ │ │ Название проекта │ │ 👤 Клиент: ООО "Компания" │ │ 📅 Дата завершения: 15.11.2024 │ └─────────────────────────────────────────────────────────────────┘ ┌──────┬──────────────────────────────────────────────────────────┐ │ IMG1 │ │ │[✓] │ │ │──────│ ◀ ▶ │ │ IMG2 │ │ │ │ ГЛАВНОЕ ИЗОБРАЖЕНИЕ │ │──────│ │ │ IMG3 │ (600px height) │ │ │ │ │──────│ │ │ IMG4 │ [🔍 Изображение 1 из 5] │ │ │ "Подпись к фото" │ └──────┴──────────────────────────────────────────────────────────┘ 120px Flex: 1 ┌─────────────────────────────────────────────────────────────────┐ │ О проекте │ │ │ │ Lorem ipsum dolor sit amet, consectetur adipiscing elit... │ │ │ └─────────────────────────────────────────────────────────────────┘ [← Все проекты] ``` ## Структура на мобильных устройствах ``` ┌─────────────────────────────┐ │ [Badge] [Badge] │ │ │ │ Название проекта │ │ 👤 Клиент | 📅 Дата │ └─────────────────────────────┘ ┌─────────────────────────────┐ │ [IMG1][IMG2][IMG3][IMG4]>>> │ ← Горизонтальный скролл └─────────────────────────────┘ ┌─────────────────────────────┐ │ │ │ ◀ ▶ │ │ │ │ ГЛАВНОЕ ИЗОБРАЖЕНИЕ │ │ │ │ (400px) │ │ │ │ [🔍 Изображение 1 из 5] │ │ "Подпись к фото" │ └─────────────────────────────┘ ┌─────────────────────────────┐ │ О проекте │ │ │ │ Описание проекта... │ │ │ └─────────────────────────────┘ ``` ## Интерактивные элементы ### 1. Thumbnails (миниатюры) ``` ┌──────┐ │ IMG1 │ ← Неактивная (opacity: 0.6) └──────┘ ┌──────┐ │ IMG2 │ ← Активная (border: 3px blue, opacity: 1) └──────┘ ▲ │ Hover: scale(1.05) ``` ### 2. Навигация ``` Клавиатура: ← → (Arrow keys) Мышь: ▲ ▼ (Scroll wheel) Касание: ← → (Swipe gestures) Кнопки: ◀ ▶ (Click buttons) ``` ### 3. Lightbox (увеличение) ``` Клик по изображению → Открывается полноэкранный просмотр ┌─────────────────────────────────────────────────────────┐ │ ✕ │ │ │ │ ◀ ▶ │ │ │ │ ПОЛНОЭКРАННОЕ ФОТО │ │ │ │ │ │ Изображение 3 из 5 │ └─────────────────────────────────────────────────────────┘ ``` ## Изменения в админке ### Было (одна категория): ``` ┌─────────────────────────────────┐ │ Категория: [Выпадающий список ▼]│ │ ───────────────── │ │ │ Web Design │ │ │ │ Mobile App │ │ │ │ E-commerce │ │ │ ───────────────── │ └─────────────────────────────────┘ ``` ### Стало (множественные категории): ``` ┌──────────────────────────────────────────────────────────┐ │ Категории: │ │ │ │ Доступные категории Выбранные категории │ │ ┌───────────────┐ ┌────────────────┐ │ │ │ Mobile App │ ⇨ │ Web Design │ │ │ │ SEO │ │ E-commerce │ │ │ │ Marketing │ ⇦ │ UI/UX │ │ │ │ Consulting │ └────────────────┘ │ │ └───────────────┘ │ │ │ │ Подсказка: Двойной клик или стрелки для выбора │ └──────────────────────────────────────────────────────────┘ ``` ### Галерея изображений (Inline): ``` ┌──────────────────────────────────────────────────────────┐ │ Галерея изображений (3 фото): │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ Изображение │ Подпись │ Порядок │ 🗑️ │ │ │ ├────────────────────────────────────────────────────┤ │ │ │ [Выбрать файл]│ "Главная страница"│ 0 │ - │ │ │ │ [Выбрать файл]│ "Каталог товаров" │ 10 │ - │ │ │ │ [Выбрать файл]│ "Корзина" │ 20 │ - │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ [+ Добавить еще изображение] │ └──────────────────────────────────────────────────────────┘ ``` ## Пользовательский опыт ### Сценарий 1: Desktop пользователь 1. Открывает страницу проекта 2. Видит миниатюры слева, главное фото справа 3. Клик по миниатюре → фото меняется 4. Или использует стрелки ◀ ▶ 5. Или нажимает клавиши ← → 6. Или крутит колесо мыши 7. Клик по главному фото → открывается Lightbox 8. В Lightbox переключает фото стрелками ### Сценарий 2: Mobile пользователь 1. Открывает страницу проекта 2. Видит миниатюры сверху (горизонтальная полоса) 3. Свайпит влево → следующее фото 4. Свайпит вправо → предыдущее фото 5. Или тапает по миниатюре 6. Или использует кнопки ◀ ▶ 7. Тап по главному фото → Lightbox 8. В Lightbox свайпит для навигации ### Сценарий 3: Администратор 1. Заходит в админку портфолио 2. Создает новый проект или редактирует существующий 3. В поле "Категории" выбирает несколько категорий: - Web Design - E-commerce - UI/UX 4. Загружает главное изображение 5. Добавляет 5 дополнительных фото в галерею: - Каждому фото дает подпись - Устанавливает порядок: 0, 10, 20, 30, 40 6. Сохраняет 7. Открывает страницу проекта на сайте 8. Видит все категории как badges 9. Видит галерею с навигацией 10. Тестирует свайпы на планшете ## Адаптивность ### Desktop (> 768px): - Thumbnails: вертикально слева (120px width) - Main image: 600px height - Navigation buttons: 50x50px - Grid layout: Flex row ### Tablet (768px): - Thumbnails: горизонтально сверху - Main image: 400px height - Navigation buttons: 40x40px - Grid layout: Flex column-reverse ### Mobile (< 768px): - Thumbnails: 80x80px each - Main image: 400px height - Navigation buttons: 40x40px - Swipe sensitivity: 50px threshold - Touch-friendly buttons ## Технические особенности ### Performance оптимизации: ```python # В views.py item = get_object_or_404( PortfolioItem.objects.prefetch_related( 'categories', # ← Предзагрузка категорий 'gallery_images' # ← Предзагрузка галереи ), slug=slug, is_active=True ) ``` ### CSS transitions: ```css .thumbnail-item { transition: all 0.3s ease; /* ← Плавная анимация */ } .hover-zoom:hover { transform: scale(1.05); /* ← Увеличение при hover */ } ``` ### JavaScript debouncing: ```javascript // Wheel event с preventDefault для предотвращения // конфликта со скроллом страницы galleryMain.addEventListener('wheel', (e) => { if (Math.abs(e.deltaY) > 10) { e.preventDefault(); // ... navigation logic } }, { passive: false }); ``` ### Touch gestures: ```javascript const swipeThreshold = 50; // 50px минимум для свайпа function handleSwipe() { const swipeDistance = touchStartX - touchEndX; if (Math.abs(swipeDistance) > swipeThreshold) { // Обработка свайпа } } ``` ## Безопасность 1. **XSS защита**: - Caption экранируется Django templates - `{{ gallery_image.caption }}` auto-escapes HTML 2. **CSRF**: - Все формы админки защищены CSRF токенами 3. **Права доступа**: - Только авторизованные админы могут добавлять портфолио - Публичный доступ только к `is_active=True` проектам ## Масштабируемость - ✅ Поддержка неограниченного количества категорий - ✅ Поддержка неограниченного количества фото в галерее - ✅ Lazy loading возможен в будущем (добавить `loading="lazy"`) - ✅ CDN для Lightbox (не нагружает сервер) - ✅ Кэширование статики через Nginx