547 lines
19 KiB
HTML
547 lines
19 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Поставщики строительных материалов{% endblock %}
|
||
|
||
{% block content %}
|
||
<!-- Заголовок и кнопка добавления -->
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h2 class="page-title">Поставщики материалов</h2>
|
||
<a href="{{ url_for('add_client') }}" class="btn btn-primary">
|
||
<i class="fas fa-plus"></i> Новый поставщик
|
||
</a>
|
||
</div>
|
||
|
||
<!-- Поиск и сортировка - УЛУЧШЕННЫЙ СТИЛЬ -->
|
||
<div class="search-section mb-4">
|
||
<div class="search-header">
|
||
<h4 class="search-title">
|
||
<i class="fas fa-sliders-h"></i> Поиск и сортировка
|
||
</h4>
|
||
<a href="{{ url_for('index') }}" class="btn-clear">
|
||
<i class="fas fa-times"></i> Сбросить все
|
||
</a>
|
||
</div>
|
||
|
||
<form method="GET" action="{{ url_for('index') }}" id="filterForm" class="search-form">
|
||
<!-- Строка поиска -->
|
||
<div class="search-row">
|
||
<div class="search-input-wrapper">
|
||
<i class="fas fa-search search-icon"></i>
|
||
<input type="text" class="search-input" name="search" id="search"
|
||
placeholder="Поиск по названию или ИНН..."
|
||
value="{{ request.args.get('search', '') }}" autocomplete="off">
|
||
{% if request.args.get('search') %}
|
||
<a href="{{ url_for('index', sort=request.args.get('sort'), type=request.args.get('type'), rating=request.args.get('rating')) }}" class="search-clear">
|
||
<i class="fas fa-times-circle"></i>
|
||
</a>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Фильтры -->
|
||
<div class="filters-row">
|
||
<div class="filter-group">
|
||
<label for="type" class="filter-label">
|
||
<i class="fas fa-building"></i> Тип поставщика
|
||
</label>
|
||
<select class="filter-select" name="type" id="type">
|
||
<option value="all" {% if request.args.get('type') == 'all' or not request.args.get('type') %}selected{% endif %}>Все типы</option>
|
||
<option value="ЗАО" {% if request.args.get('type') == 'ЗАО' %}selected{% endif %}>ЗАО</option>
|
||
<option value="ОАО" {% if request.args.get('type') == 'ОАО' %}selected{% endif %}>ОАО</option>
|
||
<option value="ООО" {% if request.args.get('type') == 'ООО' %}selected{% endif %}>ООО</option>
|
||
<option value="ПАО" {% if request.args.get('type') == 'ПАО' %}selected{% endif %}>ПАО</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="filter-group">
|
||
<label for="sort" class="filter-label">
|
||
<i class="fas fa-sort-amount-down"></i> Сортировка
|
||
</label>
|
||
<select class="filter-select" name="sort" id="sort">
|
||
<option value="name_asc" {% if request.args.get('sort') == 'name_asc' or not request.args.get('sort') %}selected{% endif %}>Название (А-Я)</option>
|
||
<option value="name_desc" {% if request.args.get('sort') == 'name_desc' %}selected{% endif %}>Название (Я-А)</option>
|
||
<option value="rating_desc" {% if request.args.get('sort') == 'rating_desc' %}selected{% endif %}>Сначала высокий рейтинг</option>
|
||
<option value="rating_asc" {% if request.args.get('sort') == 'rating_asc' %}selected{% endif %}>Сначала низкий рейтинг</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="filter-group">
|
||
<label for="rating" class="filter-label">
|
||
<i class="fas fa-star"></i> Мин. рейтинг
|
||
</label>
|
||
<select class="filter-select" name="rating" id="rating">
|
||
<option value="0" {% if request.args.get('rating') == '0' or not request.args.get('rating') %}selected{% endif %}>Любой</option>
|
||
<option value="4" {% if request.args.get('rating') == '4' %}selected{% endif %}>4+</option>
|
||
<option value="4.5" {% if request.args.get('rating') == '4.5' %}selected{% endif %}>4.5+</option>
|
||
<option value="4.8" {% if request.args.get('rating') == '4.8' %}selected{% endif %}>4.8+</option>
|
||
</select>
|
||
</div>
|
||
|
||
<button type="submit" class="btn-apply">
|
||
<i class="fas fa-check"></i> Применить
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Активные фильтры -->
|
||
{% if request.args.get('search') or (request.args.get('type') and request.args.get('type') != 'all') or (request.args.get('rating') and request.args.get('rating') != '0') %}
|
||
<div class="active-filters mb-3">
|
||
<span class="active-filters-label">Активные фильтры:</span>
|
||
<div class="filter-tags">
|
||
{% if request.args.get('search') %}
|
||
<span class="filter-tag">
|
||
Поиск: "{{ request.args.get('search') }}"
|
||
<a href="{{ url_for('index', sort=request.args.get('sort'), type=request.args.get('type'), rating=request.args.get('rating')) }}" class="remove-tag">
|
||
<i class="fas fa-times"></i>
|
||
</a>
|
||
</span>
|
||
{% endif %}
|
||
{% if request.args.get('type') and request.args.get('type') != 'all' %}
|
||
<span class="filter-tag">
|
||
Тип: {{ request.args.get('type') }}
|
||
<a href="{{ url_for('index', search=request.args.get('search'), sort=request.args.get('sort'), rating=request.args.get('rating')) }}" class="remove-tag">
|
||
<i class="fas fa-times"></i>
|
||
</a>
|
||
</span>
|
||
{% endif %}
|
||
{% if request.args.get('rating') and request.args.get('rating') != '0' %}
|
||
<span class="filter-tag">
|
||
Рейтинг ≥ {{ request.args.get('rating') }}
|
||
<a href="{{ url_for('index', search=request.args.get('search'), sort=request.args.get('sort'), type=request.args.get('type')) }}" class="remove-tag">
|
||
<i class="fas fa-times"></i>
|
||
</a>
|
||
</span>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- Список поставщиков -->
|
||
{% if partners %}
|
||
<div class="row">
|
||
{% for partner in partners %}
|
||
{% include 'components/partner_card.html' %}
|
||
{% endfor %}
|
||
</div>
|
||
|
||
<!-- Информация о результатах поиска -->
|
||
<div class="row mt-3">
|
||
<div class="col-12">
|
||
<p class="text-muted">
|
||
<i class="fas fa-info-circle"></i>
|
||
Найдено поставщиков: <strong>{{ partners|length }}</strong>
|
||
{% if request.args.get('search') %}
|
||
по запросу "{{ request.args.get('search') }}"
|
||
{% endif %}
|
||
{% if request.args.get('type') and request.args.get('type') != 'all' %}
|
||
, тип: {{ request.args.get('type') }}
|
||
{% endif %}
|
||
{% if request.args.get('rating') and request.args.get('rating') != '0' %}
|
||
, рейтинг ≥ {{ request.args.get('rating') }}
|
||
{% endif %}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
{% else %}
|
||
<div class="alert alert-info">
|
||
<i class="fas fa-info-circle"></i>
|
||
{% if request.args.get('search') or request.args.get('type') != 'all' or request.args.get('rating') != '0' %}
|
||
<strong>Ничего не найдено</strong> по вашему запросу.
|
||
<br><a href="{{ url_for('index') }}" class="alert-link">Сбросить все фильтры</a>
|
||
{% else %}
|
||
Нет данных о поставщиках. <a href="{{ url_for('add_client') }}" class="alert-link">Добавьте первого поставщика</a>.
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- JavaScript -->
|
||
<script>
|
||
// Автоматическое применение при изменении фильтров
|
||
let filterTimeout;
|
||
|
||
document.getElementById('sort').addEventListener('change', function() {
|
||
clearTimeout(filterTimeout);
|
||
filterTimeout = setTimeout(() => {
|
||
document.getElementById('filterForm').submit();
|
||
}, 300);
|
||
});
|
||
|
||
document.getElementById('type').addEventListener('change', function() {
|
||
clearTimeout(filterTimeout);
|
||
filterTimeout = setTimeout(() => {
|
||
document.getElementById('filterForm').submit();
|
||
}, 300);
|
||
});
|
||
|
||
document.getElementById('rating').addEventListener('change', function() {
|
||
clearTimeout(filterTimeout);
|
||
filterTimeout = setTimeout(() => {
|
||
document.getElementById('filterForm').submit();
|
||
}, 300);
|
||
});
|
||
|
||
// Поиск с debounce
|
||
let searchTimeout;
|
||
document.getElementById('search').addEventListener('input', function() {
|
||
clearTimeout(searchTimeout);
|
||
searchTimeout = setTimeout(() => {
|
||
if (this.value.length >= 2 || this.value.length === 0) {
|
||
document.getElementById('filterForm').submit();
|
||
}
|
||
}, 800);
|
||
});
|
||
|
||
document.getElementById('search').addEventListener('keypress', function(e) {
|
||
if (e.key === 'Enter') {
|
||
e.preventDefault();
|
||
document.getElementById('filterForm').submit();
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
.page-title {
|
||
color: #A0522D;
|
||
font-size: 1.8rem;
|
||
font-weight: 600;
|
||
font-family: 'Verdana', sans-serif;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: #A0522D;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 8px;
|
||
padding: 10px 20px;
|
||
font-family: 'Verdana', sans-serif;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background: #8B4513;
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 8px rgba(160, 82, 45, 0.2);
|
||
}
|
||
|
||
/* ===== УЛУЧШЕННЫЙ ПОИСК И ФИЛЬТРЫ (КАК В КАТАЛОГЕ) ===== */
|
||
.search-section {
|
||
background: white;
|
||
border-radius: 16px;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||
padding: 20px;
|
||
margin-bottom: 25px;
|
||
border: 1px solid #DEB887;
|
||
}
|
||
|
||
.search-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.search-title {
|
||
font-size: 1.2rem;
|
||
font-weight: 600;
|
||
color: #2c3e50;
|
||
margin: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.search-title i {
|
||
color: #A0522D;
|
||
}
|
||
|
||
.btn-clear {
|
||
background: none;
|
||
border: 1px solid #DEB887;
|
||
padding: 8px 16px;
|
||
border-radius: 30px;
|
||
color: #6c757d;
|
||
font-size: 0.9rem;
|
||
transition: all 0.2s ease;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
|
||
.btn-clear:hover {
|
||
background: #FAEBD7;
|
||
border-color: #A0522D;
|
||
color: #A0522D;
|
||
}
|
||
|
||
.search-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 15px;
|
||
}
|
||
|
||
.search-row {
|
||
width: 100%;
|
||
}
|
||
|
||
.search-input-wrapper {
|
||
position: relative;
|
||
width: 100%;
|
||
}
|
||
|
||
.search-icon {
|
||
position: absolute;
|
||
left: 15px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: #adb5bd;
|
||
font-size: 1rem;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.search-input {
|
||
width: 100%;
|
||
height: 48px;
|
||
padding: 0 45px 0 45px;
|
||
border: 2px solid #DEB887;
|
||
border-radius: 30px;
|
||
font-size: 1rem;
|
||
transition: all 0.2s ease;
|
||
background: white;
|
||
}
|
||
|
||
.search-input:focus {
|
||
outline: none;
|
||
border-color: #A0522D;
|
||
box-shadow: 0 0 0 4px rgba(160, 82, 45, 0.1);
|
||
}
|
||
|
||
.search-input::placeholder {
|
||
color: #adb5bd;
|
||
}
|
||
|
||
.search-clear {
|
||
position: absolute;
|
||
right: 15px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: #adb5bd;
|
||
text-decoration: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.search-clear:hover {
|
||
color: #A0522D;
|
||
}
|
||
|
||
.filters-row {
|
||
display: flex;
|
||
gap: 15px;
|
||
align-items: flex-end;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.filter-group {
|
||
flex: 1;
|
||
min-width: 180px;
|
||
}
|
||
|
||
.filter-label {
|
||
display: block;
|
||
font-size: 0.85rem;
|
||
font-weight: 600;
|
||
color: #495057;
|
||
margin-bottom: 6px;
|
||
letter-spacing: 0.3px;
|
||
}
|
||
|
||
.filter-label i {
|
||
color: #A0522D;
|
||
margin-right: 4px;
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
.filter-select {
|
||
width: 100%;
|
||
height: 42px;
|
||
padding: 0 35px 0 12px;
|
||
border: 2px solid #DEB887;
|
||
border-radius: 10px;
|
||
font-size: 0.95rem;
|
||
color: #2c3e50;
|
||
background-color: white;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
appearance: none;
|
||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23A0522D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
|
||
background-repeat: no-repeat;
|
||
background-position: right 12px center;
|
||
background-size: 16px;
|
||
}
|
||
|
||
.filter-select:hover {
|
||
border-color: #A0522D;
|
||
}
|
||
|
||
.filter-select:focus {
|
||
outline: none;
|
||
border-color: #A0522D;
|
||
box-shadow: 0 0 0 3px rgba(160, 82, 45, 0.1);
|
||
}
|
||
|
||
.btn-apply {
|
||
background: #A0522D;
|
||
color: white;
|
||
border: none;
|
||
padding: 0 25px;
|
||
height: 42px;
|
||
border-radius: 10px;
|
||
font-size: 0.95rem;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.btn-apply:hover {
|
||
background: #8B4513;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 12px rgba(160, 82, 45, 0.3);
|
||
}
|
||
|
||
/* Активные фильтры */
|
||
.active-filters {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
flex-wrap: wrap;
|
||
padding: 10px 15px;
|
||
background: #FAEBD7;
|
||
border-radius: 30px;
|
||
font-size: 0.9rem;
|
||
margin-bottom: 20px;
|
||
border: 1px solid #DEB887;
|
||
}
|
||
|
||
.active-filters-label {
|
||
color: #6c757d;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.filter-tags {
|
||
display: flex;
|
||
gap: 8px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.filter-tag {
|
||
background: white;
|
||
border: 1px solid #DEB887;
|
||
padding: 6px 12px;
|
||
border-radius: 30px;
|
||
font-size: 0.9rem;
|
||
color: #2c3e50;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.remove-tag {
|
||
color: #adb5bd;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
.remove-tag:hover {
|
||
color: #dc3545;
|
||
}
|
||
|
||
/* ===== СТИЛИ ДЛЯ КАРТОЧЕК ПОСТАВЩИКОВ ===== */
|
||
.card {
|
||
border: 1px solid #DEB887;
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.text-muted {
|
||
font-family: 'Verdana', sans-serif;
|
||
color: #6c757d;
|
||
}
|
||
|
||
.alert {
|
||
border-radius: 12px;
|
||
border: 1px solid #DEB887;
|
||
background: #FAEBD7;
|
||
border-left: 4px solid #A0522D;
|
||
font-family: 'Verdana', sans-serif;
|
||
padding: 15px 20px;
|
||
}
|
||
|
||
.alert-link {
|
||
color: #A0522D;
|
||
font-weight: 600;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.alert-link:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
i {
|
||
color: #A0522D;
|
||
margin-right: 6px;
|
||
}
|
||
|
||
.btn-primary i, .btn-clear i, .btn-apply i {
|
||
color: inherit;
|
||
}
|
||
|
||
/* Стили для карточек поставщиков */
|
||
.partner-card {
|
||
background: white;
|
||
border: 1px solid #DEB887;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.partner-card:hover {
|
||
box-shadow: 0 8px 16px rgba(160, 82, 45, 0.1);
|
||
border-color: #A0522D;
|
||
}
|
||
|
||
/* ===== АДАПТИВНОСТЬ ===== */
|
||
@media (max-width: 768px) {
|
||
.filters-row {
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
}
|
||
|
||
.filter-group {
|
||
width: 100%;
|
||
}
|
||
|
||
.btn-apply {
|
||
width: 100%;
|
||
justify-content: center;
|
||
}
|
||
|
||
.active-filters {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
border-radius: 12px;
|
||
}
|
||
}
|
||
</style>
|
||
{% endblock %} |