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
- )}
-
);
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 ? (
-
);