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
+47
View File
@@ -0,0 +1,47 @@
import { Box, Title, Text, Button, Group, Stack, Image, Center } from '@mantine/core';
import { IconArrowLeft } from '@tabler/icons-react';
import { Link } from 'react-router-dom';
import { DoubleNavbar } from '../components/DoubleNavbar'; // Ajusta ruta si es necesario
import { MantineCardWithShader } from '../components/HoloShader'; // Ajusta ruta si es necesario
export function Error_404() {
return (
<Box style={{ display: 'flex', height: '100vh' }}>
<DoubleNavbar />
<Box style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '2rem' }}>
<Stack align="center" maw={500} mx="auto">
<MantineCardWithShader />
<Title order={1}>
Página no encontrada
</Title>
<Text size="lg">
Parece que la página que estás buscando no existe o fue removida. Pero no te preocupes, puedes volver al inicio fácilmente.
</Text>
<Group mt="md">
<Button
component={Link}
to="/"
size="md"
variant="gradient"
gradient={{ from: 'blue', to: 'cyan' }}
leftSection={<IconArrowLeft size={18} />}
>
Volver al inicio
</Button>
</Group>
</Stack>
</Box>
</Box>
);
}
+20
View File
@@ -0,0 +1,20 @@
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';
import { Welcome } from '../components/Welcome/Welcome';
import MiBoton from '../components/botoncito';
import { Center, Box } from '@mantine/core';
import { DoubleNavbar } from '../components/DoubleNavbar';
export function Prueba_1() {
return (
<Box style={{ display: 'flex', height: '100vh' }}>
<DoubleNavbar /> {/* Sidebar fijo a la izquierda */}
{/* Contenido principal */}
</Box>
);
}
+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>
);
}
+22 -5
View File
@@ -1,11 +1,28 @@
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';
import { Welcome } from '../components/Welcome/Welcome';
import MiBoton from '../components/botoncito';
import { Center, Box } from '@mantine/core';
import { DoubleNavbar } from '../components/DoubleNavbar';
import { MantineCardWithShader } from '../components/HoloShader';
export function HomePage() {
return (
<>
<Welcome />
<ColorSchemeToggle />
</>
<Box style={{ display: 'flex', height: '100vh' }}>
<DoubleNavbar /> {/* Sidebar fijo a la izquierda */}
{/* Contenido principal */}
<Box style={{ flex: 1, padding: '24px' }}>
<Welcome />
<ColorSchemeToggle />
<Center mt="md">
<MiBoton />
</Center>
</Box>
</Box>
);
}
}