From f4d46080a67aead33f427d5fc1c79a9559d9938a Mon Sep 17 00:00:00 2001 From: Alexis Date: Thu, 28 May 2026 12:37:07 +0200 Subject: [PATCH] Enhance Login and Register components with new UI elements and improved layout. Added demo visualization in Login and refined registration flow in Register, including error handling and user guidance. --- frontend/src/pages/Login.jsx | 251 +++++++++++++++++++++++++++++--- frontend/src/pages/Register.jsx | 80 ++++++---- 2 files changed, 277 insertions(+), 54 deletions(-) diff --git a/frontend/src/pages/Login.jsx b/frontend/src/pages/Login.jsx index 0afb43b..c91df6a 100644 --- a/frontend/src/pages/Login.jsx +++ b/frontend/src/pages/Login.jsx @@ -3,7 +3,195 @@ import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { useAuth } from '../context/AuthContext'; import { authService } from '../services/authService'; import { API_BASE_URL } from '../config'; -import { FiEye, FiEyeOff } from 'react-icons/fi'; +import { FiArrowLeft, FiEye, FiEyeOff } from 'react-icons/fi'; +import { ComposedChart, Line, XAxis, YAxis, CartesianGrid, ReferenceArea, ReferenceLine, ResponsiveContainer } from 'recharts'; + +const DEMO_TERMS = [ + { name: 'Muy Bajo', xVal: 0.10, mf: { supportStart: 0.00, coreStart: 0.00, coreEnd: 0.10, supportEnd: 0.22 } }, + { name: 'Bajo', xVal: 0.28, mf: { supportStart: 0.12, coreStart: 0.22, coreEnd: 0.33, supportEnd: 0.44 } }, + { name: 'Medio', xVal: 0.50, mf: { supportStart: 0.35, coreStart: 0.44, coreEnd: 0.56, supportEnd: 0.65 } }, + { name: 'Alto', xVal: 0.72, mf: { supportStart: 0.56, coreStart: 0.67, coreEnd: 0.78, supportEnd: 0.88 } }, + { name: 'Muy Alto', xVal: 0.90, mf: { supportStart: 0.78, coreStart: 0.90, coreEnd: 1.00, supportEnd: 1.00 } }, +]; +const DEMO_COLORS = ['#ef4444', '#f59e0b', '#10b981', '#3b82f6', '#d946ef']; + +function FakeDemoPanel() { + const [visibleCount, setVisibleCount] = useState(0); + const [fading, setFading] = useState(false); + + useEffect(() => { + let timeout; + if (visibleCount < DEMO_TERMS.length) { + timeout = setTimeout(() => setVisibleCount(v => v + 1), 1300); + } else { + timeout = setTimeout(() => { + setFading(true); + setTimeout(() => { + setVisibleCount(0); + setFading(false); + }, 500); + }, 2400); + } + return () => clearTimeout(timeout); + }, [visibleCount]); + + const visibleTerms = DEMO_TERMS.slice(0, visibleCount); + const activeIndex = visibleCount - 1; + + return ( +
+ {/* Mini header badge */} +
+ Paso 2 + · + Modelar Conceptos Difusos + + + En vivo + +
+ + {/* Term pills */} +
+ {DEMO_TERMS.map((term, index) => { + const color = DEMO_COLORS[index % DEMO_COLORS.length]; + const isVisible = index < visibleCount; + const isActive = index === activeIndex; + return ( + + {term.name} + + ); + })} +
+ + {/* Chart */} +
+ + + + + + {visibleTerms.map((term, index) => { + const color = DEMO_COLORS[index % DEMO_COLORS.length]; + const isActive = index === activeIndex; + return ( + + ); + })} + {visibleTerms.map((term, index) => { + const color = DEMO_COLORS[index % DEMO_COLORS.length]; + const isActive = index === activeIndex; + return ( + + ); + })} + {visibleTerms.map((term, index) => { + const color = DEMO_COLORS[index % DEMO_COLORS.length]; + const isActive = index === activeIndex; + const trapezeData = [ + { x: term.mf.supportStart, y: 0 }, + { x: term.mf.coreStart, y: 1 }, + { x: term.mf.coreEnd, y: 1 }, + { x: term.mf.supportEnd, y: 0 }, + ]; + return ( + + ); + })} + + +
+ + {/* Terms table */} +
+
+ Términos modelados + {visibleCount} / {DEMO_TERMS.length} +
+
+ {DEMO_TERMS.map((term, index) => { + const isVisible = index < visibleCount; + const isActive = index === activeIndex; + const color = DEMO_COLORS[index % DEMO_COLORS.length]; + return ( +
+ + + {term.name} + + {isVisible && ( + + [{term.mf.coreStart.toFixed(2)}, {term.mf.coreEnd.toFixed(2)}] + + )} + {isActive && ( + + )} +
+ ); + })} +
+
+
+ ); +} export default function Login() { const [email, setEmail] = useState(''); @@ -71,21 +259,37 @@ export default function Login() { }; return ( -
-
- -
-

Deck of Cards

-

Accede a tu historial y gráficas guardadas

+
+
+
+

Deck of Cards

+

Modela y compara de forma visual

+

+ Construye funciones de pertenencia difusa, guarda tu historial y vuelve a trabajar donde lo dejaste. +

+ + + Ir al editor principal + +
- {error && ( -
- {error} +
+
+

Deck of Cards

+

Accede a tu historial y gráficas guardadas

- )} -
+ {error && ( +
+ {error} +
+ )} + +
Entrar - + -
-
-
O
+
+
+
O
+
+ + + +

¿Nuevo por aquí? Crea una cuenta

- - - -

¿Nuevo por aquí? Crea una cuenta

); diff --git a/frontend/src/pages/Register.jsx b/frontend/src/pages/Register.jsx index 02881ff..09174f4 100644 --- a/frontend/src/pages/Register.jsx +++ b/frontend/src/pages/Register.jsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { useNavigate, Link } from 'react-router-dom'; import { useAuth } from '../context/AuthContext'; import { authService } from '../services/authService'; -import { FiEye, FiEyeOff } from 'react-icons/fi'; +import { FiArrowLeft, FiEye, FiEyeOff } from 'react-icons/fi'; export default function Register() { const [username, setUsername] = useState(''); @@ -95,34 +95,51 @@ export default function Register() { }; return ( -
-
- -
-

- {verificationRequired ? 'Verifica tu email' : 'Crear Cuenta'} -

-

- {verificationRequired - ? `Introduce el código enviado a ${pendingEmail}` - : 'Inicia sesión para guardar tu progreso'} +

+
+
+

Deck of Cards

+

+ Crea tu cuenta y guarda cada modelo +

+

+ Registra tus criterios, conserva resultados en el historial y retoma tus análisis cuando quieras.

+ + + Ir al editor principal +
- {error && ( -
- {error} +
+
+

+ {verificationRequired ? 'Verifica tu email' : 'Crear Cuenta'} +

+

+ {verificationRequired + ? `Introduce el código enviado a ${pendingEmail}` + : 'Inicia sesión para guardar tu progreso'} +

- )} - {infoMessage && ( -
- {infoMessage} -
- )} + {error && ( +
+ {error} +
+ )} - {!verificationRequired ? ( -
+ {infoMessage && ( +
+ {infoMessage} +
+ )} + + {!verificationRequired ? ( +
{isSubmitting ? 'Enviando código...' : 'Registrarse'} - - ) : ( -
+
+ ) : ( +
{isResending ? 'Reenviando...' : 'Reenviar código'} - - )} + + )} -

- ¿Ya tienes cuenta? Inicia sesión aquí -

+

+ ¿Ya tienes cuenta? Inicia sesión aquí +

+
);