feat: Implement user management functionality with login and CRUD operations

This commit is contained in:
2025-06-21 01:40:19 +02:00
parent 3438102dc0
commit 3d5deef0fb
10 changed files with 212 additions and 6 deletions
+7
View File
@@ -8,6 +8,7 @@ import { VisualizacionesRandom } from './domains/Experiments/Visualizaciones_Ran
import { Camara_noir } from './domains/CamaraNoir/Camaras_noir';
import EditorTest from "./domains/TextEditor/Editor_Test";
import { ChatPage } from './domains/Llms/Chat/ChatPage';
import { LoginPage } from './domains/Usuarios/Login.page';
const router = createBrowserRouter([
@@ -69,6 +70,12 @@ const router = createBrowserRouter([
},
// Login
{
path: '/login',
element: <LoginPage />,
},
// FitzStudio Pages -------------------------------------------------------
// Error 404
@@ -0,0 +1,65 @@
import { useState } from 'react';
import { TextInput, PasswordInput, Button, Paper, Title, Container, Group, Alert } from '@mantine/core';
import { IconUser, IconLock } from '@tabler/icons-react';
export function LoginPage() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError('');
// Aquí deberías llamar a tu endpoint de login (ajusta la URL y payload)
try {
const res = await fetch('/api/v1/usuarios/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
if (!res.ok) throw new Error('Credenciales incorrectas');
// Aquí puedes guardar el usuario/token en el estado global o localStorage
window.location.href = '/';
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
};
return (
<Container size={420} my={40}>
<Title align="center" mb={20}>Iniciar sesión</Title>
<Paper withBorder shadow="md" p={30} mt={30} radius="md">
<form onSubmit={handleSubmit}>
<TextInput
label="Email"
placeholder="tucorreo@ejemplo.com"
icon={<IconUser size={18} />}
value={email}
onChange={e => setEmail(e.target.value)}
required
mb={10}
/>
<PasswordInput
label="Contraseña"
placeholder="Tu contraseña"
icon={<IconLock size={18} />}
value={password}
onChange={e => setPassword(e.target.value)}
required
mb={20}
/>
{error && <Alert color="red" mb={10}>{error}</Alert>}
<Group mt="md">
<Button type="submit" loading={loading} fullWidth>
Entrar
</Button>
</Group>
</form>
</Paper>
</Container>
);
}