91 lines
6.4 KiB
HTML
91 lines
6.4 KiB
HTML
{% extends "page.html" %}
|
|
{% block page_content %}
|
|
<div class="card">
|
|
<div class="card-header"><h2>Клиенты</h2>
|
|
{% if error %}<div class="alert alert-error" style="margin-bottom:12px;padding:8px 12px;background:rgba(239,68,68,0.1);border:1px solid rgba(239,68,68,0.3);border-radius:6px;color:var(--danger);font-size:13px;">{{ error }}</div>{% endif %}
|
|
</div>
|
|
<button class="btn btn-primary btn-sm" onclick="document.getElementById('modal-customer').classList.add('open')">+ Добавить</button>
|
|
</div>
|
|
<form method="get" class="search-box"><input type="text" name="search" placeholder="Поиск по названию или ИНН..." value="{{ search }}"><button class="btn btn-primary btn-sm">Найти</button></form>
|
|
<div class="table-wrap">
|
|
<table><thead><tr><th>Название</th><th>ИНН</th><th>Контакты</th><th>Статус</th><th>Объекты</th><th>Активные SLA</th><th class="actions"></th></tr></thead>
|
|
<tbody>{% for d in customers %}<tr>
|
|
<td>{{ d.c.name }}</td><td>{{ d.c.inn }}</td>
|
|
<td><small>{{ d.c.contact_person }}<br>{{ d.c.contact_phone }}</small></td>
|
|
<td><span class="badge badge-{{ d.c.status }}">{{ {'active':'Активен','inactive':'Неактивен','prospect':'Перспективный'}[d.c.status] }}</span></td>
|
|
<td><a href="/service/objects?customer_id={{ d.c.id }}">{{ d.objects_count }}</a></td>
|
|
<td>{{ d.active_contracts }}</td>
|
|
<td class="actions">
|
|
<button class="btn btn-secondary btn-sm" onclick="editCustomer({{ d.c.id }},'{{ d.c.name|e }}','{{ d.c.inn|e }}','{{ d.c.kpp|e }}','{{ d.c.legal_address|e }}','{{ d.c.contact_person|e }}','{{ d.c.contact_phone|e }}','{{ d.c.contact_email|e }}','{{ d.c.status }}','{{ d.c.notes|e }}')">✎</button>
|
|
{% if user.role == 'owner' %}
|
|
<form method="post" action="/service/customers/delete" style="display:inline" onsubmit="return confirm('Удалить клиента?')">
|
|
<input type="hidden" name="id" value="{{ d.c.id }}"><button class="btn btn-danger btn-sm">✕</button>
|
|
</form>{% endif %}
|
|
</td>
|
|
</tr>{% endfor %}</tbody></table>
|
|
</div>
|
|
</div>
|
|
<div class="modal-overlay" id="modal-customer"><div class="modal">
|
|
<button type="button" class="modal-close" onclick="this.closest('.modal-overlay').classList.remove('open')">✕</button>
|
|
<h2 id="modal-customer-title">Новый клиент</h2>
|
|
<form method="post" id="modal-customer-form" action="/service/customers/create">
|
|
<input type="hidden" name="id" id="customer-id">
|
|
<div class="form-row">
|
|
<div class="form-group"><label>Название <span style="color:var(--danger)">*</span></label><input type="text" name="name" id="customer-name" required></div>
|
|
<div class="form-group"><label>ИНН <span style="color:var(--danger)">*</span></label><input type="text" name="inn" id="customer-inn" required pattern="\d{10,12}" title="ИНН: 10 или 12 цифр" inputmode="numeric"></div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group"><label>КПП</label><input type="text" name="kpp" id="customer-kpp" pattern="\d{9}" title="КПП: 9 цифр" maxlength="9" inputmode="numeric"></div>
|
|
<div class="form-group"><label>Юр. адрес</label><input type="text" name="legal_address" id="customer-legal_address"></div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group"><label>Контактное лицо <span style="color:var(--danger)">*</span></label><input type="text" name="contact_person" id="customer-contact_person" required></div>
|
|
<div class="form-group"><label>Телефон <span style="color:var(--danger)">*</span></label><input type="text" name="contact_phone" id="customer-contact_phone" required></div>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group"><label>Email</label><input type="email" name="contact_email" id="customer-contact_email"></div>
|
|
<div class="form-group"><label>Статус</label><select name="status" id="customer-status"><option value="active">Активен</option><option value="inactive">Неактивен</option><option value="prospect">Перспективный</option></select></div>
|
|
</div>
|
|
<div class="form-group"><label>Заметки</label><textarea name="notes" id="customer-notes"></textarea></div>
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn-primary">Сохранить</button>
|
|
<button type="button" class="btn btn-secondary" onclick="this.closest('.modal-overlay').classList.remove('open')">Отмена</button>
|
|
</div>
|
|
</form>
|
|
</div></div>
|
|
<script>
|
|
function phoneMask(input){
|
|
var x = input.value.replace(/\D/g, '').match(/(\d{0,1})(\d{0,3})(\d{0,3})(\d{0,2})(\d{0,2})/);
|
|
if (!x) return;
|
|
var val = '8';
|
|
if (x[2]) val += ' (' + x[2];
|
|
if (x[3]) val += ') ' + x[3];
|
|
if (x[4]) val += '-' + x[4];
|
|
if (x[5]) val += '-' + x[5];
|
|
input.value = val;
|
|
}
|
|
document.addEventListener('DOMContentLoaded', function(){
|
|
var phoneInput = document.getElementById('customer-contact_phone');
|
|
phoneInput.addEventListener('focus', function(){
|
|
if (!this.value || this.value === '8') this.value = '8 (';
|
|
});
|
|
phoneInput.addEventListener('input', function(){ phoneMask(this); });
|
|
});
|
|
function editCustomer(id,name,inn,kpp,addr,person,phone,email,status,notes){
|
|
document.getElementById('modal-customer').classList.add('open');
|
|
document.getElementById('modal-customer-title').textContent = 'Редактировать клиента';
|
|
document.getElementById('modal-customer-form').action = '/service/customers/edit';
|
|
document.getElementById('customer-id').value = id;
|
|
document.getElementById('customer-name').value = name;
|
|
document.getElementById('customer-inn').value = inn;
|
|
document.getElementById('customer-kpp').value = kpp;
|
|
document.getElementById('customer-legal_address').value = addr;
|
|
document.getElementById('customer-contact_person').value = person;
|
|
document.getElementById('customer-contact_phone').value = phone;
|
|
document.getElementById('customer-contact_email').value = email;
|
|
document.getElementById('customer-status').value = status;
|
|
document.getElementById('customer-notes').value = notes;
|
|
}
|
|
</script>
|
|
{% endblock %}
|