Finalizacion modulo restaurante, con busqueda y creacion de clientes;
This commit is contained in:
@@ -3,7 +3,7 @@ const controlador = {};
|
|||||||
|
|
||||||
controlador.verClientesJsonApp = (req, res) => {
|
controlador.verClientesJsonApp = (req, res) => {
|
||||||
req.getConnection((err, conn) => {
|
req.getConnection((err, conn) => {
|
||||||
conn.query('SELECT client_rucCed, client_nombre, client_direccion, client_celular, client_email FROM clientes order by client_nombre DESC LIMIT 100', (err, rows) => {//se obtiene error o consulta filas(rows)
|
conn.query('SELECT client_rucCed, client_nombre, client_direccion, client_celular, client_email FROM clientes order by client_id DESC LIMIT 100', (err, rows) => {//se obtiene error o consulta filas(rows)
|
||||||
//conn.query('SELECT * FROM clientes LIMIT 62668,15', (err, rows) => {//se obtiene error o consulta filas(rows)
|
//conn.query('SELECT * FROM clientes LIMIT 62668,15', (err, rows) => {//se obtiene error o consulta filas(rows)
|
||||||
if (err) {
|
if (err) {
|
||||||
res.json(err);
|
res.json(err);
|
||||||
@@ -135,6 +135,29 @@ controlador.eliminarCliente = (req, res) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* controlador para obtener las ciudades de la base de datos
|
||||||
|
* @param {*} req
|
||||||
|
* @param {*} res
|
||||||
|
*/
|
||||||
|
controlador.obtenerCiudades = (req, res) => {
|
||||||
|
req.getConnection((err, conn) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).json({ error: 'Error de conexión' });
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.query(
|
||||||
|
'SELECT id_ciudad, nombre, perteneceA FROM localizacion_ciudad ORDER BY nombre ASC',
|
||||||
|
(err, ciudades) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).json({ error: 'Error al consultar ciudades' });
|
||||||
|
}
|
||||||
|
res.json(ciudades);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
//********* CONSULTA CLIENTES APP-SIGMA********//
|
//********* CONSULTA CLIENTES APP-SIGMA********//
|
||||||
controlador.app_pedidos_clientes = (req, res) => {
|
controlador.app_pedidos_clientes = (req, res) => {
|
||||||
const consulta = "%" + req.query.consulta + "%";
|
const consulta = "%" + req.query.consulta + "%";
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
margin-left: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,3 +59,78 @@
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input[type="text"] {
|
||||||
|
flex: 1;
|
||||||
|
padding-right: 50px;
|
||||||
|
/* espacio para el botón */
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
gap: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botón Guardar */
|
||||||
|
.btn-aceptar {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: baseline;
|
||||||
|
background-color: #03a9f4;
|
||||||
|
color: white;
|
||||||
|
border-radius: 8px 0px 0px 8px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.btn-aceptar:hover {
|
||||||
|
background-color: #43a047;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botón Cancelar */
|
||||||
|
.btn-cancelar {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: baseline;
|
||||||
|
background-color: #03a9f4;
|
||||||
|
color: white;
|
||||||
|
border-radius: 0px 8px 8px 0px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.btn-cancelar:hover {
|
||||||
|
background-color: #e53935;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botón Consultar RUC */
|
||||||
|
#btn_rucCed_sinc {
|
||||||
|
background-color: #03a9f4;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 0px 8px 8px 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btn_rucCed_sinc:hover {
|
||||||
|
background-color: #028fcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btn_rucCed_sinc i {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,9 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/********* TABLAS *********/
|
/********* TABLAS *********/
|
||||||
|
.table_container{
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
.detalles {
|
.detalles {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;padding: 20px;
|
width: 100%;padding: 20px;
|
||||||
|
|||||||
146
src/public/css/restaurant_usuarios.css
Normal file
146
src/public/css/restaurant_usuarios.css
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/* restaurant_form.css */
|
||||||
|
|
||||||
|
#txt_nombre,
|
||||||
|
/*#txt_idRuc,*/
|
||||||
|
#txt_direc,
|
||||||
|
#txt_telf,
|
||||||
|
#txt_mail,
|
||||||
|
#ciudad,
|
||||||
|
#reg {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #2d3e50;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 15px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#txt_nombre::placeholder,
|
||||||
|
#txt_idRuc::placeholder,
|
||||||
|
#txt_direc::placeholder,
|
||||||
|
#txt_telf::placeholder,
|
||||||
|
#txt_mail::placeholder,
|
||||||
|
#ciudad::placeholder {
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
#txt_nombre:focus,
|
||||||
|
#txt_idRuc:focus,
|
||||||
|
#txt_direc:focus,
|
||||||
|
#txt_telf:focus,
|
||||||
|
#txt_mail:focus,
|
||||||
|
#ciudad:focus,
|
||||||
|
#reg:focus {
|
||||||
|
outline: none;
|
||||||
|
background-color: #3c5770;
|
||||||
|
box-shadow: 0 0 4px #03a9f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formCliente_box {
|
||||||
|
background-color: #1f497d;
|
||||||
|
padding: 30px 25px;
|
||||||
|
border-radius: 12px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 30px auto;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.formCliente-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="submit"],
|
||||||
|
a.btn.btn-primary,
|
||||||
|
#consultas_ruc {
|
||||||
|
background-color: #03a9f4;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="submit"]:hover,
|
||||||
|
a.btn.btn-primary:hover,
|
||||||
|
#consultas_ruc:hover {
|
||||||
|
background-color: #028fcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#consultas_ruc {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#div_rucCed {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#txt_idRuc {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px 0px 0px 8px;
|
||||||
|
background-color: #2d3e50;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 15px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** selctor de ciudad ***/
|
||||||
|
|
||||||
|
.grupo_inpuText_btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: stretch;
|
||||||
|
/* cambia a stretch para igualar altura */
|
||||||
|
}
|
||||||
|
|
||||||
|
.grupo_inpuText_btn input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 8px 0px 0px 8px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grupo_inpuText_btn button {
|
||||||
|
padding: 0 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: #2196F3;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grupo_inpuText_btn input,
|
||||||
|
.grupo_inpuText_btn button {
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
/* ajusta según lo necesites */
|
||||||
|
}
|
||||||
@@ -11,6 +11,16 @@ async function mostrar_form(nombre_form_aRender){
|
|||||||
var tabla = await generaTab_clientes(cli.Clientes);
|
var tabla = await generaTab_clientes(cli.Clientes);
|
||||||
await render(tabla);
|
await render(tabla);
|
||||||
break;
|
break;
|
||||||
|
case 'nuevo_cliente':
|
||||||
|
var card = await mostrar_formClientes();
|
||||||
|
await render(card);
|
||||||
|
await cargarCiudades();
|
||||||
|
break;
|
||||||
|
case 'buscar_cliente':
|
||||||
|
cli_busq = document.getElementById("txt_bucarCliente").value;
|
||||||
|
var tabla = await generaTab_clientes(await get_json("/consultaClientesJson?consulta=" + cli_busq));
|
||||||
|
await render(tabla);
|
||||||
|
break;
|
||||||
case 'pedidos':
|
case 'pedidos':
|
||||||
let pedidos = await get_json("/consultaPedidos?origen=%");
|
let pedidos = await get_json("/consultaPedidos?origen=%");
|
||||||
var thead = "<td>ID</td><td>Nombre</td><td>Fecha</td><td>Origen</td><td>Valor</td><td>Estado</td>";
|
var thead = "<td>ID</td><td>Nombre</td><td>Fecha</td><td>Origen</td><td>Valor</td><td>Estado</td>";
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ function add_toping(cod) {
|
|||||||
<div class="topping_container">
|
<div class="topping_container">
|
||||||
<div class="select_topping">
|
<div class="select_topping">
|
||||||
<select>
|
<select>
|
||||||
<option value="Opcion">Término Crudo</option>
|
<option value="Promo 1">Promo 1</option>
|
||||||
<option value="Término Medio">Término Medio</option>
|
<option value="Promo 2">Promo 2</option>
|
||||||
<option value="Término Casi Cocido">Término Casi Cocido</option>
|
<option value="Promo 3">Promo 2</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="texto_obsv">
|
<div class="texto_obsv">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ async function generaTab_pedidos(json, heder_tab) {
|
|||||||
<div class="panel_header">
|
<div class="panel_header">
|
||||||
<h2>Pedidos Recientes</h2>
|
<h2>Pedidos Recientes</h2>
|
||||||
<input type="date" id="select_fecha" name="filtro_fecha">
|
<input type="date" id="select_fecha" name="filtro_fecha">
|
||||||
</div>
|
</div><div class="table_container">
|
||||||
<table><thead><tr>${heder_tab}</tr></thead><tbody>`;
|
<table><thead><tr>${heder_tab}</tr></thead><tbody>`;
|
||||||
for (let key in json) {
|
for (let key in json) {
|
||||||
let valor = json[key].PedUsoPrdct_valor;
|
let valor = json[key].PedUsoPrdct_valor;
|
||||||
@@ -21,7 +21,7 @@ async function generaTab_pedidos(json, heder_tab) {
|
|||||||
</tr>`;
|
</tr>`;
|
||||||
tab = tab + fila;
|
tab = tab + fila;
|
||||||
}
|
}
|
||||||
tab = tab + "</tbody></table></div>" + bt_add("add_pedido", "Nuevo Pedido");
|
tab = tab + "</tbody></table></div></div>" + bt_add("add_pedido", "Nuevo Pedido");
|
||||||
//console.log(json);
|
//console.log(json);
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
@@ -31,9 +31,15 @@ async function generaTab_clientes(json) {
|
|||||||
var tab = `
|
var tab = `
|
||||||
<div class="panel_table">
|
<div class="panel_table">
|
||||||
<div class="panel_header">
|
<div class="panel_header">
|
||||||
<h2>Clientes</h2>
|
<h2>Clientes</h2><br>
|
||||||
<input type="date" id="select_fecha" name="filtro_fecha">
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="grupo_inpuText_btn" id="div_buscarCliente">
|
||||||
|
<input name="input_buscaCliente" type="text" class="form-control" placeholder="Buscar Clientes" id="txt_bucarCliente">
|
||||||
|
<button type="button" id="btn_buscar" title="Consultar cliente" onclick="mostrar_form('buscar_cliente')">
|
||||||
|
<i class="fa fa-search"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="table_container">
|
||||||
<table><thead><tr>${thead}</tr></thead><tbody>`;
|
<table><thead><tr>${thead}</tr></thead><tbody>`;
|
||||||
for (let key in json) {
|
for (let key in json) {
|
||||||
let fila = `<tr onclick="pop_addCliente('${json[key].client_rucCed}', '${json[key].client_nombre}')">
|
let fila = `<tr onclick="pop_addCliente('${json[key].client_rucCed}', '${json[key].client_nombre}')">
|
||||||
@@ -45,7 +51,7 @@ async function generaTab_clientes(json) {
|
|||||||
</tr>`;
|
</tr>`;
|
||||||
tab = tab + fila;
|
tab = tab + fila;
|
||||||
}
|
}
|
||||||
tab = tab + "</tbody></table></div>";
|
tab = tab + "</tbody></table></div></div>"+bt_add("crear_cliente", "Cliente Nuevo");
|
||||||
//console.log(json);
|
//console.log(json);
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
@@ -209,6 +215,8 @@ function ir_a(ruta) {
|
|||||||
break;
|
break;
|
||||||
case "add_pedido": mostrar_form('mesas');
|
case "add_pedido": mostrar_form('mesas');
|
||||||
break;
|
break;
|
||||||
|
case "crear_cliente": mostrar_form('nuevo_cliente');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
console.log(ruta);
|
console.log(ruta);
|
||||||
}
|
}
|
||||||
|
|||||||
390
src/public/js/app_restaurant_users.js
Normal file
390
src/public/js/app_restaurant_users.js
Normal file
@@ -0,0 +1,390 @@
|
|||||||
|
function mostrar_formClientes() {
|
||||||
|
var contHtml = `
|
||||||
|
<div class="formCliente_box">
|
||||||
|
<form class="formCliente" action="/addCliente" method="post">
|
||||||
|
<h3 class="formCliente-title">Nuevo Cliente</h3>
|
||||||
|
<div class="form-group">
|
||||||
|
<input name="client_nombre" type="text" class="form-control" placeholder="Nombre Cliente" id="txt_nombre">
|
||||||
|
</div>
|
||||||
|
<div class="form-group" id="div_rucCed">
|
||||||
|
<input name="client_rucCed" type="text" class="form-control" placeholder="Cedula/RUC" id="txt_idRuc">
|
||||||
|
<button type="button" id="btn_rucCed_sinc" title="Consultar RUC">
|
||||||
|
<i class="fa fa-cloud-download"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input name="client_direccion" type="text" class="form-control" placeholder="Direccion" id="txt_direc">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input name="client_telefono" type="text" class="form-control" placeholder="Numero Telefonico" id="txt_telf">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input name="client_email" type="text" class="form-control" placeholder="Correo E." id="txt_mail">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<select name="client_Ciudad" class="form-control" id="ciudad">
|
||||||
|
<option value="">Cargando ciudades...</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<input name="client_estado" type="hidden" value="1">
|
||||||
|
<div class="button-group">
|
||||||
|
<a href="#" class="btn-aceptar" onClick="crear_cliente()"><i class="fa fa-save"></i> Guardar</a>
|
||||||
|
<a href="#" class="btn-cancelar" onClick="mostrar_form('clientes')"><i class="fa fa-times"></i> Cancelar</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>`;
|
||||||
|
return contHtml;
|
||||||
|
}
|
||||||
|
// Función para crear cliente
|
||||||
|
function crear_cliente() {
|
||||||
|
// Obtener todos los campos del formulario
|
||||||
|
const clienteData = {
|
||||||
|
client_nombre: document.getElementById('txt_nombre').value.trim(),
|
||||||
|
client_rucCed: document.getElementById('txt_idRuc').value.trim(),
|
||||||
|
client_direccion: document.getElementById('txt_direc').value.trim(),
|
||||||
|
client_telefono: document.getElementById('txt_telf').value.trim(),
|
||||||
|
client_email: document.getElementById('txt_mail').value.trim(),
|
||||||
|
client_Ciudad: document.getElementById('ciudad').value.trim(), // ID de la ciudad seleccionada
|
||||||
|
client_estado: 1, // Valor por defecto
|
||||||
|
client_fechaReg: new Date().toISOString().slice(0, 19).replace('T', ' ') // Formato DATETIME para MySQL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Validar campos obligatorios
|
||||||
|
const errores = [];
|
||||||
|
|
||||||
|
if (!clienteData.client_nombre) {
|
||||||
|
errores.push('El nombre del cliente es obligatorio');
|
||||||
|
mostrarError('txt_nombre');
|
||||||
|
} else {
|
||||||
|
limpiarError('txt_nombre');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clienteData.client_rucCed) {
|
||||||
|
errores.push('La cédula/RUC es obligatoria');
|
||||||
|
mostrarError('txt_idRuc');
|
||||||
|
} else if (!validarRucCedula(clienteData.client_rucCed)) {
|
||||||
|
errores.push('La cédula/RUC no tiene un formato válido');
|
||||||
|
mostrarError('txt_idRuc');
|
||||||
|
} else {
|
||||||
|
limpiarError('txt_idRuc');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clienteData.client_direccion) {
|
||||||
|
errores.push('La dirección es obligatoria');
|
||||||
|
mostrarError('txt_direc');
|
||||||
|
} else {
|
||||||
|
limpiarError('txt_direc');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar email si se proporciona
|
||||||
|
if (clienteData.client_email && !validarEmail(clienteData.client_email)) {
|
||||||
|
errores.push('El formato del email no es válido');
|
||||||
|
mostrarError('txt_mail');
|
||||||
|
} else {
|
||||||
|
limpiarError('txt_mail');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar teléfono si se proporciona
|
||||||
|
if (clienteData.client_telefono && !validarTelefono(clienteData.client_telefono)) {
|
||||||
|
errores.push('El formato del teléfono no es válido');
|
||||||
|
mostrarError('txt_telf');
|
||||||
|
} else {
|
||||||
|
limpiarError('txt_telf');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si hay errores, mostrarlos y no enviar
|
||||||
|
if (errores.length > 0) {
|
||||||
|
mostrarMensaje(errores.join('<br>'), 'error');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enviar datos al servidor
|
||||||
|
enviarDatosCliente(clienteData);
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para enviar datos al servidor
|
||||||
|
async function enviarDatosCliente(data) {
|
||||||
|
try {
|
||||||
|
// Mostrar loader
|
||||||
|
mostrarLoader(true);
|
||||||
|
|
||||||
|
const response = await fetch('/addCliente', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
mostrarLoader(false);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
// Si la respuesta es exitosa
|
||||||
|
const result = await response.text();
|
||||||
|
mostrarMensaje('Cliente guardado exitosamente', 'success');
|
||||||
|
|
||||||
|
// Limpiar formulario
|
||||||
|
limpiarFormulario();
|
||||||
|
|
||||||
|
// Opcional: redirigir después de 2 segundos
|
||||||
|
setTimeout(() => {
|
||||||
|
mostrar_form('clientes');
|
||||||
|
//window.location.href = '/clientes';
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new Error(`Error del servidor: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
mostrarLoader(false);
|
||||||
|
console.error('Error al enviar datos:', error);
|
||||||
|
mostrarMensaje('Error al guardar el cliente. Intente nuevamente.', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para validar RUC/Cédula (básica para Ecuador)
|
||||||
|
function validarRucCedula(valor) {
|
||||||
|
// Remover espacios y guiones
|
||||||
|
valor = valor.replace(/[\s-]/g, '');
|
||||||
|
|
||||||
|
// Debe tener entre 10 y 13 dígitos
|
||||||
|
if (!/^\d{10,13}$/.test(valor)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validación básica para cédula ecuatoriana (10 dígitos)
|
||||||
|
if (valor.length === 10) {
|
||||||
|
return validarCedulaEcuador(valor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Para RUC (13 dígitos) - validación básica
|
||||||
|
if (valor.length === 13) {
|
||||||
|
return valor.substring(10) === '001'; // Terminación típica de RUC
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // Aceptar otros formatos
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validación específica para cédula ecuatoriana
|
||||||
|
function validarCedulaEcuador(cedula) {
|
||||||
|
if (cedula.length !== 10) return false;
|
||||||
|
|
||||||
|
const provincia = parseInt(cedula.substring(0, 2));
|
||||||
|
if (provincia < 1 || provincia > 24) return false;
|
||||||
|
|
||||||
|
const tercerDigito = parseInt(cedula.charAt(2));
|
||||||
|
if (tercerDigito > 6) return false;
|
||||||
|
|
||||||
|
// Algoritmo de validación
|
||||||
|
const coeficientes = [2, 1, 2, 1, 2, 1, 2, 1, 2];
|
||||||
|
let suma = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < 9; i++) {
|
||||||
|
let producto = parseInt(cedula.charAt(i)) * coeficientes[i];
|
||||||
|
if (producto > 9) producto -= 9;
|
||||||
|
suma += producto;
|
||||||
|
}
|
||||||
|
|
||||||
|
const digitoVerificador = parseInt(cedula.charAt(9));
|
||||||
|
const residuo = suma % 10;
|
||||||
|
const resultado = residuo === 0 ? 0 : 10 - residuo;
|
||||||
|
|
||||||
|
return resultado === digitoVerificador;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para validar email
|
||||||
|
function validarEmail(email) {
|
||||||
|
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
return regex.test(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para validar teléfono
|
||||||
|
function validarTelefono(telefono) {
|
||||||
|
// Permitir números con o sin guiones, espacios, paréntesis
|
||||||
|
const regex = /^[\d\s\-\(\)\+]{7,14}$/;
|
||||||
|
return regex.test(telefono);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para mostrar errores en campos
|
||||||
|
function mostrarError(campoId) {
|
||||||
|
const campo = document.getElementById(campoId);
|
||||||
|
campo.style.borderColor = '#ef4444';
|
||||||
|
campo.style.boxShadow = '0 0 0 3px rgba(239, 68, 68, 0.1)';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para limpiar errores en campos
|
||||||
|
function limpiarError(campoId) {
|
||||||
|
const campo = document.getElementById(campoId);
|
||||||
|
campo.style.borderColor = '#e1e8ed';
|
||||||
|
campo.style.boxShadow = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para mostrar mensajes
|
||||||
|
function mostrarMensaje(mensaje, tipo) {
|
||||||
|
// Crear elemento de mensaje si no existe
|
||||||
|
let mensajeDiv = document.getElementById('mensaje-sistema');
|
||||||
|
if (!mensajeDiv) {
|
||||||
|
mensajeDiv = document.createElement('div');
|
||||||
|
mensajeDiv.id = 'mensaje-sistema';
|
||||||
|
mensajeDiv.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: white;
|
||||||
|
font-weight: 500;
|
||||||
|
z-index: 9999;
|
||||||
|
max-width: 400px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
`;
|
||||||
|
document.body.appendChild(mensajeDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurar estilo según tipo
|
||||||
|
if (tipo === 'error') {
|
||||||
|
mensajeDiv.style.background = 'linear-gradient(135deg, #ef4444, #dc2626)';
|
||||||
|
} else {
|
||||||
|
mensajeDiv.style.background = 'linear-gradient(135deg, #10b981, #059669)';
|
||||||
|
}
|
||||||
|
|
||||||
|
mensajeDiv.innerHTML = mensaje;
|
||||||
|
mensajeDiv.style.display = 'block';
|
||||||
|
mensajeDiv.style.opacity = '1';
|
||||||
|
|
||||||
|
// Ocultar después de 5 segundos
|
||||||
|
setTimeout(() => {
|
||||||
|
mensajeDiv.style.opacity = '0';
|
||||||
|
setTimeout(() => {
|
||||||
|
mensajeDiv.style.display = 'none';
|
||||||
|
}, 300);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para mostrar/ocultar loader
|
||||||
|
function mostrarLoader(mostrar) {
|
||||||
|
let loader = document.getElementById('loader-sistema');
|
||||||
|
if (!loader) {
|
||||||
|
loader = document.createElement('div');
|
||||||
|
loader.id = 'loader-sistema';
|
||||||
|
loader.innerHTML = `
|
||||||
|
<div style="
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10000;
|
||||||
|
">
|
||||||
|
<div style="
|
||||||
|
background: white;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 15px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||||
|
">
|
||||||
|
<div style="
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 4px solid #f3f3f3;
|
||||||
|
border-top: 4px solid #667eea;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin: 0 auto 15px;
|
||||||
|
"></div>
|
||||||
|
<p style="margin: 0; color: #333; font-weight: 500;">Guardando cliente...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(loader);
|
||||||
|
|
||||||
|
// Agregar animación CSS
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.textContent = `
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
loader.style.display = mostrar ? 'block' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para limpiar formulario
|
||||||
|
function limpiarFormulario() {
|
||||||
|
document.getElementById('txt_nombre').value = '';
|
||||||
|
document.getElementById('txt_idRuc').value = '';
|
||||||
|
document.getElementById('txt_direc').value = '';
|
||||||
|
document.getElementById('txt_telf').value = '';
|
||||||
|
document.getElementById('txt_mail').value = '';
|
||||||
|
document.getElementById('ciudad').value = '';
|
||||||
|
|
||||||
|
// Limpiar errores visuales
|
||||||
|
['txt_nombre', 'txt_idRuc', 'txt_direc', 'txt_telf', 'txt_mail', 'ciudad'].forEach(id => {
|
||||||
|
limpiarError(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Función para cargar ciudades desde la base de datos
|
||||||
|
async function cargarCiudades() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/ciudades', {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const ciudades = await response.json();
|
||||||
|
const selectCiudad = document.getElementById('ciudad');
|
||||||
|
|
||||||
|
// Limpiar opciones existentes
|
||||||
|
selectCiudad.innerHTML = '<option value="">Seleccione una ciudad...</option>';
|
||||||
|
|
||||||
|
// Agregar opciones de ciudades
|
||||||
|
ciudades.forEach(ciudad => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = ciudad.id_ciudad;
|
||||||
|
option.textContent = ciudad.nombre + (ciudad.perteneceA ? ` (${ciudad.perteneceA})` : '');
|
||||||
|
selectCiudad.appendChild(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error al cargar ciudades:', error);
|
||||||
|
mostrarMensaje('Error al cargar las ciudades', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener para prevenir envío del formulario tradicional
|
||||||
|
/*document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Cargar ciudades al iniciar
|
||||||
|
cargarCiudades();
|
||||||
|
|
||||||
|
const form = document.querySelector('.formCliente');
|
||||||
|
if (form) {
|
||||||
|
form.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault(); // Prevenir envío tradicional
|
||||||
|
crear_cliente(); // Usar nuestra función personalizada
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// También prevenir en los enlaces de botones
|
||||||
|
const btnGuardar = document.querySelector('.btn-aceptar');
|
||||||
|
if (btnGuardar) {
|
||||||
|
btnGuardar.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
crear_cliente();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});*/
|
||||||
@@ -13,6 +13,7 @@ rutas.get('/pedidos', controlador_init.app_sigma);//Una app para PEDIDOS
|
|||||||
rutas.get('/recepcionPedidos', controlador_init.recibe_pedidos);//receptar pedidos
|
rutas.get('/recepcionPedidos', controlador_init.recibe_pedidos);//receptar pedidos
|
||||||
rutas.post('/recepcionPedidos_post', controlador_init.recibe_pedidos_post);//receptar pedidos
|
rutas.post('/recepcionPedidos_post', controlador_init.recibe_pedidos_post);//receptar pedidos
|
||||||
|
|
||||||
|
|
||||||
rutas.get('/', controlador_init.app_login);//FORM LOGIN DE LA APP
|
rutas.get('/', controlador_init.app_login);//FORM LOGIN DE LA APP
|
||||||
rutas.post('/login', controlador_init.auth);//Authenticacion de Web APP
|
rutas.post('/login', controlador_init.auth);//Authenticacion de Web APP
|
||||||
rutas.get('/login_test', controlador_init.login_test);//login testing css / dev
|
rutas.get('/login_test', controlador_init.login_test);//login testing css / dev
|
||||||
|
|||||||
@@ -21,8 +21,11 @@ rutas.get('/eliminarCliente/:client_id', controladorClientes.eliminarCliente);
|
|||||||
rutas.post('/addCliente', controladorClientes.guardaCliente);//almacena en bd el nuevo cliente
|
rutas.post('/addCliente', controladorClientes.guardaCliente);//almacena en bd el nuevo cliente
|
||||||
rutas.get('/addClienteForm', controladorClientes.verFormNclientes);//muesta form para crear cliente
|
rutas.get('/addClienteForm', controladorClientes.verFormNclientes);//muesta form para crear cliente
|
||||||
|
|
||||||
|
// Ruta para obtener ciudades
|
||||||
|
rutas.get('/api/ciudades', controladorClientes.obtenerCiudades);
|
||||||
|
|
||||||
//APP_SIGMA consultas
|
//APP_SIGMA consultas
|
||||||
rutas.get('/consultaClientesJson', controladorClientes.app_pedidos_clientes);//consulta clientes app-sigma
|
rutas.get('/consultaClientesJson', controladorClientes.app_pedidos_clientes);//consulta clientes: /consultaClientesJson?consulta=dato
|
||||||
rutas.get('/busquedaSRI/', controladorClientes.buscarCli_sri);//API consulta clientes
|
rutas.get('/busquedaSRI/', controladorClientes.buscarCli_sri);//API consulta clientes
|
||||||
|
|
||||||
//API CONSULTA CLIENTES: https://NAME_SERVER/api_consultaClientes?id=numero_rucOcedula => https://app.factura-e.net/api_consultaClientes?id=0701637498001
|
//API CONSULTA CLIENTES: https://NAME_SERVER/api_consultaClientes?id=numero_rucOcedula => https://app.factura-e.net/api_consultaClientes?id=0701637498001
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<link rel="stylesheet" href="../css/restaurant_form.css">
|
<link rel="stylesheet" href="../css/restaurant_form.css">
|
||||||
<link rel="stylesheet" href="../css/botones.css">
|
<link rel="stylesheet" href="../css/botones.css">
|
||||||
<link rel="stylesheet" href="../css/restaurant_dashMesero.css">
|
<link rel="stylesheet" href="../css/restaurant_dashMesero.css">
|
||||||
|
<link rel="stylesheet" href="../css/restaurant_usuarios.css">
|
||||||
<link rel="icon" sizes="64x64" href="../img/favicon_restaurant/favicon.ico">
|
<link rel="icon" sizes="64x64" href="../img/favicon_restaurant/favicon.ico">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
@@ -167,6 +168,7 @@
|
|||||||
<script src="../js/app_restaurant.js"></script>
|
<script src="../js/app_restaurant.js"></script>
|
||||||
<script src="../js/app_restaurant_tabGen.js"></script>
|
<script src="../js/app_restaurant_tabGen.js"></script>
|
||||||
<script src="../js/app_restaurant_detallePed.js"></script>
|
<script src="../js/app_restaurant_detallePed.js"></script>
|
||||||
|
<script src="../js/app_restaurant_users.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user