128 lines
5.8 KiB
Twig
128 lines
5.8 KiB
Twig
{% extends 'layouts/base.twig' %}
|
||
|
||
{% block title %}Импорт клиентов - {{ parent() }}{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container" style="max-width: 700px;">
|
||
<div class="card shadow">
|
||
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="fa-solid fa-file-import me-2"></i>Импорт клиентов</h5>
|
||
<a href="{{ base_url('/clients') }}" class="btn btn-light btn-sm">
|
||
<i class="fa-solid fa-arrow-left"></i> Назад
|
||
</a>
|
||
</div>
|
||
<div class="card-body p-4">
|
||
<form id="importForm" action="{{ base_url('/clients/import') }}" method="POST" enctype="multipart/form-data">
|
||
{{ csrf_field()|raw }}
|
||
|
||
{# Инструкция #}
|
||
<div class="alert alert-info mb-4">
|
||
<h6 class="alert-heading"><i class="fa-solid fa-info-circle me-2"></i>Инструкция по импорту</h6>
|
||
<ul class="mb-0">
|
||
<li>Загрузите файл в формате <strong>CSV</strong> (разделитель — точка с запятой)</li>
|
||
<li>Файл должен содержать заголовки в первой строке</li>
|
||
<li>Обязательные поля: <strong>Имя</strong></li>
|
||
<li>Опционально: Email, Телефон</li>
|
||
</ul>
|
||
</div>
|
||
|
||
{# Ссылка на шаблон #}
|
||
<div class="mb-4">
|
||
<a href="{{ base_url('/clients/export?format=csv') }}" class="btn btn-outline-secondary btn-sm">
|
||
<i class="fa-solid fa-download me-2"></i>Скачать шаблон
|
||
</a>
|
||
</div>
|
||
|
||
{# Загрузка файла #}
|
||
<div class="mb-4">
|
||
<label for="file" class="form-label fw-medium">Выберите файл</label>
|
||
<input type="file"
|
||
class="form-control"
|
||
id="file"
|
||
name="file"
|
||
accept=".csv"
|
||
required>
|
||
<div class="form-text">Поддерживается только формат CSV</div>
|
||
</div>
|
||
|
||
{# Кнопка отправки #}
|
||
<div class="d-flex justify-content-end">
|
||
<a href="{{ base_url('/clients') }}" class="btn btn-secondary me-3">Отмена</a>
|
||
<button type="submit" class="btn btn-primary" id="submitBtn">
|
||
<i class="fa-solid fa-upload me-2"></i>Импортировать
|
||
</button>
|
||
</div>
|
||
</form>
|
||
|
||
{# Результат импорта (скрыт по умолчанию) #}
|
||
<div id="importResult" class="mt-4" style="display: none;">
|
||
<div class="alert alert-success">
|
||
<h6><i class="fa-solid fa-check-circle me-2"></i>Импорт завершён</h6>
|
||
<p class="mb-0" id="importMessage"></p>
|
||
</div>
|
||
<div id="importErrors" class="alert alert-warning" style="display: none;">
|
||
<h6><i class="fa-solid fa-exclamation-triangle me-2"></i>Ошибки</h6>
|
||
<ul class="mb-0 small" id="errorsList"></ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const form = document.getElementById('importForm');
|
||
const submitBtn = document.getElementById('submitBtn');
|
||
const resultDiv = document.getElementById('importResult');
|
||
const messageEl = document.getElementById('importMessage');
|
||
const errorsDiv = document.getElementById('importErrors');
|
||
const errorsList = document.getElementById('errorsList');
|
||
|
||
form.addEventListener('submit', async function(e) {
|
||
e.preventDefault();
|
||
|
||
const formData = new FormData(form);
|
||
|
||
// Блокируем кнопку
|
||
submitBtn.disabled = true;
|
||
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Загрузка...';
|
||
|
||
try {
|
||
const response = await fetch(form.action, {
|
||
method: 'POST',
|
||
body: formData
|
||
});
|
||
|
||
const data = await response.json();
|
||
|
||
// Показываем результат
|
||
resultDiv.style.display = 'block';
|
||
messageEl.textContent = data.message;
|
||
|
||
if (data.errors && data.errors.length > 0) {
|
||
errorsDiv.style.display = 'block';
|
||
errorsList.innerHTML = data.errors.map(err => '<li>' + err + '</li>').join('');
|
||
} else {
|
||
errorsDiv.style.display = 'none';
|
||
}
|
||
|
||
if (data.success) {
|
||
// Очищаем форму
|
||
form.reset();
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('Error:', error);
|
||
resultDiv.style.display = 'block';
|
||
messageEl.innerHTML = '<span class="text-danger">Произошла ошибка при загрузке файла</span>';
|
||
errorsDiv.style.display = 'none';
|
||
} finally {
|
||
// Разблокируем кнопку
|
||
submitBtn.disabled = false;
|
||
submitBtn.innerHTML = '<i class="fa-solid fa-upload me-2"></i>Импортировать';
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
{% endblock %}
|