Advertisement
fortu

Partes

May 4th, 2025
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 33.70 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="es">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Parte de Servicio - Vigilante</title>
  7.     <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  8.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
  9.     <style>
  10.         body {
  11.             background-color: #e0e0e0; /* Gris más oscuro */
  12.         }
  13.         .error { color: red; display: block; margin-top: -10px; margin-bottom: 10px; }
  14.         .contenido { display: block; }
  15.         .oculto { display: none; }
  16.         .fotoPreview {
  17.             max-width: 100px;
  18.             max-height: 100px;
  19.             margin-top: 10px;
  20.             display: inline-block;
  21.             border: 1px solid #ccc;
  22.             border-radius: 5px;
  23.         }
  24.         #otroTurnoInput { display: none; }
  25.         .menu button {
  26.             background-color: #007bff; /* Color azul para los botones del menú */
  27.             color: white;
  28.             padding: 10px 20px;
  29.             border: none;
  30.             border-radius: 5px;
  31.             margin: 5px;
  32.             cursor: pointer;
  33.         }
  34.         .menu button:hover {
  35.             background-color: #0056b3; /* Color azul más oscuro al pasar el ratón */
  36.         }
  37.         .form-label {
  38.             font-weight: bold; /* Etiquetas de formulario en negrita */
  39.         }
  40.         .btn-success {
  41.             background-color: #28a745; /* Color verde para el botón de enviar */
  42.             color: white;
  43.             border: none;
  44.         }
  45.         .btn-success:hover {
  46.             background-color: #218838; /* Color verde más oscuro al pasar el ratón */
  47.         }
  48.         .btn-primary {
  49.             background-color: #007bff; /* Color azul para el botón de descargar PDF */
  50.             color: white;
  51.             border: none;
  52.         }
  53.         .btn-primary:hover {
  54.             background-color: #0056b3; /* Color azul más oscuro al pasar el ratón */
  55.         }
  56.         .header {
  57.             background-color: #f0f0f0; /* Color de fondo gris claro para el encabezado */
  58.         }
  59.         .footer {
  60.             background-color: #f0f0f0; /* Color de fondo gris claro para el pie de página */
  61.         }
  62.     </style>
  63. </head>
  64. <body>
  65.     <div class="contenido" id="paginaPrincipal">
  66.         <div class="header text-center p-4 mb-4">
  67.             <img src="logo_grupo5.png" alt="Logo de Grupo 5 Seguridad" class="img-fluid" style="max-width: 150px; margin-bottom: 10px;">
  68.             <h1>GRUPO 5 SEGURIDAD</h1>
  69.             <p>Dirección: Calle Ejemplo, 123 - Teléfono: 123-456-789</p>
  70.         </div>
  71.  
  72.         <div class="menu d-flex justify-content-center mb-4">
  73.             <button id="btnServicio" onclick="mostrarFormulario('servicio')"><i class="fas fa-file-alt"></i> Parte Diario de Servicio</button>
  74.             <button id="btnIncidencias" onclick="mostrarFormulario('incidencias')"><i class="fas fa-exclamation-triangle"></i> Parte de Incidencias</button>
  75.         </div>
  76.     </div>
  77.  
  78.     <div id="formulario" class="oculto">
  79.         <h2 id="tituloFormulario" class="text-center mb-4"></h2>
  80.         <form id="parteTrabajo" class="container">
  81.             <div class="mb-3">
  82.                 <label for="servicio" class="form-label">Nombre del Servicio:</label>
  83.                 <input type="text" id="servicio" class="form-control" required>
  84.                 <span id="servicioError" class="error"></span>
  85.             </div>
  86.  
  87.             <div class="mb-3">
  88.                 <label for="lugar" class="form-label">Dirección del Servicio:</label>
  89.                 <input type="text" id="lugar" class="form-control" required>
  90.                 <span id="lugarError" class="error"></span>
  91.             </div>
  92.  
  93.             <div class="mb-3">
  94.                 <label for="vigilante" class="form-label">Nombre del Vigilante:</label>
  95.                 <input type="text" id="vigilante" class="form-control" required>
  96.                 <span id="vigilanteError" class="error"></span>
  97.             </div>
  98.  
  99.             <div class="mb-3">
  100.                 <label for="tip" class="form-label">N° de T.I.P.:</label>
  101.                 <input type="text" id="tip" class="form-control" required>
  102.                 <span id="tipError" class="error"></span>
  103.             </div>
  104.  
  105.             <div class="mb-3">
  106.                 <label for="fecha" class="form-label">Fecha:</label>
  107.                 <input type="date" id="fecha" class="form-control" required>
  108.                 <span id="fechaError" class="error"></span>
  109.             </div>
  110.  
  111.             <div class="mb-3">
  112.                 <label for="turno" class="form-label">Turno:</label>
  113.                 <select id="turno" class="form-select" required>
  114.                     <option value="">Selecciona un turno</option>
  115.                     <option value="Mañana">Mañana</option>
  116.                     <option value="Tarde">Tarde</option>
  117.                     <option value="Noche">Noche</option>
  118.                     <option value="Otro">Otro</option>
  119.                 </select>
  120.                 <span id="turnoError" class="error"></span>
  121.                 <input type="text" id="otroTurnoInput" class="form-control mt-2" placeholder="Ingresa otro turno">
  122.             </div>
  123.  
  124.             <div id="campoIncidencias" class="mb-3" style="display:none;">
  125.                 <label for="incidencias" class="form-label">Incidencias:</label>
  126.                 <textarea id="incidencias" class="form-control" rows="5"></textarea>
  127.                 <span id="incidenciasError" class="error"></span>
  128.             </div>
  129.  
  130.             <div class="mb-3">
  131.                 <label for="observaciones" class="form-label">Observaciones:</label>
  132.                 <textarea id="observaciones" class="form-control" rows="5" required></textarea>
  133.                 <span id="observacionesError" class="error"></span>
  134.             </div>
  135.  
  136.             <div id="campoAdjuntarFoto" style="display:none;" class="mb-3">
  137.                 <label for="foto" class="form-label">Adjuntar Fotografías:</label>
  138.                 <input type="file" id="foto" class="form-control" accept="image/*" multiple>
  139.                 <span id="fotoError" class="error"></span>
  140.                 <div id="fotosPreview"></div>
  141.             </div>
  142.  
  143.             <label>Firma del Vigilante:</label>
  144.             <canvas id="firmaCanvas" width="300" height="150" style="border: 1px solid #ccc;"></canvas>
  145.             <button type="button" onclick="limpiarFirma()" class="btn btn-secondary mt-2">Borrar Firma</button>
  146.  
  147.             <button type="submit" class="btn btn-success mt-3">Enviar</button>
  148.             <button type="button" id="btnDescargarPDF" class="btn btn-primary mt-3" style="display:none;">Descargar PDF</button>
  149.         </form>
  150.     </div>
  151.  
  152.     <div class="footer text-center p-3 mt-4">
  153.         <p>© 2025 Todos los derechos reservados | Autor: Carlos López</p>
  154.     </div>
  155.  
  156.     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  157.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
  158.     <script>
  159.         const canvas = document.getElementById("firmaCanvas");
  160.         const ctx = canvas.getContext("2d");
  161.         let dibujando = false;
  162.         let ultimoX = 0;
  163.         let ultimoY = 0;
  164.         ctx.lineWidth = 3;
  165.         ctx.lineCap = 'round';
  166.  
  167.         function iniciarDibujo(event) {
  168.             dibujando = true;
  169.             ultimoX = obtenerPosicionX(event);
  170.             ultimoY = obtenerPosicionY(event);
  171.         }
  172.  
  173.         function finalizarDibujo() {
  174.             dibujando = false;
  175.         }
  176.  
  177.         function dibujar(event) {
  178.             if (!dibujando) return;
  179.             const x = obtenerPosicionX(event);
  180.             const y = obtenerPosicionY(event);
  181.             ctx.beginPath();
  182.             ctx.moveTo(ultimoX, ultimoY);
  183.             ctx.lineTo(x, y);
  184.             ctx.stroke();
  185.             ultimoX = x;
  186.             ultimoY = y;
  187.             event.preventDefault();
  188.         }
  189.  
  190.         function obtenerPosicionX(event) {
  191.             const rect = canvas.getBoundingClientRect();
  192.             return (event.clientX || event.touches[0].clientX) - rect.left;
  193.         }
  194.  
  195.         function obtenerPosicionY(event) {
  196.             const rect = canvas.getBoundingClientRect();
  197.             return (event.clientY || event.touches[0].clientY) - rect.top;
  198.         }
  199.  
  200.         function limpiarFirma() {
  201.             ctx.clearRect(0, 0, canvas.width, canvas.height);
  202.         }
  203.  
  204.         canvas.addEventListener("mousedown", iniciarDibujo);
  205.         canvas.addEventListener("mouseup", finalizarDibujo);
  206.         canvas.addEventListener("mousemove", dibujar);
  207.         canvas.addEventListener("touchstart", iniciarDibujo);
  208.         canvas.addEventListener("touchend", finalizarDibujo);
  209.         canvas.addEventListener("touchmove", dibujar);
  210.  
  211.         document.getElementById("turno").addEventListener("change", function() {
  212.             const otroTurnoInput = document.getElementById("otroTurnoInput");
  213.             if (this.value === "Otro") {
  214.                 otroTurnoInput.style.display = "block";
  215.             } else {
  216.                 otroTurnoInput.style.display = "none";
  217.             }
  218.         });
  219.  
  220.         document.getElementById("parteTrabajo").addEventListener("submit", function(event) {
  221.             const servicio = document.getElementById("servicio").value;
  222.             const lugar = document.getElementById("lugar").value;
  223.             const vigilante = document.getElementById("vigilante").value;
  224.             const tip = document.getElementById("tip").value;
  225.             const fecha = document.getElementById("fecha").value;
  226.             const turnoSelect = document.getElementById("turno");
  227.             const otroTurnoInput = document.getElementById("otroTurnoInput");
  228.             const turno = turnoSelect.value === "Otro" ? otroTurnoInput.value : turnoSelect.value;
  229.             const incidencias = document.getElementById("incidencias").value;
  230.             const observaciones = document.getElementById("observaciones").value;
  231.             let errores = false;
  232.  
  233.             document.querySelectorAll(".error").forEach(span => span.textContent = "");
  234.  
  235.             if (!servicio) {
  236.                 document.getElementById("servicioError").textContent = "Este campo debe rellenarse obligatoriamente";
  237.                 errores = true;
  238.             }
  239.             if (!lugar) {
  240.                 document.getElementById("lugarError").textContent = "Este campo debe rellenarse obligatoriamente";
  241.                 errores = true;
  242.             }
  243.             if (!vigilante) {
  244.                 document.getElementById("vigilanteError").textContent = "Este campo debe rellenarse obligatoriamente";
  245.                 errores = true;
  246.             }
  247.             if (!tip) {
  248.                 document.getElementById("tipError").textContent = "Este campo debe rellenarse obligatoriamente";
  249.                 errores = true;
  250.             } else if (!/^\d+$/.test(tip)) { // Validación numérica con expresión regular
  251.                 document.getElementById("tipError").textContent = "Debe ingresar solo dígitos";
  252.                 errores = true;
  253.             }
  254.             if (!fecha) {
  255.                 document.getElementById("fechaError").textContent = "Este campo debe rellenarse obligatoriamente";
  256.                 errores = true;
  257.             }
  258.             if (!turno) {
  259.                 document.getElementById("turnoError").textContent = "Este campo debe rellenarse obligatoriamente";
  260.                 errores = true;
  261.             } else if (turnoSelect.value === "Otro" && !otroTurnoInput.value) {
  262.                document.getElementById("turnoError").textContent = "Por favor, ingrese el otro turno";
  263.                 errores = true;
  264.             }
  265.             if (document.getElementById("campoIncidencias").style.display === "block" && !incidencias) {
  266.                document.getElementById("incidenciasError").textContent = "Este campo debe rellenarse obligatoriamente";
  267.                 errores = true;
  268.             }
  269.             if (!observaciones) {
  270.                 document.getElementById("observacionesError").textContent = "Este campo debe rellenarse obligatoriamente";
  271.                 errores = true;
  272.             }
  273.  
  274.             if (errores) {
  275.                 event.preventDefault();
  276.             }
  277.         });
  278.  
  279.         function mostrarFormulario(tipo) {
  280.             const paginaPrincipal = document.getElementById("paginaPrincipal");
  281.             const formulario = document.getElementById("formulario");
  282.             const campoIncidencias = document.getElementById("campoIncidencias");
  283.             const campoAdjuntarFoto = document.getElementById("campoAdjuntarFoto");
  284.             const btnServicio = document.getElementById("btnServicio");
  285.             const btnIncidencias = document.getElementById("btnIncidencias");
  286.             const btnDescargarPDF = document.getElementById("btnDescargarPDF");
  287.             const tituloFormulario = document.getElementById("tituloFormulario");
  288.  
  289.             if (tipo === 'servicio') {
  290.                 tituloFormulario.innerText = "Parte Diario de Servicio";
  291.                 campoIncidencias.style.display = "none";
  292.                 campoAdjuntarFoto.style.display = "none";
  293.             } else if (tipo === 'incidencias') {
  294.                 tituloFormulario.innerText = "Parte de Incidencias";
  295.                 campoIncidencias.style.display = "block";
  296.                 campoAdjuntarFoto.style.display = "block";
  297.             }
  298.  
  299.             paginaPrincipal.style.display = "none";
  300.             formulario.style.display = "block";
  301.             btnDescargarPDF.style.display = "inline-block";
  302.  
  303.             btnServicio.classList.remove("activo");
  304.             btnIncidencias.classList.remove("activo");
  305.             document.getElementById(tipo === 'servicio' ? "btnServicio" : "btnIncidencias").classList.add("activo");
  306.         }
  307.  
  308.         document.getElementById("foto").addEventListener("change", function() {
  309.             const previewContainer = document.getElementById("fotosPreview");
  310.             previewContainer.innerHTML = ''; // Limpiar previsualizaciones anteriores
  311.             const files = this.files;
  312.  
  313.             for (const file of files) {
  314.                 const reader = new FileReader();
  315.                 reader.onload = function(e) {
  316.                     const img = document.createElement("img");
  317.                     img.src = e.target.result;
  318.                     img.classList.add("fotoPreview");
  319.                     previewContainer.appendChild(img);
  320.                 }
  321.                 reader.readAsDataURL(file);
  322.             }
  323.         });
  324.  
  325.         document.getElementById("btnDescargarPDF").addEventListener("click", function() {
  326.             const { jsPDF } = window.jspdf;
  327.             const doc = new jsPDF();
  328.             const anchoPagina = doc.internal.pageSize.getWidth();
  329.             const margen = 10;
  330.             let yPos = 20;
  331.  
  332.             // Encabezado
  333.             const logoImg = new Image();
  334.             logoImg.onload = function() {
  335.                 doc.addImage(logoImg, 'PNG', margen, yPos, 50, 20); // Ajusta las dimensiones y posición según necesites
  336.                 doc.setFontSize(18);
  337.                 doc.text("Parte de Servicio - Vigilante", anchoPagina / 2, yPos + 15, { align: "center" });
  338.                 yPos += 30;
  339.  
  340.                 // Tabla de datos
  341.                 doc.autoTable({
  342.                     head: [["Campo", "Valor"]],
  343.                     body: [
  344.                         ["Nombre del Servicio", document.getElementById("servicio").value],
  345.                         ["Dirección del Servicio", document.getElementById("lugar").value],
  346.                         ["Nombre del Vigilante", document.getElementById("vigilante").value],
  347.                         ["N° de T.I.P.", document.getElementById("tip").value],
  348.                         ["Fecha", document.getElementById("fecha").value],
  349.                         ["Turno", document.getElementById("turno").value === "Otro" ? document.getElementById("otroTurnoInput").value : document.getElementById("turno").value],
  350.                         ["Incidencias", document.getElementById("incidencias").value || "N/A"],
  351.                         ["Observaciones", document.getElementById("observaciones").value]
  352.                     ],
  353.                     startY: yPos,
  354.                     margin: { horizontal: margen },
  355.                     styles: { cellPadding: 5, fontSize: 10 },
  356.                     headStyles: { fillColor: [220, 220, 220]<!DOCTYPE html>
  357. <html lang="es">
  358. <head>
  359.     <meta charset="UTF-8">
  360.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  361.     <title>Parte de Servicio - Vigilante</title>
  362.     <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  363.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
  364.     <style>
  365.         body {
  366.             background-color: #e0e0e0; /* Gris más oscuro */
  367.         }
  368.         .error { color: red; display: block; margin-top: -10px; margin-bottom: 10px; }
  369.         .contenido { display: block; }
  370.         .oculto { display: none; }
  371.         .fotoPreview {
  372.             max-width: 100px;
  373.             max-height: 100px;
  374.             margin-top: 10px;
  375.             display: inline-block;
  376.             border: 1px solid #ccc;
  377.             border-radius: 5px;
  378.         }
  379.         #otroTurnoInput { display: none; }
  380.         .menu button {
  381.             background-color: #007bff; /* Color azul para los botones del menú */
  382.             color: white;
  383.             padding: 10px 20px;
  384.             border: none;
  385.             border-radius: 5px;
  386.             margin: 5px;
  387.             cursor: pointer;
  388.         }
  389.         .menu button:hover {
  390.             background-color: #0056b3; /* Color azul más oscuro al pasar el ratón */
  391.         }
  392.         .form-label {
  393.             font-weight: bold; /* Etiquetas de formulario en negrita */
  394.         }
  395.         .btn-success {
  396.             background-color: #28a745; /* Color verde para el botón de enviar */
  397.             color: white;
  398.             border: none;
  399.         }
  400.         .btn-success:hover {
  401.             background-color: #218838; /* Color verde más oscuro al pasar el ratón */
  402.         }
  403.         .btn-primary {
  404.             background-color: #007bff; /* Color azul para el botón de descargar PDF */
  405.             color: white;
  406.             border: none;
  407.         }
  408.         .btn-primary:hover {
  409.             background-color: #0056b3; /* Color azul más oscuro al pasar el ratón */
  410.         }
  411.         .header {
  412.             background-color: #f0f0f0; /* Color de fondo gris claro para el encabezado */
  413.         }
  414.         .footer {
  415.             background-color: #f0f0f0; /* Color de fondo gris claro para el pie de página */
  416.         }
  417.     </style>
  418. </head>
  419. <body>
  420.     <div class="contenido" id="paginaPrincipal">
  421.         <div class="header text-center p-4 mb-4">
  422.             <img src="logo_empresa.png" alt="Logo de la Empresa" class="img-fluid" style="max-width: 150px; margin-bottom: 10px;">
  423.             <h1>Nombre de la Empresa</h1>
  424.             <p>Dirección: Calle Ejemplo, 123 - Teléfono: 123-456-789</p>
  425.         </div>
  426.  
  427.         <div class="menu d-flex justify-content-center mb-4">
  428.             <button id="btnServicio" onclick="mostrarFormulario('servicio')"><i class="fas fa-file-alt"></i> Parte Diario de Servicio</button>
  429.             <button id="btnIncidencias" onclick="mostrarFormulario('incidencias')"><i class="fas fa-exclamation-triangle"></i> Parte de Incidencias</button>
  430.         </div>
  431.     </div>
  432.  
  433.     <div id="formulario" class="oculto">
  434.         <h2 id="tituloFormulario" class="text-center mb-4"></h2>
  435.         <form id="parteTrabajo" class="container">
  436.             <div class="mb-3">
  437.                 <label for="servicio" class="form-label">Nombre del Servicio:</label>
  438.                 <input type="text" id="servicio" class="form-control" required>
  439.                 <span id="servicioError" class="error"></span>
  440.             </div>
  441.  
  442.             <div class="mb-3">
  443.                 <label for="lugar" class="form-label">Dirección del Servicio:</label>
  444.                 <input type="text" id="lugar" class="form-control" required>
  445.                 <span id="lugarError" class="error"></span>
  446.             </div>
  447.  
  448.             <div class="mb-3">
  449.                 <label for="vigilante" class="form-label">Nombre del Vigilante:</label>
  450.                 <input type="text" id="vigilante" class="form-control" required>
  451.                 <span id="vigilanteError" class="error"></span>
  452.             </div>
  453.  
  454.             <div class="mb-3">
  455.                 <label for="tip" class="form-label">N° de T.I.P.:</label>
  456.                 <input type="text" id="tip" class="form-control" required>
  457.                 <span id="tipError" class="error"></span>
  458.             </div>
  459.  
  460.             <div class="mb-3">
  461.                 <label for="fecha" class="form-label">Fecha:</label>
  462.                 <input type="date" id="fecha" class="form-control" required>
  463.                 <span id="fechaError" class="error"></span>
  464.             </div>
  465.  
  466.             <div class="mb-3">
  467.                 <label for="turno" class="form-label">Turno:</label>
  468.                 <select id="turno" class="form-select" required>
  469.                     <option value="">Selecciona un turno</option>
  470.                     <option value="Mañana">Mañana</option>
  471.                     <option value="Tarde">Tarde</option>
  472.                     <option value="Noche">Noche</option>
  473.                     <option value="Otro">Otro</option>
  474.                 </select>
  475.                 <span id="turnoError" class="error"></span>
  476.                 <input type="text" id="otroTurnoInput" class="form-control mt-2" placeholder="Ingresa otro turno">
  477.             </div>
  478.  
  479.             <div id="campoIncidencias" class="mb-3" style="display:none;">
  480.                 <label for="incidencias" class="form-label">Incidencias:</label>
  481.                 <textarea id="incidencias" class="form-control" rows="5"></textarea>
  482.                 <span id="incidenciasError" class="error"></span>
  483.             </div>
  484.  
  485.             <div class="mb-3">
  486.                 <label for="observaciones" class="form-label">Observaciones:</label>
  487.                 <textarea id="observaciones" class="form-control" rows="5" required></textarea>
  488.                 <span id="observacionesError" class="error"></span>
  489.             </div>
  490.            
  491.             <div id="campoAdjuntarFoto" style="display:none;" class="mb-3">
  492.                 <label for="foto" class="form-label">Adjuntar Fotografías:</label>
  493.                 <input type="file" id="foto" class="form-control" accept="image/*" multiple>
  494.                 <span id="fotoError" class="error"></span>
  495.                 <div id="fotosPreview"></div>
  496.             </div>
  497.  
  498.             <label>Firma del Vigilante:</label>
  499.             <canvas id="firmaCanvas" width="300" height="150"></canvas>
  500.             <button type="button" onclick="limpiarFirma()">Borrar Firma</button>
  501.  
  502.             <button type="submit" class="btn btn-success">Enviar</button>
  503.             <button type="button" id="btnDescargarPDF" class="btn btn-primary" style="display:none;">Descargar PDF</button>
  504.         </form>
  505.     </div>
  506.  
  507.     <div class="footer text-center p-3">
  508.         <p>© 2025 Todos los derechos reservados | Autor: Carlos López</p>
  509.     </div>
  510.  
  511.     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  512.     <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
  513.     <script>
  514.         const canvas = document.getElementById("firmaCanvas");
  515.         const ctx = canvas.getContext("2d");
  516.         let dibujando = false;
  517.         let ultimoX = 0;
  518.         let ultimoY = 0;
  519.         ctx.lineWidth = 3;
  520.         ctx.lineCap = 'round';
  521.  
  522.         function iniciarDibujo(event) {
  523.             dibujando = true;
  524.             ultimoX = obtenerPosicionX(event);
  525.             ultimoY = obtenerPosicionY(event);
  526.         }
  527.  
  528.         function finalizarDibujo() {
  529.             dibujando = false;
  530.         }
  531.  
  532.         function dibujar(event) {
  533.             if (!dibujando) return;
  534.             const x = obtenerPosicionX(event);
  535.             const y = obtenerPosicionY(event);
  536.             ctx.beginPath();
  537.             ctx.moveTo(ultimoX, ultimoY);
  538.             ctx.lineTo(x, y);
  539.             ctx.stroke();
  540.             ultimoX = x;
  541.             ultimoY = y;
  542.             event.preventDefault();
  543.         }
  544.  
  545.         function obtenerPosicionX(event) {
  546.             const rect = canvas.getBoundingClientRect();
  547.             return (event.clientX || event.touches[0].clientX) - rect.left;
  548.         }
  549.  
  550.         function obtenerPosicionY(event) {
  551.             const rect = canvas.getBoundingClientRect();
  552.             return (event.clientY || event.touches[0].clientY) - rect.top;
  553.         }
  554.  
  555.         function limpiarFirma() {
  556.             ctx.clearRect(0, 0, canvas.width, canvas.height);
  557.         }
  558.  
  559.         canvas.addEventListener("mousedown", iniciarDibujo);
  560.         canvas.addEventListener("mouseup", finalizarDibujo);
  561.         canvas.addEventListener("mousemove", dibujar);
  562.         canvas.addEventListener("touchstart", iniciarDibujo);
  563.         canvas.addEventListener("touchend", finalizarDibujo);
  564.         canvas.addEventListener("touchmove", dibujar);
  565.  
  566.         document.getElementById("turno").addEventListener("change", function() {
  567.             const otroTurnoInput = document.getElementById("otroTurnoInput");
  568.             if (this.value === "Otro") {
  569.                 otroTurnoInput.style.display = "block";
  570.             } else {
  571.                 otroTurnoInput.style.display = "none";
  572.             }
  573.         });
  574.  
  575.         document.getElementById("parteTrabajo").addEventListener("submit", function(event) {
  576.             const servicio = document.getElementById("servicio").value;
  577.             const lugar = document.getElementById("lugar").value;
  578.             const vigilante = document.getElementById("vigilante").value;
  579.             const tip = document.getElementById("tip").value;
  580.             const fecha = document.getElementById("fecha").value;
  581.             const turnoSelect = document.getElementById("turno");
  582.             const turno = turnoSelect.value === "Otro" ? document.getElementById("otroTurnoInput").value : turnoSelect.value;
  583.             const incidencias = document.getElementById("incidencias").value;
  584.             const observaciones = document.getElementById("observaciones").value;
  585.             let errores = false;
  586.  
  587.             document.querySelectorAll(".error").forEach(span => span.textContent = "");
  588.  
  589.             if (!servicio) {
  590.                 document.getElementById("servicioError").textContent = "Este campo debe rellenarse obligatoriamente";
  591.                 errores = true;
  592.             }
  593.             if (!lugar) {
  594.                 document.getElementById("lugarError").textContent = "Este campo debe rellenarse obligatoriamente";
  595.                 errores = true;
  596.             }
  597.             if (!vigilante) {
  598.                 document.getElementById("vigilanteError").textContent = "Este campo debe rellenarse obligatoriamente";
  599.                 errores = true;
  600.             }
  601.             if (!tip) {
  602.                 document.getElementById("tipError").textContent = "Este campo debe rellenarse obligatoriamente";
  603.                 errores = true;
  604.             } else if (!/^\d+$/.test(tip)) { // Validación numérica con expresión regular
  605.                 document.getElementById("tipError").textContent = "Debe ingresar solo dígitos";
  606.                 errores = true;
  607.             }
  608.             if (!fecha) {
  609.                 document.getElementById("fechaError").textContent = "Este campo debe rellenarse obligatoriamente";
  610.                 errores = true;
  611.             }
  612.             if (!turno) {
  613.                 document.getElementById("turnoError").textContent = "Este campo debe rellenarse obligatoriamente";
  614.                 errores = true;
  615.             }
  616.             if (document.getElementById("campoIncidencias").style.display === "block" && !incidencias) {
  617.                document.getElementById("incidenciasError").textContent = "Este campo debe rellenarse obligatoriamente";
  618.                 errores = true;
  619.             }
  620.             if (!observaciones) {
  621.                 document.getElementById("observacionesError").textContent = "Este campo debe rellenarse obligatoriamente";
  622.                 errores = true;
  623.             }
  624.  
  625.             if (errores) {
  626.                 event.preventDefault();
  627.             }
  628.         });
  629.  
  630.         function mostrarFormulario(tipo) {
  631.             const paginaPrincipal = document.getElementById("paginaPrincipal");
  632.             const formulario = document.getElementById("formulario");
  633.             const campoIncidencias = document.getElementById("campoIncidencias");
  634.             const campoAdjuntarFoto = document.getElementById("campoAdjuntarFoto");
  635.             const btnServicio = document.getElementById("btnServicio");
  636.             const btnIncidencias = document.getElementById("btnIncidencias");
  637.             const btnDescargarPDF = document.getElementById("btnDescargarPDF");
  638.             const tituloFormulario = document.getElementById("tituloFormulario");
  639.  
  640.             if (tipo === 'servicio') {
  641.                 tituloFormulario.innerText = "Parte Diario de Servicio";
  642.                 campoIncidencias.style.display = "none";
  643.                 campoAdjuntarFoto.style.display = "none";
  644.             } else if (tipo === 'incidencias') {
  645.                 tituloFormulario.innerText = "Parte de Incidencias";
  646.                 campoIncidencias.style.display = "block";
  647.                 campoAdjuntarFoto.style.display = "block";
  648.             }
  649.  
  650.             paginaPrincipal.style.display = "none";
  651.             formulario.style.display = "block";
  652.             btnDescargarPDF.style.display = "inline-block";
  653.  
  654.             btnServicio.classList.remove("activo");
  655.             btnIncidencias.classList.remove("activo");
  656.             document.getElementById(tipo === 'servicio' ? "btnServicio" : "btnIncidencias").classList.add("activo");
  657.         }
  658.  
  659.         document.getElementById("foto").addEventListener("change", function() {
  660.             const previewContainer = document.getElementById("fotosPreview");
  661.             previewContainer.innerHTML = ''; // Limpiar previsualizaciones anteriores
  662.             const files = this.files;
  663.  
  664.             for (const file of files) {
  665.                 const reader = new FileReader();
  666.                 reader.onload = function(e) {
  667.                     const img = document.createElement("img");
  668.                     img.src = e.target.result;
  669.                     img.classList.add("fotoPreview");
  670.                     previewContainer.appendChild(img);
  671.                 }
  672.                 reader.readAsDataURL(file);
  673.             }
  674.         });
  675.  
  676.         document.getElementById("btnDescargarPDF").addEventListener("click", function() {
  677.             const { jsPDF } = window.jspdf;
  678.             const doc = new jsPDF();
  679.             const anchoPagina = doc.internal.pageSize.getWidth();
  680.             const margen = 10;
  681.             let yPos = 20;
  682.  
  683.             // Encabezado
  684.             doc.setFontSize(18);
  685.             doc.text("Parte de Servicio - Vigilante", anchoPagina / 2, yPos, { align: "center" });
  686.             yPos += 20;
  687.  
  688.             // Tabla de datos
  689.             doc.autoTable({
  690.                 head: [["Campo", "Valor"]],
  691.                 body: [
  692.                     ["Nombre del Servicio", document.getElementById("servicio").value],
  693.                     ["Dirección del Servicio", document.getElementById("lugar").value],
  694.                     ["Nombre del Vigilante", document.getElementById("vigilante").value],
  695.                     ["N° de T.I.P.", document.getElementById("tip").value],
  696.                     ["Fecha", document.getElementById("fecha").value],
  697.                     ["Turno", document.getElementById("turno").value === "Otro" ? document.getElementById("otroTurnoInput").value : document.getElementById("turno").value],
  698.                     ["Incidencias", document.getElementById("incidencias").value || "N/A"],
  699.                     ["Observaciones", document.getElementById("observaciones").value]
  700.                 ],
  701.                 startY: yPos,
  702.                 margin: { horizontal: margen },
  703.                 styles: { cellPadding: 5, fontSize: 10 },
  704.                 headStyles: { fillColor: [220, 220, 220] }
  705.             });
  706.             yPos = doc.autoTable.previous.finalY + 20;
  707.  
  708.             // Firma
  709.             doc.text("Firma del Vigilante:", margen, yPos);
  710.             yPos += 10;
  711.             const firmaDataURL = canvas.toDataURL();
  712.             doc.addImage(firmaDataURL, 'PNG', margen, yPos, 50, 25);
  713.             yPos += 40;
  714.  
  715.             // Fotos
  716.             const fotos = document.getElementById("foto").files;
  717.             if (fotos && fotos.length > 0) {
  718.                doc.text("Fotos Adjuntas:", margen, yPos);
  719.                 yPos += 10;
  720.                 let xPos = margen;
  721.                 for (let i = 0; i < fotos.length; i++) {
  722.                    const reader = new FileReader();
  723.                    reader.onload = function(e) {
  724.                        doc.addImage(e.target.result, 'JPEG', xPos, yPos, 50, 25);
  725.                        xPos += 60;
  726.                        if ((i + 1) % 3 === 0) {
  727.                            yPos += 30;
  728.                            xPos = margen;
  729.                        }
  730.                    }
  731.                    reader.readAsDataURL(fotos[i]);
  732.                }
  733.                yPos += 30;
  734.            }
  735.  
  736.            // Pie de página
  737.            const fechaActual = new Date().toLocaleDateString();
  738.            doc.text(`Fecha de creación: ${fechaActual} | Autor: Carlos López`, anchoPagina / 2, doc.internal.pageSize.getHeight() - 10, { align: "center" });
  739.  
  740.            doc.save("parte_servicio.pdf");
  741.        });
  742.    </script>
  743. </body>
  744. </html>
  745.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement