project2463/templates/index.html

547 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% 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 %}