Files
octopus/myproject/customers/templates/customers/customer_list.html
Andrey Smakotin b27fb1236a Добавлена нумерация страниц в пагинацию
- Вместо текста 'X / Y' теперь кликабельные цифры страниц
- Показывается до 10 страниц (±5 от текущей)
- Текущая страница выделена (active)
- Умная логика: если на странице 15, показывает 10-20
- Все параметры фильтров сохраняются при клике на номер страницы
2026-01-03 15:13:41 +03:00

208 lines
12 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="container-fluid">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<h1>Клиенты</h1>
<p class="text-muted mb-0">
Всего клиентов: <strong>{{ total_customers }}</strong>
</p>
</div>
<div class="btn-group" role="group">
<a href="{% url 'customers:customer-import' %}" class="btn btn-outline-success">
<i class="bi bi-upload"></i> Импорт
</a>
<a href="{% url 'customers:customer-export' %}" class="btn btn-outline-info">
<i class="bi bi-download"></i> Экспорт
</a>
<a href="{% url 'customers:customer-create' %}" class="btn btn-primary">
<i class="bi bi-plus-circle"></i> Добавить клиента
</a>
</div>
</div>
<!-- Поиск и фильтры -->
<div class="card mb-3">
<div class="card-body">
<form method="get" class="row g-3">
<!-- Поиск -->
<div class="col-md-6">
<input type="text" class="form-control" name="q" value="{{ query }}"
placeholder="Поиск по имени, email или телефону..."
autofocus>
</div>
<!-- Фильтры -->
<div class="col-md-6">
<div class="d-flex gap-3 align-items-center">
<div class="form-check">
{{ filter.form.has_notes }}
<label class="form-check-label" for="{{ filter.form.has_notes.id_for_label }}">
Есть заметки
</label>
</div>
<div class="form-check">
{{ filter.form.no_phone }}
<label class="form-check-label" for="{{ filter.form.no_phone.id_for_label }}">
Нет телефона
</label>
</div>
<div class="form-check">
{{ filter.form.no_email }}
<label class="form-check-label" for="{{ filter.form.no_email.id_for_label }}">
Нет email
</label>
</div>
</div>
</div>
<!-- Кнопки -->
<div class="col-12">
<div class="btn-group" role="group">
<button type="submit" class="btn btn-primary">
<i class="bi bi-search"></i> Поиск / Фильтр
</button>
{% if query or filter.form.has_notes.value or filter.form.no_phone.value or filter.form.no_email.value %}
<a href="{% url 'customers:customer-list' %}" class="btn btn-outline-secondary">
<i class="bi bi-x-circle"></i> Очистить
</a>
{% endif %}
</div>
</div>
</form>
</div>
</div>
<!-- Таблица клиентов -->
<div class="card">
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead>
<tr>
<th>Имя</th>
<th>Email</th>
<th>Телефон</th>
<th>Заметки</th>
<th class="text-end">Действия</th>
</tr>
</thead>
<tbody>
{% for customer in page_obj %}
<tr
style="cursor:pointer"
onclick="window.location='{% url 'customers:customer-detail' customer.pk %}'"
>
<td class="fw-semibold">{{ customer.full_name }}</td>
<td>{{ customer.email|default:'—' }}</td>
<td>{{ customer.phone|default:'—' }}</td>
<td>
{% if customer.notes %}
<div style="max-width: 300px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
title="{{ customer.notes }}">
{{ customer.notes|truncatewords:10 }}
</div>
{% else %}
{% endif %}
</td>
<td class="text-end" onclick="event.stopPropagation();">
<a href="{% url 'customers:customer-detail' customer.pk %}"
class="btn btn-sm btn-outline-primary" title="Просмотр">
<i class="bi bi-eye"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
{# Сохраняем все GET-параметры кроме page #}
{% with params=request.GET.copy %}
{% if params.page %}{{ params.pop|slice:":0" }}{% endif %}
<nav aria-label="Page navigation" class="mt-3">
<ul class="pagination pagination-sm justify-content-center mb-0">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1&{{ params.urlencode }}" title="Первая страница">
&laquo;&laquo;
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}&{{ params.urlencode }}" title="Предыдущая">
&laquo;
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">&laquo;&laquo;</span>
</li>
<li class="page-item disabled">
<span class="page-link">&laquo;</span>
</li>
{% endif %}
{# Цифры страниц: показываем до 10 страниц #}
{% with start_page=page_obj.number|add:"-5" end_page=page_obj.number|add:"5" %}
{% for num in page_obj.paginator.page_range %}
{% if num >= start_page|default:1 and num <= end_page and num <= page_obj.paginator.num_pages %}
{% if num == page_obj.number %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}&{{ params.urlencode }}">{{ num }}</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
{% endwith %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}&{{ params.urlencode }}" title="Следующая">
&raquo;
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}&{{ params.urlencode }}" title="Последняя страница">
&raquo;&raquo;
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">&raquo;</span>
</li>
<li class="page-item disabled">
<span class="page-link">&raquo;&raquo;</span>
</li>
{% endif %}
</ul>
</nav>
{% endwith %}
{% endif %}
{% else %}
<p>Клиенты не найдены.</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}