Skip to content

Commit f3beefb

Browse files
fix: Integración completa con parámetros de seguridad y despliegue
Se realizó la integración completa del frontend con la API, incluyendo la implementación de parámetros de seguridad para la autenticación y autorización de las solicitudes. También se configuraron los procesos de despliegue, asegurando que la aplicación esté lista para ser desplegada en producción. Nota: El manejo de excepciones en el frontend aún no ha sido implementado, por lo que los errores no se gestionan adecuadamente, pendiente funcionalidad de editar salon.
1 parent f4016ac commit f3beefb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1202
-804
lines changed

.github/workflows/ci-cd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
env:
1313
AZURE_WEBAPP_NAME: elysiumFrontEnd
1414
AZURE_WEBAPP_PACKAGE_PATH: '.'
15-
NODE_VERSION: '22.x'
15+
NODE_VERSION: '18.x'
1616

1717
jobs:
1818
build-and-deploy:

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"react": "^19.0.0",
1616
"react-datepicker": "^8.2.1",
1717
"react-day-picker": "^9.6.4",
18-
"react-dom": "^19.0.0",
18+
"react-dom": "^19.1.0",
1919
"react-native": "^0.78.1",
2020
"react-router-dom": "^7.4.1",
2121
"react-scripts": "^5.0.1",

src/App.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ function AppRoutes({ user, setUser }) {
186186
<Routes>
187187
{user.isAdmin ? (
188188
<>
189-
<Route path="/administrador" element={<AdministratorHome token={localStorage.getItem("token")} />} />
190-
<Route path="/administrador/salones" element={<GestionarSalones />} />
189+
<Route path="/administrador" element={<AdministratorHome />} />
190+
<Route path="/administrador/salones" element={<GestionarSalones user={user} />} />
191191
<Route path="/administrador/usuarios" element={<GestionarUsuarios />} />
192192
<Route path="*" element={<Navigate to="/administrador" />} />
193193
</>

src/api/salon.jsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const SALON_API = "/salones";
1515
*/
1616
export async function getSalones(filtros = {}) {
1717
try {
18-
const response = await api.get(SALON_API, { params: filtros });
18+
const response = await api.get(SALON_API, filtros );
1919
return response.data;
2020
} catch (error) {
2121
throw new Error(error.response.data.message);
@@ -66,7 +66,7 @@ export async function getDisponible(mnemonico) {
6666
*/
6767
export async function agregarSalon(salon) {
6868
try {
69-
const response = await api.post(SALON_API, { params: salon });
69+
const response = await api.post(SALON_API, salon );
7070
return response.data;
7171
} catch (error) {
7272
throw new Error(error.response.data.message);
@@ -82,8 +82,7 @@ export async function agregarSalon(salon) {
8282
*/
8383
export async function actualizarSalon(mnemonico, salon) {
8484
try {
85-
const response = await api.patch(`${SALON_API}/${mnemonico}`, { params: salon });
86-
return response.data;
85+
await api.patch(`${SALON_API}/${mnemonico}`, salon );
8786
} catch (error) {
8887
throw new Error(error.response.data.message);
8988
}
Lines changed: 4 additions & 0 deletions
Loading

src/components/Admin/charts/DemandaChart.jsx

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,59 @@ const DemandaChart = ({ reservas }) => {
55
const chartRef = useRef(null);
66

77
useEffect(() => {
8-
const svg = d3.select(chartRef.current);
8+
const container = chartRef.current;
9+
const svg = d3.select(container);
910
svg.selectAll("*").remove(); // Limpia el SVG
1011

1112
if (!reservas || reservas.length === 0) return;
1213

13-
const width = 600;
14-
const height = 500;
14+
const containerWidth = container.clientWidth || 600; // Usa el tamaño del contenedor
15+
const containerHeight = containerWidth * 0.7; // Relación de aspecto
1516

16-
svg.attr("width", width).attr("height", height);
17+
svg
18+
.attr("viewBox", `0 0 ${containerWidth} ${containerHeight}`)
19+
.attr("preserveAspectRatio", "xMidYMid meet"); // Mantiene proporción
1720

1821
// Agrupar reservas por salón
19-
const reservasPorSalon = d3.rollup(
20-
reservas,
21-
(v) => v.length,
22-
(d) => d.idSalon
23-
);
24-
// Convertir a arreglo de objetos
25-
const data = Array.from(reservasPorSalon, ([salon, count]) => ({
26-
salon,
27-
count,
28-
}));
29-
30-
// Usamos d3.hierarchy para crear una estructura para el pack layout.
31-
const root = d3.hierarchy({ children: data }).sum((d) => d.count);
22+
const reservasPorSalon = d3.rollup(reservas, (v) => v.length, (d) => d.idSalon);
23+
const data = Array.from(reservasPorSalon, ([salon, count]) => ({ salon, count }));
3224

33-
// Configurar el pack layout
34-
const pack = d3.pack().size([width, height]).padding(10);
25+
const root = d3.hierarchy({ children: data }).sum((d) => d.count);
26+
const pack = d3.pack().size([containerWidth, containerHeight]).padding(10);
3527

3628
const nodes = pack(root).leaves();
37-
38-
// Escala de colores
3929
const color = d3.scaleOrdinal(d3.schemeSet3);
4030

41-
// Dibujar las burbujas
4231
const node = svg
4332
.selectAll("g")
4433
.data(nodes)
4534
.enter()
4635
.append("g")
4736
.attr("transform", (d) => `translate(${d.x}, ${d.y})`);
4837

49-
node
50-
.append("circle")
51-
.attr("r", 0)
52-
.attr("fill", (d, i) => color(i))
53-
.transition()
54-
.duration(800)
55-
.attr("r", (d) => d.r);
56-
57-
// Agregar etiquetas dentro de cada burbuja (nombre del salón y cantidad)
58-
node
59-
.append("text")
60-
.attr("text-anchor", "middle")
61-
.attr("dy", "-0.3em")
38+
node.append("circle").attr("r", 0).attr("fill", (d, i) => color(i))
39+
.transition().duration(800).attr("r", (d) => d.r);
40+
41+
node.append("text").attr("text-anchor", "middle").attr("dy", "-0.3em")
6242
.attr("font-size", (d) => Math.min((2 * d.r) / d.data.salon.length, 18))
63-
.attr("fill", "#000")
64-
.text((d) => d.data.salon);
65-
66-
node
67-
.append("text")
68-
.attr("text-anchor", "middle")
69-
.attr("dy", "1em")
70-
.attr("font-size", "12px")
71-
.attr("fill", "#000")
72-
.text((d) => d.data.count);
43+
.attr("fill", "#000").text((d) => d.data.salon);
44+
45+
node.append("text").attr("text-anchor", "middle").attr("dy", "1em")
46+
.attr("font-size", "12px").attr("fill", "#000").text((d) => d.data.count);
47+
48+
// Función para actualizar el gráfico cuando se cambia el tamaño de la ventana
49+
const updateSize = () => {
50+
const newWidth = container.clientWidth || 600;
51+
const newHeight = newWidth * 0.7;
52+
svg.attr("viewBox", `0 0 ${newWidth} ${newHeight}`);
53+
};
54+
55+
window.addEventListener("resize", updateSize);
56+
updateSize(); // Llama la función al inicio
57+
7358
}, [reservas]);
7459

75-
return <svg ref={chartRef}></svg>;
60+
return <svg ref={chartRef} style={{ width: "100%", height: "auto" }}></svg>;
7661
};
7762

78-
export default DemandaChart;
63+
export default DemandaChart;

src/components/Admin/charts/DiaSalonChart.jsx

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,28 @@ const DiaSalonChart = ({ reservas }) => {
55
const chartRef = useRef(null);
66

77
useEffect(() => {
8-
const svg = d3.select(chartRef.current);
8+
const container = chartRef.current;
9+
const svg = d3.select(container);
910
svg.selectAll("*").remove(); // Limpia el contenido del SVG
1011

1112
if (!reservas || reservas.length === 0) return;
1213

13-
const width = 500;
14-
const height = 500;
15-
const radius = Math.min(width, height) / 2;
16-
svg.attr("width", width).attr("height", height);
14+
// Ajustar tamaño dinámico según el contenedor
15+
const containerWidth = container.clientWidth || 500;
16+
const containerHeight = containerWidth * 0.7; // Mantener proporción
17+
18+
svg
19+
.attr("viewBox", `0 0 ${containerWidth} ${containerHeight}`)
20+
.attr("preserveAspectRatio", "xMidYMid meet");
21+
22+
const radius = Math.min(containerWidth, containerHeight) / 2;
1723

1824
const g = svg
1925
.append("g")
20-
.attr("transform", `translate(${width / 2}, ${height / 2})`);
26+
.attr("transform", `translate(${containerWidth / 2}, ${containerHeight / 2})`);
2127

2228
// Agrupar reservas por salón
23-
const reservasPorSalon = d3.rollup(
24-
reservas,
25-
(v) => v.length,
26-
(d) => d.idSalon
27-
);
29+
const reservasPorSalon = d3.rollup(reservas, (v) => v.length, (d) => d.idSalon);
2830
const data = Array.from(reservasPorSalon, ([salon, count]) => ({ salon, count }));
2931

3032
// Configurar el pie chart
@@ -33,15 +35,14 @@ const DiaSalonChart = ({ reservas }) => {
3335
const color = d3.scaleOrdinal(d3.schemeCategory10);
3436

3537
const arcs = g
36-
.selectAll("arc")
38+
.selectAll(".arc")
3739
.data(pie(data))
3840
.enter()
3941
.append("g")
4042
.attr("class", "arc");
4143

4244
arcs
4345
.append("path")
44-
.attr("d", arc)
4546
.attr("fill", (d, i) => color(i))
4647
.transition()
4748
.duration(800)
@@ -52,17 +53,28 @@ const DiaSalonChart = ({ reservas }) => {
5253
};
5354
});
5455

55-
// Agregar etiquetas para cada salón
56+
// Agregar etiquetas dentro de cada sección del gráfico
5657
arcs
5758
.append("text")
5859
.attr("transform", (d) => `translate(${arc.centroid(d)})`)
5960
.attr("text-anchor", "middle")
6061
.attr("font-size", "12px")
6162
.attr("fill", "#fff")
6263
.text((d) => d.data.salon);
64+
65+
// Función para ajustar el tamaño cuando la pantalla cambie
66+
const updateSize = () => {
67+
const newWidth = container.clientWidth || 500;
68+
const newHeight = newWidth * 0.7;
69+
svg.attr("viewBox", `0 0 ${newWidth} ${newHeight}`);
70+
};
71+
72+
window.addEventListener("resize", updateSize);
73+
updateSize(); // Llama a la función al inicio
74+
6375
}, [reservas]);
6476

65-
return <svg ref={chartRef}></svg>;
77+
return <svg ref={chartRef} style={{ width: "100%", height: "auto" }}></svg>;
6678
};
6779

6880
export default DiaSalonChart;
Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,48 @@
1-
// src/components/Admin/charts/EstadoChart.jsx
21
import React, { useEffect, useRef } from "react";
32
import * as d3 from "d3";
43

54
const EstadoChart = ({ reservas }) => {
65
const chartRef = useRef(null);
76

87
useEffect(() => {
9-
const svg = d3.select(chartRef.current);
8+
const container = chartRef.current;
9+
const svg = d3.select(container);
1010
svg.selectAll("*").remove(); // Limpia el SVG
1111

1212
if (!reservas || reservas.length === 0) return;
1313

14-
const width = 500;
15-
const height = 500;
16-
const radius = Math.min(width, height) / 2;
17-
svg.attr("width", width).attr("height", height);
14+
// Ajustar tamaño dinámico según el contenedor
15+
const containerWidth = container.clientWidth || 500;
16+
const containerHeight = containerWidth * 0.7; // Mantener proporción
17+
18+
svg
19+
.attr("viewBox", `0 0 ${containerWidth} ${containerHeight}`)
20+
.attr("preserveAspectRatio", "xMidYMid meet");
21+
22+
const radius = Math.min(containerWidth, containerHeight) / 2;
1823

1924
const g = svg
2025
.append("g")
21-
.attr("transform", `translate(${width / 2}, ${height / 2})`);
22-
23-
// Agrupar reservas por estado (suponiendo que la propiedad 'estado' es una cadena, ej: "ACTIVA" o "INACTIVA")
24-
const reservasPorEstado = d3.rollup(
25-
reservas,
26-
(v) => v.length,
27-
(d) => d.estado
28-
);
29-
const data = Array.from(reservasPorEstado, ([estado, count]) => ({
30-
estado,
31-
count,
32-
}));
26+
.attr("transform", `translate(${containerWidth / 2}, ${containerHeight / 2})`);
27+
28+
// Agrupar reservas por estado
29+
const reservasPorEstado = d3.rollup(reservas, (v) => v.length, (d) => d.estado);
30+
const data = Array.from(reservasPorEstado, ([estado, count]) => ({ estado, count }));
3331

3432
// Configurar el pie/donut chart
3533
const pie = d3.pie().value((d) => d.count);
36-
const arc = d3
37-
.arc()
38-
.innerRadius(radius * 0.5) // Radio interior para efecto donut
39-
.outerRadius(radius);
40-
41-
// Escala de colores con una paleta profesional (usamos d3.schemeSet2)
42-
const color = d3
43-
.scaleOrdinal()
44-
.domain(data.map((d) => d.estado))
45-
.range(d3.schemeSet2);
34+
const arc = d3.arc().innerRadius(radius * 0.5).outerRadius(radius);
35+
const color = d3.scaleOrdinal().domain(data.map((d) => d.estado)).range(d3.schemeSet2);
4636

4737
const arcs = g
48-
.selectAll("arc")
38+
.selectAll(".arc")
4939
.data(pie(data))
5040
.enter()
5141
.append("g")
5242
.attr("class", "arc");
5343

5444
arcs
5545
.append("path")
56-
.attr("d", arc)
5746
.attr("fill", (d) => color(d.data.estado))
5847
.transition()
5948
.duration(800)
@@ -72,9 +61,20 @@ const EstadoChart = ({ reservas }) => {
7261
.attr("font-size", "14px")
7362
.attr("fill", "#000")
7463
.text((d) => `${d.data.estado}: ${d.data.count}`);
64+
65+
// Función para ajustar el tamaño cuando la pantalla cambie
66+
const updateSize = () => {
67+
const newWidth = container.clientWidth || 500;
68+
const newHeight = newWidth * 0.7;
69+
svg.attr("viewBox", `0 0 ${newWidth} ${newHeight}`);
70+
};
71+
72+
window.addEventListener("resize", updateSize);
73+
updateSize(); // Llama a la función al inicio
74+
7575
}, [reservas]);
7676

77-
return <svg ref={chartRef}></svg>;
77+
return <svg ref={chartRef} style={{ width: "100%", height: "auto" }}></svg>;
7878
};
7979

8080
export default EstadoChart;

0 commit comments

Comments
 (0)