Browse Source

Se añadio el dashboard para vizualizar los resultados y estadisticas de las encuestas enviadas y respondidas

delta
mramirezg 3 weeks ago
parent
commit
0c754d72c2
10 changed files with 372 additions and 8 deletions
  1. +1
    -1
      pom.xml
  2. BIN
      src/main/bundles/dev.bundle
  3. BIN
      src/main/bundles/prod.bundle
  4. +12
    -0
      src/main/frontend/themes/sistema-mantenimiento/styles.css
  5. +38
    -0
      src/main/java/mx/gob/jumapacelaya/models/encuestas/ConteoEncuestas.java
  6. +68
    -0
      src/main/java/mx/gob/jumapacelaya/models/encuestas/ConteoRespuestas.java
  7. +49
    -4
      src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java
  8. +2
    -2
      src/main/java/mx/gob/jumapacelaya/ui/ConfiguracionView.java
  9. +2
    -1
      src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java
  10. +200
    -0
      src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java

+ 1
- 1
pom.xml View File

@ -6,7 +6,7 @@
<groupId>mx.gob.jumapacelaya</groupId> <groupId>mx.gob.jumapacelaya</groupId>
<artifactId>sistema-mantenimiento</artifactId> <artifactId>sistema-mantenimiento</artifactId>
<name>sistema-mantenimiento</name> <name>sistema-mantenimiento</name>
<version>1.0-SNAPSHOT</version>
<version>2.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>


BIN
src/main/bundles/dev.bundle View File


BIN
src/main/bundles/prod.bundle View File


+ 12
- 0
src/main/frontend/themes/sistema-mantenimiento/styles.css View File

@ -126,6 +126,18 @@ vaadin-popover-overlay::part(overlay) {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
} }
.dashboard-widget-content {
padding: 1.5rem;
}
.pregunta-widget-container {
border-top: 3px solid #a02142;
}
.pregunta-widget-container span {
line-height: 1.2;
}
@media (max-width: 900px) { @media (max-width: 900px) {


+ 38
- 0
src/main/java/mx/gob/jumapacelaya/models/encuestas/ConteoEncuestas.java View File

@ -0,0 +1,38 @@
package mx.gob.jumapacelaya.models.encuestas;
public class ConteoEncuestas {
private int totalEnviadas;
private int totalRespondidas;
private Double porcentajeRespondidas;
public ConteoEncuestas(int totalEnviadas, int totalRespondidas, Double porcentajeRespondidas) {
this.totalEnviadas = totalEnviadas;
this.totalRespondidas = totalRespondidas;
this.porcentajeRespondidas = porcentajeRespondidas;
}
public int getTotalEnviadas() {
return totalEnviadas;
}
public void setTotalEnviadas(int totalEnviadas) {
this.totalEnviadas = totalEnviadas;
}
public int getTotalRespondidas() {
return totalRespondidas;
}
public void setTotalRespondidas(int totalRespondidas) {
this.totalRespondidas = totalRespondidas;
}
public Double getPorcentajeRespondidas() {
return porcentajeRespondidas;
}
public void setPorcentajeRespondidas(Double porcentajeRespondidas) {
this.porcentajeRespondidas = porcentajeRespondidas;
}
}

+ 68
- 0
src/main/java/mx/gob/jumapacelaya/models/encuestas/ConteoRespuestas.java View File

@ -0,0 +1,68 @@
package mx.gob.jumapacelaya.models.encuestas;
public class ConteoRespuestas {
private int preguntaId;
private String pregunta;
private int totalRespuestas;
private int totalSi;
private int totalNo;
private Double porcentaje;
public ConteoRespuestas(int preguntaId, String pregunta, int totalRespuestas, int totalSi, int totalNo, Double porcentaje) {
this.preguntaId = preguntaId;
this.pregunta = pregunta;
this.totalRespuestas = totalRespuestas;
this.totalSi = totalSi;
this.totalNo = totalNo;
this.porcentaje = porcentaje;
}
public int getPreguntaId() {
return preguntaId;
}
public void setPreguntaId(int preguntaId) {
this.preguntaId = preguntaId;
}
public String getPregunta() {
return pregunta;
}
public void setPregunta(String pregunta) {
this.pregunta = pregunta;
}
public int getTotalRespuestas() {
return totalRespuestas;
}
public void setTotalRespuestas(int totalRespuestas) {
this.totalRespuestas = totalRespuestas;
}
public int getTotalSi() {
return totalSi;
}
public void setTotalSi(int totalSi) {
this.totalSi = totalSi;
}
public int getTotalNo() {
return totalNo;
}
public void setTotalNo(int totalNo) {
this.totalNo = totalNo;
}
public Double getPorcentaje() {
return porcentaje;
}
public void setPorcentaje(Double porcentaje) {
this.porcentaje = porcentaje;
}
}

+ 49
- 4
src/main/java/mx/gob/jumapacelaya/services/DatabaseService.java View File

@ -1,9 +1,7 @@
package mx.gob.jumapacelaya.services; package mx.gob.jumapacelaya.services;
import mx.gob.jumapacelaya.models.*; import mx.gob.jumapacelaya.models.*;
import mx.gob.jumapacelaya.models.encuestas.MantenimientosSinEncuesta;
import mx.gob.jumapacelaya.models.encuestas.Pregunta;
import mx.gob.jumapacelaya.models.encuestas.Respuesta;
import mx.gob.jumapacelaya.models.encuestas.*;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
@ -204,7 +202,6 @@ public class DatabaseService {
); );
planAnualList.add(planAnual); planAnualList.add(planAnual);
} }
System.out.println("Registros obtenidos: " + planAnualList.size());
} catch (SQLException e) { } catch (SQLException e) {
logger.error("Error al obtener plan anual: ", e); logger.error("Error al obtener plan anual: ", e);
} }
@ -944,6 +941,7 @@ public class DatabaseService {
} }
/*************************************** ENCUESTAS ******************************************************************************************************/ /*************************************** ENCUESTAS ******************************************************************************************************/
public List<Pregunta> getPreguntas() { public List<Pregunta> getPreguntas() {
List<Pregunta> preguntas = new ArrayList<>(); List<Pregunta> preguntas = new ArrayList<>();
@ -1072,5 +1070,52 @@ public class DatabaseService {
} }
return null; return null;
} }
public List<ConteoEncuestas> getTotalEncuestas() {
List<ConteoEncuestas> totalEncuestas = new ArrayList<>();
String query = "SELECT * FROM VW_CONTEO_ENCUESTAS";
try (Connection conn = getMysqlConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
while (rs.next()) {
ConteoEncuestas conteo = new ConteoEncuestas(
rs.getInt("TOTAL_ENVIADAS"),
rs.getInt("TOTAL_RESPONDIDAS"),
rs.getDouble("PORCENTAJE_TOTAL")
);
totalEncuestas.add(conteo);
}
} catch (SQLException e) {
logger.error("Error al obtener el total de encuestas: ", e);
}
return totalEncuestas;
}
public List<ConteoRespuestas> getTotalRespuestas() {
List<ConteoRespuestas> totalRespuestas = new ArrayList<>();
String query = "SELECT * FROM VW_CONTEO_RESPUESTAS";
try (Connection conn = getMysqlConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
while (rs.next()) {
ConteoRespuestas conteo = new ConteoRespuestas(
rs.getInt("PREGUNTAID"),
rs.getString("PREGUNTA"),
rs.getInt("TOTALREGISTROS"),
rs.getInt("TOTALSI"),
rs.getInt("TOTALNO"),
rs.getDouble("PORCENTAJE")
);
totalRespuestas.add(conteo);
}
} catch (SQLException e) {
logger.error("Error al obtener el total de respuestas: ", e);
}
return totalRespuestas;
}
/***************************************************************************************************************************************/ /***************************************************************************************************************************************/
} }

+ 2
- 2
src/main/java/mx/gob/jumapacelaya/ui/ConfiguracionView.java View File

@ -16,7 +16,7 @@ import jakarta.annotation.security.PermitAll;
import java.util.List; import java.util.List;
@PermitAll @PermitAll
@PageTitle("Configuración del sistema")
@PageTitle("Preferencias del Sistema")
@Route(value = "configuracion", layout = MainLayout.class) @Route(value = "configuracion", layout = MainLayout.class)
public class ConfiguracionView extends VerticalLayout { public class ConfiguracionView extends VerticalLayout {
@ -42,7 +42,7 @@ public class ConfiguracionView extends VerticalLayout {
public ConfiguracionView() { public ConfiguracionView() {
setSpacing(true); setSpacing(true);
add(new H2("⚙\uFE0F Configuración del Sistema"));
add(new H2("⚙\uFE0F Preferencias del Sistema"));
loadCssVariablesFromLocalStorage(); loadCssVariablesFromLocalStorage();


+ 2
- 1
src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java View File

@ -93,7 +93,8 @@ public class MainLayout extends AppLayout implements BeforeEnterObserver {
nav.addItem(new SideNavItem("Plan Anual", PlanAnualView.class, VaadinIcon.CALENDAR.create())); nav.addItem(new SideNavItem("Plan Anual", PlanAnualView.class, VaadinIcon.CALENDAR.create()));
nav.addItem(new SideNavItem("Listado de Actividades", ActDiariaView.class, VaadinIcon.EDIT.create())); nav.addItem(new SideNavItem("Listado de Actividades", ActDiariaView.class, VaadinIcon.EDIT.create()));
nav.addItem(new SideNavItem("Mantenimiento Correctivo", MantCorrectivoView.class, VaadinIcon.WRENCH.create())); nav.addItem(new SideNavItem("Mantenimiento Correctivo", MantCorrectivoView.class, VaadinIcon.WRENCH.create()));
nav.addItem(new SideNavItem("Configuración del sistema", ConfiguracionView.class, VaadinIcon.COG.create()));
nav.addItem(new SideNavItem("Resultados de Encuestas", ResultEncuestasView.class, VaadinIcon.CLIPBOARD_TEXT.create()));
nav.addItem(new SideNavItem("Preferencias del Sistema", ConfiguracionView.class, VaadinIcon.COG.create()));
nav.getStyle().set("border-radius", "5px"); nav.getStyle().set("border-radius", "5px");
return nav; return nav;


+ 200
- 0
src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java View File

@ -0,0 +1,200 @@
package mx.gob.jumapacelaya.ui;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dashboard.Dashboard;
import com.vaadin.flow.component.dashboard.DashboardSection;
import com.vaadin.flow.component.dashboard.DashboardWidget;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.SvgIcon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.models.encuestas.ConteoEncuestas;
import mx.gob.jumapacelaya.models.encuestas.ConteoRespuestas;
import mx.gob.jumapacelaya.services.DatabaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vaadin.lineawesome.LineAwesomeIcon;
import java.util.List;
@PermitAll
@PageTitle("Resultados de Encuestas")
@Route(value = "resultados-encuestas", layout = MainLayout.class)
public class ResultEncuestasView extends VerticalLayout {
private static final Logger logger = LoggerFactory.getLogger(ResultEncuestasView.class);
private final DatabaseService databaseService;
private DashboardWidget totalEncu;
private DashboardWidget totalResp;
private DashboardWidget porcentajeResp;
private DashboardWidget pregunta1;
private DashboardWidget pregunta2;
private DashboardWidget pregunta3;
private DashboardWidget pregunta4;
private DashboardWidget pregunta5;
private DashboardWidget pregunta6;
public ResultEncuestasView(DatabaseService databaseService) {
this.databaseService = databaseService;
createToolbar();
createDashboard();
}
public HorizontalLayout createToolbar() {
Button btnExport = new Button("Exportar a PDF", LineAwesomeIcon.FILE_PDF.create());
btnExport.addThemeVariants(ButtonVariant.LUMO_SMALL);
HorizontalLayout toolbar = new HorizontalLayout(btnExport);
toolbar.setAlignItems(Alignment.BASELINE);
toolbar.setWidthFull();
add(toolbar);
return toolbar;
}
public Dashboard createDashboard() {
Dashboard dashboard = new Dashboard();
dashboard.setMinimumColumnWidth("150px");
dashboard.setMaximumColumnCount(3);
// Secciónes del dashboard
DashboardSection generalSection = dashboard.addSection("General");
DashboardSection preguntasSection = dashboard.addSection("Preguntas");
// Widgets para la sección General
totalEncu = new DashboardWidget("Total Encuestas");
totalResp = new DashboardWidget("Total Respuestas");
porcentajeResp = new DashboardWidget("Porcentaje de Respuestas");
generalSection.add(totalEncu);
generalSection.add(totalResp);
generalSection.add(porcentajeResp);
// Widget para la sección Preguntas
pregunta1 = new DashboardWidget("Pregunta 1");
pregunta2 = new DashboardWidget("Pregunta 2");
pregunta3 = new DashboardWidget("Pregunta 3");
pregunta4 = new DashboardWidget("Pregunta 4");
pregunta5 = new DashboardWidget("Pregunta 5");
pregunta6 = new DashboardWidget("Pregunta 6");
preguntasSection.add(pregunta1);
preguntasSection.add(pregunta2);
preguntasSection.add(pregunta3);
preguntasSection.add(pregunta4);
preguntasSection.add(pregunta5);
preguntasSection.add(pregunta6);
mostrarTotales();
mostrarPreguntas();
add(dashboard);
return dashboard;
}
private Div createDiv(String valor, LineAwesomeIcon icon, String color) {
Div content = new Div();
content.setClassName("dashboard-widget-content");
content.getStyle()
.set("display", "flex")
.set("align-items", "center")
.set("justify-content", "center")
.set("gap", "15px");
SvgIcon vIcon = icon.create();
vIcon.getStyle().set("color", color);
vIcon.setSize("40px");
Span text = new Span(valor);
text.getStyle().set("font-size", "2.2rem");
text.getStyle().set("font-weight", "800");
content.add(vIcon, text);
return content;
}
private Div createPreguntaContent(ConteoRespuestas data) {
Div container = new Div();
container.setClassName("pregunta-widget-container");
container.getStyle().set("padding", "10px");
Span txtPregunta = new Span(data.getPregunta());
txtPregunta.getStyle().set("font-size", "0.9em")
.set("display", "block")
.set("margin-bottom", "15px")
.set("height", "45px")
.set("overflow", "hidden");
HorizontalLayout metrics = new HorizontalLayout();
metrics.setJustifyContentMode(JustifyContentMode.BETWEEN);
metrics.setWidthFull();
metrics.add(
createStat("Si", String.valueOf(data.getTotalSi()), "#27ae60"),
createStat("No", String.valueOf(data.getTotalNo()), "#e74c3c"),
createStat("%", String.format("%.0f", data.getPorcentaje()), "#BC955B")
);
container.add(txtPregunta, metrics);
return container;
}
private VerticalLayout createStat(String label, String value, String color) {
Span l = new Span(label);
l.getStyle().set("font-size", "0.7em").set("color", "gray");
Span v = new Span(value);
v.getStyle().set("font-weight", "bold").set("color", color);
VerticalLayout vl = new VerticalLayout(l,v);
vl.setAlignItems(Alignment.CENTER);
vl.setSpacing(false);
vl.setPadding(false);
return vl;
}
public void mostrarTotales() {
List<ConteoEncuestas> datos = databaseService.getTotalEncuestas();
if (!datos.isEmpty()) {
ConteoEncuestas totales = datos.get(0);
totalEncu.setContent(createDiv(
String.valueOf(totales.getTotalEnviadas()),
LineAwesomeIcon.CLIPBOARD_LIST_SOLID, "#BC955B"
));
totalResp.setContent(createDiv(
String.valueOf(totales.getTotalRespondidas()),
LineAwesomeIcon.CHECK_CIRCLE, "#BC955B"
));
porcentajeResp.setContent(createDiv(
String.valueOf(totales.getPorcentajeRespondidas()),
LineAwesomeIcon.PERCENT_SOLID, "#BC955B"
));
}
}
public void mostrarPreguntas() {
List<ConteoRespuestas> lista = databaseService.getTotalRespuestas();
DashboardWidget[] widgets = {pregunta1,pregunta2,pregunta3,pregunta4,pregunta5,pregunta6};
for (int i = 0; i < lista.size() && i < widgets.length; i++) {
ConteoRespuestas data = lista.get(i);
DashboardWidget widget = widgets[i];
widget.setTitle("Pregunta #" + data.getPreguntaId());
widget.setContent(createPreguntaContent(data));
}
}
}

Loading…
Cancel
Save