feat: Add Consulta_API page and routing, implement API request functionality

- Introduced a new page for API consultation (`Consulta_API`) with a form to send requests.
- Added routing for the new page and a 404 error page.
- Created a `MetodoSelect` component for selecting HTTP methods.
- Implemented a `MiBoton` component for a customizable button.
- Updated the `HomePage` layout to include a sidebar (`DoubleNavbar`) and main content area.
- Enhanced the `Welcome` component with a new greeting and description.
- Added a holographic shader background to the 404 error page.
- Updated dependencies in `yarn.lock` for new components and features.
- Styled the sidebar and main content for better user experience.
This commit is contained in:
2025-05-06 00:12:54 +02:00
parent 613cd90662
commit 27f71a05f3
14 changed files with 1012 additions and 25 deletions
+139
View File
@@ -0,0 +1,139 @@
import { useState } from 'react';
import {
TextInput,
Textarea,
Button,
Box,
Center,
Stack,
Badge,
Group,
} from '@mantine/core';
import { DoubleNavbar } from '../components/DoubleNavbar';
import { MetodoSelect } from '../components/MetodoSelect'; // 👈 Importación del nuevo componente
import { useEffect } from 'react';
export function Consulta_API() {
const [direccion, setDireccion] = useState('http://localhost:8000/api/saludo');
const [metodo, setMetodo] = useState('GET');
const [contenido, setContenido] = useState('');
const [respuesta, setRespuesta] = useState('');
const [codigoRespuesta, setCodigoRespuesta] = useState<number | null>(null);
const colorCodigo = (status: number): string => {
if (status >= 200 && status < 300) return 'green';
if (status >= 300 && status < 400) return 'yellow';
if (status >= 400 && status < 500) return 'orange';
return 'red';
};
const llamarAPI = async () => {
try {
const options: RequestInit = {
method: metodo,
mode: 'cors',
headers: {},
};
if (metodo !== 'GET') {
options.headers = {
'Content-Type': 'application/json',
};
try {
JSON.parse(contenido);
options.body = contenido;
} catch (err) {
setRespuesta('Error: El contenido no es un JSON válido');
setCodigoRespuesta(null);
return;
}
}
const res = await fetch(direccion, options);
setCodigoRespuesta(res.status);
const contentType = res.headers.get('content-type');
if (contentType?.includes('application/json')) {
const data = await res.json();
const formatted = JSON.stringify(data, null, 2);
setRespuesta(formatted);
} else {
const text = await res.text();
setRespuesta(text);
}
} catch (error: any) {
console.error('Error en la API:', error);
setRespuesta(`Error: ${error.message || error}`);
setCodigoRespuesta(null);
}
};
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.ctrlKey && e.key === 'Enter') {
e.preventDefault();
llamarAPI();
}
};
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
}, [metodo, direccion, contenido]);
return (
<Box style={{ display: 'flex', height: '100vh' }}>
<DoubleNavbar />
<Box style={{ flex: 1, padding: 40 }}>
<Center style={{ height: '100%' }}>
<Stack style={{ width: 600 }}>
<TextInput
label="Dirección"
placeholder="http://localhost:8000/api/..."
value={direccion}
onChange={(e) => setDireccion(e.currentTarget.value)}
/>
<MetodoSelect metodo={metodo} setMetodo={setMetodo} />
<Textarea
label="Contenido (JSON)"
placeholder='{"contenido": "Hola"}'
value={contenido}
onChange={(e) => setContenido(e.currentTarget.value)}
autosize
minRows={3}
/>
<Button onClick={llamarAPI} color="blue">
Enviar solicitud
</Button>
{codigoRespuesta !== null && (
<Group>
<Badge color={colorCodigo(codigoRespuesta)} size="lg">
Código: {codigoRespuesta}
</Badge>
</Group>
)}
<Textarea
label="Respuesta de la API"
value={respuesta}
readOnly
autosize
minRows={6}
/>
</Stack>
</Center>
</Box>
</Box>
);
}