This repository has been archived on 2025-11-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Fitz_Studio/frontend/src/components/DoubleNavbar.tsx
T
egutierrez 27f71a05f3 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.
2025-05-06 00:12:54 +02:00

155 lines
4.5 KiB
TypeScript

import {
IconCalendarStats,
IconDeviceDesktopAnalytics,
IconFingerprint,
IconGauge,
IconHome2,
IconSettings,
IconUser,
IconArrowBarLeft,
IconArrowBarRight,
} from '@tabler/icons-react';
import {
Title,
Tooltip,
UnstyledButton,
ActionIcon,
} from '@mantine/core';
import { Link, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
import classes from './DoubleNavbar.module.css';
const mainLinksdata = [
{ icon: IconHome2, label: 'Home' },
{ icon: IconGauge, label: 'Dashboard' },
{ icon: IconDeviceDesktopAnalytics, label: 'Analytics' },
{ icon: IconCalendarStats, label: 'Releases' },
{ icon: IconUser, label: 'Account' },
{ icon: IconFingerprint, label: 'Security' },
{ icon: IconSettings, label: 'Settings' },
];
const submenuLinks: Record<string, { label: string; to: string }[]> = {
Home: [
{ label: 'Inicio', to: '/' },
{ label: 'Consulta Api', to: '/Consulta_API' },
],
Dashboard: [
{ label: 'Resumen', to: '/dashboard/resumen' },
{ label: 'Estadísticas', to: '/dashboard/estadisticas' },
{ label: 'Usuarios', to: '/dashboard/usuarios' },
],
Analytics: [
{ label: 'Conversiones', to: '/analytics/conversiones' },
{ label: 'Tráfico', to: '/analytics/trafico' },
{ label: 'Tendencias', to: '/analytics/tendencias' },
],
Releases: [
{ label: 'Notas de versión', to: '/releases/notas-de-version' },
{ label: 'Historial', to: '/releases/historial' },
],
Account: [
{ label: 'Perfil', to: '/account/perfil' },
{ label: 'Suscripciones', to: '/account/suscripciones' },
],
Security: [
{ label: 'Contraseña', to: '/security/contraseña' },
{ label: '2FA', to: '/security/2fa' },
],
Settings: [
{ label: 'Preferencias', to: '/settings/preferencias' },
{ label: 'Notificaciones', to: '/settings/notificaciones' },
],
};
export function DoubleNavbar() {
const location = useLocation();
const [collapsed, setCollapsed] = useState(false);
const [manualActiveTab, setManualActiveTab] = useState<string | null>(null);
// Detectar cuál pestaña es activa por la ruta actual
const matchedMain = Object.entries(submenuLinks).find(([mainKey, items]) =>
items.some((item) => location.pathname.startsWith(item.to))
);
const routeBasedActive = matchedMain?.[0] ?? 'Home';
const active = manualActiveTab ?? routeBasedActive;
const activeLink =
submenuLinks[active]?.find((item) => location.pathname === item.to)?.label ?? '';
const mainLinks = mainLinksdata.map((link) => (
<Tooltip
label={link.label}
position="right"
withArrow
transitionProps={{ duration: 0 }}
key={link.label}
>
<UnstyledButton
onClick={() => setManualActiveTab(link.label)}
className={classes.mainLink}
data-active={link.label === active || undefined}
>
<link.icon size={22} stroke={1.5} />
</UnstyledButton>
</Tooltip>
));
const links = (submenuLinks[active] || []).map((item) => (
<Link
className={classes.link}
data-active={activeLink === item.label || undefined}
to={item.to}
key={item.label}
style={{ display: collapsed ? 'none' : 'block' }}
>
{item.label}
</Link>
));
// Resetea pestaña seleccionada si la ruta cambia (opcional)
useEffect(() => {
setManualActiveTab(null);
}, [location.pathname]);
return (
<nav className={`${classes.navbar} ${collapsed ? classes.collapsed : ''}`}>
<div className={classes.wrapper}>
<div className={classes.aside}>
{/* Sección superior: logo + mainLinks */}
<div className={classes.topSection}>
<div className={classes.logo}>
<img
src="/src/favicon.svg"
alt="Logo"
style={{ width: 30, height: 30 }}
/>
</div>
{mainLinks}
</div>
{/* Botón de colapsar separado abajo */}
<ActionIcon
variant="subtle"
onClick={() => setCollapsed((c) => !c)}
className={classes.collapseButton}
size="lg"
>
{collapsed ? <IconArrowBarRight size={20} /> : <IconArrowBarLeft size={20} />}
</ActionIcon>
</div>
<div className={classes.main}>
{!collapsed && (
<Title order={4} className={classes.title}>
{active}
</Title>
)}
{links}
</div>
</div>
</nav>
);
}