bp/app/Views/superadmin/subscriptions/create.twig

210 lines
7.5 KiB
Twig
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 'superadmin/layout.twig' %}
{% block title %}Добавить подписку - Суперадмин{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1>Добавить подписку</h1>
<a href="{{ base_url('/superadmin/subscriptions') }}" class="btn btn-outline-secondary">
<i class="fa-solid fa-arrow-left"></i> Назад к списку
</a>
</div>
<div class="card">
<div class="card-body">
<form action="{{ base_url('/superadmin/subscriptions/store') }}" method="post" class="row g-3">
{{ csrf_field()|raw }}
<div class="col-md-6">
<label class="form-label">Организация *</label>
<div class="autocomplete-wrapper">
<input type="text" class="form-control autocomplete-input" placeholder="Начните вводить название организации..."
data-url="{{ base_url('/superadmin/organizations/search') }}" autocomplete="off">
<input type="hidden" name="organization_id" class="autocomplete-value" value="">
<div class="autocomplete-dropdown"></div>
</div>
</div>
<div class="col-md-6">
<label class="form-label">Модуль *</label>
<select name="module_code" class="form-select" required>
<option value="">Выберите модуль...</option>
{% for code, module in modules %}
<option value="{{ code }}">{{ module.name }} - {{ module.price_monthly }} руб/мес</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label">Количество дней</label>
<input type="number" name="duration_days" class="form-control" value="30" min="0" placeholder="0 - бессрочно">
<div class="form-text">0 - подписка без срока истечения</div>
</div>
<div class="col-md-4">
<label class="form-label">Статус</label>
<select name="status" class="form-select">
<option value="active">Активна</option>
<option value="trial">Триал</option>
<option value="expired">Истекла</option>
<option value="cancelled">Отменена</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Истекает</label>
<input type="text" class="form-control" disabled value="Будет рассчитано автоматически">
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">
<i class="fa-solid fa-plus"></i> Создать подписку
</button>
</div>
</form>
</div>
</div>
<style>
.autocomplete-wrapper {
position: relative;
}
.autocomplete-input {
width: 100%;
}
.autocomplete-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #fff;
border: 1px solid #ddd;
border-top: none;
border-radius: 0 0 5px 5px;
max-height: 250px;
overflow-y: auto;
display: none;
z-index: 1000;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.autocomplete-dropdown.active {
display: block;
}
.autocomplete-item {
padding: 12px 15px;
cursor: pointer;
border-bottom: 1px solid #eee;
transition: background-color 0.2s;
}
.autocomplete-item:hover,
.autocomplete-item.selected {
background-color: #f8f9fa;
}
.autocomplete-item:last-child {
border-bottom: none;
}
.autocomplete-empty {
padding: 12px 15px;
color: #6c757d;
text-align: center;
}
</style>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
const input = document.querySelector('.autocomplete-input');
const hiddenInput = document.querySelector('.autocomplete-value');
const dropdown = document.querySelector('.autocomplete-dropdown');
let timeout = null;
input.addEventListener('input', function() {
clearTimeout(timeout);
const value = this.value.trim();
if (value.length < 2) {
dropdown.classList.remove('active');
hiddenInput.value = '';
return;
}
timeout = setTimeout(() => {
fetch(this.dataset.url + '?q=' + encodeURIComponent(value))
.then(response => response.json())
.then(data => {
dropdown.innerHTML = '';
if (data.results && data.results.length > 0) {
data.results.forEach(item => {
const div = document.createElement('div');
div.className = 'autocomplete-item';
div.textContent = item.text;
div.dataset.id = item.id;
div.addEventListener('click', function() {
input.value = this.textContent;
hiddenInput.value = this.dataset.id;
dropdown.classList.remove('active');
});
dropdown.appendChild(div);
});
} else {
const div = document.createElement('div');
div.className = 'autocomplete-empty';
div.textContent = 'Организации не найдены';
dropdown.appendChild(div);
}
dropdown.classList.add('active');
})
.catch(error => {
console.error('Error:', error);
});
}, 300);
});
document.addEventListener('click', function(e) {
if (!e.target.closest('.autocomplete-wrapper')) {
dropdown.classList.remove('active');
}
});
input.addEventListener('focus', function() {
if (this.value.trim().length >= 2) {
this.dispatchEvent(new Event('input'));
}
});
input.addEventListener('keydown', function(e) {
const items = dropdown.querySelectorAll('.autocomplete-item');
const selected = dropdown.querySelector('.selected');
let index = Array.from(items).indexOf(selected);
if (e.key === 'ArrowDown') {
e.preventDefault();
if (items.length > 0) {
if (index < items.length - 1) {
if (selected) selected.classList.remove('selected');
items[index + 1].classList.add('selected');
}
}
} else if (e.key === 'ArrowUp') {
e.preventDefault();
if (index > 0) {
if (selected) selected.classList.remove('selected');
items[index - 1].classList.add('selected');
}
} else if (e.key === 'Enter' && selected) {
e.preventDefault();
input.value = selected.textContent;
hiddenInput.value = selected.dataset.id;
dropdown.classList.remove('active');
} else if (e.key === 'Escape') {
dropdown.classList.remove('active');
}
});
});
</script>
{% endblock %}