{"id":478,"date":"2025-10-08T14:33:54","date_gmt":"2025-10-08T14:33:54","guid":{"rendered":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/?page_id=478"},"modified":"2025-10-13T20:35:34","modified_gmt":"2025-10-13T20:35:34","slug":"quejas-y-denuncias","status":"publish","type":"page","link":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/quejas-y-denuncias\/","title":{"rendered":"Quejas y Denuncias"},"content":{"rendered":"\n<div class=\"wrap\">\n  <h1>Formato de denuncia<\/h1>\n  <p class=\"muted\">Completa la informaci\u00f3n y env\u00edala. Ver\u00e1s una confirmaci\u00f3n al finalizar.<\/p>\n\n  <div class=\"card\">\n    <form id=\"denunciaForm\" novalidate>\n      <fieldset>\n        <legend>Datos generales<\/legend>\n        <div class=\"row two\">\n          <div>\n            <label for=\"lugar\" class=\"req\">Lugar*<\/label>\n            <input value=\"Oaxaca de Ju\u00e1rez, Oaxaca.\" id=\"lugar\" name=\"lugar\" type=\"text\" required \/>\n          <\/div>\n          <div>\n            <label for=\"fecha\" class=\"req\">Fecha*<\/label>\n            <input id=\"fecha\" name=\"fecha\" type=\"date\" required \/>\n          <\/div>\n        <\/div>\n      <\/fieldset>\n\n      <fieldset>\n        <legend>Datos de contacto del denunciante<\/legend>\n        <label for=\"nombreDenunciante\" class=\"req\">Nombre del denunciante*<\/label>\n        <input id=\"nombreDenunciante\" name=\"nombreDenunciante\" type=\"text\" autocomplete=\"name\" required \/>\n\n        <label for=\"domicilioMedio\" class=\"req\">Domicilio y\/o medio para recibir notificaciones*<\/label>\n        <input id=\"domicilioMedio\" name=\"domicilioMedio\" type=\"text\" required \/>\n\n        <div class=\"row two\">\n          <div>\n            <label for=\"celular\">N\u00famero de celular<\/label>\n            <input id=\"celular\" name=\"celular\" type=\"tel\" inputmode=\"tel\" \/>\n          <\/div>\n          <div>\n            <label for=\"correo\">Correo electr\u00f3nico<\/label>\n            <input id=\"correo\" name=\"correo\" type=\"email\" inputmode=\"email\" autocomplete=\"email\" \/>\n          <\/div>\n        <\/div>\n\n        <div class=\"inline\" style=\"margin-top:14px\">\n          <input id=\"chkLengua\" name=\"hablaLenguaIndigena\" type=\"checkbox\" \/>\n          <label for=\"chkLengua\" style=\"margin:0;font-weight:600\">Habla alguna lengua ind\u00edgena<\/label>\n        <\/div>\n        <label for=\"lengua\" class=\"hint\">\u00bfCu\u00e1l?<\/label>\n        <input id=\"lengua\" name=\"lengua\" type=\"text\" placeholder=\"Especifica la lengua\" disabled \/>\n      <\/fieldset>\n\n      <fieldset>\n        <legend>Documentaci\u00f3n adjunta<\/legend>\n\n        <!-- Campo de archivo SIEMPRE visible (opcional) -->\n        <div class=\"inline\" style=\"margin-bottom:8px\">\n          <label for=\"ineArchivo\" style=\"margin:0 12px 0 0; font-weight:600\">\n            Adjuntar archivo (JPG\/PNG\/PDF, opcional)\n          <\/label>\n          <input id=\"ineArchivo\" name=\"ineArchivo\" type=\"file\" accept=\"image\/jpeg,image\/png,application\/pdf\" \/>\n          <small class=\"hint\">Tama\u00f1o m\u00e1x: 5 MB<\/small>\n        <\/div>\n\n        <!-- Checks para indicar a qu\u00e9 corresponde el adjunto -->\n        <div class=\"inline\">\n          <input id=\"ine\" name=\"identificacionOficial\" type=\"checkbox\" \/>\n          <label for=\"ine\" style=\"margin:0;font-weight:600\">Identificaci\u00f3n oficial (INE, original o copia)<\/label>\n        <\/div>\n        <div class=\"inline\">\n          <input id=\"mandato\" name=\"mandatoRepresentante\" type=\"checkbox\" \/>\n          <label for=\"mandato\" style=\"margin:0;font-weight:600\">Mandato o acta que se\u00f1ale nombramiento como representante legal (si es persona moral)<\/label>\n        <\/div>\n      <\/fieldset>\n\n      <fieldset>\n        <legend>Personas servidoras p\u00fablicas denunciadas<\/legend>\n        <label for=\"servidores\">Nombre del o los servidores p\u00fablicos denunciados (si lo conoce)<\/label>\n        <textarea id=\"servidores\" name=\"servidores\" rows=\"3\" placeholder=\"Puedes escribir varios nombres separados por coma o salto de l\u00ednea\"><\/textarea>\n      <\/fieldset>\n\n      <fieldset>\n        <legend>Informaci\u00f3n del expediente (si aplica)<\/legend>\n        <div class=\"row two\">\n          <div>\n            <label for=\"numeroExpediente\">N\u00fam. de expediente \/ juicio \/ tr\u00e1mite<\/label>\n            <input id=\"numeroExpediente\" name=\"numeroExpediente\" type=\"text\" \/>\n          <\/div>\n          <div>\n            <label for=\"ubicacionExpediente\">Ubicaci\u00f3n del expediente (Sala y Secretar\u00eda)<\/label>\n            <input id=\"ubicacionExpediente\" name=\"ubicacionExpediente\" type=\"text\" \/>\n          <\/div>\n        <\/div>\n      <\/fieldset>\n\n      <fieldset>\n        <legend>Narraci\u00f3n de los hechos*<\/legend>\n        <p class=\"hint\">Ordena los acontecimientos e incluye datos de tiempo, modo y lugar.<\/p>\n        <textarea id=\"narracion\" name=\"narracion\" rows=\"10\" required placeholder=\"Escribe aqu\u00ed la narraci\u00f3n circunstanciada de los hechos\"><\/textarea>\n      <\/fieldset>\n\n      <p class=\"muted\">\n        <span class=\"badge\">Nota<\/span>\n        El \u00d3rgano Interno de Control es competente para conocer actos u omisiones relacionados con faltas administrativas conforme a la Ley General de Responsabilidades Administrativas.\n      <\/p>\n\n      <div class=\"actions\">\n        <button type=\"submit\" class=\"btn-primary\" id=\"submitBtn\">Enviar denuncia<\/button>\n        <button type=\"reset\" class=\"btn-secondary\" id=\"resetBtn\">Limpiar<\/button>\n      <\/div>\n\n      <div id=\"status\" class=\"status\" role=\"status\" aria-live=\"polite\" style=\"display:none\"><\/div>\n    <\/form>\n  <\/div>\n<\/div>\n\n<script>\n(function () {\n  \/\/ --- Utilidad: obtener YYYY-MM-DD de hoy (zona horaria del navegador) ---\n  function todayStr() {\n    const d = new Date();\n    const pad = n => String(n).padStart(2, '0');\n    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n  }\n\n  \/\/ Referencias base\n  const form      = document.getElementById('denunciaForm');\n  const submitBtn = document.getElementById('submitBtn');\n  const resetBtn  = document.getElementById('resetBtn');\n\n  \/\/ Guardamos etiquetas originales\n  const SUBMIT_LABEL = submitBtn ? submitBtn.innerHTML : 'Enviar denuncia';\n  const RESET_LABEL  = resetBtn  ? resetBtn.innerHTML  : 'Limpiar';\n\n  \/\/ Lengua ind\u00edgena: habilitar\/deshabilitar campo\n  const chkLengua = document.getElementById('chkLengua');\n  const lengua    = document.getElementById('lengua');\n  chkLengua.addEventListener('change', () => {\n    lengua.disabled = !chkLengua.checked;\n    if (!chkLengua.checked) lengua.value = '';\n  });\n\n  \/\/ &#x1f449; Sugerir la fecha de hoy en el campo \"fecha\"\n  const fecha = document.getElementById('fecha');\n  if (fecha) {\n    const hoy = todayStr();\n    if (!fecha.value) fecha.value = hoy;\n    \/\/ fecha.max = hoy; \/\/ (opcional) impedir fechas futuras\n  }\n\n  \/\/ Helpers\n  function setButtonsDisabled(disabled) {\n    if (submitBtn) submitBtn.disabled = disabled;\n    if (resetBtn)  resetBtn.disabled  = disabled;\n  }\n  function showLoading(btn, text) {\n    if (!btn) return;\n    btn.setAttribute('aria-busy', 'true');\n    btn.innerHTML = `<span class=\"btn-spinner\" aria-hidden=\"true\"><\/span>${text}`;\n  }\n  function hideLoading(btn, originalLabel) {\n    if (!btn) return;\n    btn.removeAttribute('aria-busy');\n    btn.innerHTML = originalLabel;\n  }\n\n  \/\/ Archivo -> DataURL (Base64)\n  function fileToDataURL(file) {\n    return new Promise((resolve, reject) => {\n      const reader = new FileReader();\n      reader.onerror = () => reject(new Error('No se pudo leer el archivo.'));\n      reader.onload  = () => resolve(reader.result); \/\/ data:<mime>;base64,XXXX\n      reader.readAsDataURL(file);\n    });\n  }\n\n  \/\/ Reset: deshabilitar mientras se limpia y re-habilitar luego\n  if (resetBtn) {\n    resetBtn.addEventListener('click', () => {\n      setButtonsDisabled(true);\n      showLoading(resetBtn, 'Limpiando\u2026');\n    });\n  }\n  form.addEventListener('reset', () => {\n    lengua.disabled = !chkLengua.checked;\n\n    \/\/ volver a sugerir la fecha de hoy tras limpiar\n    if (fecha && !fecha.value) {\n      const hoy = todayStr();\n      fecha.value = hoy;\n      \/\/ fecha.max = hoy; \/\/ (opcional)\n    }\n\n    setTimeout(() => {\n      hideLoading(resetBtn, RESET_LABEL);\n      setButtonsDisabled(false);\n    }, 150);\n  });\n\n  form.addEventListener('submit', async (e) => {\n    e.preventDefault();\n    setButtonsDisabled(true);            \/\/ &#x1f512; bloquear ambos\n    showLoading(submitBtn, 'Enviando\u2026'); \/\/ &#x25b6;&#xfe0f; spinner en Enviar\n\n    \/\/ Validaci\u00f3n m\u00ednima\n    const required = ['lugar', 'fecha', 'nombreDenunciante', 'domicilioMedio', 'narracion'];\n    for (const id of required) {\n      const el = document.getElementById(id);\n      if (!el.value.trim()) {\n        el.focus();\n        alert('Por favor completa los campos obligatorios marcados con *.');\n        hideLoading(submitBtn, SUBMIT_LABEL);\n        setButtonsDisabled(false);\n        return;\n      }\n    }\n\n    \/\/ Construcci\u00f3n del payload (JSON)\n    const data = {\n      lugar: document.getElementById('lugar').value.trim(),\n      fecha: document.getElementById('fecha').value,\n      nombreDenunciante: document.getElementById('nombreDenunciante').value.trim(),\n      domicilioMedio: document.getElementById('domicilioMedio').value.trim(),\n      celular: document.getElementById('celular').value.trim() || null,\n      correo: document.getElementById('correo').value.trim() || null,\n      hablaLenguaIndigena: document.getElementById('chkLengua').checked,\n      lengua: document.getElementById('lengua').value.trim() || null,\n      identificacionOficial: document.getElementById('ine').checked,\n      mandatoRepresentante: document.getElementById('mandato').checked,\n      servidoresDenunciados: document.getElementById('servidores').value.trim() || null,\n      numeroExpediente: document.getElementById('numeroExpediente').value.trim() || null,\n      ubicacionExpediente: document.getElementById('ubicacionExpediente').value.trim() || null,\n      narracion: document.getElementById('narracion').value.trim()\n    };\n\n    \/\/ Determinar a qu\u00e9 corresponde el adjunto seg\u00fan checkboxes\n    const esINE = document.getElementById('ine').checked;\n    const esMandato = document.getElementById('mandato').checked;\n    let adjuntoTipo = 'OTRO';\n    if (esINE && esMandato) adjuntoTipo = 'INE+MANDATO';\n    else if (esINE)          adjuntoTipo = 'INE';\n    else if (esMandato)      adjuntoTipo = 'MANDATO';\n    data.adjuntoTipo = adjuntoTipo;\n\n    \/\/ Adjuntar archivo en Base64 si el usuario eligi\u00f3 uno (opcional)\n    const inputFile = document.getElementById('ineArchivo');\n    if (inputFile && inputFile.files && inputFile.files.length > 0) {\n      const file = inputFile.files[0];\n      const allowed = ['image\/jpeg','image\/png','application\/pdf'];\n      if (!allowed.includes(file.type)) {\n        alert('Tipo de archivo no permitido. Usa JPG, PNG o PDF.');\n        hideLoading(submitBtn, SUBMIT_LABEL);\n        setButtonsDisabled(false);\n        return;\n      }\n      const MAX = 5 * 1024 * 1024; \/\/ 5 MB\n      if (file.size > MAX) {\n        alert('Archivo demasiado grande (m\u00e1x 5 MB).');\n        hideLoading(submitBtn, SUBMIT_LABEL);\n        setButtonsDisabled(false);\n        return;\n      }\n      try {\n        const dataURL = await fileToDataURL(file);\n        data.ineArchivoB64    = dataURL;\n        data.ineArchivoNombre = file.name;\n        data.ineArchivoTipo   = file.type;\n        data.ineArchivoTamano = file.size;\n      } catch (err) {\n        alert('No se pudo leer el archivo adjunto.');\n        hideLoading(submitBtn, SUBMIT_LABEL);\n        setButtonsDisabled(false);\n        return;\n      }\n    }\n\n    try {\n      const endpoint = 'https:\/\/tjaccoaxaca.gob.mx\/enviar-mail.php';\n      const resp = await fetch(endpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application\/json' },\n        body: JSON.stringify(data)\n      });\n\n      let payload = {};\n      try { payload = await resp.json(); } catch (_) {}\n\n      if (resp.ok) {\n        alert('\u00a1Denuncia enviada con \u00e9xito! Hemos recibido tu informaci\u00f3n.');\n        form.reset();\n      } else {\n        const detail = payload?.message || payload?.detalle || '';\n        alert('No se pudo enviar la denuncia.' + (detail ? '\\nDetalle: ' + detail : ''));\n      }\n    } catch (err) {\n      alert('Ocurri\u00f3 un error de conexi\u00f3n al enviar la denuncia.');\n      console.error(err);\n    } finally {\n      hideLoading(submitBtn, SUBMIT_LABEL);\n      setButtonsDisabled(false); \/\/ &#x1f513; reactivar al terminar el proceso\n    }\n  });\n})();\n<\/script>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><a href=\"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-content\/uploads\/2025\/10\/Aviso-de-Privacidad-simplificado-1.pdf\">Aviso de Privacidad Simplificado&#8230;<\/a><\/p>\n<\/div><\/div>\n\n\n\n<p><a href=\"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-content\/uploads\/2025\/10\/AVISO-DE-PRIVACIDAD-INTEGRAL-1.pdf\">Aviso de Privacidad Integral&#8230;<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Formato de denuncia Completa la informaci\u00f3n y env\u00edala. Ver\u00e1s una confirmaci\u00f3n al finalizar. Datos generales Lugar* Fecha* Datos de contacto del denunciante Nombre del denunciante* Domicilio y\/o medio para recibir notificaciones* N\u00famero de celular Correo electr\u00f3nico Habla alguna lengua ind\u00edgena \u00bfCu\u00e1l? Documentaci\u00f3n adjunta Adjuntar archivo (JPG\/PNG\/PDF, opcional) Tama\u00f1o m\u00e1x: 5 MB Identificaci\u00f3n oficial (INE, original o copia) Mandato o acta [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"_links":{"self":[{"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/pages\/478"}],"collection":[{"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/comments?post=478"}],"version-history":[{"count":24,"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/pages\/478\/revisions"}],"predecessor-version":[{"id":616,"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/pages\/478\/revisions\/616"}],"wp:attachment":[{"href":"https:\/\/tjaccoaxaca.gob.mx\/inicio\/wp-json\/wp\/v2\/media?parent=478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}