Оптимизирована галерея фотографий и убраны индикаторы качества с фото
- Создан отдельный CSS файл products/static/products/css/gallery.css для стилей галереи - Перенесены все стили модальной карусели из quality_indicator.css в gallery.css - Добавлены современные стрелки навигации с широкой областью нажатия (80px) - Улучшена видимость элементов управления: контрастные обводки, тени, градиенты - Круглые индикаторы с полупрозрачной подложкой для видимости на любом фоне - Адаптивные размеры для планшетов (60px) и мобильных (50px) - Убраны визуальные индикаторы качества фото из углов изображений - Оставлена только текстовая информация о качестве под фотографиями - Упрощена разметка списка товаров - удалены ненужные обёртки и стили
This commit is contained in:
244
myproject/products/static/products/css/gallery.css
Normal file
244
myproject/products/static/products/css/gallery.css
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
/**
|
||||||
|
* Стили для фото-галереи товаров
|
||||||
|
* Современный дизайн карусели с адаптивной навигацией
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
Модальная галерея товара
|
||||||
|
========================= */
|
||||||
|
|
||||||
|
/* Компактный modal footer */
|
||||||
|
.modal-footer.py-2 {
|
||||||
|
padding-top: 0.5rem !important;
|
||||||
|
padding-bottom: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Стандартные индикаторы Bootstrap в стиле круглых точек */
|
||||||
|
#photoCarousel .carousel-indicators {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
margin: 0;
|
||||||
|
z-index: 15;
|
||||||
|
background: linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent);
|
||||||
|
padding: 8px 15px 5px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-indicators button {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 4px;
|
||||||
|
padding: 0;
|
||||||
|
border: 2px solid rgba(0, 0, 0, 0.3);
|
||||||
|
background-color: rgba(255, 255, 255, 0.6);
|
||||||
|
opacity: 0.8;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-indicators button:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
|
border-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-indicators button.active {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
opacity: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
border-color: rgba(0, 0, 0, 0.6);
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Современные кнопки навигации с широкой областью нажатия */
|
||||||
|
#photoCarousel .carousel-control-prev,
|
||||||
|
#photoCarousel .carousel-control-next {
|
||||||
|
width: 80px;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease, background-color 0.3s ease;
|
||||||
|
background: linear-gradient(to right, rgba(0, 0, 0, 0.3), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-next {
|
||||||
|
background: linear-gradient(to left, rgba(0, 0, 0, 0.3), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel:hover .carousel-control-prev,
|
||||||
|
#photoCarousel:hover .carousel-control-next {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev:hover {
|
||||||
|
background: linear-gradient(to right, rgba(0, 0, 0, 0.5), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-next:hover {
|
||||||
|
background: linear-gradient(to left, rgba(0, 0, 0, 0.5), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Современные иконки стрелок */
|
||||||
|
#photoCarousel .carousel-control-prev-icon,
|
||||||
|
#photoCarousel .carousel-control-next-icon {
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
/* Скрываем стандартные SVG иконки Bootstrap */
|
||||||
|
background-image: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Переопределяем стандартные стрелки Bootstrap на современные */
|
||||||
|
#photoCarousel .carousel-control-prev-icon::before,
|
||||||
|
#photoCarousel .carousel-control-next-icon::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-top: 3px solid #333;
|
||||||
|
border-right: 3px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev-icon::before {
|
||||||
|
transform: translate(-40%, -50%) rotate(-135deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-next-icon::before {
|
||||||
|
transform: translate(-60%, -50%) rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Эффект при наведении на иконку */
|
||||||
|
#photoCarousel .carousel-control-prev:hover .carousel-control-prev-icon,
|
||||||
|
#photoCarousel .carousel-control-next:hover .carousel-control-next-icon {
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev:hover .carousel-control-prev-icon::before,
|
||||||
|
#photoCarousel .carousel-control-next:hover .carousel-control-next-icon::before {
|
||||||
|
border-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
Адаптивность
|
||||||
|
========================= */
|
||||||
|
|
||||||
|
/* Планшеты и средние экраны */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
/* Уменьшаем отступы modal body на мобильных */
|
||||||
|
.modal-body.p-2 {
|
||||||
|
padding: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Уменьшаем высоту изображения на маленьких экранах */
|
||||||
|
.carousel-item > div {
|
||||||
|
min-height: 40vh !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item img {
|
||||||
|
max-height: 55vh !important;
|
||||||
|
max-width: 95vw !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Компактный footer */
|
||||||
|
.modal-footer {
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#galleryQualityStatus .badge {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
padding: 0.25rem 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Индикаторы чуть меньше на мобильных */
|
||||||
|
#photoCarousel .carousel-indicators button {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
margin: 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-indicators button.active {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Стрелки меньше на планшетах */
|
||||||
|
#photoCarousel .carousel-control-prev,
|
||||||
|
#photoCarousel .carousel-control-next {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev-icon,
|
||||||
|
#photoCarousel .carousel-control-next-icon {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev-icon::before,
|
||||||
|
#photoCarousel .carousel-control-next-icon::before {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-width: 2.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Мобильные телефоны */
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
#photoCarousel .carousel-indicators button {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-indicators button.active {
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Текст счетчика более компактный */
|
||||||
|
.text-nowrap {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Кнопки навигации меньше на мобильных */
|
||||||
|
#photoCarousel .carousel-control-prev,
|
||||||
|
#photoCarousel .carousel-control-next {
|
||||||
|
width: 50px;
|
||||||
|
/* Стрелки видимы всегда на мобильных */
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel:hover .carousel-control-prev,
|
||||||
|
#photoCarousel:hover .carousel-control-next {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev-icon,
|
||||||
|
#photoCarousel .carousel-control-next-icon {
|
||||||
|
width: 2.2rem;
|
||||||
|
height: 2.2rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photoCarousel .carousel-control-prev-icon::before,
|
||||||
|
#photoCarousel .carousel-control-next-icon::before {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load quality_tags %}
|
{% load quality_tags %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
{% block title %}{{ product.name }}{% endblock %}
|
{% block title %}{{ product.name }}{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'products/css/gallery.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -40,9 +45,6 @@
|
|||||||
<img src="{{ photo.get_thumbnail_url }}"
|
<img src="{{ photo.get_thumbnail_url }}"
|
||||||
alt="Фото товара"
|
alt="Фото товара"
|
||||||
style="max-width: 100%; max-height: 100%; object-fit: contain;">
|
style="max-width: 100%; max-height: 100%; object-fit: contain;">
|
||||||
|
|
||||||
<!-- Индикатор качества в углу -->
|
|
||||||
{% quality_indicator photo %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-2 text-center">
|
<div class="card-body p-2 text-center">
|
||||||
{% if photo.order == 0 %}
|
{% if photo.order == 0 %}
|
||||||
@@ -70,54 +72,58 @@
|
|||||||
<h5 class="modal-title" id="photoGalleryModalLabel">Галерея фотографий товара</h5>
|
<h5 class="modal-title" id="photoGalleryModalLabel">Галерея фотографий товара</h5>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body p-2 p-md-3">
|
||||||
<div id="photoCarousel" class="carousel slide" data-bs-ride="false">
|
<div id="photoCarousel" class="carousel slide" data-bs-ride="carousel">
|
||||||
<div class="carousel-inner">
|
<!-- Индикаторы (круглые точки) -->
|
||||||
{% for photo in product_photos %}
|
|
||||||
<div class="carousel-item {% if forloop.first %}active{% endif %}">
|
|
||||||
<div class="text-center" style="min-height: 60vh; display: flex; align-items: center; justify-content: center; background-color: #f8f9fa;">
|
|
||||||
<!-- Large 1200x1200 WebP для полного размера просмотра -->
|
|
||||||
<img src="{{ photo.get_large_url }}" class="d-block" alt="Фото товара" style="height: auto; width: auto; max-height: 75vh; max-width: 85vw; object-fit: contain;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Навигация и индикаторы под фото -->
|
|
||||||
{% if photos_count > 1 %}
|
{% if photos_count > 1 %}
|
||||||
<div class="d-flex justify-content-center align-items-center mt-3 gap-3">
|
<div class="carousel-indicators">
|
||||||
<button class="btn btn-outline-secondary" type="button" data-bs-target="#photoCarousel" data-bs-slide="prev">
|
|
||||||
<i class="bi bi-chevron-left"></i> Предыдущее
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="carousel-indicators position-static m-0">
|
|
||||||
{% for photo in product_photos %}
|
{% for photo in product_photos %}
|
||||||
<button type="button" data-bs-target="#photoCarousel" data-bs-slide-to="{{ forloop.counter0 }}"
|
<button type="button" data-bs-target="#photoCarousel" data-bs-slide-to="{{ forloop.counter0 }}"
|
||||||
{% if forloop.first %}class="active" aria-current="true"{% endif %}
|
{% if forloop.first %}class="active" aria-current="true"{% endif %}
|
||||||
aria-label="Слайд {{ forloop.counter }}"
|
aria-label="Слайд {{ forloop.counter }}"></button>
|
||||||
style="background-color: #6c757d;"></button>
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- Слайды с фотографиями -->
|
||||||
|
<div class="carousel-inner">
|
||||||
|
{% for photo in product_photos %}
|
||||||
|
<div class="carousel-item {% if forloop.first %}active{% endif %}">
|
||||||
|
<div class="text-center" style="min-height: 50vh; display: flex; align-items: center; justify-content: center; background-color: #f8f9fa;">
|
||||||
|
<img src="{{ photo.get_large_url }}" class="d-block" alt="Фото товара" style="height: auto; width: auto; max-height: 65vh; max-width: 90vw; object-fit: contain;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-outline-secondary" type="button" data-bs-target="#photoCarousel" data-bs-slide="next">
|
<!-- Кнопки навигации -->
|
||||||
Следующее <i class="bi bi-chevron-right"></i>
|
{% if photos_count > 1 %}
|
||||||
|
<button class="carousel-control-prev" type="button" data-bs-target="#photoCarousel" data-bs-slide="prev">
|
||||||
|
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||||
|
<span class="visually-hidden">Предыдущее</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="carousel-control-next" type="button" data-bs-target="#photoCarousel" data-bs-slide="next">
|
||||||
|
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||||
|
<span class="visually-hidden">Следующее</span>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Дополнительная информация под каруселью -->
|
||||||
|
{% if photos_count > 1 %}
|
||||||
<div class="text-center mt-2">
|
<div class="text-center mt-2">
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
<span id="currentSlide">1</span> из {{ photos_count }}
|
<span id="currentSlide">1</span> из {{ photos_count }}
|
||||||
<span id="mainBadge" {% if not product_photos.0.order == 0 %}style="display: none;"{% endif %} class="badge bg-success ms-2">⭐ Главное</span>
|
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer py-2 flex-wrap">
|
||||||
<div id="galleryQualityStatus" class="me-auto">
|
<div id="galleryQualityStatus" class="me-auto d-flex align-items-center gap-2">
|
||||||
<!-- Индикатор качества текущего фото в галерее -->
|
<!-- Индикатор качества текущего фото в галерее -->
|
||||||
|
<span id="mainBadge" {% if not product_photos.0.order == 0 %}style="display: none;"{% endif %} class="badge bg-success">⭐ Главное</span>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Закрыть</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -315,7 +321,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const photoCarousel = document.getElementById('photoCarousel');
|
const photoCarousel = document.getElementById('photoCarousel');
|
||||||
|
|
||||||
if (photoGalleryModal && photoCarousel) {
|
if (photoGalleryModal && photoCarousel) {
|
||||||
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
|
||||||
const currentSlideEl = document.getElementById('currentSlide');
|
const currentSlideEl = document.getElementById('currentSlide');
|
||||||
const mainBadgeEl = document.getElementById('mainBadge');
|
const mainBadgeEl = document.getElementById('mainBadge');
|
||||||
|
|
||||||
@@ -338,11 +343,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const button = event.relatedTarget;
|
const button = event.relatedTarget;
|
||||||
const slideIndex = button.getAttribute('data-bs-slide-to');
|
const slideIndex = button.getAttribute('data-bs-slide-to');
|
||||||
if (slideIndex !== null) {
|
if (slideIndex !== null) {
|
||||||
|
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||||
carousel.to(parseInt(slideIndex));
|
carousel.to(parseInt(slideIndex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Обновление счетчика, бейджа и статуса качества при переключении слайдов
|
// Обновление статуса при переключении слайдов
|
||||||
photoCarousel.addEventListener('slid.bs.carousel', function (event) {
|
photoCarousel.addEventListener('slid.bs.carousel', function (event) {
|
||||||
const activeIndex = event.to;
|
const activeIndex = event.to;
|
||||||
const photoInfo = photos[activeIndex];
|
const photoInfo = photos[activeIndex];
|
||||||
@@ -360,26 +366,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Обновляем статус качества
|
// Обновляем статус качества
|
||||||
const qualityStatusEl = document.getElementById('galleryQualityStatus');
|
const qualityStatusEl = document.getElementById('galleryQualityStatus');
|
||||||
if (qualityStatusEl && photoInfo) {
|
if (qualityStatusEl && photoInfo) {
|
||||||
let qualityHTML = '';
|
updateQualityStatus(qualityStatusEl, photoInfo);
|
||||||
|
|
||||||
if (photoInfo.quality_warning) {
|
|
||||||
qualityHTML = '<span class="badge bg-danger"><i class="bi bi-exclamation-circle"></i> Требует обновления</span>';
|
|
||||||
} else {
|
|
||||||
const qualityInfo = {
|
|
||||||
'excellent': { symbol: '🟢', label: 'Отлично', color: 'success' },
|
|
||||||
'good': { symbol: '🟡', label: 'Хорошо', color: 'info' },
|
|
||||||
'acceptable': { symbol: '🟠', label: 'Приемлемо', color: 'warning' },
|
|
||||||
'poor': { symbol: '🔴', label: 'Плохо', color: 'danger' },
|
|
||||||
'very_poor': { symbol: '🔴', label: 'Очень плохо', color: 'danger' },
|
|
||||||
};
|
|
||||||
|
|
||||||
const info = qualityInfo[photoInfo.quality_level] || { symbol: '⚪', label: 'Неизвестно', color: 'secondary' };
|
|
||||||
const sizeInfo = photoInfo.width && photoInfo.height ? ` (${photoInfo.width}×${photoInfo.height}px)` : '';
|
|
||||||
|
|
||||||
qualityHTML = `<span class="badge bg-${info.color}">${info.symbol} ${info.label}${sizeInfo}</span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
qualityStatusEl.innerHTML = qualityHTML;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -387,9 +374,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const handleKeydown = function(event) {
|
const handleKeydown = function(event) {
|
||||||
if (event.key === 'ArrowLeft') {
|
if (event.key === 'ArrowLeft') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||||
carousel.prev();
|
carousel.prev();
|
||||||
} else if (event.key === 'ArrowRight') {
|
} else if (event.key === 'ArrowRight') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||||
carousel.next();
|
carousel.next();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -401,7 +390,17 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Инициализируем статус качества первого фото
|
// Инициализируем статус качества первого фото
|
||||||
const qualityStatusEl = document.getElementById('galleryQualityStatus');
|
const qualityStatusEl = document.getElementById('galleryQualityStatus');
|
||||||
if (qualityStatusEl && photos[0]) {
|
if (qualityStatusEl && photos[0]) {
|
||||||
const photoInfo = photos[0];
|
updateQualityStatus(qualityStatusEl, photos[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Удаляем обработчик клавиш при закрытии модального окна
|
||||||
|
photoGalleryModal.addEventListener('hidden.bs.modal', function () {
|
||||||
|
document.removeEventListener('keydown', handleKeydown);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Функция обновления статуса качества
|
||||||
|
function updateQualityStatus(element, photoInfo) {
|
||||||
let qualityHTML = '';
|
let qualityHTML = '';
|
||||||
|
|
||||||
if (photoInfo.quality_warning) {
|
if (photoInfo.quality_warning) {
|
||||||
@@ -421,14 +420,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
qualityHTML = `<span class="badge bg-${info.color}">${info.symbol} ${info.label}${sizeInfo}</span>`;
|
qualityHTML = `<span class="badge bg-${info.color}">${info.symbol} ${info.label}${sizeInfo}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
qualityStatusEl.innerHTML = qualityHTML;
|
element.innerHTML = qualityHTML;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Удаляем обработчик клавиш при закрытии модального окна
|
|
||||||
photoGalleryModal.addEventListener('hidden.bs.modal', function () {
|
|
||||||
document.removeEventListener('keydown', handleKeydown);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -188,9 +188,6 @@
|
|||||||
title="Нажмите для увеличения">
|
title="Нажмите для увеличения">
|
||||||
<img src="{{ photo.get_thumbnail_url }}" class="card-img-top" alt="{{ kit.name }}"
|
<img src="{{ photo.get_thumbnail_url }}" class="card-img-top" alt="{{ kit.name }}"
|
||||||
style="height: 100%; width: 100%; object-fit: cover;">
|
style="height: 100%; width: 100%; object-fit: cover;">
|
||||||
|
|
||||||
<!-- Индикатор качества в углу -->
|
|
||||||
{% quality_indicator photo %}
|
|
||||||
</div>
|
</div>
|
||||||
{% if photo.order == 0 %}
|
{% if photo.order == 0 %}
|
||||||
<div class="card-footer bg-success text-white text-center small">⭐ Главное</div>
|
<div class="card-footer bg-success text-white text-center small">⭐ Главное</div>
|
||||||
|
|||||||
@@ -142,15 +142,8 @@
|
|||||||
<td>
|
<td>
|
||||||
{% if item.photos.all %}
|
{% if item.photos.all %}
|
||||||
{% with photo=item.photos.first %}
|
{% with photo=item.photos.first %}
|
||||||
<div class="photo-list-item">
|
|
||||||
<img src="{{ photo.get_thumbnail_url }}" alt="{{ item.name }}"
|
<img src="{{ photo.get_thumbnail_url }}" alt="{{ item.name }}"
|
||||||
class="img-thumbnail rounded" style="width: 60px; height: 60px; object-fit: cover;">
|
class="img-thumbnail rounded" style="width: 60px; height: 60px; object-fit: cover;">
|
||||||
{% if item.item_type == 'product' %}
|
|
||||||
<span class="quality-icon" title="{{ photo.get_quality_level_display }}">
|
|
||||||
{{ photo|quality_icon_only }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="text-muted small">Нет фото</span>
|
<span class="text-muted small">Нет фото</span>
|
||||||
@@ -320,27 +313,4 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Стили для индикатора качества фото */
|
|
||||||
.photo-list-item {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-list-item .quality-icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
right: 2px;
|
|
||||||
font-size: 14px;
|
|
||||||
background: rgba(255, 255, 255, 0.9);
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user