From ec5de65adbcccd5b1f34747b4f46429027b12774 Mon Sep 17 00:00:00 2001 From: IO420 <320154041@pcpuma.acatlan.unam.mx> Date: Thu, 27 Nov 2025 14:56:38 -0600 Subject: [PATCH 1/2] added new button --- src/app/(Operador)/cambiarPass/page.tsx | 22 +---- src/app/styles/layout/BarNavigation.scss | 2 - src/app/styles/layout/BarNavigationAdmin.scss | 2 - src/app/styles/layout/ForgotPasswordPage.scss | 3 +- src/components/Equipo_Computo/pregunta7.css | 1 - src/components/Perifericos/Pregunta1EP.tsx | 2 + src/components/Perifericos/pregunta5EP.scss | 4 +- src/components/ToggleButton.module.scss | 92 +++++++++++++++++++ src/components/ToggleButton.tsx | 51 ++++++++++ 9 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 src/components/ToggleButton.module.scss create mode 100644 src/components/ToggleButton.tsx diff --git a/src/app/(Operador)/cambiarPass/page.tsx b/src/app/(Operador)/cambiarPass/page.tsx index 5c0b19f..8e51e82 100644 --- a/src/app/(Operador)/cambiarPass/page.tsx +++ b/src/app/(Operador)/cambiarPass/page.tsx @@ -7,40 +7,28 @@ import Cookies from "js-cookie"; import "../../styles/layout/ForgotPasswordPage.scss"; export default function UpdateUserPage() { - const [id_User, setId_User] = useState(""); const [nombre, setNombre] = useState(""); const [contrasenaN, setContrasenaN] = useState(""); const [contrasenaV, setContrasenaV] = useState(""); - const [tipoUsuario, setTipoUsuario] = useState(""); const [loading, setLoading] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - if (!id_User || isNaN(Number(id_User))) { - toast.error("El ID de usuario es obligatorio y debe ser un número."); - return; - } - - if (nombre && nombre.trim().length < 3) { + if (!nombre || nombre.trim().length < 3) { toast.error("El nombre debe tener al menos 3 caracteres."); return; } - if (contrasenaN && contrasenaN.length < 6) { + if (!contrasenaN || contrasenaN.length < 6) { toast.error("La nueva contraseña debe tener al menos 6 caracteres."); return; } - if (contrasenaV && contrasenaV.length < 6) { + if (!contrasenaV || contrasenaV.length < 6) { toast.error("La contraseña actual debe tener al menos 6 caracteres."); return; } - if (tipoUsuario && isNaN(Number(tipoUsuario))) { - toast.error("El tipo de usuario debe ser un número."); - return; - } - try { setLoading(true); @@ -50,11 +38,9 @@ export default function UpdateUserPage() { const response = await axios.post( `${process.env.NEXT_PUBLIC_API_URL}/auth/UpdateUsuario`, { - id_User: Number(id_User), nombre, contrasenaN, contrasenaV, - tipoUsuario: tipoUsuario ? Number(tipoUsuario) : undefined, }, { headers } ); @@ -71,8 +57,6 @@ export default function UpdateUserPage() {

Actualizar contraseña

-

Ingresa el ID y los campos que deseas modificar.

-
diff --git a/src/app/styles/layout/BarNavigation.scss b/src/app/styles/layout/BarNavigation.scss index a001dfd..36415c4 100644 --- a/src/app/styles/layout/BarNavigation.scss +++ b/src/app/styles/layout/BarNavigation.scss @@ -109,7 +109,6 @@ border-radius: 6px; cursor: pointer; font-weight: bold; - font-size: 2rem; display: flex; align-items: center; justify-content: center; @@ -171,7 +170,6 @@ .logout-button { margin-top: 10px; - font-size: 1.75rem; padding: 6px 12px; max-width: 180px; } diff --git a/src/app/styles/layout/BarNavigationAdmin.scss b/src/app/styles/layout/BarNavigationAdmin.scss index 7213c37..f63327e 100644 --- a/src/app/styles/layout/BarNavigationAdmin.scss +++ b/src/app/styles/layout/BarNavigationAdmin.scss @@ -109,7 +109,6 @@ border-radius: 6px; cursor: pointer; font-weight: bold; - font-size: 2rem; display: flex; align-items: center; justify-content: center; @@ -170,7 +169,6 @@ .logout-button { margin-top: 10px; - font-size: 1.75rem; padding: 6px 12px; max-width: 180px; } diff --git a/src/app/styles/layout/ForgotPasswordPage.scss b/src/app/styles/layout/ForgotPasswordPage.scss index b97bb9e..932cca1 100644 --- a/src/app/styles/layout/ForgotPasswordPage.scss +++ b/src/app/styles/layout/ForgotPasswordPage.scss @@ -9,7 +9,6 @@ justify-content: center; align-items: center; width: 100%; - min-height: 100vh; padding: 2rem; color: #222; @@ -26,7 +25,7 @@ font-size: 3rem; font-weight: 700; margin-bottom: 1.5rem; - color: #bd8c01; // Amarillo tipo login + color: #bd8c01; } p { diff --git a/src/components/Equipo_Computo/pregunta7.css b/src/components/Equipo_Computo/pregunta7.css index 1fa8209..d06496f 100644 --- a/src/components/Equipo_Computo/pregunta7.css +++ b/src/components/Equipo_Computo/pregunta7.css @@ -17,7 +17,6 @@ padding: 15px; border-radius: 8px; font-size: 16px; - margin-bottom: 25px; } .tabla-contenedor { diff --git a/src/components/Perifericos/Pregunta1EP.tsx b/src/components/Perifericos/Pregunta1EP.tsx index 820d711..45d3665 100644 --- a/src/components/Perifericos/Pregunta1EP.tsx +++ b/src/components/Perifericos/Pregunta1EP.tsx @@ -3,6 +3,7 @@ import React, { useState, useEffect } from "react"; import style from "./pregunta1EP.module.scss"; import axios from "axios"; import Cookies from "js-cookie"; +import ToggleButton from "../ToggleButton"; interface EquiposImpresion { inyeccionTinta: string; @@ -122,6 +123,7 @@ export default function Pregunta1EP() {
Equipos de impresión.
+
{/* Columna 1 */}
diff --git a/src/components/Perifericos/pregunta5EP.scss b/src/components/Perifericos/pregunta5EP.scss index 0f7af6f..fa78065 100644 --- a/src/components/Perifericos/pregunta5EP.scss +++ b/src/components/Perifericos/pregunta5EP.scss @@ -1,5 +1,7 @@ - .container { + display: flex; + flex-direction: column; + justify-content: space-between; width: 100%; } diff --git a/src/components/ToggleButton.module.scss b/src/components/ToggleButton.module.scss new file mode 100644 index 0000000..d012116 --- /dev/null +++ b/src/components/ToggleButton.module.scss @@ -0,0 +1,92 @@ +:root { + --bg-off: #fff; + --bg-on: linear-gradient(90deg, #003e79 0%, #015cb8 100%); + --thumb-off: #015cb8; + --thumb-on: #fff; + --shadow: 0 6px 18px rgba(99, 102, 241, 0.18); +} + +.toggle { + --padding: 6px; + display: inline-flex; + align-items: center; + gap: 12px; + padding: 6px 12px; + border: none; + background: transparent; + cursor: pointer; + user-select: none; + border-radius: 999px; + transition: transform 160ms ease, box-shadow 160ms ease; + outline: none; +} + +.toggle:active { + transform: scale(0.98); +} + +.track { + width: 70px; + height: 34px; + background: var(--bg-off); + border-radius: 999px; + display: inline-block; + padding: var(--padding); + box-sizing: border-box; + position: relative; + transition: background 220ms cubic-bezier(.2,.9,.2,1), box-shadow 220ms ease; + box-shadow: none; +} + +/* When the component has the `on` class, style the inner track and thumb accordingly. */ +.on .track { + background: var(--bg-on); + box-shadow: var(--shadow); +} + +.thumb { + width: 22px; + height: 22px; + background: var(--thumb-off); + border-radius: 50%; + display: block; + transform: translateX(0); + transition: transform 220ms cubic-bezier(.2,.9,.2,1), box-shadow 220ms ease; + box-shadow: 0 4px 10px rgba(16,24,40,0.12); +} + +.on .thumb { + background: var(--thumb-on); + transform: translateX(38px); + box-shadow: 0 6px 16px rgba(91, 90, 255, 0.18); +} + +.label { +position: absolute; +right: 10px; +top: 8px; + font-family: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial; + font-size: 14px; + font-weight: 600; + color: #0f172a; + letter-spacing: 0.2px; +} + +.on .label { + right: 45%; + color: #fff; + text-shadow: 0 1px 0 rgba(0,0,0,0.12); +} + +/* Focus visible for accessibility */ +.toggle:focus-visible .track { + box-shadow: 0 0 0 4px rgba(99,102,241,0.12); +} + +/* Small responsive tweak */ +@media (max-width: 420px) { + .track { width: 52px; height: 30px; } + .thumb { width: 20px; height: 20px; } + .on .thumb { transform: translateX(24px); } + .label { font-size: 13px; } +} diff --git a/src/components/ToggleButton.tsx b/src/components/ToggleButton.tsx new file mode 100644 index 0000000..49a2b30 --- /dev/null +++ b/src/components/ToggleButton.tsx @@ -0,0 +1,51 @@ +// ToggleButton.tsx +// Usa este archivo como `ToggleButton.tsx` + +import React, { useState } from 'react'; +import styles from './ToggleButton.module.scss'; + +export type ToggleButtonProps = { + /** estado inicial: true -> presionado ("desuso") */ + defaultOn?: boolean; + /** callback cuando cambia el estado */ + onChange?: (on: boolean) => void; + /** texto cuando está apagado (por defecto: "uso") */ + offLabel?: string; + /** texto cuando está encendido (por defecto: "desuso") */ + onLabel?: string; + className?: string; +}; + +const ToggleButton: React.FC = ({ + defaultOn = false, + onChange, + offLabel = 'Uso', + onLabel = 'Baja', + className = '', +}) => { + const [on, setOn] = useState(defaultOn); + + function toggle() { + const next = !on; + setOn(next); + onChange?.(next); + } + + return ( + + ); +}; + +export default ToggleButton; From be978b1879e4ba8eba48242c3625ab284ee2e055 Mon Sep 17 00:00:00 2001 From: IO420 <320154041@pcpuma.acatlan.unam.mx> Date: Thu, 27 Nov 2025 15:28:59 -0600 Subject: [PATCH 2/2] modified toggle --- src/components/Equipo_Computo/Pregunta7.tsx | 33 ++++++--- src/components/Equipo_Computo/pregunta7.css | 5 +- src/components/Perifericos/Pregunta1EP.tsx | 2 +- .../Perifericos/pregunta2EP.module.scss | 3 + src/components/Perifericos/pregunta5EP.scss | 3 +- .../{ => Toggle}/ToggleButton.module.scss | 74 ++++++++++++------- src/components/{ => Toggle}/ToggleButton.tsx | 37 +++++----- 7 files changed, 98 insertions(+), 59 deletions(-) rename src/components/{ => Toggle}/ToggleButton.module.scss (50%) rename src/components/{ => Toggle}/ToggleButton.tsx (54%) diff --git a/src/components/Equipo_Computo/Pregunta7.tsx b/src/components/Equipo_Computo/Pregunta7.tsx index ed3c7d0..0b3fa9c 100644 --- a/src/components/Equipo_Computo/Pregunta7.tsx +++ b/src/components/Equipo_Computo/Pregunta7.tsx @@ -17,10 +17,11 @@ type RespuestaAntiguedad = { export default function Pregunta7() { const [datos, setDatos] = useState([ - { nombre: "Impresión", valores: ["0.00", "0.00", "0.00", "0.00", "0.00"] }, + { nombre: "Impresión", valores: ["0.00", "0.00", "0.00", "0.00"] }, { nombre: "Digitalización", - valores: ["0.00", "0.00", "0.00", "0.00", "0.00"], + valores: ["0.00", "0.00", "0.00", "0.00" + ], }, ]); @@ -40,7 +41,9 @@ export default function Pregunta7() { for (const item of items) { const total = Number(item.total) || 0; - const antig = item.antiguedad ? item.antiguedad.toUpperCase().trim() : null; + const antig = item.antiguedad + ? item.antiguedad.toUpperCase().trim() + : null; switch (antig) { case "MENORES DE 2": @@ -62,7 +65,7 @@ export default function Pregunta7() { const total = menores2 + entre2_3 + entre4_5 + mayores6 + notfound; - if (total === 0) return ["0.00", "0.00", "0.00", "0.00", "0.00"]; + if (total === 0) return ["0.00", "0.00", "0.00", "0.00"]; const pct = (v: number) => ((v / total) * 100).toFixed(2); @@ -71,7 +74,6 @@ export default function Pregunta7() { pct(entre2_3), pct(entre4_5), pct(mayores6), - pct(notfound), ]; }; @@ -93,7 +95,10 @@ export default function Pregunta7() { setDatos([ { nombre: "Impresión", valores: transformarDatos(impresion) }, - { nombre: "Digitalización", valores: transformarDatos(digitalizacion) }, + { + nombre: "Digitalización", + valores: transformarDatos(digitalizacion), + }, ]); }) .catch((err) => console.error("Error cargando datos:", err)) @@ -103,11 +108,13 @@ export default function Pregunta7() { const calcularTotalFila = (valores: string[]) => valores.reduce((t, v) => t + Number(v), 0); - if (loading) return
Cargando datos...
; - return (
-
+
+ Censo de equipos periféricos - Equipo de digitalización +
+ +
Antigüedad que tienen los equipos periféricos del área universitaria.
@@ -120,7 +127,7 @@ export default function Pregunta7() { Entre 2 y 3 años Entre 4 y 5 años Mayor a 6 años - No registrados + Total @@ -142,7 +149,11 @@ export default function Pregunta7() { ))} - 100.1 ? "total-error" : ""}`}> + 100.1 ? "total-error" : "" + }`} + > {total.toFixed(2)}% diff --git a/src/components/Equipo_Computo/pregunta7.css b/src/components/Equipo_Computo/pregunta7.css index d06496f..978e92f 100644 --- a/src/components/Equipo_Computo/pregunta7.css +++ b/src/components/Equipo_Computo/pregunta7.css @@ -1,5 +1,7 @@ .contenedor-pregunta { - font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + display: flex; + flex-direction: column; + gap: 10px; } .contenedor-censo{ @@ -7,7 +9,6 @@ color: white; padding: 15px; font-size: 16px; - margin-bottom: 25px; border-radius: 4px; } diff --git a/src/components/Perifericos/Pregunta1EP.tsx b/src/components/Perifericos/Pregunta1EP.tsx index 45d3665..5565f70 100644 --- a/src/components/Perifericos/Pregunta1EP.tsx +++ b/src/components/Perifericos/Pregunta1EP.tsx @@ -3,7 +3,7 @@ import React, { useState, useEffect } from "react"; import style from "./pregunta1EP.module.scss"; import axios from "axios"; import Cookies from "js-cookie"; -import ToggleButton from "../ToggleButton"; +import ToggleButton from "../Toggle/ToggleButton"; interface EquiposImpresion { inyeccionTinta: string; diff --git a/src/components/Perifericos/pregunta2EP.module.scss b/src/components/Perifericos/pregunta2EP.module.scss index 2e95bbe..fa06868 100644 --- a/src/components/Perifericos/pregunta2EP.module.scss +++ b/src/components/Perifericos/pregunta2EP.module.scss @@ -1,4 +1,7 @@ .container_P2 { + display: flex; + flex-direction: column; + gap: 10px; max-width: 1200px; label { diff --git a/src/components/Perifericos/pregunta5EP.scss b/src/components/Perifericos/pregunta5EP.scss index fa78065..24ba525 100644 --- a/src/components/Perifericos/pregunta5EP.scss +++ b/src/components/Perifericos/pregunta5EP.scss @@ -1,7 +1,7 @@ .container { display: flex; flex-direction: column; - justify-content: space-between; + gap: 10px; width: 100%; } @@ -31,7 +31,6 @@ .item { flex: 1; - min-width: 150px; } label { diff --git a/src/components/ToggleButton.module.scss b/src/components/Toggle/ToggleButton.module.scss similarity index 50% rename from src/components/ToggleButton.module.scss rename to src/components/Toggle/ToggleButton.module.scss index d012116..41246b9 100644 --- a/src/components/ToggleButton.module.scss +++ b/src/components/Toggle/ToggleButton.module.scss @@ -4,14 +4,20 @@ --thumb-off: #015cb8; --thumb-on: #fff; --shadow: 0 6px 18px rgba(99, 102, 241, 0.18); + --curve: cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.containerToggle{ + display: flex; + justify-content: end; } .toggle { - --padding: 6px; + --padding: 4px; display: inline-flex; align-items: center; gap: 12px; - padding: 6px 12px; + border: none; background: transparent; cursor: pointer; @@ -21,8 +27,8 @@ outline: none; } -.toggle:active { - transform: scale(0.98); +.toggle:active .track { + box-shadow: inset 0 0 0 2em rgba(0, 0, 0, 0.06); } .track { @@ -34,59 +40,77 @@ padding: var(--padding); box-sizing: border-box; position: relative; - transition: background 220ms cubic-bezier(.2,.9,.2,1), box-shadow 220ms ease; - box-shadow: none; + transition: background 280ms var(--curve), box-shadow 220ms ease; + border: 1px solid #e8eae9; } -/* When the component has the `on` class, style the inner track and thumb accordingly. */ .on .track { background: var(--bg-on); box-shadow: var(--shadow); + border-color: transparent; } .thumb { - width: 22px; - height: 22px; + width: 23px; + height: 23px; background: var(--thumb-off); border-radius: 50%; display: block; transform: translateX(0); - transition: transform 220ms cubic-bezier(.2,.9,.2,1), box-shadow 220ms ease; - box-shadow: 0 4px 10px rgba(16,24,40,0.12); + transition: transform 260ms var(--curve), background 240ms ease, + padding 260ms ease, margin 260ms ease, box-shadow 240ms ease; + box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12); +} + +/* Rebote estilo iOS */ +.toggle:active .thumb { + padding-right: 4px; +} + +.on:active .thumb { + margin-left: -4px; } .on .thumb { background: var(--thumb-on); - transform: translateX(38px); + transform: translateX(36px); box-shadow: 0 6px 16px rgba(91, 90, 255, 0.18); } .label { -position: absolute; -right: 10px; -top: 8px; - font-family: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial; + position: absolute; + right: 10px; + top: 8px; font-size: 14px; font-weight: 600; color: #0f172a; letter-spacing: 0.2px; + transition: color 240ms ease, right 260ms var(--curve); } .on .label { - right: 45%; + right: 45%; color: #fff; - text-shadow: 0 1px 0 rgba(0,0,0,0.12); + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.12); } -/* Focus visible for accessibility */ .toggle:focus-visible .track { - box-shadow: 0 0 0 4px rgba(99,102,241,0.12); + box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.12); } -/* Small responsive tweak */ @media (max-width: 420px) { - .track { width: 52px; height: 30px; } - .thumb { width: 20px; height: 20px; } - .on .thumb { transform: translateX(24px); } - .label { font-size: 13px; } + .track { + width: 52px; + height: 30px; + } + .thumb { + width: 22px; + height: 22px; + } + .on .thumb { + transform: translateX(24px); + } + .label { + font-size: 13px; + } } diff --git a/src/components/ToggleButton.tsx b/src/components/Toggle/ToggleButton.tsx similarity index 54% rename from src/components/ToggleButton.tsx rename to src/components/Toggle/ToggleButton.tsx index 49a2b30..f32a6de 100644 --- a/src/components/ToggleButton.tsx +++ b/src/components/Toggle/ToggleButton.tsx @@ -1,8 +1,8 @@ // ToggleButton.tsx // Usa este archivo como `ToggleButton.tsx` -import React, { useState } from 'react'; -import styles from './ToggleButton.module.scss'; +import React, { useState } from "react"; +import styles from "./ToggleButton.module.scss"; export type ToggleButtonProps = { /** estado inicial: true -> presionado ("desuso") */ @@ -19,9 +19,9 @@ export type ToggleButtonProps = { const ToggleButton: React.FC = ({ defaultOn = false, onChange, - offLabel = 'Uso', - onLabel = 'Baja', - className = '', + offLabel = "Uso", + onLabel = "Baja", + className = "", }) => { const [on, setOn] = useState(defaultOn); @@ -32,19 +32,20 @@ const ToggleButton: React.FC = ({ } return ( - +
+ +
); };