Common components

This commit is contained in:
Juan Pablo Vial
2025-11-12 10:16:19 -03:00
parent c254ac11fe
commit 4760b08673
11 changed files with 1161 additions and 822 deletions

View File

@ -1,534 +1,87 @@
<div class="ui modal" id="add_reservation_modal">
<div class="header">
Agregar Cierre
</div>
<div class="content">
<form class="ui form" id="add_reservation_form">
<input type="hidden" name="add_project_id" />
<div class="three wide required field">
<label>Fecha</label>
<div class="ui calendar" id="add_date">
<div class="ui icon input">
<i class="calendar icon"></i>
<input type="text" name="add_date" />
</div>
</div>
</div>
<div class="fields">
<div class="three wide required field">
<label>RUT</label>
<div class="ui right labeled input" id="add_rut">
<input type="text" name="add_buyer_rut" placeholder="RUT" />
<div class="ui basic label">-<span id="add_digit"></span></div>
</div>
</div>
<div class="field">
<label></label>
<div class="ui inline loader" id="add_rut_loader"></div>
</div>
</div>
<div class="fields">
<div class="three wide required field">
<label>Nombre</label>
<input type="text" name="add_buyer_name" placeholder="Nombre" />
</div>
<div class="six wide required field">
<label>Apellidos</label>
<input type="text" name="add_buyer_last_name" placeholder="Apellido Paterno" />
</div>
<div class="six wide field">
<label></label>
<input type="text" name="add_buyer_last_name2" placeholder="Apellido Materno" />
</div>
</div>
<div class="fields">
<div class="three wide field">
<label>Dirección</label>
<input type="text" name="add_buyer_address_street" placeholder="Calle" />
</div>
<div class="field">
<label></label>
<input type="text" name="add_buyer_address_number" placeholder="" />
</div>
<div class="three wide field">
<label></label>
<input type="text" name="add_buyer_address_extra" placeholder="Otros Detalles" />
</div>
</div>
<div class="fields">
<div class="three wide field">
<label>Comuna</label>
<div class="ui search selection dropdown" id="add_comuna">
<input type="hidden" name="comuna" />
<i class="dropdown icon"></i>
<div class="default text">Comuna</div>
<div class="menu"></div>
</div>
</div>
<div class="seven wide field">
<label>Región</label>
<div class="ui search selection dropdown" id="add_region">
<input type="hidden" name="region" />
<i class="dropdown icon"></i>
<div class="default text">Región</div>
<div class="menu">
@foreach($regions as $region)
<div class="item" data-value="{{$region->id}}">{{$region->numeral}} - {{$region->descripcion}}</div>
@endforeach
</div>
</div>
</div>
</div>
<div class="fields">
<div class="field">
<label>Telefono</label>
<input type="text" name="add_buyer_phone" placeholder="Telefono" />
</div>
<div class="field">
<label>Correo</label>
<div class="ui labeled input">
<input type="text" name="add_buyer_email_name" placeholder="Correo" />
<div class="ui basic label">@</div>
<input type="text" name="add_buyer_email_domain" placeholder="Dominio" />
</div>
</div>
</div>
<div class="fields">
<div class="field">
<label>Estado Civil</label>
<input type="text" name="add_buyer_marital_status" placeholder="Estado Civil" />
</div>
<div class="field">
<label>Profesión</label>
<input type="text" name="add_buyer_profession" placeholder="Profesión" />
</div>
<div class="field">
<label>Fecha de Nacimiento</label>
<div class="ui calendar" id="add_birthdate">
<div class="ui icon input">
<i class="calendar icon"></i>
<input type="text" name="birthdate" />
</div>
</div>
</div>
</div>
<div class="six wide field">
<label>Operador *</label>
<div class="ui clearable search selection dropdown" id="add_broker">
<input type="hidden" name="add_broker" />
<i class="dropdown icon"></i>
<div class="default text">Operador</div>
<div class="menu"></div>
</div>
</div>
<div class="field">
<label>Agregar Promoción</label>
<button type="button" class="ui icon button" id="add_promotion">
<i class="plus icon"></i>
</button>
</div>
<div id="add_promotions"></div>
<h4 class="ui dividing header">Unidades <span id="add_project_name"></span></h4>
<div class="fields" id="add_unit_buttons"></div>
<div id="add_units"></div>
<h4 class="ui dividing header">Forma de Pago</h4>
<div class="fields">
<div class="field">
<div class="ui checkbox">
<input type="checkbox" name="has_pie" id="add_has_pie" />
<label>¿Tiene Pie?</label>
</div>
</div>
<div class="field" id="add_pie">
<label>Pie</label>
<div class="ui right labeled input">
<input type="text" name="pie" />
<div class="ui basic label">UF</div>
</div>
</div>
<div class="field" id="add_cuotas">
<label>Cuotas</label>
<input type="text" name="cuotas" />
</div>
</div>
<div class="fields">
<div class="field">
<div class="ui checkbox">
<input type="checkbox" name="has_credit" id="add_has_credit" />
<label>¿Tiene Crédito?</label>
</div>
</div>
<div class="field" id="add_credit">
<label>Crédito</label>
<div class="ui right labeled input">
<input type="text" name="credit" />
<div class="ui basic label">UF</div>
</div>
</div>
</div>
</form>
</div>
<div class="actions">
<div class="ui cancel button">
Cancelar
</div>
<div class="ui green ok button">
Agregar
</div>
</div>
</div>
@include('layout.body.scripts.rut')
@include('ventas.reservations.modal.common.modal', ['prefix' => 'add', 'modalTitle' => 'Agregar Cierre', 'okText' => 'Agregar'])
@push('page_scripts')
<script>
class AddModalPromotions {
ids = {
button: '',
elements: ''
class AddModalPromotions extends ModalPromotions {
constructor() {
super('add')
}
data = {
promotions: [],
selected: []
}
class AddModalUnits extends ModalUnits {
constructor() {
super({prefix: 'add', parent: null});
}
components = {
button: null,
promotions: null,
}
display = {
button: ''
}
class AddModalPayments extends ModalPayments {
constructor() {
super('add');
}
constructor() {
this.ids = {
button: 'add_promotion',
elements: 'add_promotions'
}
this.setup()
}
class AddReservationModal extends ReservationModal {
constructor(projects_id) {
super({projects_id, prefix: 'add', components: {
promotions: new AddModalPromotions(),
units: new AddModalUnits(),
payments: new AddModalPayments()
}});
}
add() {
const idx = Math.max(this.data.selected.length, 0, Math.max(...this.data.selected) + 1)
this.data.selected.push(idx)
this.draw.promotions()
}
reset() {
this.data.selected = []
this.draw.promotions()
}
remove(idx) {
this.data.selected = this.data.selected.filter(promotion => promotion !== idx)
this.draw.promotions()
}
draw = {
promotion: idx => {
const promotions = this.data.promotions.map(promotion => {
return `<div class="item" data-value="${promotion.value}">${promotion.name}</div>`
})
return [
`<div class="fields promotion" data-id="${idx}">`,
'<div class="three wide field">',
'<label>Promoción</label>',
`<div class="ui search selection dropdown">`,
'<input type="hidden" name="add_promotions[]" />',
'<i class="dropdown icon"></i>',
'<div class="default text">Promoción</div>',
`<div class="menu">${promotions.join('')}</div>`,
'</div>',
'</div>',
'<div class="two wide field">',
'<label></label>',
`<button class="ui red tiny icon button remove_promotion" type="button" data-id="${idx}"><i class="trash icon"></i></button>`,
'</div>',
'</div>'
].join('')
},
promotions: () => {
if (this.data.promotions.length === 0) {
this.components.button.parentElement.style.display = 'none'
this.components.promotions.innerHTML = ''
return
}
this.components.button.parentElement.style.display = this.display.button
if (this.data.selected.length === 0) {
return
}
this.components.promotions.innerHTML = this.data.selected.map(idx => {
return this.draw.promotion(idx)
}).join('')
this.components.promotions.querySelectorAll('.dropdown').forEach(dropdown => {
$(dropdown).dropdown()
})
this.components.promotions.querySelectorAll('.remove_promotion').forEach(button => {
button.addEventListener('click', () => {
const idx = Number(button.dataset.id)
this.remove(idx)
})
})
const url = '/api/ventas/reservation/add'
const form = document.getElementById(this.ids.form)
const body = new FormData(form)
const date = this.components.$date.calendar('get date')
body.set(`${this.prefix}_date`, [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'))
body.set(`${this.prefix}_buyer_rut`, Rut.clean(this.components.rut.querySelector('input').value))
body.set(`${this.prefix}_buyer_digit`, this.components.digit.textContent)
body.set(`${this.prefix}_buyer_address_comuna_id`, this.components.$comuna.dropdown('get value'))
body.set(`${this.prefix}_broker_rut`, Rut.clean(this.components.$broker.dropdown('get value')))
body.set(`${this.prefix}_buyer_email`, form.querySelector(`input[name='${this.prefix}_buyer_email_name']`).value + '@' + form.querySelector(`input[name='${this.prefix}_buyer_email_domain']`).value)
const birthdate = this.components.$birthdate.calendar('get date')
body.set(`${this.prefix}_buyer_birthdate`, [birthdate.getFullYear(), birthdate.getMonth() + 1, birthdate.getDate()].join('-'))
if (this.components.payments.components.pie.$checkbox.checkbox('is unchecked')) {
body.delete(`${this.prefix}_pie`)
body.delete(`${this.prefix}_cuotas`)
}
body.delete(`${this.prefix}_has_pie`)
if (this.components.payments.components.credit.$checkbox.checkbox('is unchecked')) {
body.delete(`${this.prefix}_credit`)
}
body.delete(`${this.prefix}_has_credit`)
body.delete('comuna')
body.delete('region')
body.delete('broker')
body.delete(`${this.prefix}_broker`)
body.delete('birthdate')
body.delete(`${this.prefix}_buyer_email_name`)
body.delete(`${this.prefix}_buyer_email_domain`)
const method = 'post'
return APIClient.fetch(url, {method, body}).then(response => response.json()).then(json => {
if (json.success) {
window.location.reload()
}
})
}
setup() {
this.components.button = document.getElementById(this.ids.button)
this.components.promotions = document.getElementById(this.ids.elements)
this.components.button.addEventListener('click', () => {
super.setup()
this.components.$modal.modal({
onApprove: () => {
this.add()
}
})
this.components.form.addEventListener('submit', event => {
event.preventDefault()
this.add()
return false
})
this.display.button = this.components.button.parentElement.style.display
this.draw.promotions()
}
}
class AddModalUnits {
parent = null
ids = {
buttons_holder: '',
units: ''
}
data = {
button_map: {},
types: {},
units: [],
}
components = {
buttons_holder: null,
units: null,
}
constructor(parent) {
this.parent = parent
this.ids = {
buttons_holder: 'add_unit_buttons',
units: 'add_units'
}
this.data.button_map = {
'departamento': 'building',
'estacionamiento': 'car',
'bodega': 'warehouse',
'terraza': 'vector square'
}
this.setup()
}
get promotions() {
return this.parent.data.promotions[this.parent.data.current_project]
}
draw = {
button: type => {
return [
'<div class="field">',
`<button class="ui icon button" type="button" data-type="${type}" title="${type.charAt(0).toUpperCase() + type.slice(1)}">`,
'<i class="plus icon"></i>',
`<i class="${this.data.button_map[type]} icon"></i>`,
'</button>',
'</div>'
].join('')
},
buttons: () => {
this.components.buttons_holder.innerHTML = Object.keys(this.data.types).map(type => {
return this.draw.button(type)
}).join('')
this.components.buttons_holder.querySelectorAll('.button').forEach(button => {
button.addEventListener('click', () => {
const type = button.dataset.type
this.add(type)
})
})
},
units: () => {
if (this.data.units.length === 0) {
this.components.units.innerHTML = ''
return
}
this.components.units.innerHTML = this.data.units.map(unit => {
return this.draw.unit(unit)
}).join('')
this.components.units.querySelectorAll('.dropdown.add_units').forEach(dropdown => {
$(dropdown).dropdown({
onChange: (value, text, $selectedItem) => {
const unitPromotions = this.promotions.filter(promotion => promotion.units.length > 0)
const promotions = unitPromotions.filter(promotion => promotion.units.filter(unit => unit.id === parseInt(value)).length > 0)
$selectedItem.parent().parent().parent().parent().find('.add_promotions_unit')
.dropdown('change values', promotions.map(promotion => {
return {
value: promotion.id,
name: promotion.description,
text: promotion.description,
}
}))
}
})
})
this.components.units.querySelectorAll('.dropdown.add_promotions_unit').forEach(dropdown => {
$(dropdown).dropdown()
})
this.components.units.querySelectorAll('.remove_unit').forEach(button => {
button.addEventListener('click', () => {
const idx = Number(button.dataset.id)
this.remove(idx)
})
})
},
unit: unit => {
let promotions = ''
if (unit.type === 'departamento') {
if (this.promotions.filter(promotion => promotion.units.length > 0).length > 0) {
promotions = [
'<div class="three wide field">',
'<label>Promociones</label>',
'<div class="ui multiple search selection dropdown add_promotions_unit">',
'<input type="hidden" name="add_units_promotions[]" />',
'<i class="dropdown icon"></i>',
'<div class="default text">Promociones</div>',
'<div class="menu">',
'</div>',
'</div>',
'</div>'
].join('')
}
}
return [
'<div class="fields">',
'<div class="four wide field">',
`<label>${unit.type.charAt(0).toUpperCase() + unit.type.slice(1)}</label>`,
`<div class="ui search selection dropdown add_units">`,
'<input type="hidden" name="add_units[]" />',
'<i class="dropdown icon"></i>',
`<div class="default text">${unit.type.charAt(0).toUpperCase() + unit.type.slice(1)}</div>`,
'<div class="menu">',
this.data.types[unit.type].map(unit => {
return `<div class="item" data-value="${unit.value}">${unit.name}</div>`
}).join(''),
'</div>',
'</div>',
'</div>',
'<div class="three wide field">',
'<label>Valor</label>',
'<div class="ui right labeled input">',
'<input type="text" name="add_units_value[]" placeholder="Valor" />',
'<div class="ui basic label">UF</div>',
'</div>',
'</div>',
promotions,
'<div class="field">',
'<label></label>',
`<button class="ui red tiny icon button remove_unit" type="button" data-id="${unit.idx}"><i class="trash icon"></i></button>`,
'</div>',
'</div>',
].join('')
}
}
reset() {
this.data.units = []
this.draw.units()
}
add(type) {
const idx = Math.max(this.data.units.length, 0, Math.max(...this.data.units.map(unit => unit.idx)) + 1)
this.data.units.push({idx, type})
this.draw.units()
}
remove(idx) {
this.data.units = this.data.units.filter(unit => unit.idx !== idx)
this.draw.units()
}
setup() {
this.components.buttons_holder = document.getElementById(this.ids.buttons_holder)
this.components.units = document.getElementById(this.ids.units)
this.draw.buttons()
}
}
class AddModalPayments {
ids = {
pie: {
checkbox: 'add_has_pie',
value: 'add_pie',
installments: 'add_cuotas'
},
credit: {
checkbox: 'add_has_credit',
value: 'add_credit'
}
}
components = {
pie: {
$checkbox: null,
value: null,
installments: null
},
credit: {
$checkbox: null,
value: null
}
}
data = {
pie: {
value: '',
installments: ''
},
credit: {
value: ''
}
}
constructor() {
this.setup()
}
reset() {
this.components.pie.$checkbox.prop('checked', false)
this.components.pie.value.value = ''
this.components.pie.installments.value = ''
this.components.credit.$checkbox.prop('checked', false)
this.components.credit.value.value = ''
}
show = {
pie: () => {
this.components.pie.value.style.display = this.data.pie.value
this.components.pie.installments.style.display = this.data.pie.installments
},
credit: () => {
this.components.credit.value.style.display = this.data.credit.value
}
}
hide = {
pie: () => {
this.components.pie.value.style.display = 'none'
this.components.pie.installments.style.display = 'none'
},
credit: () => {
this.components.credit.value.style.display = 'none'
},
all: () => {
this.hide.pie()
this.hide.credit()
}
}
setup() {
this.components.pie.$checkbox = $(`#${this.ids.pie.checkbox}`)
this.components.pie.value = document.getElementById(this.ids.pie.value)
this.components.pie.installments = document.getElementById(this.ids.pie.installments)
this.components.credit.$checkbox = $(`#${this.ids.credit.checkbox}`)
this.components.credit.value = document.getElementById(this.ids.credit.value)
this.components.pie.$checkbox.checkbox()
this.components.pie.$checkbox.change(changeEvent => {
if (this.components.pie.$checkbox.is(':checked')) {
this.show.pie()
return
}
this.hide.pie()
})
this.components.credit.$checkbox.checkbox()
this.components.credit.$checkbox.change(changeEvent => {
if (this.components.credit.$checkbox.is(':checked')) {
this.show.credit()
return
}
this.hide.credit()
})
this.data.pie.value = this.components.pie.value.style.display
this.data.pie.installments = this.components.pie.installments.style.display
this.data.credit.value = this.components.credit.value.style.display
this.hide.all()
}
}
class AddReservationModal {
/*class AddReservationModal {
ids = {
modal: '',
form: '',
@ -949,6 +502,6 @@
this.components.$broker.dropdown()
this.components.$loader = $(`#${this.ids.loader}`)
}
}
}*/
</script>
@endpush