Replace browser prompt()-based editing with proper Bootstrap 5 modal dialogs for testimonials, services, FAQs, and leads. This provides better UX with form validation, structured input fields, and i18n support (ES/RU) instead of raw prompt dialogs. - Add testimonialModal, serviceModal, faqModal, leadModal to admin.html - Add show*/save* methods in admin.js for each entity type - Wire leads.html 'Add lead' button to leadModal - Add modal JS modules (FAQModal, LeadModal, ServiceModal) - Add unit and e2e tests for modals and API client
103 lines
4.3 KiB
JavaScript
103 lines
4.3 KiB
JavaScript
export class ServiceModal {
|
|
constructor(app) {
|
|
this.app = app
|
|
this.id = 'serviceModal'
|
|
this.element = null
|
|
this.bsModal = null
|
|
this._editId = null
|
|
}
|
|
|
|
open(service = null) {
|
|
if (!this.element) this._build()
|
|
this._editId = service ? service.id : null
|
|
const title = this.element.querySelector('.modal-title')
|
|
const inputs = this.element.querySelectorAll('input[name], textarea[name]')
|
|
if (service) {
|
|
title.innerHTML = '<i class="bi bi-pencil me-2"></i>Editar servicio'
|
|
inputs.forEach(i => {
|
|
const key = i.getAttribute('name')
|
|
if (service[key] !== undefined) i.value = service[key]
|
|
if (i.type === 'checkbox') i.checked = service[key] !== false
|
|
})
|
|
} else {
|
|
title.innerHTML = '<i class="bi bi-briefcase me-2"></i>Añadir servicio'
|
|
inputs.forEach(i => { i.value = ''; if (i.type === 'checkbox') i.checked = true })
|
|
}
|
|
this.bsModal = new bootstrap.Modal(this.element)
|
|
this.bsModal.show()
|
|
}
|
|
|
|
close() {
|
|
if (this.bsModal) this.bsModal.hide()
|
|
}
|
|
|
|
async save() {
|
|
const data = this._collect()
|
|
if (!data.title_es || !data.title_es.trim()) {
|
|
this.app.showNotification('Título es obligatorio', 'error')
|
|
return
|
|
}
|
|
const res = this._editId
|
|
? await API.updateService(this._editId, data)
|
|
: await API.createService(data)
|
|
if (res.success) {
|
|
this.close()
|
|
this.app.showNotification(this._editId ? 'Servicio actualizado' : 'Servicio creado', 'success')
|
|
this.app.refreshSection('services')
|
|
} else {
|
|
this.app.showNotification(res.error || 'Error al guardar', 'error')
|
|
}
|
|
}
|
|
|
|
_collect() {
|
|
const d = {}
|
|
this.element.querySelectorAll('input[name], textarea[name], select[name]').forEach(i => {
|
|
const k = i.getAttribute('name')
|
|
d[k] = i.type === 'checkbox' ? i.checked : i.value
|
|
})
|
|
d.order_num = parseInt(d.order_num) || 0
|
|
d.is_active = d.is_active !== undefined ? d.is_active : true
|
|
return d
|
|
}
|
|
|
|
_build() {
|
|
const el = document.createElement('div')
|
|
el.id = this.id
|
|
el.className = 'modal fade'
|
|
el.innerHTML = `
|
|
<div class="modal-dialog modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title"><i class="bi bi-briefcase me-2"></i>Añadir servicio</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3"><label class="form-label">Icono (clase Bootstrap)</label>
|
|
<input type="text" class="form-control" name="icon" placeholder="bi bi-key"></div>
|
|
<div class="mb-3"><label class="form-label">Título (ES)</label>
|
|
<input type="text" class="form-control" name="title_es" placeholder="Asesoría Legal"></div>
|
|
<div class="mb-3"><label class="form-label">Título (RU)</label>
|
|
<input type="text" class="form-control" name="title_ru" placeholder="Юридическая консультация"></div>
|
|
<div class="mb-3"><label class="form-label">Descripción (ES)</label>
|
|
<textarea class="form-control" rows="3" name="description_es" placeholder="Descripción del servicio..."></textarea></div>
|
|
<div class="mb-3"><label class="form-label">Descripción (RU)</label>
|
|
<textarea class="form-control" rows="3" name="description_ru" placeholder="Описание услуги..."></textarea></div>
|
|
<div class="mb-3"><label class="form-label">Orden</label>
|
|
<input type="number" class="form-control" name="order_num" placeholder="0"></div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="is_active" id="serviceActive" checked>
|
|
<label class="form-check-label" for="serviceActive">Activo</label>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
<button type="button" class="btn btn-primary" onclick="window.app.modals.service.save()">
|
|
<i class="bi bi-check-lg me-2"></i>Guardar servicio</button>
|
|
</div>
|
|
</div>
|
|
</div>`
|
|
document.body.appendChild(el)
|
|
this.element = el
|
|
}
|
|
}
|