Modificaciones en el componente
This commit is contained in:
+6
-2
@@ -9,6 +9,7 @@ import { Funcionario, PayloadBusqueda } from '@/types/Funcionarios';
|
||||
|
||||
export default function Home() {
|
||||
const [resultados, setResultados] = useState<Funcionario[]>([]);
|
||||
const [currentAreaLabel, setCurrentAreaLabel] = useState<string>('');
|
||||
// Zoom / Pan state
|
||||
const imgRef = useRef<HTMLDivElement | null>(null);
|
||||
const [scale, setScale] = useState<number>(1);
|
||||
@@ -93,10 +94,13 @@ export default function Home() {
|
||||
return (
|
||||
<main className="container-fluid py-4 bg-light min-h-screen">
|
||||
<div className="row">
|
||||
<BuscarFuncionario onResultados={setResultados} />
|
||||
<BuscarFuncionario onResultados={setResultados} onAreaSelected={(id, label) => { setCurrentAreaLabel(label); buscarPorArea(id); }} onClear={() => { setCurrentAreaLabel(''); setResultados([]); }} />
|
||||
|
||||
<div className="col-12 col-md-9">
|
||||
<h2 className="text-dorado mb-4">Directorio de Funcionarios</h2>
|
||||
{currentAreaLabel && <h3 className="text-dorado mb-3 ms-2">{currentAreaLabel}</h3>}
|
||||
|
||||
|
||||
|
||||
<div className="row g-4 m-2">
|
||||
{resultados.length === 0 ? (
|
||||
@@ -133,7 +137,7 @@ export default function Home() {
|
||||
touchAction: 'none',
|
||||
}}
|
||||
>
|
||||
<OrganigramaInteractivo onAreaSelect={(id: number) => buscarPorArea(id)} isPanningRef={isPanning} />
|
||||
<OrganigramaInteractivo onAreaSelect={(id: number) => { buscarPorArea(id); }} isPanningRef={isPanning} onAreaLabel={(id, label) => setCurrentAreaLabel(label)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,12 +5,15 @@ import axios from 'axios';
|
||||
import { Funcionario } from '../types/Funcionarios';
|
||||
import { PayloadBusqueda } from '../types/Funcionarios';
|
||||
import { errorBuscar, funcionarioNoEncontrado } from '@/utils/alerts';
|
||||
import AREAS from '@/data/areas';
|
||||
|
||||
interface BuscarFuncionarioProps {
|
||||
onResultados: (data: Funcionario[]) => void;
|
||||
onAreaSelected?: (id: number, label: string) => void;
|
||||
onClear?: () => void;
|
||||
}
|
||||
|
||||
export default function BuscarFuncionario({ onResultados }: BuscarFuncionarioProps) {
|
||||
export default function BuscarFuncionario({ onResultados, onAreaSelected, onClear }: BuscarFuncionarioProps) {
|
||||
const [nombre, setNombre] = useState('');
|
||||
const [apellidos, setApellidos] = useState('');
|
||||
const [area, setArea] = useState('0');
|
||||
@@ -25,6 +28,11 @@ export default function BuscarFuncionario({ onResultados }: BuscarFuncionarioPro
|
||||
return;
|
||||
}
|
||||
|
||||
// Si es búsqueda manual, limpiar etiqueta de área en el padre
|
||||
if (tipo === 'manual') {
|
||||
onClear?.();
|
||||
}
|
||||
|
||||
// Tipo de búsqueda
|
||||
if (area !== '0') {
|
||||
payload.tipoBusqueda = 'area';
|
||||
@@ -50,7 +58,7 @@ export default function BuscarFuncionario({ onResultados }: BuscarFuncionarioPro
|
||||
//Limpiar campos después de buscar
|
||||
setNombre('');
|
||||
setApellidos('');
|
||||
setArea('0');
|
||||
//setArea('0');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error al buscar funcionario:', error);
|
||||
@@ -115,82 +123,32 @@ export default function BuscarFuncionario({ onResultados }: BuscarFuncionarioPro
|
||||
name="bus_depid"
|
||||
className="form-select"
|
||||
value={area}
|
||||
onChange={(e) => setArea(e.target.value)}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
const label = e.target.options[e.target.selectedIndex]?.text || '';
|
||||
setArea(val);
|
||||
if (val !== '0' && label) {
|
||||
onAreaSelected?.(parseInt(val, 10), label);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<option value="0">-- Selecciona un área --</option>
|
||||
<option value="128">Coordinación de Actividades Deportivas y Recreativas</option>
|
||||
<option value="122">Coordinación de Comunicación Social</option>
|
||||
<option value="9">Coordinación de Cuerpos Colegiados</option>
|
||||
<option value="126">Coordinación de Derecho del Sistema de Universidad Abierta y Educación a Distancia</option>
|
||||
<option value="206">Coordinación de Especializaciones</option>
|
||||
<option value="120">Coordinación de Estudios de Posgrado</option>
|
||||
<option value="182">Coordinación de la Unidad de Investigación Multidisciplinaria Aplicada</option>
|
||||
<option value="174">Coordinación de LICEL Sistema de Universidad Abierta y Educación a Distancia</option>
|
||||
<option value="221">Coordinación de Maestrías y Doctorados</option>
|
||||
<option value="152">Coordinación de Relaciones Internacionales del Sistema de Universidad Abierta y Educación a Distancia</option>
|
||||
<option value="121">Coordinación de Servicios Académicos</option>
|
||||
<option value="125">Coordinación del Centro de Difusión Cultural</option>
|
||||
<option value="124">Coordinación del Centro de Educación Continua</option>
|
||||
<option value="129">Coordinación del Centro de Enseñanza de Idiomas</option>
|
||||
<option value="214">Coordinación del Centro de Estudios Municipales y Metropolitanos</option>
|
||||
<option value="176">Coordinación del Centro Tecnológico para la Educación a Distancia</option>
|
||||
<option value="58">Coordinación del Programa de Actuaría</option>
|
||||
<option value="57">Coordinación del Programa de Arquitectura</option>
|
||||
<option value="46">Coordinación del Programa de Comunicación</option>
|
||||
<option value="56">Coordinación del Programa de Derecho</option>
|
||||
<option value="55">Coordinación del Programa de Diseño Gráfico</option>
|
||||
<option value="54">Coordinación del Programa de Economía</option>
|
||||
<option value="49">Coordinación del Programa de Enseñanza de Inglés</option>
|
||||
<option value="52">Coordinación del Programa de Humanidades</option>
|
||||
<option value="51">Coordinación del Programa de Ingeniería Civil</option>
|
||||
<option value="48">Coordinación del Programa de Matemáticas Aplicadas y Computación</option>
|
||||
<option value="47">Coordinación del Programa de Pedagogía</option>
|
||||
<option value="44">Coordinación del Programa de Sociología</option>
|
||||
<option value="43">Coordinación del Programa Político</option>
|
||||
<option value="194">Departamento de Intendencia</option>
|
||||
<option value="193">Departamento de Investigación en Comunicación y Estudios Culturales</option>
|
||||
<option value="222">Departamento de Orientación Académica del Sistema de Universidad Abierta y Educación a Distancia</option>
|
||||
<option value="204">Departamento de Proyectos Administrativos</option>
|
||||
<option value="86">Departamento de Talleres y Laboratorios</option>
|
||||
<option value="72">Dirección</option>
|
||||
<option value="80">División de Ciencias Jurídicas</option>
|
||||
<option value="79">División de Ciencias Socioeconómicas</option>
|
||||
<option value="78">División de Diseño y Edificación</option>
|
||||
<option value="77">División de Humanidades</option>
|
||||
<option value="76">División de Matemáticas e Ingeniería</option>
|
||||
<option value="74">División del Sistema de Universidad Abierta y Educación a Distancia</option>
|
||||
<option value="70">Especialización en Costos en la Construcción</option>
|
||||
<option value="69">Especialización en Finanzas Públicas</option>
|
||||
<option value="68">Especialización en Geotecnia</option>
|
||||
<option value="71">Especialización en Sistemas de Calidad</option>
|
||||
<option value="220">Especialización en Tecnología Digital para la Enseñanza de Matemáticas</option>
|
||||
<option value="207">Grupo de Trabajo de Educación para Adultos (GTEA)</option>
|
||||
<option value="173">Maestría en Docencia para la Educación Media Superior</option>
|
||||
<option value="224">Posgrado en Ciencias Políticas y Sociales</option>
|
||||
<option value="62">Posgrado en Derecho</option>
|
||||
<option value="164">Posgrado en Economía</option>
|
||||
<option value="197">Posgrado en Pedagogía</option>
|
||||
<option value="63">Posgrado en Urbanismo</option>
|
||||
<option value="226">Programa Único de Especializaciones en Derecho</option>
|
||||
<option value="127">Secretaría Administrativa</option>
|
||||
<option value="181">Secretaría de Asuntos Académicos Estudiantiles</option>
|
||||
<option value="177">Secretaría de Extensión Universitaria y Vinculación Institucional</option>
|
||||
<option value="119">Secretaría de Posgrado e Investigación</option>
|
||||
<option value="8">Secretaría General</option>
|
||||
<option value="6">Unidad de Administración Escolar</option>
|
||||
<option value="5">Unidad de Administración y Recursos</option>
|
||||
<option value="4">Unidad de Planeación</option>
|
||||
<option value="3">Unidad de Servicios a la Comunidad</option>
|
||||
<option value="2">Unidad de Servicios Editoriales</option>
|
||||
<option value="1">Unidad de Talleres, Laboratorios y Audiovisuales</option>
|
||||
<option value="130">Unidad del Centro de Desarrollo Tecnológico</option>
|
||||
<option value="123">Unidad del Centro de Información y Documentación</option>
|
||||
{AREAS.map((a) => (
|
||||
<option key={a.id} value={String(a.id)}>{a.label}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Botón de buscar (sin limpiar) */}
|
||||
<div className="d-grid gap-2">
|
||||
<button className="btn btn-primary bg-dorado" type="submit">Buscar</button>
|
||||
<div className="d-flex gap-2">
|
||||
<button className="btn btn-primary bg-dorado" type="submit">Buscar</button>
|
||||
<button type="button" className="btn btn-outline-secondary" onClick={() => {
|
||||
setNombre('');
|
||||
setApellidos('');
|
||||
setArea('0');
|
||||
onClear?.();
|
||||
}}>Limpiar filtros</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,47 +1,19 @@
|
||||
import React from 'react';
|
||||
import AREAS from '@/data/areas';
|
||||
|
||||
interface Props {
|
||||
onAreaSelect: (areaId: number) => void;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
isPanningRef?: React.MutableRefObject<boolean>;
|
||||
onAreaLabel?: (id: number, label: string) => void;
|
||||
}
|
||||
|
||||
// Map display substrings (lowercase) to the area id used in BuscarFuncionario
|
||||
const areaMap: Record<string, number> = {
|
||||
'coordinación de actividades deportivas y recreativas': 128,
|
||||
'coordinación de comunicación social': 122,
|
||||
'coordinación de cuerpos colegiados': 9,
|
||||
'coordinación de derecho del sistema de universidad abierta y educación a distancia': 126,
|
||||
'coordinación de especializaciones': 206,
|
||||
'coordinación de estudios de posgrado': 120,
|
||||
'coordinación de la unidad de investigación multidisciplinaria aplicada': 182,
|
||||
'coordinación de licel sistema de universidad abierta y educación a distancia': 174,
|
||||
'coordinación de maestrías y doctorados': 221,
|
||||
'coordinación de relaciones internacionales del sistema de universidad abierta y educación a distancia': 152,
|
||||
'coordinación de servicios académicos': 121,
|
||||
'coordinación del centro de difusión cultural': 125,
|
||||
'coordinación del centro de educación continua': 124,
|
||||
'coordinación del centro de enseñanza de idiomas': 129,
|
||||
'coordinación del centro de estudios municipales y metropolitanos': 214,
|
||||
'coordinación del centro tecnológico para la educación a distancia': 176,
|
||||
'dirección': 72,
|
||||
'división de ciencias jurídicas': 80,
|
||||
'división de ciencias socioeconómicas': 79,
|
||||
'división de diseño y edificación': 78,
|
||||
'división de humanidades': 77,
|
||||
'división de matemáticas e ingeniería': 76,
|
||||
'secretaría de asuntos académicos estudiantiles': 181,
|
||||
'secretaría de extensión universitaria y vinculación institucional': 177,
|
||||
'secretaría de posgrado e investigación': 119,
|
||||
'secretaría general': 8,
|
||||
'unidad de administración escolar': 6,
|
||||
'unidad de servicios editoriales': 2,
|
||||
'unidad de talleres, laboratorios y audiovisuales': 1,
|
||||
'unidad del centro de desarrollo tecnológico': 130,
|
||||
'unidad del centro de información y documentación': 123,
|
||||
// add more mappings as needed
|
||||
};
|
||||
const areaMap: Record<string, number> = AREAS.reduce((acc, cur) => {
|
||||
acc[cur.label.toLowerCase()] = cur.id;
|
||||
return acc;
|
||||
}, {} as Record<string, number>);
|
||||
|
||||
const svgContent = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1497.56 1125.56">${
|
||||
@@ -52,7 +24,7 @@ const svgContent = `
|
||||
// Instead of inlining the full SVG string here (long), we'll import it via require at runtime by fetching the file relative to the app.
|
||||
// But to keep this component self-contained, we'll render an <object> fallback and then query inside it.
|
||||
|
||||
export default function OrganigramaInteractivo({ onAreaSelect, className, style, isPanningRef }: Props) {
|
||||
export default function OrganigramaInteractivo({ onAreaSelect, className, style, isPanningRef, onAreaLabel }: Props) {
|
||||
const containerRef = React.useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const normalize = (s: string) =>
|
||||
@@ -63,9 +35,9 @@ export default function OrganigramaInteractivo({ onAreaSelect, className, style,
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
|
||||
const normalizedAreaEntries = React.useMemo(() => {
|
||||
return Object.keys(areaMap).map((k) => ({ key: normalize(k), id: areaMap[k] }));
|
||||
}, []);
|
||||
const normalizedAreaEntries = React.useMemo(() => {
|
||||
return Object.keys(areaMap).map((k) => ({ key: normalize(k), id: areaMap[k], label: k }));
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
@@ -123,24 +95,26 @@ export default function OrganigramaInteractivo({ onAreaSelect, className, style,
|
||||
|
||||
const normalized = normalize(textContent);
|
||||
// Try to match any normalized key in areaMap
|
||||
for (const entry of normalizedAreaEntries) {
|
||||
if (normalized.includes(entry.key) || entry.key.includes(normalized)) {
|
||||
onAreaSelect(entry.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const entry of normalizedAreaEntries) {
|
||||
if (normalized.includes(entry.key) || entry.key.includes(normalized)) {
|
||||
onAreaSelect(entry.id);
|
||||
onAreaLabel?.(entry.id, entry.label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If target element directly has a title or id
|
||||
if (target) {
|
||||
const el = target as HTMLElement;
|
||||
const title = (el.getAttribute('title') || el.getAttribute('id') || '').toString();
|
||||
const n = normalize(title);
|
||||
for (const entry of normalizedAreaEntries) {
|
||||
if (n.includes(entry.key) || entry.key.includes(n)) {
|
||||
onAreaSelect(entry.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const entry of normalizedAreaEntries) {
|
||||
if (n.includes(entry.key) || entry.key.includes(n)) {
|
||||
onAreaSelect(entry.id);
|
||||
onAreaLabel?.(entry.id, entry.label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
export const AREAS: Array<{ id: number; label: string }> = [
|
||||
{ id: 0, label: '-- Selecciona un área --' },
|
||||
{ id: 128, label: 'Coordinación de Actividades Deportivas y Recreativas' },
|
||||
{ id: 122, label: 'Coordinación de Comunicación Social' },
|
||||
{ id: 9, label: 'Coordinación de Cuerpos Colegiados' },
|
||||
{ id: 126, label: 'Coordinación de Derecho del Sistema de Universidad Abierta y Educación a Distancia' },
|
||||
{ id: 206, label: 'Coordinación de Especializaciones' },
|
||||
{ id: 120, label: 'Coordinación de Estudios de Posgrado' },
|
||||
{ id: 182, label: 'Coordinación de la Unidad de Investigación Multidisciplinaria Aplicada' },
|
||||
{ id: 174, label: 'Coordinación de LICEL Sistema de Universidad Abierta y Educación a Distancia' },
|
||||
{ id: 221, label: 'Coordinación de Maestrías y Doctorados' },
|
||||
{ id: 152, label: 'Coordinación de Relaciones Internacionales del Sistema de Universidad Abierta y Educación a Distancia' },
|
||||
{ id: 121, label: 'Coordinación de Servicios Académicos' },
|
||||
{ id: 125, label: 'Coordinación del Centro de Difusión Cultural' },
|
||||
{ id: 124, label: 'Coordinación del Centro de Educación Continua' },
|
||||
{ id: 129, label: 'Coordinación del Centro de Enseñanza de Idiomas' },
|
||||
{ id: 214, label: 'Coordinación del Centro de Estudios Municipales y Metropolitanos' },
|
||||
{ id: 176, label: 'Coordinación del Centro Tecnológico para la Educación a Distancia' },
|
||||
{ id: 58, label: 'Coordinación del Programa de Actuaría' },
|
||||
{ id: 57, label: 'Coordinación del Programa de Arquitectura' },
|
||||
{ id: 46, label: 'Coordinación del Programa de Comunicación' },
|
||||
{ id: 56, label: 'Coordinación del Programa de Derecho' },
|
||||
{ id: 55, label: 'Coordinación del Programa de Diseño Gráfico' },
|
||||
{ id: 54, label: 'Coordinación del Programa de Economía' },
|
||||
{ id: 49, label: 'Coordinación del Programa de Enseñanza de Inglés' },
|
||||
{ id: 52, label: 'Coordinación del Programa de Humanidades' },
|
||||
{ id: 51, label: 'Coordinación del Programa de Ingeniería Civil' },
|
||||
{ id: 48, label: 'Coordinación del Programa de Matemáticas Aplicadas y Computación' },
|
||||
{ id: 47, label: 'Coordinación del Programa de Pedagogía' },
|
||||
{ id: 44, label: 'Coordinación del Programa de Sociología' },
|
||||
{ id: 43, label: 'Coordinación del Programa Político' },
|
||||
{ id: 194, label: 'Departamento de Intendencia' },
|
||||
{ id: 193, label: 'Departamento de Investigación en Comunicación y Estudios Culturales' },
|
||||
{ id: 222, label: 'Departamento de Orientación Académica del Sistema de Universidad Abierta y Educación a Distancia' },
|
||||
{ id: 204, label: 'Departamento de Proyectos Administrativos' },
|
||||
{ id: 86, label: 'Departamento de Talleres y Laboratorios' },
|
||||
{ id: 72, label: 'Dirección' },
|
||||
{ id: 80, label: 'División de Ciencias Jurídicas' },
|
||||
{ id: 79, label: 'División de Ciencias Socioeconómicas' },
|
||||
{ id: 78, label: 'División de Diseño y Edificación' },
|
||||
{ id: 77, label: 'División de Humanidades' },
|
||||
{ id: 76, label: 'División de Matemáticas e Ingeniería' },
|
||||
{ id: 74, label: 'División del Sistema de Universidad Abierta y Educación a Distancia' },
|
||||
{ id: 70, label: 'Especialización en Costos en la Construcción' },
|
||||
{ id: 69, label: 'Especialización en Finanzas Públicas' },
|
||||
{ id: 68, label: 'Especialización en Geotecnia' },
|
||||
{ id: 71, label: 'Especialización en Sistemas de Calidad' },
|
||||
{ id: 220, label: 'Especialización en Tecnología Digital para la Enseñanza de Matemáticas' },
|
||||
{ id: 207, label: 'Grupo de Trabajo de Educación para Adultos (GTEA)' },
|
||||
{ id: 173, label: 'Maestría en Docencia para la Educación Media Superior' },
|
||||
{ id: 224, label: 'Posgrado en Ciencias Políticas y Sociales' },
|
||||
{ id: 62, label: 'Posgrado en Derecho' },
|
||||
{ id: 164, label: 'Posgrado en Economía' },
|
||||
{ id: 197, label: 'Posgrado en Pedagogía' },
|
||||
{ id: 63, label: 'Posgrado en Urbanismo' },
|
||||
{ id: 226, label: 'Programa Único de Especializaciones en Derecho' },
|
||||
{ id: 127, label: 'Secretaría Administrativa' },
|
||||
{ id: 181, label: 'Secretaría de Asuntos Académicos Estudiantiles' },
|
||||
{ id: 177, label: 'Secretaría de Extensión Universitaria y Vinculación Institucional' },
|
||||
{ id: 119, label: 'Secretaría de Posgrado e Investigación' },
|
||||
{ id: 8, label: 'Secretaría General' },
|
||||
{ id: 6, label: 'Unidad de Administración Escolar' },
|
||||
{ id: 5, label: 'Unidad de Administración y Recursos' },
|
||||
{ id: 4, label: 'Unidad de Planeación' },
|
||||
{ id: 3, label: 'Unidad de Servicios a la Comunidad' },
|
||||
{ id: 2, label: 'Unidad de Servicios Editoriales' },
|
||||
{ id: 1, label: 'Unidad de Talleres, Laboratorios y Audiovisuales' },
|
||||
{ id: 130, label: 'Unidad del Centro de Desarrollo Tecnológico' },
|
||||
{ id: 123, label: 'Unidad del Centro de Información y Documentación' },
|
||||
];
|
||||
|
||||
export default AREAS;
|
||||
Reference in New Issue
Block a user