@zauru-sdk/components 2.0.96 → 2.0.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/Layouts/errorLayout/index.d.ts +3 -2
- package/dist/NavBar/NavBar.types.d.ts +6 -12
- package/dist/esm/Layouts/errorLayout/index.js +14 -10
- package/dist/esm/NavBar/NavBar.js +16 -7
- package/dist/esm/Table/ZauruTable.js +0 -1
- package/package.json +4 -4
- package/src/Layouts/errorLayout/index.tsx +58 -53
- package/src/NavBar/NavBar.tsx +63 -45
- package/src/NavBar/NavBar.types.ts +6 -13
- package/src/NavBar/index.tsx +0 -2
- package/src/Table/ZauruTable.tsx +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.98](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.97...v2.0.98) (2025-01-07)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @zauru-sdk/components
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [2.0.97](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.96...v2.0.97) (2025-01-07)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @zauru-sdk/components
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [2.0.96](https://github.com/intuitiva/zauru-typescript-sdk/compare/v2.0.95...v2.0.96) (2025-01-03)
|
|
7
23
|
|
|
8
24
|
**Note:** Version bump only for package @zauru-sdk/components
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export declare const ErrorLayout: ({ from, error: parentError, }: {
|
|
1
|
+
export declare const ErrorLayout: ({ from, isRootLevel, error: parentError, }: {
|
|
2
2
|
from?: string;
|
|
3
|
+
isRootLevel?: boolean;
|
|
3
4
|
error?: Error;
|
|
4
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type NavBarItem = {
|
|
2
2
|
name: string;
|
|
3
3
|
link: string;
|
|
4
4
|
loggedIn: boolean;
|
|
5
5
|
icon?: any;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
selectedColor?: "green";
|
|
7
|
+
color?: ColorInterface;
|
|
8
|
+
childrens?: Exclude<NavBarItem, "loggedIn">[];
|
|
9
|
+
reduxNotificationBadge?: (state: any) => string | number;
|
|
8
10
|
};
|
|
9
11
|
export type NavBarProps = {
|
|
10
12
|
title: string;
|
|
11
13
|
loggedIn: boolean;
|
|
12
|
-
items: Array<
|
|
14
|
+
items: Array<NavBarItem>;
|
|
13
15
|
selectedColor: "pink" | "purple" | "slate" | "green" | "yellow" | "red" | "sky";
|
|
14
16
|
LinkComponent?: any;
|
|
15
17
|
version?: string;
|
|
@@ -26,14 +28,6 @@ export type ColorInterface = {
|
|
|
26
28
|
ring600: string;
|
|
27
29
|
ring500: string;
|
|
28
30
|
};
|
|
29
|
-
export type NavItemProps = {
|
|
30
|
-
name: string;
|
|
31
|
-
link: string;
|
|
32
|
-
icon?: any;
|
|
33
|
-
color: ColorInterface;
|
|
34
|
-
specialColor?: ColorInterface;
|
|
35
|
-
childrens?: Exclude<NavItemProps, "index" | "color">[];
|
|
36
|
-
};
|
|
37
31
|
export type EntityNameType = {
|
|
38
32
|
entityName: string;
|
|
39
33
|
};
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { isRouteErrorResponse, Links, Meta, Scripts, useRouteError, Link, } from "@remix-run/react";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
export const ErrorLayout = ({ from, error: parentError, }) => {
|
|
4
|
+
export const ErrorLayout = ({ from, isRootLevel = true, error: parentError, }) => {
|
|
5
5
|
try {
|
|
6
6
|
const error = useRouteError();
|
|
7
7
|
const [showDetails, setShowDetails] = useState(!!parentError);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
const baseError = (_jsxs("div", { className: "min-h-screen flex flex-col items-center justify-center p-4", children: [_jsx("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), _jsx("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Ups!" }), _jsxs("div", { className: "w-full max-w-2xl flex flex-col items-center", children: [_jsx("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: isRouteErrorResponse(error)
|
|
9
|
+
? `Error ${error.status}: ${error.statusText}`
|
|
10
|
+
: error instanceof Error
|
|
11
|
+
? error.message
|
|
12
|
+
: "Ha ocurrido un error inesperado" }), from && (_jsxs("p", { className: "text-lg text-gray-400 mb-4 text-center", children: ["Error lanzado desde: ", from] })), parentError && (_jsxs("div", { className: "mb-4 text-center", children: [_jsx("button", { onClick: () => setShowDetails(!showDetails), className: "text-blue-400 hover:text-blue-300 transition duration-300", children: showDetails ? "Ocultar detalles" : "Ver más detalles" }), showDetails && (_jsx("p", { className: "mt-2 text-gray-400 text-sm", children: parentError instanceof Error
|
|
13
|
+
? parentError.message
|
|
14
|
+
: String(parentError) }))] }))] }), _jsx(Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), _jsx("div", { className: "mt-12 text-gray-500 text-center", children: _jsx("p", { children: "Si el problema persiste, por favor contacta a soporte." }) })] }));
|
|
15
|
+
if (!isRootLevel) {
|
|
16
|
+
return baseError;
|
|
17
|
+
}
|
|
18
|
+
return (_jsxs("html", { lang: "es", className: "bg-gray-900 text-white", children: [_jsxs("head", { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: "\u00A1Ups! Algo sali\u00F3 mal *" }), _jsx(Meta, {}), _jsx(Links, {})] }), _jsxs("body", { className: "min-h-screen flex flex-col items-center justify-center p-4", children: [baseError, _jsx(Scripts, {})] })] }));
|
|
15
19
|
}
|
|
16
20
|
catch (error) {
|
|
17
|
-
console.error(error);
|
|
18
|
-
return
|
|
21
|
+
console.error("Error en el layout de error:", error);
|
|
22
|
+
return null;
|
|
19
23
|
}
|
|
20
24
|
};
|
|
@@ -3,11 +3,23 @@ import React, { useState, useEffect } from "react";
|
|
|
3
3
|
import { DropDownArrowSvgIcon, LogoutDropDownSvgIcon, MenuAlt4Svg, OpcionButtonSvgIcon, } from "@zauru-sdk/icons";
|
|
4
4
|
import { COLORS } from "./NavBar.utils.js";
|
|
5
5
|
import { Link, useNavigate } from "@remix-run/react";
|
|
6
|
+
import { useAppSelector } from "@zauru-sdk/redux";
|
|
6
7
|
const OptionsDropDownButton = ({ color, options, name }) => {
|
|
7
8
|
const [showOptionsMenu, setShowOptionsMenu] = useState(true);
|
|
8
9
|
return (_jsx("div", { className: "nav-item ml-auto", children: _jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "relative inline-block", children: [_jsxs("button", { onClick: () => setShowOptionsMenu(!showOptionsMenu), className: `relative flex items-center p-2 text-xs text-white ${color.bg700} active:${color.bg900} border border-transparent rounded-full uppercase focus:ring-opacity-40 focus:outline-none`, children: [name ?? _jsx(OpcionButtonSvgIcon, {}), _jsx(DropDownArrowSvgIcon, {})] }), _jsx("div", { className: "absolute right-0 z-20 w-56 py-2 mt-2 overflow-hidden bg-white rounded-md shadow-xl dark:bg-gray-800", hidden: showOptionsMenu, onMouseLeave: () => setShowOptionsMenu(true), children: options.map((option, index) => (_jsx(React.Fragment, { children: option }, index))) })] }) }) }));
|
|
9
10
|
};
|
|
10
|
-
const NavItem = ({ name, link, icon,
|
|
11
|
+
const NavItem = ({ name, link, icon, selectedColor, childrens = [], reduxNotificationBadge, }) => {
|
|
12
|
+
const specialColor = selectedColor
|
|
13
|
+
? COLORS[selectedColor]
|
|
14
|
+
: COLORS["slate"];
|
|
15
|
+
// Selecciona solo la parte del estado relevante
|
|
16
|
+
const relevantState = useAppSelector((state) => reduxNotificationBadge ? reduxNotificationBadge(state) : undefined);
|
|
17
|
+
const [notificationBadge, setNotificationBadge] = useState();
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
setNotificationBadge(relevantState);
|
|
20
|
+
}, [relevantState]);
|
|
21
|
+
return (_jsx("li", { className: "nav-item relative", children: childrens.length > 0 ? (_jsx(OptionsDropDownButton, { name: name, color: specialColor, options: childrens.map((x, index) => (_jsx(Link, { to: x.link, className: `block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`, children: x.name }, index))) })) : (_jsx("div", { className: `${specialColor.bg700} container text-white w-full sm:w-auto h-10 text-sm py-1 uppercase shadow hover:shadow-lg outline-none rounded-full focus:outline-none my-auto sm:my-0 sm:mr-1 mb-1 ease-linear transition-all duration-150`, children: _jsxs(Link, { className: "px-3 flex items-center text-xs leading-snug text-white uppercase hover:opacity-75 relative", to: link, children: [_jsxs("div", { className: "mx-auto pt-2", children: [icon, _jsx("span", { children: name })] }), notificationBadge !== undefined && (_jsx("span", { className: "absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center w-5 h-5", children: notificationBadge }))] }) })) }));
|
|
22
|
+
};
|
|
11
23
|
export const NavBar = ({ title, loggedIn, items, selectedColor, version, }) => {
|
|
12
24
|
const color = COLORS[selectedColor];
|
|
13
25
|
const [NavBarOpen, setNavBarOpen] = useState(false);
|
|
@@ -22,15 +34,12 @@ export const NavBar = ({ title, loggedIn, items, selectedColor, version, }) => {
|
|
|
22
34
|
navigate(0);
|
|
23
35
|
};
|
|
24
36
|
const renderNavItems = (items) => (_jsx("div", { className: "flex flex-col lg:flex-row w-full", children: items.map((item, index) => {
|
|
25
|
-
|
|
26
|
-
? COLORS[item.color]
|
|
27
|
-
: undefined;
|
|
28
|
-
return (_jsx(NavItem, { name: item.name, link: item.link, icon: item.icon, specialColor: specialColor, color: color, childrens: item.childrens?.map((x) => {
|
|
37
|
+
return (_jsx(NavItem, { name: item.name, link: item.link, icon: item.icon, selectedColor: item.selectedColor, color: color, loggedIn: item.loggedIn, reduxNotificationBadge: item.reduxNotificationBadge, childrens: item.childrens?.map((x) => {
|
|
29
38
|
return { ...x };
|
|
30
39
|
}) }, index));
|
|
31
40
|
}) }));
|
|
32
41
|
const options = (_jsxs(_Fragment, { children: [_jsx("ul", { className: "w-full lg:flex lg:items-center", children: renderNavItems(items.filter((item) => item.loggedIn === loggedIn)) }), _jsx("ul", { className: "sm:flex sm:flex-col lg:flex-row ml-auto", children: loggedIn && (_jsx(OptionsDropDownButton, { color: color, options: [
|
|
33
|
-
_jsx(Link, { className: `block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`, to: "/logout",
|
|
42
|
+
_jsx(Link, { className: `block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`, to: "/logout", children: _jsxs("div", { className: "mx-auto pt-2", children: [_jsx(LogoutDropDownSvgIcon, {}), _jsx("span", { children: "Cerrar sesi\u00F3n" })] }) }),
|
|
34
43
|
] })) })] }));
|
|
35
|
-
return (_jsx("nav", { className: `py-3 ${color.bg600}`, children: _jsxs("div", { className: "flex items-center justify-between ml-5 mr-5", children: [_jsxs("div", { className: "flex justify-between items-center w-full lg:w-auto", children: [_jsx(Link, { className: "text-sm font-bold leading-relaxed inline-block mr-4 py-2 whitespace-nowrap uppercase text-white", to: "/home",
|
|
44
|
+
return (_jsx("nav", { className: `py-3 ${color.bg600}`, children: _jsxs("div", { className: "flex items-center justify-between ml-5 mr-5", children: [_jsxs("div", { className: "flex justify-between items-center w-full lg:w-auto", children: [_jsx(Link, { className: "text-sm font-bold leading-relaxed inline-block mr-4 py-2 whitespace-nowrap uppercase text-white", to: "/home", children: _jsxs(_Fragment, { children: [_jsx("div", { className: "inline-block mr-2 mb-2 align-middle", children: _jsx("img", { className: "w-auto h-7", src: "/logo.png", alt: "logo-zauru" }) }), title] }) }), version !== currentVersion && (_jsx("button", { className: `ml-2 px-2 py-1 text-xs text-white ${color.bg700} rounded-full hover:${color.bg900} transition-colors duration-200`, onClick: refreshPage, children: "\uD83D\uDD04 Actualizar versi\u00F3n" })), _jsx("button", { className: `rounded lg:hidden focus:outline-none focus:ring focus:${color.ring600} focus:ring-opacity-50`, "aria-label": "Toggle mobile menu", type: "button", onClick: () => setNavBarOpen(!NavBarOpen), children: _jsx(MenuAlt4Svg, { open: NavBarOpen }) })] }), _jsx("div", { className: `lg:hidden fixed top-0 left-0 z-50 w-64 h-full ${color.bg700} dark:bg-gray-900 shadow-lg transform ${NavBarOpen ? "translate-x-0" : "-translate-x-full"} transition-transform duration-300 ease-in-out overflow-y-auto`, children: _jsx("div", { className: "p-4", children: options }) }), _jsx("div", { className: "hidden lg:flex lg:items-center w-full lg:w-auto", children: options })] }) }));
|
|
36
45
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zauru-sdk/components",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.98",
|
|
4
4
|
"description": "Componentes reutilizables en las WebApps de Zauru.",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"@reduxjs/toolkit": "^2.2.1",
|
|
35
35
|
"@remix-run/react": "^2.8.1",
|
|
36
36
|
"@zauru-sdk/common": "^2.0.94",
|
|
37
|
-
"@zauru-sdk/hooks": "^2.0.
|
|
38
|
-
"@zauru-sdk/icons": "^2.0.
|
|
37
|
+
"@zauru-sdk/hooks": "^2.0.98",
|
|
38
|
+
"@zauru-sdk/icons": "^2.0.98",
|
|
39
39
|
"@zauru-sdk/types": "^2.0.92",
|
|
40
40
|
"@zauru-sdk/utils": "^2.0.96",
|
|
41
41
|
"framer-motion": "^11.7.0",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"styled-components": "^5.3.5",
|
|
50
50
|
"zod": "^3.23.8"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "d11348b60330f33f29cffbdfa4399bba8bb59c97"
|
|
53
53
|
}
|
|
@@ -10,80 +10,85 @@ import { useState } from "react";
|
|
|
10
10
|
|
|
11
11
|
export const ErrorLayout = ({
|
|
12
12
|
from,
|
|
13
|
+
isRootLevel = true,
|
|
13
14
|
error: parentError,
|
|
14
15
|
}: {
|
|
15
16
|
from?: string;
|
|
17
|
+
isRootLevel?: boolean;
|
|
16
18
|
error?: Error;
|
|
17
19
|
}) => {
|
|
18
20
|
try {
|
|
19
21
|
const error = useRouteError();
|
|
20
22
|
const [showDetails, setShowDetails] = useState(!!parentError);
|
|
21
23
|
|
|
24
|
+
const baseError = (
|
|
25
|
+
<div className="min-h-screen flex flex-col items-center justify-center p-4">
|
|
26
|
+
<img src="/logo.png" alt="Zauru Logo" className="mb-8 h-20" />
|
|
27
|
+
<h1 className="text-5xl font-extrabold text-red-500 mb-6">¡Ups!</h1>
|
|
28
|
+
<div className="w-full max-w-2xl flex flex-col items-center">
|
|
29
|
+
<p className="text-2xl text-gray-300 mb-8 text-center">
|
|
30
|
+
{isRouteErrorResponse(error)
|
|
31
|
+
? `Error ${error.status}: ${error.statusText}`
|
|
32
|
+
: error instanceof Error
|
|
33
|
+
? error.message
|
|
34
|
+
: "Ha ocurrido un error inesperado"}
|
|
35
|
+
</p>
|
|
36
|
+
{from && (
|
|
37
|
+
<p className="text-lg text-gray-400 mb-4 text-center">
|
|
38
|
+
Error lanzado desde: {from}
|
|
39
|
+
</p>
|
|
40
|
+
)}
|
|
41
|
+
{parentError && (
|
|
42
|
+
<div className="mb-4 text-center">
|
|
43
|
+
<button
|
|
44
|
+
onClick={() => setShowDetails(!showDetails)}
|
|
45
|
+
className="text-blue-400 hover:text-blue-300 transition duration-300"
|
|
46
|
+
>
|
|
47
|
+
{showDetails ? "Ocultar detalles" : "Ver más detalles"}
|
|
48
|
+
</button>
|
|
49
|
+
{showDetails && (
|
|
50
|
+
<p className="mt-2 text-gray-400 text-sm">
|
|
51
|
+
{parentError instanceof Error
|
|
52
|
+
? parentError.message
|
|
53
|
+
: String(parentError)}
|
|
54
|
+
</p>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
<Link
|
|
60
|
+
to="/"
|
|
61
|
+
className="bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105"
|
|
62
|
+
>
|
|
63
|
+
Regresar al inicio
|
|
64
|
+
</Link>
|
|
65
|
+
<div className="mt-12 text-gray-500 text-center">
|
|
66
|
+
<p>Si el problema persiste, por favor contacta a soporte.</p>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!isRootLevel) {
|
|
72
|
+
return baseError;
|
|
73
|
+
}
|
|
74
|
+
|
|
22
75
|
return (
|
|
23
76
|
<html lang="es" className="bg-gray-900 text-white">
|
|
24
77
|
<head>
|
|
25
78
|
<meta charSet="utf-8" />
|
|
26
79
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
27
|
-
<title>¡Ups! Algo salió mal
|
|
80
|
+
<title>¡Ups! Algo salió mal *</title>
|
|
28
81
|
<Meta />
|
|
29
82
|
<Links />
|
|
30
83
|
</head>
|
|
31
84
|
<body className="min-h-screen flex flex-col items-center justify-center p-4">
|
|
32
|
-
|
|
33
|
-
<h1 className="text-5xl font-extrabold text-red-500 mb-6">¡Ups!</h1>
|
|
34
|
-
<div className="w-full max-w-2xl flex flex-col items-center">
|
|
35
|
-
<p className="text-2xl text-gray-300 mb-8 text-center">
|
|
36
|
-
{isRouteErrorResponse(error)
|
|
37
|
-
? `Error ${error.status}: ${error.statusText}`
|
|
38
|
-
: error instanceof Error
|
|
39
|
-
? error.message
|
|
40
|
-
: "Ha ocurrido un error inesperado"}
|
|
41
|
-
</p>
|
|
42
|
-
{from && (
|
|
43
|
-
<p className="text-lg text-gray-400 mb-4 text-center">
|
|
44
|
-
Error lanzado desde: {from}
|
|
45
|
-
</p>
|
|
46
|
-
)}
|
|
47
|
-
{parentError && (
|
|
48
|
-
<div className="mb-4 text-center">
|
|
49
|
-
<button
|
|
50
|
-
onClick={() => setShowDetails(!showDetails)}
|
|
51
|
-
className="text-blue-400 hover:text-blue-300 transition duration-300"
|
|
52
|
-
>
|
|
53
|
-
{showDetails ? "Ocultar detalles" : "Ver más detalles"}
|
|
54
|
-
</button>
|
|
55
|
-
{showDetails && (
|
|
56
|
-
<p className="mt-2 text-gray-400 text-sm">
|
|
57
|
-
{parentError instanceof Error
|
|
58
|
-
? parentError.message
|
|
59
|
-
: String(parentError)}
|
|
60
|
-
</p>
|
|
61
|
-
)}
|
|
62
|
-
</div>
|
|
63
|
-
)}
|
|
64
|
-
</div>
|
|
65
|
-
<Link
|
|
66
|
-
to="/"
|
|
67
|
-
className="bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105"
|
|
68
|
-
>
|
|
69
|
-
Regresar al inicio
|
|
70
|
-
</Link>
|
|
71
|
-
<div className="mt-12 text-gray-500 text-center">
|
|
72
|
-
<p>Si el problema persiste, por favor contacta a soporte.</p>
|
|
73
|
-
</div>
|
|
85
|
+
{baseError}
|
|
74
86
|
<Scripts />
|
|
75
87
|
</body>
|
|
76
88
|
</html>
|
|
77
89
|
);
|
|
78
|
-
} catch (error
|
|
79
|
-
console.error(error);
|
|
80
|
-
return
|
|
81
|
-
<html lang="es" className="bg-gray-900 text-white">
|
|
82
|
-
<head>
|
|
83
|
-
<title>¡Ups! Algo salió mal</title>
|
|
84
|
-
</head>
|
|
85
|
-
<body>Error al renderizar el layout de error {error}</body>
|
|
86
|
-
</html>
|
|
87
|
-
);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error("Error en el layout de error:", error);
|
|
92
|
+
return null;
|
|
88
93
|
}
|
|
89
94
|
};
|
package/src/NavBar/NavBar.tsx
CHANGED
|
@@ -9,11 +9,11 @@ import { COLORS } from "./NavBar.utils.js";
|
|
|
9
9
|
import type {
|
|
10
10
|
ColorInterface,
|
|
11
11
|
EntityProps,
|
|
12
|
-
|
|
12
|
+
NavBarItem,
|
|
13
13
|
NavBarProps,
|
|
14
|
-
NavItemProps,
|
|
15
14
|
} from "./NavBar.types.js";
|
|
16
15
|
import { Link, useNavigate } from "@remix-run/react";
|
|
16
|
+
import { useAppSelector } from "@zauru-sdk/redux";
|
|
17
17
|
|
|
18
18
|
const OptionsDropDownButton = ({ color, options, name }: EntityProps) => {
|
|
19
19
|
const [showOptionsMenu, setShowOptionsMenu] = useState(true);
|
|
@@ -48,46 +48,67 @@ const NavItem = ({
|
|
|
48
48
|
name,
|
|
49
49
|
link,
|
|
50
50
|
icon,
|
|
51
|
-
|
|
52
|
-
specialColor,
|
|
51
|
+
selectedColor,
|
|
53
52
|
childrens = [],
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
reduxNotificationBadge,
|
|
54
|
+
}: NavBarItem) => {
|
|
55
|
+
const specialColor: ColorInterface = selectedColor
|
|
56
|
+
? COLORS[selectedColor]
|
|
57
|
+
: COLORS["slate"];
|
|
58
|
+
|
|
59
|
+
// Selecciona solo la parte del estado relevante
|
|
60
|
+
const relevantState = useAppSelector((state) =>
|
|
61
|
+
reduxNotificationBadge ? reduxNotificationBadge(state) : undefined
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const [notificationBadge, setNotificationBadge] = useState<
|
|
65
|
+
undefined | string | number
|
|
66
|
+
>();
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
setNotificationBadge(relevantState);
|
|
70
|
+
}, [relevantState]);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<li className="nav-item relative">
|
|
74
|
+
{childrens.length > 0 ? (
|
|
75
|
+
<OptionsDropDownButton
|
|
76
|
+
name={name}
|
|
77
|
+
color={specialColor}
|
|
78
|
+
options={childrens.map((x, index) => (
|
|
79
|
+
<Link
|
|
80
|
+
key={index}
|
|
81
|
+
to={x.link}
|
|
82
|
+
className={`block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`}
|
|
83
|
+
>
|
|
84
|
+
{x.name}
|
|
85
|
+
</Link>
|
|
86
|
+
))}
|
|
87
|
+
/>
|
|
88
|
+
) : (
|
|
89
|
+
<div
|
|
90
|
+
className={`${specialColor.bg700} container text-white w-full sm:w-auto h-10 text-sm py-1 uppercase shadow hover:shadow-lg outline-none rounded-full focus:outline-none my-auto sm:my-0 sm:mr-1 mb-1 ease-linear transition-all duration-150`}
|
|
91
|
+
>
|
|
62
92
|
<Link
|
|
63
|
-
|
|
64
|
-
to={
|
|
65
|
-
className={`block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`}
|
|
93
|
+
className="px-3 flex items-center text-xs leading-snug text-white uppercase hover:opacity-75 relative"
|
|
94
|
+
to={link}
|
|
66
95
|
>
|
|
67
|
-
|
|
96
|
+
<div className="mx-auto pt-2">
|
|
97
|
+
{icon}
|
|
98
|
+
<span>{name}</span>
|
|
99
|
+
</div>
|
|
100
|
+
{/* Badge de notificaciones */}
|
|
101
|
+
{notificationBadge !== undefined && (
|
|
102
|
+
<span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center w-5 h-5">
|
|
103
|
+
{notificationBadge}
|
|
104
|
+
</span>
|
|
105
|
+
)}
|
|
68
106
|
</Link>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
specialColor ? specialColor.bg700 : color.bg700
|
|
75
|
-
} container text-white w-full sm:w-auto h-10 text-sm py-1 uppercase shadow hover:shadow-lg outline-none rounded-full focus:outline-none my-auto sm:my-0 sm:mr-1 mb-1 ease-linear transition-all duration-150`}
|
|
76
|
-
>
|
|
77
|
-
<Link
|
|
78
|
-
className="px-3 flex items-center text-xs leading-snug text-white uppercase hover:opacity-75"
|
|
79
|
-
to={link}
|
|
80
|
-
prefetch="none"
|
|
81
|
-
>
|
|
82
|
-
<div className="mx-auto pt-2">
|
|
83
|
-
{icon}
|
|
84
|
-
<span>{name}</span>
|
|
85
|
-
</div>
|
|
86
|
-
</Link>
|
|
87
|
-
</div>
|
|
88
|
-
)}
|
|
89
|
-
</li>
|
|
90
|
-
);
|
|
107
|
+
</div>
|
|
108
|
+
)}
|
|
109
|
+
</li>
|
|
110
|
+
);
|
|
111
|
+
};
|
|
91
112
|
|
|
92
113
|
export const NavBar = ({
|
|
93
114
|
title,
|
|
@@ -111,20 +132,19 @@ export const NavBar = ({
|
|
|
111
132
|
navigate(0);
|
|
112
133
|
};
|
|
113
134
|
|
|
114
|
-
const renderNavItems = (items:
|
|
135
|
+
const renderNavItems = (items: NavBarItem[]) => (
|
|
115
136
|
<div className="flex flex-col lg:flex-row w-full">
|
|
116
137
|
{items.map((item, index) => {
|
|
117
|
-
const specialColor: ColorInterface | undefined = item.color
|
|
118
|
-
? COLORS[item.color]
|
|
119
|
-
: undefined;
|
|
120
138
|
return (
|
|
121
139
|
<NavItem
|
|
122
140
|
key={index}
|
|
123
141
|
name={item.name}
|
|
124
142
|
link={item.link}
|
|
125
143
|
icon={item.icon}
|
|
126
|
-
|
|
144
|
+
selectedColor={item.selectedColor}
|
|
127
145
|
color={color}
|
|
146
|
+
loggedIn={item.loggedIn}
|
|
147
|
+
reduxNotificationBadge={item.reduxNotificationBadge}
|
|
128
148
|
childrens={item.childrens?.map((x) => {
|
|
129
149
|
return { ...x } as any;
|
|
130
150
|
})}
|
|
@@ -147,7 +167,6 @@ export const NavBar = ({
|
|
|
147
167
|
<Link
|
|
148
168
|
className={`block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`}
|
|
149
169
|
to="/logout"
|
|
150
|
-
prefetch="none"
|
|
151
170
|
>
|
|
152
171
|
<div className="mx-auto pt-2">
|
|
153
172
|
{<LogoutDropDownSvgIcon />}
|
|
@@ -168,7 +187,6 @@ export const NavBar = ({
|
|
|
168
187
|
<Link
|
|
169
188
|
className="text-sm font-bold leading-relaxed inline-block mr-4 py-2 whitespace-nowrap uppercase text-white"
|
|
170
189
|
to={"/home"}
|
|
171
|
-
prefetch="none"
|
|
172
190
|
children={
|
|
173
191
|
<>
|
|
174
192
|
<div className="inline-block mr-2 mb-2 align-middle">
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type NavBarItem = {
|
|
2
2
|
name: string;
|
|
3
3
|
link: string;
|
|
4
4
|
loggedIn: boolean;
|
|
5
5
|
icon?: any;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
selectedColor?: "green";
|
|
7
|
+
color?: ColorInterface;
|
|
8
|
+
childrens?: Exclude<NavBarItem, "loggedIn">[];
|
|
9
|
+
reduxNotificationBadge?: (state: any) => string | number;
|
|
8
10
|
};
|
|
9
11
|
|
|
10
12
|
export type NavBarProps = {
|
|
11
13
|
title: string;
|
|
12
14
|
loggedIn: boolean;
|
|
13
|
-
items: Array<
|
|
15
|
+
items: Array<NavBarItem>;
|
|
14
16
|
selectedColor:
|
|
15
17
|
| "pink"
|
|
16
18
|
| "purple"
|
|
@@ -37,15 +39,6 @@ export type ColorInterface = {
|
|
|
37
39
|
ring500: string;
|
|
38
40
|
};
|
|
39
41
|
|
|
40
|
-
export type NavItemProps = {
|
|
41
|
-
name: string;
|
|
42
|
-
link: string;
|
|
43
|
-
icon?: any;
|
|
44
|
-
color: ColorInterface;
|
|
45
|
-
specialColor?: ColorInterface;
|
|
46
|
-
childrens?: Exclude<NavItemProps, "index" | "color">[];
|
|
47
|
-
};
|
|
48
|
-
|
|
49
42
|
export type EntityNameType = {
|
|
50
43
|
entityName: string;
|
|
51
44
|
};
|
package/src/NavBar/index.tsx
CHANGED