Оптимизирована галерея фотографий и убраны индикаторы качества с фото
- Создан отдельный 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' %}
|
||||
{% load quality_tags %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}{{ product.name }}{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'products/css/gallery.css' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
@@ -40,9 +45,6 @@
|
||||
<img src="{{ photo.get_thumbnail_url }}"
|
||||
alt="Фото товара"
|
||||
style="max-width: 100%; max-height: 100%; object-fit: contain;">
|
||||
|
||||
<!-- Индикатор качества в углу -->
|
||||
{% quality_indicator photo %}
|
||||
</div>
|
||||
<div class="card-body p-2 text-center">
|
||||
{% if photo.order == 0 %}
|
||||
@@ -70,54 +72,58 @@
|
||||
<h5 class="modal-title" id="photoGalleryModalLabel">Галерея фотографий товара</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="photoCarousel" class="carousel slide" data-bs-ride="false">
|
||||
<div class="modal-body p-2 p-md-3">
|
||||
<div id="photoCarousel" class="carousel slide" data-bs-ride="carousel">
|
||||
<!-- Индикаторы (круглые точки) -->
|
||||
{% if photos_count > 1 %}
|
||||
<div class="carousel-indicators">
|
||||
{% for photo in product_photos %}
|
||||
<button type="button" data-bs-target="#photoCarousel" data-bs-slide-to="{{ forloop.counter0 }}"
|
||||
{% if forloop.first %}class="active" aria-current="true"{% endif %}
|
||||
aria-label="Слайд {{ forloop.counter }}"></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: 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 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 %}
|
||||
</div>
|
||||
|
||||
<!-- Кнопки навигации -->
|
||||
{% 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 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>
|
||||
|
||||
<!-- Навигация и индикаторы под фото -->
|
||||
<!-- Дополнительная информация под каруселью -->
|
||||
{% if photos_count > 1 %}
|
||||
<div class="d-flex justify-content-center align-items-center mt-3 gap-3">
|
||||
<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 %}
|
||||
<button type="button" data-bs-target="#photoCarousel" data-bs-slide-to="{{ forloop.counter0 }}"
|
||||
{% if forloop.first %}class="active" aria-current="true"{% endif %}
|
||||
aria-label="Слайд {{ forloop.counter }}"
|
||||
style="background-color: #6c757d;"></button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<button class="btn btn-outline-secondary" type="button" data-bs-target="#photoCarousel" data-bs-slide="next">
|
||||
Следующее <i class="bi bi-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-2">
|
||||
<small class="text-muted">
|
||||
<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>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div id="galleryQualityStatus" class="me-auto">
|
||||
<div class="modal-footer py-2 flex-wrap">
|
||||
<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>
|
||||
<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>
|
||||
@@ -315,7 +321,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const photoCarousel = document.getElementById('photoCarousel');
|
||||
|
||||
if (photoGalleryModal && photoCarousel) {
|
||||
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||
const currentSlideEl = document.getElementById('currentSlide');
|
||||
const mainBadgeEl = document.getElementById('mainBadge');
|
||||
|
||||
@@ -338,11 +343,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const button = event.relatedTarget;
|
||||
const slideIndex = button.getAttribute('data-bs-slide-to');
|
||||
if (slideIndex !== null) {
|
||||
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||
carousel.to(parseInt(slideIndex));
|
||||
}
|
||||
});
|
||||
|
||||
// Обновление счетчика, бейджа и статуса качества при переключении слайдов
|
||||
// Обновление статуса при переключении слайдов
|
||||
photoCarousel.addEventListener('slid.bs.carousel', function (event) {
|
||||
const activeIndex = event.to;
|
||||
const photoInfo = photos[activeIndex];
|
||||
@@ -360,26 +366,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Обновляем статус качества
|
||||
const qualityStatusEl = document.getElementById('galleryQualityStatus');
|
||||
if (qualityStatusEl && photoInfo) {
|
||||
let qualityHTML = '';
|
||||
|
||||
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;
|
||||
updateQualityStatus(qualityStatusEl, photoInfo);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -387,9 +374,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const handleKeydown = function(event) {
|
||||
if (event.key === 'ArrowLeft') {
|
||||
event.preventDefault();
|
||||
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||
carousel.prev();
|
||||
} else if (event.key === 'ArrowRight') {
|
||||
event.preventDefault();
|
||||
const carousel = bootstrap.Carousel.getOrCreateInstance(photoCarousel);
|
||||
carousel.next();
|
||||
}
|
||||
};
|
||||
@@ -401,27 +390,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Инициализируем статус качества первого фото
|
||||
const qualityStatusEl = document.getElementById('galleryQualityStatus');
|
||||
if (qualityStatusEl && photos[0]) {
|
||||
const photoInfo = photos[0];
|
||||
let qualityHTML = '';
|
||||
|
||||
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;
|
||||
updateQualityStatus(qualityStatusEl, photos[0]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -429,6 +398,30 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
photoGalleryModal.addEventListener('hidden.bs.modal', function () {
|
||||
document.removeEventListener('keydown', handleKeydown);
|
||||
});
|
||||
|
||||
// Функция обновления статуса качества
|
||||
function updateQualityStatus(element, photoInfo) {
|
||||
let qualityHTML = '';
|
||||
|
||||
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>`;
|
||||
}
|
||||
|
||||
element.innerHTML = qualityHTML;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -188,9 +188,6 @@
|
||||
title="Нажмите для увеличения">
|
||||
<img src="{{ photo.get_thumbnail_url }}" class="card-img-top" alt="{{ kit.name }}"
|
||||
style="height: 100%; width: 100%; object-fit: cover;">
|
||||
|
||||
<!-- Индикатор качества в углу -->
|
||||
{% quality_indicator photo %}
|
||||
</div>
|
||||
{% if photo.order == 0 %}
|
||||
<div class="card-footer bg-success text-white text-center small">⭐ Главное</div>
|
||||
|
||||
@@ -142,15 +142,8 @@
|
||||
<td>
|
||||
{% if item.photos.all %}
|
||||
{% with photo=item.photos.first %}
|
||||
<div class="photo-list-item">
|
||||
<img src="{{ photo.get_thumbnail_url }}" alt="{{ item.name }}"
|
||||
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>
|
||||
<img src="{{ photo.get_thumbnail_url }}" alt="{{ item.name }}"
|
||||
class="img-thumbnail rounded" style="width: 60px; height: 60px; object-fit: cover;">
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<span class="text-muted small">Нет фото</span>
|
||||
@@ -320,27 +313,4 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</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 %}
|
||||
|
||||
Reference in New Issue
Block a user