Commit e0e7c07a63d69bf52595b475b28fa2bab5a28fe9

Authored by Antigravity AI
1 parent 99c89404

Hito: Landing Page AdminLTE 3 y aislamiento de iFrame para Visor GIS.

GIS-GEOSERVER/VERSION.txt
... ... @@ -7,4 +7,5 @@ V e r s i o n d e E s t a b i l i z a c i o n S I G ( A b r i l 2 0 2
7 7 Version de Estabilizacion SIG (Abril 2026) - 2026.04.05.01.49.29 ID DOCKER: c68e229b6d94
8 8 Mapa Coloreado
9 9 Version de Estabilizacion SIG (Abril 2026) - 2026.04.05.04.28.49 ID DOCKER: c68e229b6d94. Observación: Fix de las contraseñas WMS y polígonos a full color.
10   -Versión de Estabilización SIG (Abril 2026) - 2026.04.05.06.31.00 ID DOCKER: c68e229b6d94. Observación: Reestructuracion pura de BaseMap y soporte Google auto-escalado satelital.
11 10 \ No newline at end of file
  11 +Versión de Estabilización SIG (Abril 2026) - 2026.04.05.06.31.00 ID DOCKER: c68e229b6d94. Observación: Reestructuracion pura de BaseMap y soporte Google auto-escalado satelital.
  12 +Versión SIG (Abril 2026) - 2026.04.06.01.13.00 ID DOCKER: d983a409769d. Observación: Integración exitosa de Landing Page AdminLTE 3 con aislamiento de iFrame para Visor GIS.
12 13 \ No newline at end of file
... ...
GIS-GEOSERVER/src/main/java/com/sigem/gis/controller/WebViewController.java
... ... @@ -16,6 +16,16 @@ public class WebViewController {
16 16 return "forward:/mapas.html";
17 17 }
18 18  
  19 + @GetMapping("/landing")
  20 + public String landing() {
  21 + return "forward:/landing.html";
  22 + }
  23 +
  24 + @GetMapping("/widgets")
  25 + public String widgets() {
  26 + return "forward:/widgets.html";
  27 + }
  28 +
19 29 @GetMapping("/")
20 30 public String index() {
21 31 return "redirect:/login";
... ...
GIS-GEOSERVER/src/main/java/com/sigem/gis/security/SecurityConfig.java
... ... @@ -29,7 +29,7 @@ public class SecurityConfig {
29 29 .requestMatchers("/api/auth/**").permitAll() // Login
30 30 .requestMatchers("/api/admin/**").permitAll() // Admin FDW
31 31 .requestMatchers("/api/gis/**").permitAll() // API Datos GIS (Estadísticas)
32   - .requestMatchers("/login.html", "/", "/mapas/**", "/login", "/error").permitAll()
  32 + .requestMatchers("/login.html", "/", "/mapas/**", "/login", "/error", "/landing", "/landing.html", "/widgets", "/widgets.html").permitAll()
33 33 .requestMatchers("/mapas_institucional.html").permitAll()
34 34 .requestMatchers("/css/**", "/js/**", "/img/**", "/vendor/**").permitAll() // Recursos
35 35 .requestMatchers("/gwc/**", "/sigem/**", "/wms/**", "/wfs/**", "/rest/**").permitAll() // Proxy Geoserver
... ... @@ -41,7 +41,8 @@ public class SecurityConfig {
41 41 .httpBasic(basic -> basic.disable()) // Deshabilitar específicamente HTTP Basic
42 42 .formLogin(form -> form.disable()) // Deshabilitar específicamente el formulario por defecto
43 43 // Interceptor que inyecta la lógica de JWT antes de procesar el Username/Password estándar
44   - .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
  44 + .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
  45 + .headers(headers -> headers.frameOptions(frame -> frame.sameOrigin()));
45 46  
46 47 return http.build();
47 48 }
... ...
GIS-GEOSERVER/src/main/resources/static/landing.html 0 → 100644
  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">
  6 + <title>SIGEMWEB - Dashboard</title>
  7 +
  8 + <!-- Google Font: Source Sans Pro -->
  9 + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  10 + <!-- Font Awesome -->
  11 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  12 + <!-- Theme style -->
  13 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
  14 + <style>
  15 + .content-wrapper { padding: 0; margin-left: 250px; height: calc(100vh - 57px); overflow: hidden; }
  16 + iframe#main-iframe { width: 100%; height: 100%; border: none; }
  17 + .brand-link { background-color: #0056b3 !important; color: white !important; font-weight: bold;}
  18 + .main-header { background-color: #006ddb !important; border-bottom: none; }
  19 + .navbar-light .navbar-nav .nav-link { color: white; font-weight: 600;}
  20 + /* Treeview in popup */
  21 + .modal-treeview ul { list-style-type: none; padding-left: 20px; }
  22 + .modal-treeview li { margin-bottom: 5px; cursor: default;}
  23 + .modal-treeview li span { font-size: 14px; font-weight: 500; }
  24 + .modal-treeview li span.clickable:hover { color: #0056b3; cursor: pointer; font-weight: bold; }
  25 + </style>
  26 +</head>
  27 +<body class="hold-transition sidebar-mini layout-fixed">
  28 +<div class="wrapper">
  29 +
  30 + <!-- Navbar -->
  31 + <nav class="main-header navbar navbar-expand navbar-light">
  32 + <!-- Left navbar links -->
  33 + <ul class="navbar-nav">
  34 + <li class="nav-item">
  35 + <a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
  36 + </li>
  37 + <li class="nav-item d-none d-sm-inline-block">
  38 + <span class="nav-link" style="color: white; font-size: 18px; margin-left:10px;">Municipalidad de <span id="nav-entidad-text" style="font-weight: 800;">...</span> <span style="font-size: 14px; font-weight: 300;">¡Emergente y Sostenible!</span></span>
  39 + </li>
  40 + </ul>
  41 +
  42 + <!-- Right navbar links -->
  43 + <ul class="navbar-nav ml-auto">
  44 + <li class="nav-item dropdown">
  45 + <a class="nav-link" data-toggle="dropdown" href="#" style="color: white;">
  46 + <i class="far fa-user mr-2"></i> <span id="nav-user-text">Cargando...</span>
  47 + </a>
  48 + <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
  49 + <a href="#" class="dropdown-item" onclick="cerrarSesion()">
  50 + <i class="fas fa-sign-out-alt mr-2 text-danger"></i> Cerrar Sesión
  51 + </a>
  52 + </div>
  53 + </li>
  54 + </ul>
  55 + </nav>
  56 + <!-- /.navbar -->
  57 +
  58 + <!-- Main Sidebar Container -->
  59 + <aside class="main-sidebar sidebar-dark-primary elevation-4">
  60 + <!-- Brand Logo -->
  61 + <a href="#" class="brand-link text-center mb-2">
  62 + <span class="brand-text"><b>SIGEM</b>WEB</span>
  63 + </a>
  64 +
  65 + <!-- Sidebar Menu -->
  66 + <nav class="mt-2">
  67 + <ul class="nav nav-pills nav-sidebar flex-column text-sm" data-widget="treeview" role="menu" data-accordion="false">
  68 +
  69 + <li class="nav-item">
  70 + <a href="#" class="nav-link" onclick="loadContent('/gis-geoserver/widgets')">
  71 + <i class="nav-icon fas fa-tachometer-alt"></i>
  72 + <p>Dashboard <span class="right badge badge-primary">New</span></p>
  73 + </a>
  74 + </li>
  75 +
  76 + <!-- Legacy Tree -->
  77 + <li class="nav-item menu-open">
  78 + <a href="#" class="nav-link active" style="background-color: #343a40;">
  79 + <i class="nav-icon fas fa-chart-line"></i>
  80 + <p>
  81 + Control de Gestión
  82 + <i class="right fas fa-angle-left"></i>
  83 + </p>
  84 + </a>
  85 + <ul class="nav nav-treeview">
  86 + <li class="nav-item menu-open">
  87 + <a href="#" class="nav-link">
  88 + <i class="far fa-dot-circle nav-icon"></i>
  89 + <p>Mapas <i class="right fas fa-angle-left"></i></p>
  90 + </a>
  91 + <ul class="nav nav-treeview" style="margin-left: 10px;">
  92 + <li class="nav-item menu-open">
  93 + <a href="#" class="nav-link">
  94 + <i class="fas fa-map nav-icon text-info"></i>
  95 + <p>Tributarios <i class="right fas fa-angle-left"></i></p>
  96 + </a>
  97 + <ul class="nav nav-treeview" style="margin-left: 10px;">
  98 + <li class="nav-item">
  99 + <a href="#" class="nav-link" data-toggle="modal" data-target="#modalMorosidad">
  100 + <i class="fas fa-layer-group nav-icon text-warning"></i>
  101 + <p>Mapa Morosidad/Pago</p>
  102 + </a>
  103 + </li>
  104 + </ul>
  105 + </li>
  106 + </ul>
  107 + </li>
  108 + </ul>
  109 + </li>
  110 +
  111 + <!-- Dummy Options -->
  112 + <li class="nav-header">OTRAS OPCIONES</li>
  113 + <li class="nav-item">
  114 + <a href="#" class="nav-link" onclick="notImplemented()">
  115 + <i class="nav-icon fas fa-file-invoice-dollar text-muted"></i>
  116 + <p>Liquidaciones</p>
  117 + </a>
  118 + </li>
  119 + <li class="nav-item">
  120 + <a href="#" class="nav-link" onclick="notImplemented()">
  121 + <i class="nav-icon fas fa-users text-muted"></i>
  122 + <p>Contribuyentes</p>
  123 + </a>
  124 + </li>
  125 +
  126 + </ul>
  127 + </nav>
  128 + <!-- /.sidebar-menu -->
  129 + </aside>
  130 +
  131 + <!-- Content Wrapper. Contains page content -->
  132 + <div class="content-wrapper">
  133 + <iframe id="main-iframe" src="/gis-geoserver/widgets"></iframe>
  134 + </div>
  135 +
  136 + <!-- Main Footer -->
  137 + <footer class="main-footer" style="padding: 5px; font-size: 12px;">
  138 + <strong>Sistema de Información Geográfica Municipal.</strong>
  139 + Todos los derechos reservados.
  140 + </footer>
  141 +</div>
  142 +<!-- ./wrapper -->
  143 +
  144 +<!-- Modal Pop-up para Selección de Mapa (Exactamente como el legado) -->
  145 +<div class="modal fade" id="modalMorosidad" tabindex="-1" role="dialog" aria-hidden="true">
  146 + <div class="modal-dialog modal-sm" role="document" style="margin-top: 15vh;">
  147 + <div class="modal-content shadow-lg" style="border: 1px solid #17a2b8;">
  148 + <div class="modal-header bg-info" style="padding: 10px;">
  149 + <h6 class="modal-title" style="font-weight: bold;"><i class="fas fa-filter"></i> Selección Capas Geo</h6>
  150 + <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
  151 + <span aria-hidden="true">&times;</span>
  152 + </button>
  153 + </div>
  154 + <div class="modal-body modal-treeview">
  155 + <ul>
  156 + <li><i class="fas fa-minus-square mr-1 text-secondary"></i> <span>MAPA DE MOROSIDAD</span>
  157 + <ul>
  158 + <li><i class="fas fa-plus-square mr-1 text-secondary"></i> <span>IMPUESTOS ADEUDADOS</span>
  159 + <ul>
  160 + <li><i class="fas fa-plus mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">Impuesto Inmobiliario</span></li>
  161 + <li><i class="fas fa-plus mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">Patente Comercial</span></li>
  162 + <li><i class="fas fa-plus-square mr-1 text-secondary"></i> <span>Todos</span>
  163 + <ul>
  164 + <li><i class="far fa-window-restore mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">POR TOTAL</span></li>
  165 + <li><i class="far fa-clock mr-1 text-muted"></i> <span class="text-primary font-weight-bold clickable" onclick="loadMap()">ULTIMO PAGO / TODOS</span></li>
  166 + </ul>
  167 + </li>
  168 + </ul>
  169 + </li>
  170 + <li><i class="fas fa-plus-square mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">IMPUESTOS PAGADOS</span></li>
  171 + </ul>
  172 + </li>
  173 + </ul>
  174 + </div>
  175 + </div>
  176 + </div>
  177 +</div>
  178 +
  179 +<!-- jQuery -->
  180 +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  181 +<!-- Bootstrap 4 -->
  182 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
  183 +<!-- AdminLTE App -->
  184 +<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
  185 +
  186 +<script>
  187 + // Recuperar datos de sesión
  188 + const token = localStorage.getItem('jwt');
  189 + const userName = localStorage.getItem('user_name');
  190 + const entidad = localStorage.getItem('entidad');
  191 +
  192 + if (!token) {
  193 + window.location.href = "/gis-geoserver/login";
  194 + }
  195 +
  196 + document.getElementById('nav-user-text').innerText = userName || 'Operador Local';
  197 + document.getElementById('nav-entidad-text').innerText = entidad || 'N/D';
  198 +
  199 + function notImplemented() {
  200 + alert("OPCIÓN NO IMPLEMENTADA");
  201 + }
  202 +
  203 + function loadContent(url) {
  204 + document.getElementById('main-iframe').src = url;
  205 + }
  206 +
  207 + function loadMap() {
  208 + // Cierra el modal de forma programática usando jQuery de Bootstrap
  209 + $('#modalMorosidad').modal('hide');
  210 + // Redirige el iframe central hacia nuestro impecable mapas.html
  211 + loadContent('/gis-geoserver/mapas');
  212 + }
  213 +
  214 + function cerrarSesion() {
  215 + localStorage.clear();
  216 + window.location.href = "/gis-geoserver/login";
  217 + }
  218 +</script>
  219 +</body>
  220 +</html>
... ...
GIS-GEOSERVER/src/main/resources/static/login.html
1 1 <!DOCTYPE html>
2 2 <html lang="es">
3 3 <head>
4   - <meta charset="UTF-8">
5   - <meta name="viewport" content="width=device-width, initial-scale=1.0">
6   - <title>Inicie Sesión - Ecosistema SIGEM</title>
7   - <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
8   - <style>
9   - * { margin: 0; padding: 0; box-sizing: border-box; }
10   - body {
11   - font-family: 'Inter', sans-serif;
12   - background: linear-gradient(-45deg, #0d1b2a, #1b263b, #415a77, #778da9);
13   - background-size: 400% 400%;
14   - animation: gradientBG 15s ease infinite;
15   - height: 100vh;
16   - display: flex;
17   - justify-content: center;
18   - align-items: center;
19   - color: #fff;
20   - }
21   - @keyframes gradientBG {
22   - 0% { background-position: 0% 50%; }
23   - 50% { background-position: 100% 50%; }
24   - 100% { background-position: 0% 50%; }
25   - }
26   - .login-container {
27   - background: rgba(255, 255, 255, 0.05);
28   - backdrop-filter: blur(20px);
29   - -webkit-backdrop-filter: blur(20px);
30   - border: 1px solid rgba(255, 255, 255, 0.1);
31   - border-radius: 24px;
32   - padding: 40px;
33   - width: 100%;
34   - max-width: 400px;
35   - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
36   - animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
37   - opacity: 0;
38   - transform: translateY(30px);
39   - }
40   - @keyframes slideUp { to { opacity: 1; transform: translateY(0); } }
41   - .logo-area { text-align: center; margin-bottom: 30px; }
42   - .logo-area h1 { font-weight: 800; font-size: 28px; letter-spacing: -0.5px; }
43   - .logo-area span { color: #facc15; }
44   - .logo-area p { font-size: 14px; font-weight: 300; color: #cbd5e1; margin-top: 5px; }
45   - .input-group { margin-bottom: 20px; }
46   - .input-group label {
47   - display: block; font-size: 13px; font-weight: 600; color: #94a3b8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px;
48   - }
49   - .input-group input, .input-group select {
50   - width: 100%; padding: 14px 16px; background: rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.1);
51   - border-radius: 12px; color: #fff; font-size: 15px; font-family: 'Inter', sans-serif; transition: all 0.3s ease;
52   - }
53   - .input-group select { appearance: none; cursor: pointer; }
54   - .input-group select option { color: #000; }
55   - .input-group input:focus, .input-group select:focus {
56   - outline: none; border-color: #facc15; background: rgba(0, 0, 0, 0.4); box-shadow: 0 0 0 3px rgba(250, 204, 21, 0.2);
57   - }
58   - .btn-submit {
59   - width: 100%; padding: 16px; background: linear-gradient(135deg, #eab308, #ca8a04);
60   - color: #000; border: none; border-radius: 12px; font-size: 16px; font-weight: 700; cursor: pointer;
61   - transition: transform 0.2s, box-shadow 0.2s; box-shadow: 0 10px 15px -3px rgba(234, 179, 8, 0.3);
62   - margin-top: 10px;
63   - }
64   - .btn-submit:hover { transform: translateY(-2px); box-shadow: 0 15px 25px -5px rgba(234, 179, 8, 0.4); }
65   - .btn-submit:active { transform: translateY(0); }
66   -
67   - #error-msg {
68   - display: none; color: #fca5a5; font-size: 14px; font-weight: 600; text-align: center;
69   - background: rgba(239, 68, 68, 0.2); padding: 10px; border-radius: 8px; margin-top: 15px; border: 1px solid rgba(239, 68, 68, 0.3);
70   - }
71   -
72   - .loader {
73   - display: none; border: 3px solid rgba(0, 0, 0, 0.1); border-radius: 50%;
74   - border-top: 3px solid #000; width: 24px; height: 24px; animation: spin 1s linear infinite; margin: 0 auto;
75   - }
76   - @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
77   - </style>
78   -</head>
79   -<body>
  4 + <meta charset="utf-8">
  5 + <meta name="viewport" content="width=device-width, initial-scale=1">
  6 + <title>Inicie Sesión - Ecosistema SIGEM</title>
80 7  
81   -<div class="login-container">
82   - <div class="logo-area">
83   - <h1>SIGEM<span>WEB</span></h1>
84   - <p>Visor Georreferenciado Multi-Tenant</p>
85   - </div>
  8 + <!-- Google Font: Source Sans Pro (Estandar de AdminLTE) -->
  9 + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  10 + <!-- Font Awesome -->
  11 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  12 + <!-- Theme style AdminLTE 3 -->
  13 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
  14 + <style>
  15 + .login-page {
  16 + background: linear-gradient(135deg, #e0eafc 0%, #cfdef3 100%);
  17 + }
  18 + .card-primary.card-outline {
  19 + border-top: 3px solid #0056b3;
  20 + }
  21 + .btn-primary {
  22 + background-color: #0056b3;
  23 + border-color: #0056b3;
  24 + }
  25 + .btn-primary:hover {
  26 + background-color: #004494;
  27 + border-color: #004494;
  28 + }
  29 + .login-logo a {
  30 + color: #333 !important;
  31 + }
  32 + </style>
  33 +</head>
  34 +<body class="hold-transition login-page">
  35 +<div class="login-box">
  36 + <div class="login-logo">
  37 + <a href="#"><b>SIGEM</b>WEB</a>
  38 + </div>
  39 + <!-- /.login-logo -->
  40 + <div class="card card-outline card-primary shadow-lg">
  41 + <div class="card-body login-card-body rounded">
  42 + <p class="login-box-msg font-weight-bold" style="color: #555;">Visor Georreferenciado Multi-Tenant</p>
86 43  
87   - <form id="loginForm">
88   - <div class="input-group">
89   - <label for="municipioSearch">Municipalidad (Entidad)</label>
90   - <input type="text" id="municipioSearch" placeholder="Escriba para buscar (ej. 505)" autocomplete="off" style="margin-bottom: 5px;">
91   - <select id="entidad" required size="3" style="height: 100px; overflow-y: auto;">
  44 + <form id="loginForm">
  45 + <label for="municipioSearch" class="text-xs text-muted mb-1" style="font-size: 0.8rem; text-transform: uppercase;">1. Entidad (Municipalidad)</label>
  46 + <div class="input-group mb-2">
  47 + <input type="text" id="municipioSearch" class="form-control" placeholder="Buscar municipio (ej. 505)" autocomplete="off">
  48 + <div class="input-group-append">
  49 + <div class="input-group-text">
  50 + <span class="fas fa-search"></span>
  51 + </div>
  52 + </div>
  53 + </div>
  54 + <div class="form-group mb-3">
  55 + <select id="entidad" class="form-control" required size="3" style="height: 85px; cursor: pointer; font-size: 0.9rem;">
92 56 <option value="505">Entidad 505 (Piloto GIS)</option>
93 57 <option value="800">Entidad 800 (Pruebas)</option>
94 58 <option value="900">Entidad 900 (Desarrollo)</option>
95   - </select>
96   - <p style="font-size: 11px; color: #94a3b8; margin-top: 5px;">Seleccione de la lista superior</p>
  59 + </select>
97 60 </div>
98   - <div class="input-group">
99   - <label for="username">Usuario</label>
100   - <input type="text" id="username" placeholder="Usu_alias (ej. operador)" required autocomplete="username">
  61 +
  62 + <label class="text-xs text-muted mb-1" style="font-size: 0.8rem; text-transform: uppercase;">2. Credenciales</label>
  63 + <div class="input-group mb-3">
  64 + <input type="text" id="username" class="form-control" placeholder="Usu_alias (ej. operador)" required autocomplete="username">
  65 + <div class="input-group-append">
  66 + <div class="input-group-text">
  67 + <span class="fas fa-user"></span>
  68 + </div>
  69 + </div>
101 70 </div>
102   - <div class="input-group">
103   - <label for="password">Contraseña</label>
104   - <input type="password" id="password" placeholder="Tu clave alfanumérica" required autocomplete="current-password">
  71 + <div class="input-group mb-3">
  72 + <input type="password" id="password" class="form-control" placeholder="Tu clave alfanumérica" required autocomplete="current-password">
  73 + <div class="input-group-append">
  74 + <div class="input-group-text">
  75 + <span class="fas fa-lock"></span>
  76 + </div>
  77 + </div>
105 78 </div>
106   -
107   - <button type="submit" class="btn-submit" id="btn-login">
108   - <span id="btn-text">INICIAR SESIÓN</span>
109   - <div class="loader" id="spinner"></div>
110   - </button>
111   -
112   - <div id="error-msg"></div>
113   - </form>
  79 +
  80 + <div id="error-msg" class="alert alert-danger p-2 mb-3 text-center" style="display:none; font-size: 13px;"></div>
  81 +
  82 + <div class="row mt-4">
  83 + <div class="col-12">
  84 + <button type="submit" class="btn btn-primary btn-block font-weight-bold" id="btn-login" style="padding: 10px;">
  85 + <span id="btn-text">INICIAR SESIÓN</span>
  86 + <div class="spinner-border spinner-border-sm text-light" id="spinner" role="status" style="display:none; margin: auto;"></div>
  87 + </button>
  88 + </div>
  89 + </div>
  90 + </form>
  91 + </div>
  92 + <!-- /.login-card-body -->
  93 + </div>
114 94 </div>
  95 +<!-- /.login-box -->
  96 +
  97 +<!-- jQuery -->
  98 +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  99 +<!-- Bootstrap 4 -->
  100 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
  101 +<!-- AdminLTE App -->
  102 +<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
115 103  
116 104 <script>
117 105 // Filtro interactivo de municipios
... ... @@ -134,6 +122,7 @@
134 122  
135 123 // Limpiar sesión previa si por error caen al login
136 124 localStorage.removeItem('jwt');
  125 + localStorage.removeItem('user_name');
137 126  
138 127 document.getElementById('loginForm').addEventListener('submit', function(e) {
139 128 e.preventDefault();
... ... @@ -185,8 +174,8 @@
185 174 localStorage.setItem('mapa_base_id', data.mapaBase);
186 175 localStorage.setItem('map_bounds', data.bounds);
187 176  
188   - // Redirigir a la URL del Mapas de Leaflet
189   - window.location.href = "/gis-geoserver/mapas";
  177 + // Redirigir a la URL del Mapas
  178 + window.location.href = "/gis-geoserver/landing";
190 179 })
191 180 .catch(error => {
192 181 // LOGIN ERROR
... ... @@ -200,6 +189,5 @@
200 189 });
201 190 });
202 191 </script>
203   -
204 192 </body>
205 193 </html>
... ...
GIS-GEOSERVER/src/main/resources/static/widgets.html 0 → 100644
  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">
  6 + <!-- Google Font: Source Sans Pro -->
  7 + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  8 + <!-- Font Awesome -->
  9 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  10 + <!-- Theme style AdminLTE 3 -->
  11 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
  12 + <style>
  13 + body { background-color: #f4f6f9; padding: 20px; font-family: 'Source Sans Pro', sans-serif; }
  14 + .welcome-header { font-size: 24px; color: #333; margin-bottom: 20px; font-weight: 600;}
  15 + </style>
  16 +</head>
  17 +<body>
  18 + <div class="welcome-header">
  19 + <i class="fas fa-home text-primary"></i> Tablero General (Estadísticas Simuladas)
  20 + </div>
  21 +
  22 + <div class="row">
  23 + <!-- Tarjeta 1 -->
  24 + <div class="col-lg-3 col-6">
  25 + <div class="small-box bg-info shadow-sm">
  26 + <div class="inner">
  27 + <h3>99,999</h3>
  28 + <p>Lotes Registrados</p>
  29 + </div>
  30 + <div class="icon">
  31 + <i class="fas fa-map-marked-alt"></i>
  32 + </div>
  33 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  34 + </div>
  35 + </div>
  36 + <!-- Tarjeta 2 -->
  37 + <div class="col-lg-3 col-6">
  38 + <div class="small-box bg-success shadow-sm">
  39 + <div class="inner">
  40 + <h3>Gs. ---<sup style="font-size: 20px"></sup></h3>
  41 + <p>Recaudación del Día</p>
  42 + </div>
  43 + <div class="icon">
  44 + <i class="fas fa-hand-holding-usd"></i>
  45 + </div>
  46 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  47 + </div>
  48 + </div>
  49 +
  50 + <!-- Tarjeta 3 -->
  51 + <div class="col-lg-3 col-6">
  52 + <div class="small-box bg-warning shadow-sm">
  53 + <div class="inner">
  54 + <h3>---</h3>
  55 + <p>Nuevas Actividades Comerciales</p>
  56 + </div>
  57 + <div class="icon">
  58 + <i class="fas fa-store"></i>
  59 + </div>
  60 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  61 + </div>
  62 + </div>
  63 + <!-- Tarjeta 4 -->
  64 + <div class="col-lg-3 col-6">
  65 + <div class="small-box bg-danger shadow-sm">
  66 + <div class="inner">
  67 + <h3>45%</h3>
  68 + <p>Índice General de Morosidad</p>
  69 + </div>
  70 + <div class="icon">
  71 + <i class="fas fa-chart-pie"></i>
  72 + </div>
  73 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  74 + </div>
  75 + </div>
  76 + </div>
  77 +
  78 + <div class="row mt-4">
  79 + <div class="col-12">
  80 + <div class="card card-outline card-primary shadow-sm" style="border-top: 3px solid #0056b3;">
  81 + <div class="card-header">
  82 + <h3 class="card-title text-muted"><i class="fas fa-info-circle mr-1"></i> Estado del Sistema</h3>
  83 + </div>
  84 + <div class="card-body">
  85 + <p class="text-secondary text-sm">Use el menú lateral para navegar por los distintos módulos administrativos. La funcionalidad de Mapas Tributarios se encuentra activa bajo "Control de Gestión -> Mapas". Otras opciones en despliegue.</p>
  86 + </div>
  87 + </div>
  88 + </div>
  89 + </div>
  90 +
  91 +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  92 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
  93 +</body>
  94 +</html>
... ...
GIS-GEOSERVER/target/classes/com/sigem/gis/controller/WebViewController.class
No preview for this file type
GIS-GEOSERVER/target/classes/com/sigem/gis/security/SecurityConfig.class
No preview for this file type
GIS-GEOSERVER/target/classes/static/landing.html 0 → 100644
  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">
  6 + <title>SIGEMWEB - Dashboard</title>
  7 +
  8 + <!-- Google Font: Source Sans Pro -->
  9 + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  10 + <!-- Font Awesome -->
  11 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  12 + <!-- Theme style -->
  13 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
  14 + <style>
  15 + .content-wrapper { padding: 0; margin-left: 250px; height: calc(100vh - 57px); overflow: hidden; }
  16 + iframe#main-iframe { width: 100%; height: 100%; border: none; }
  17 + .brand-link { background-color: #0056b3 !important; color: white !important; font-weight: bold;}
  18 + .main-header { background-color: #006ddb !important; border-bottom: none; }
  19 + .navbar-light .navbar-nav .nav-link { color: white; font-weight: 600;}
  20 + /* Treeview in popup */
  21 + .modal-treeview ul { list-style-type: none; padding-left: 20px; }
  22 + .modal-treeview li { margin-bottom: 5px; cursor: default;}
  23 + .modal-treeview li span { font-size: 14px; font-weight: 500; }
  24 + .modal-treeview li span.clickable:hover { color: #0056b3; cursor: pointer; font-weight: bold; }
  25 + </style>
  26 +</head>
  27 +<body class="hold-transition sidebar-mini layout-fixed">
  28 +<div class="wrapper">
  29 +
  30 + <!-- Navbar -->
  31 + <nav class="main-header navbar navbar-expand navbar-light">
  32 + <!-- Left navbar links -->
  33 + <ul class="navbar-nav">
  34 + <li class="nav-item">
  35 + <a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
  36 + </li>
  37 + <li class="nav-item d-none d-sm-inline-block">
  38 + <span class="nav-link" style="color: white; font-size: 18px; margin-left:10px;">Municipalidad de <span id="nav-entidad-text" style="font-weight: 800;">...</span> <span style="font-size: 14px; font-weight: 300;">¡Emergente y Sostenible!</span></span>
  39 + </li>
  40 + </ul>
  41 +
  42 + <!-- Right navbar links -->
  43 + <ul class="navbar-nav ml-auto">
  44 + <li class="nav-item dropdown">
  45 + <a class="nav-link" data-toggle="dropdown" href="#" style="color: white;">
  46 + <i class="far fa-user mr-2"></i> <span id="nav-user-text">Cargando...</span>
  47 + </a>
  48 + <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
  49 + <a href="#" class="dropdown-item" onclick="cerrarSesion()">
  50 + <i class="fas fa-sign-out-alt mr-2 text-danger"></i> Cerrar Sesión
  51 + </a>
  52 + </div>
  53 + </li>
  54 + </ul>
  55 + </nav>
  56 + <!-- /.navbar -->
  57 +
  58 + <!-- Main Sidebar Container -->
  59 + <aside class="main-sidebar sidebar-dark-primary elevation-4">
  60 + <!-- Brand Logo -->
  61 + <a href="#" class="brand-link text-center mb-2">
  62 + <span class="brand-text"><b>SIGEM</b>WEB</span>
  63 + </a>
  64 +
  65 + <!-- Sidebar Menu -->
  66 + <nav class="mt-2">
  67 + <ul class="nav nav-pills nav-sidebar flex-column text-sm" data-widget="treeview" role="menu" data-accordion="false">
  68 +
  69 + <li class="nav-item">
  70 + <a href="#" class="nav-link" onclick="loadContent('/gis-geoserver/widgets')">
  71 + <i class="nav-icon fas fa-tachometer-alt"></i>
  72 + <p>Dashboard <span class="right badge badge-primary">New</span></p>
  73 + </a>
  74 + </li>
  75 +
  76 + <!-- Legacy Tree -->
  77 + <li class="nav-item menu-open">
  78 + <a href="#" class="nav-link active" style="background-color: #343a40;">
  79 + <i class="nav-icon fas fa-chart-line"></i>
  80 + <p>
  81 + Control de Gestión
  82 + <i class="right fas fa-angle-left"></i>
  83 + </p>
  84 + </a>
  85 + <ul class="nav nav-treeview">
  86 + <li class="nav-item menu-open">
  87 + <a href="#" class="nav-link">
  88 + <i class="far fa-dot-circle nav-icon"></i>
  89 + <p>Mapas <i class="right fas fa-angle-left"></i></p>
  90 + </a>
  91 + <ul class="nav nav-treeview" style="margin-left: 10px;">
  92 + <li class="nav-item menu-open">
  93 + <a href="#" class="nav-link">
  94 + <i class="fas fa-map nav-icon text-info"></i>
  95 + <p>Tributarios <i class="right fas fa-angle-left"></i></p>
  96 + </a>
  97 + <ul class="nav nav-treeview" style="margin-left: 10px;">
  98 + <li class="nav-item">
  99 + <a href="#" class="nav-link" data-toggle="modal" data-target="#modalMorosidad">
  100 + <i class="fas fa-layer-group nav-icon text-warning"></i>
  101 + <p>Mapa Morosidad/Pago</p>
  102 + </a>
  103 + </li>
  104 + </ul>
  105 + </li>
  106 + </ul>
  107 + </li>
  108 + </ul>
  109 + </li>
  110 +
  111 + <!-- Dummy Options -->
  112 + <li class="nav-header">OTRAS OPCIONES</li>
  113 + <li class="nav-item">
  114 + <a href="#" class="nav-link" onclick="notImplemented()">
  115 + <i class="nav-icon fas fa-file-invoice-dollar text-muted"></i>
  116 + <p>Liquidaciones</p>
  117 + </a>
  118 + </li>
  119 + <li class="nav-item">
  120 + <a href="#" class="nav-link" onclick="notImplemented()">
  121 + <i class="nav-icon fas fa-users text-muted"></i>
  122 + <p>Contribuyentes</p>
  123 + </a>
  124 + </li>
  125 +
  126 + </ul>
  127 + </nav>
  128 + <!-- /.sidebar-menu -->
  129 + </aside>
  130 +
  131 + <!-- Content Wrapper. Contains page content -->
  132 + <div class="content-wrapper">
  133 + <iframe id="main-iframe" src="/gis-geoserver/widgets"></iframe>
  134 + </div>
  135 +
  136 + <!-- Main Footer -->
  137 + <footer class="main-footer" style="padding: 5px; font-size: 12px;">
  138 + <strong>Sistema de Información Geográfica Municipal.</strong>
  139 + Todos los derechos reservados.
  140 + </footer>
  141 +</div>
  142 +<!-- ./wrapper -->
  143 +
  144 +<!-- Modal Pop-up para Selección de Mapa (Exactamente como el legado) -->
  145 +<div class="modal fade" id="modalMorosidad" tabindex="-1" role="dialog" aria-hidden="true">
  146 + <div class="modal-dialog modal-sm" role="document" style="margin-top: 15vh;">
  147 + <div class="modal-content shadow-lg" style="border: 1px solid #17a2b8;">
  148 + <div class="modal-header bg-info" style="padding: 10px;">
  149 + <h6 class="modal-title" style="font-weight: bold;"><i class="fas fa-filter"></i> Selección Capas Geo</h6>
  150 + <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
  151 + <span aria-hidden="true">&times;</span>
  152 + </button>
  153 + </div>
  154 + <div class="modal-body modal-treeview">
  155 + <ul>
  156 + <li><i class="fas fa-minus-square mr-1 text-secondary"></i> <span>MAPA DE MOROSIDAD</span>
  157 + <ul>
  158 + <li><i class="fas fa-plus-square mr-1 text-secondary"></i> <span>IMPUESTOS ADEUDADOS</span>
  159 + <ul>
  160 + <li><i class="fas fa-plus mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">Impuesto Inmobiliario</span></li>
  161 + <li><i class="fas fa-plus mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">Patente Comercial</span></li>
  162 + <li><i class="fas fa-plus-square mr-1 text-secondary"></i> <span>Todos</span>
  163 + <ul>
  164 + <li><i class="far fa-window-restore mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">POR TOTAL</span></li>
  165 + <li><i class="far fa-clock mr-1 text-muted"></i> <span class="text-primary font-weight-bold clickable" onclick="loadMap()">ULTIMO PAGO / TODOS</span></li>
  166 + </ul>
  167 + </li>
  168 + </ul>
  169 + </li>
  170 + <li><i class="fas fa-plus-square mr-1 text-muted"></i> <span class="clickable" onclick="notImplemented()">IMPUESTOS PAGADOS</span></li>
  171 + </ul>
  172 + </li>
  173 + </ul>
  174 + </div>
  175 + </div>
  176 + </div>
  177 +</div>
  178 +
  179 +<!-- jQuery -->
  180 +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  181 +<!-- Bootstrap 4 -->
  182 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
  183 +<!-- AdminLTE App -->
  184 +<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
  185 +
  186 +<script>
  187 + // Recuperar datos de sesión
  188 + const token = localStorage.getItem('jwt');
  189 + const userName = localStorage.getItem('user_name');
  190 + const entidad = localStorage.getItem('entidad');
  191 +
  192 + if (!token) {
  193 + window.location.href = "/gis-geoserver/login";
  194 + }
  195 +
  196 + document.getElementById('nav-user-text').innerText = userName || 'Operador Local';
  197 + document.getElementById('nav-entidad-text').innerText = entidad || 'N/D';
  198 +
  199 + function notImplemented() {
  200 + alert("OPCIÓN NO IMPLEMENTADA");
  201 + }
  202 +
  203 + function loadContent(url) {
  204 + document.getElementById('main-iframe').src = url;
  205 + }
  206 +
  207 + function loadMap() {
  208 + // Cierra el modal de forma programática usando jQuery de Bootstrap
  209 + $('#modalMorosidad').modal('hide');
  210 + // Redirige el iframe central hacia nuestro impecable mapas.html
  211 + loadContent('/gis-geoserver/mapas');
  212 + }
  213 +
  214 + function cerrarSesion() {
  215 + localStorage.clear();
  216 + window.location.href = "/gis-geoserver/login";
  217 + }
  218 +</script>
  219 +</body>
  220 +</html>
... ...
GIS-GEOSERVER/target/classes/static/login.html
1 1 <!DOCTYPE html>
2 2 <html lang="es">
3 3 <head>
4   - <meta charset="UTF-8">
5   - <meta name="viewport" content="width=device-width, initial-scale=1.0">
6   - <title>Inicie Sesión - Ecosistema SIGEM</title>
7   - <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
8   - <style>
9   - * { margin: 0; padding: 0; box-sizing: border-box; }
10   - body {
11   - font-family: 'Inter', sans-serif;
12   - background: linear-gradient(-45deg, #0d1b2a, #1b263b, #415a77, #778da9);
13   - background-size: 400% 400%;
14   - animation: gradientBG 15s ease infinite;
15   - height: 100vh;
16   - display: flex;
17   - justify-content: center;
18   - align-items: center;
19   - color: #fff;
20   - }
21   - @keyframes gradientBG {
22   - 0% { background-position: 0% 50%; }
23   - 50% { background-position: 100% 50%; }
24   - 100% { background-position: 0% 50%; }
25   - }
26   - .login-container {
27   - background: rgba(255, 255, 255, 0.05);
28   - backdrop-filter: blur(20px);
29   - -webkit-backdrop-filter: blur(20px);
30   - border: 1px solid rgba(255, 255, 255, 0.1);
31   - border-radius: 24px;
32   - padding: 40px;
33   - width: 100%;
34   - max-width: 400px;
35   - box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
36   - animation: slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
37   - opacity: 0;
38   - transform: translateY(30px);
39   - }
40   - @keyframes slideUp { to { opacity: 1; transform: translateY(0); } }
41   - .logo-area { text-align: center; margin-bottom: 30px; }
42   - .logo-area h1 { font-weight: 800; font-size: 28px; letter-spacing: -0.5px; }
43   - .logo-area span { color: #facc15; }
44   - .logo-area p { font-size: 14px; font-weight: 300; color: #cbd5e1; margin-top: 5px; }
45   - .input-group { margin-bottom: 20px; }
46   - .input-group label {
47   - display: block; font-size: 13px; font-weight: 600; color: #94a3b8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px;
48   - }
49   - .input-group input, .input-group select {
50   - width: 100%; padding: 14px 16px; background: rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.1);
51   - border-radius: 12px; color: #fff; font-size: 15px; font-family: 'Inter', sans-serif; transition: all 0.3s ease;
52   - }
53   - .input-group select { appearance: none; cursor: pointer; }
54   - .input-group select option { color: #000; }
55   - .input-group input:focus, .input-group select:focus {
56   - outline: none; border-color: #facc15; background: rgba(0, 0, 0, 0.4); box-shadow: 0 0 0 3px rgba(250, 204, 21, 0.2);
57   - }
58   - .btn-submit {
59   - width: 100%; padding: 16px; background: linear-gradient(135deg, #eab308, #ca8a04);
60   - color: #000; border: none; border-radius: 12px; font-size: 16px; font-weight: 700; cursor: pointer;
61   - transition: transform 0.2s, box-shadow 0.2s; box-shadow: 0 10px 15px -3px rgba(234, 179, 8, 0.3);
62   - margin-top: 10px;
63   - }
64   - .btn-submit:hover { transform: translateY(-2px); box-shadow: 0 15px 25px -5px rgba(234, 179, 8, 0.4); }
65   - .btn-submit:active { transform: translateY(0); }
66   -
67   - #error-msg {
68   - display: none; color: #fca5a5; font-size: 14px; font-weight: 600; text-align: center;
69   - background: rgba(239, 68, 68, 0.2); padding: 10px; border-radius: 8px; margin-top: 15px; border: 1px solid rgba(239, 68, 68, 0.3);
70   - }
71   -
72   - .loader {
73   - display: none; border: 3px solid rgba(0, 0, 0, 0.1); border-radius: 50%;
74   - border-top: 3px solid #000; width: 24px; height: 24px; animation: spin 1s linear infinite; margin: 0 auto;
75   - }
76   - @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
77   - </style>
78   -</head>
79   -<body>
  4 + <meta charset="utf-8">
  5 + <meta name="viewport" content="width=device-width, initial-scale=1">
  6 + <title>Inicie Sesión - Ecosistema SIGEM</title>
80 7  
81   -<div class="login-container">
82   - <div class="logo-area">
83   - <h1>SIGEM<span>WEB</span></h1>
84   - <p>Visor Georreferenciado Multi-Tenant</p>
85   - </div>
  8 + <!-- Google Font: Source Sans Pro (Estandar de AdminLTE) -->
  9 + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  10 + <!-- Font Awesome -->
  11 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  12 + <!-- Theme style AdminLTE 3 -->
  13 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
  14 + <style>
  15 + .login-page {
  16 + background: linear-gradient(135deg, #e0eafc 0%, #cfdef3 100%);
  17 + }
  18 + .card-primary.card-outline {
  19 + border-top: 3px solid #0056b3;
  20 + }
  21 + .btn-primary {
  22 + background-color: #0056b3;
  23 + border-color: #0056b3;
  24 + }
  25 + .btn-primary:hover {
  26 + background-color: #004494;
  27 + border-color: #004494;
  28 + }
  29 + .login-logo a {
  30 + color: #333 !important;
  31 + }
  32 + </style>
  33 +</head>
  34 +<body class="hold-transition login-page">
  35 +<div class="login-box">
  36 + <div class="login-logo">
  37 + <a href="#"><b>SIGEM</b>WEB</a>
  38 + </div>
  39 + <!-- /.login-logo -->
  40 + <div class="card card-outline card-primary shadow-lg">
  41 + <div class="card-body login-card-body rounded">
  42 + <p class="login-box-msg font-weight-bold" style="color: #555;">Visor Georreferenciado Multi-Tenant</p>
86 43  
87   - <form id="loginForm">
88   - <div class="input-group">
89   - <label for="municipioSearch">Municipalidad (Entidad)</label>
90   - <input type="text" id="municipioSearch" placeholder="Escriba para buscar (ej. 505)" autocomplete="off" style="margin-bottom: 5px;">
91   - <select id="entidad" required size="3" style="height: 100px; overflow-y: auto;">
  44 + <form id="loginForm">
  45 + <label for="municipioSearch" class="text-xs text-muted mb-1" style="font-size: 0.8rem; text-transform: uppercase;">1. Entidad (Municipalidad)</label>
  46 + <div class="input-group mb-2">
  47 + <input type="text" id="municipioSearch" class="form-control" placeholder="Buscar municipio (ej. 505)" autocomplete="off">
  48 + <div class="input-group-append">
  49 + <div class="input-group-text">
  50 + <span class="fas fa-search"></span>
  51 + </div>
  52 + </div>
  53 + </div>
  54 + <div class="form-group mb-3">
  55 + <select id="entidad" class="form-control" required size="3" style="height: 85px; cursor: pointer; font-size: 0.9rem;">
92 56 <option value="505">Entidad 505 (Piloto GIS)</option>
93 57 <option value="800">Entidad 800 (Pruebas)</option>
94 58 <option value="900">Entidad 900 (Desarrollo)</option>
95   - </select>
96   - <p style="font-size: 11px; color: #94a3b8; margin-top: 5px;">Seleccione de la lista superior</p>
  59 + </select>
97 60 </div>
98   - <div class="input-group">
99   - <label for="username">Usuario</label>
100   - <input type="text" id="username" placeholder="Usu_alias (ej. operador)" required autocomplete="username">
  61 +
  62 + <label class="text-xs text-muted mb-1" style="font-size: 0.8rem; text-transform: uppercase;">2. Credenciales</label>
  63 + <div class="input-group mb-3">
  64 + <input type="text" id="username" class="form-control" placeholder="Usu_alias (ej. operador)" required autocomplete="username">
  65 + <div class="input-group-append">
  66 + <div class="input-group-text">
  67 + <span class="fas fa-user"></span>
  68 + </div>
  69 + </div>
101 70 </div>
102   - <div class="input-group">
103   - <label for="password">Contraseña</label>
104   - <input type="password" id="password" placeholder="Tu clave alfanumérica" required autocomplete="current-password">
  71 + <div class="input-group mb-3">
  72 + <input type="password" id="password" class="form-control" placeholder="Tu clave alfanumérica" required autocomplete="current-password">
  73 + <div class="input-group-append">
  74 + <div class="input-group-text">
  75 + <span class="fas fa-lock"></span>
  76 + </div>
  77 + </div>
105 78 </div>
106   -
107   - <button type="submit" class="btn-submit" id="btn-login">
108   - <span id="btn-text">INICIAR SESIÓN</span>
109   - <div class="loader" id="spinner"></div>
110   - </button>
111   -
112   - <div id="error-msg"></div>
113   - </form>
  79 +
  80 + <div id="error-msg" class="alert alert-danger p-2 mb-3 text-center" style="display:none; font-size: 13px;"></div>
  81 +
  82 + <div class="row mt-4">
  83 + <div class="col-12">
  84 + <button type="submit" class="btn btn-primary btn-block font-weight-bold" id="btn-login" style="padding: 10px;">
  85 + <span id="btn-text">INICIAR SESIÓN</span>
  86 + <div class="spinner-border spinner-border-sm text-light" id="spinner" role="status" style="display:none; margin: auto;"></div>
  87 + </button>
  88 + </div>
  89 + </div>
  90 + </form>
  91 + </div>
  92 + <!-- /.login-card-body -->
  93 + </div>
114 94 </div>
  95 +<!-- /.login-box -->
  96 +
  97 +<!-- jQuery -->
  98 +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  99 +<!-- Bootstrap 4 -->
  100 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
  101 +<!-- AdminLTE App -->
  102 +<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
115 103  
116 104 <script>
117 105 // Filtro interactivo de municipios
... ... @@ -134,6 +122,7 @@
134 122  
135 123 // Limpiar sesión previa si por error caen al login
136 124 localStorage.removeItem('jwt');
  125 + localStorage.removeItem('user_name');
137 126  
138 127 document.getElementById('loginForm').addEventListener('submit', function(e) {
139 128 e.preventDefault();
... ... @@ -185,8 +174,8 @@
185 174 localStorage.setItem('mapa_base_id', data.mapaBase);
186 175 localStorage.setItem('map_bounds', data.bounds);
187 176  
188   - // Redirigir a la URL del Mapas de Leaflet
189   - window.location.href = "/gis-geoserver/mapas";
  177 + // Redirigir a la URL del Mapas
  178 + window.location.href = "/gis-geoserver/landing";
190 179 })
191 180 .catch(error => {
192 181 // LOGIN ERROR
... ... @@ -200,6 +189,5 @@
200 189 });
201 190 });
202 191 </script>
203   -
204 192 </body>
205 193 </html>
... ...
GIS-GEOSERVER/target/classes/static/widgets.html 0 → 100644
  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">
  6 + <!-- Google Font: Source Sans Pro -->
  7 + <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  8 + <!-- Font Awesome -->
  9 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  10 + <!-- Theme style AdminLTE 3 -->
  11 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
  12 + <style>
  13 + body { background-color: #f4f6f9; padding: 20px; font-family: 'Source Sans Pro', sans-serif; }
  14 + .welcome-header { font-size: 24px; color: #333; margin-bottom: 20px; font-weight: 600;}
  15 + </style>
  16 +</head>
  17 +<body>
  18 + <div class="welcome-header">
  19 + <i class="fas fa-home text-primary"></i> Tablero General (Estadísticas Simuladas)
  20 + </div>
  21 +
  22 + <div class="row">
  23 + <!-- Tarjeta 1 -->
  24 + <div class="col-lg-3 col-6">
  25 + <div class="small-box bg-info shadow-sm">
  26 + <div class="inner">
  27 + <h3>99,999</h3>
  28 + <p>Lotes Registrados</p>
  29 + </div>
  30 + <div class="icon">
  31 + <i class="fas fa-map-marked-alt"></i>
  32 + </div>
  33 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  34 + </div>
  35 + </div>
  36 + <!-- Tarjeta 2 -->
  37 + <div class="col-lg-3 col-6">
  38 + <div class="small-box bg-success shadow-sm">
  39 + <div class="inner">
  40 + <h3>Gs. ---<sup style="font-size: 20px"></sup></h3>
  41 + <p>Recaudación del Día</p>
  42 + </div>
  43 + <div class="icon">
  44 + <i class="fas fa-hand-holding-usd"></i>
  45 + </div>
  46 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  47 + </div>
  48 + </div>
  49 +
  50 + <!-- Tarjeta 3 -->
  51 + <div class="col-lg-3 col-6">
  52 + <div class="small-box bg-warning shadow-sm">
  53 + <div class="inner">
  54 + <h3>---</h3>
  55 + <p>Nuevas Actividades Comerciales</p>
  56 + </div>
  57 + <div class="icon">
  58 + <i class="fas fa-store"></i>
  59 + </div>
  60 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  61 + </div>
  62 + </div>
  63 + <!-- Tarjeta 4 -->
  64 + <div class="col-lg-3 col-6">
  65 + <div class="small-box bg-danger shadow-sm">
  66 + <div class="inner">
  67 + <h3>45%</h3>
  68 + <p>Índice General de Morosidad</p>
  69 + </div>
  70 + <div class="icon">
  71 + <i class="fas fa-chart-pie"></i>
  72 + </div>
  73 + <a href="#" class="small-box-footer" onclick="alert('OPCIÓN NO IMPLEMENTADA')">Más info <i class="fas fa-arrow-circle-right"></i></a>
  74 + </div>
  75 + </div>
  76 + </div>
  77 +
  78 + <div class="row mt-4">
  79 + <div class="col-12">
  80 + <div class="card card-outline card-primary shadow-sm" style="border-top: 3px solid #0056b3;">
  81 + <div class="card-header">
  82 + <h3 class="card-title text-muted"><i class="fas fa-info-circle mr-1"></i> Estado del Sistema</h3>
  83 + </div>
  84 + <div class="card-body">
  85 + <p class="text-secondary text-sm">Use el menú lateral para navegar por los distintos módulos administrativos. La funcionalidad de Mapas Tributarios se encuentra activa bajo "Control de Gestión -> Mapas". Otras opciones en despliegue.</p>
  86 + </div>
  87 + </div>
  88 + </div>
  89 + </div>
  90 +
  91 +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  92 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
  93 +</body>
  94 +</html>
... ...
GitLab Appliance - Powered by TurnKey Linux