diff --git a/.vscode/settings.json b/.vscode/settings.json index 6f63eef..e4a1751 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,31 @@ "editor.defaultFormatter": "dbaeumer.vscode-eslint", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.addMissingImports": true, - "source.fixAll.eslint": true - } + "source.addMissingImports": "explicit", + "source.fixAll.eslint": "explicit" + }, + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#0894ba", + "activityBar.background": "#0894ba", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#99077a", + "activityBarBadge.foreground": "#e7e7e7", + "commandCenter.border": "#e7e7e799", + "sash.hoverBorder": "#0894ba", + "statusBar.background": "#066d89", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#0894ba", + "statusBarItem.remoteBackground": "#066d89", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#066d89", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#066d8999", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#066d89", + "cSpell.words": [ + "orbis", + "Orbis" + ] } diff --git a/config/default.json b/config/default.json index f594736..df624a9 100644 --- a/config/default.json +++ b/config/default.json @@ -1,12 +1,12 @@ { "constants": { "plataforma": "web", - "publicPath": "/smartoperation", + "publicPath": "/orbistemplate", "urlServerImages" : "https://gt.via-asesores.com/smartoperation/orbisapi/dtsrv/dev/operation?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTso", "urlWebApi": "https://gt.via-asesores.com/smartoperation/orbisapi/api/dev/operation?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTso", "urlUploadApi": "https://gt.via-asesores.com/smartoperation/orbisapi/upload/dev/operation?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTso", - "appTitle": "SmartOperation", - "idApp": "smartoperation", + "appTitle": "OrbisTemplate", + "idApp": "orbistemplate", "publicKey":"-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA205Ag8sXnqc0XsPa4NiS tZSca+3afzgkMdpotsIOphZxketyBLs4QOKYsAHGw51R68fbx5oLmDCn7a4n4ZtT u39ksIQg1lwQ3y7pqfb9BbYZKhtYigL8URUVrsQ5EuZxk9BOHHez59gizNzM+Vp0 zlnOuJVZdVdp3d+d1z+oE3ejsdXLGFEjAblo8GNQxTgxOXJk2VQ+4yQX5QN+mEYS FQpJqP9z5Y+/SVXlD3e943XjuNOFZwSG2uVkW3tuKsvGBOA38xLKydY9hb5y0WdM E0/hnOvB6gfIOovSmdTonDF3224iGQJa8RXss3SN+6NeLnhJQYGBri6U4sa0lNR/ 5vip/VCzaHliYERTztT2NgW6WUZAEW05gjN6Qid2eB7lKs/ND3BQkDHUKqouNDO1 xookeBqSg7fT/l3D6D7QzJE5Jc+bdZUDrr2MeYXehzbGg8sUBXJZbOu6GUkDSM5Y C8r/SnZhhA0ancQZZW/t4TmFNiLiGrqNS4uJf4UHKKsmXHCKDKB/bdlp60lTl6YF ocGzW6tBPdDFD7S5UTPqg//ob6mvuPFJ0E6t8Le60P+UiZIdmINe9dX9darS0VNH +eCVLj1J7iQNyXrelD5sE7xhAvQ3+jp3Q4mXWVgOZi1Uh/+/iNXDxrAtzKipYAOg zuyH0DDtO3E4JSiv4qr8o+UCAwEAAQ== -----END PUBLIC KEY-----", "maxMbUpload": 4, "defaultLocale": "es" diff --git a/config/gt.json b/config/gt.json index 895d8e8..7d5b701 100644 --- a/config/gt.json +++ b/config/gt.json @@ -1,12 +1,12 @@ { "constants": { "plataforma": "web", - "publicPath": "/smartoperation", + "publicPath": "/orbistemplate", "urlServerImages" : "https://gt.via-asesores.com/smartoperation/orbisapi/dtsrv/dev/orbis?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTMw", "urlWebApi": "https://gt.via-asesores.com/smartoperation/orbisapi/api/dev/orbis?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTMw", "urlUploadApi": "https://gt.via-asesores.com/smartoperation/orbisapi/upload/dev/orbis?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTMw", - "appTitle": "SmartOperation", - "idApp": "smartoperation", + "appTitle": "OrbisTemplate", + "idApp": "orbistemplate", "publicKey":"-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA205Ag8sXnqc0XsPa4NiS tZSca+3afzgkMdpotsIOphZxketyBLs4QOKYsAHGw51R68fbx5oLmDCn7a4n4ZtT u39ksIQg1lwQ3y7pqfb9BbYZKhtYigL8URUVrsQ5EuZxk9BOHHez59gizNzM+Vp0 zlnOuJVZdVdp3d+d1z+oE3ejsdXLGFEjAblo8GNQxTgxOXJk2VQ+4yQX5QN+mEYS FQpJqP9z5Y+/SVXlD3e943XjuNOFZwSG2uVkW3tuKsvGBOA38xLKydY9hb5y0WdM E0/hnOvB6gfIOovSmdTonDF3224iGQJa8RXss3SN+6NeLnhJQYGBri6U4sa0lNR/ 5vip/VCzaHliYERTztT2NgW6WUZAEW05gjN6Qid2eB7lKs/ND3BQkDHUKqouNDO1 xookeBqSg7fT/l3D6D7QzJE5Jc+bdZUDrr2MeYXehzbGg8sUBXJZbOu6GUkDSM5Y C8r/SnZhhA0ancQZZW/t4TmFNiLiGrqNS4uJf4UHKKsmXHCKDKB/bdlp60lTl6YF ocGzW6tBPdDFD7S5UTPqg//ob6mvuPFJ0E6t8Le60P+UiZIdmINe9dX9darS0VNH +eCVLj1J7iQNyXrelD5sE7xhAvQ3+jp3Q4mXWVgOZi1Uh/+/iNXDxrAtzKipYAOg zuyH0DDtO3E4JSiv4qr8o+UCAwEAAQ== -----END PUBLIC KEY-----", "maxMbUpload": 4, "defaultLocale": "es" diff --git a/config/testing.json b/config/testing.json index ee88561..dee3b1e 100644 --- a/config/testing.json +++ b/config/testing.json @@ -1,12 +1,12 @@ { "constants": { "plataforma": "web", - "publicPath": "/smartoperation", + "publicPath": "/orbistemplate", "urlServerImages" : "https://localhost:3000/smartoperation/orbisapi/dtsrv/dev/orbis?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTMw", "urlWebApi": "https://localhost:3000/smartoperation/orbisapi/api/dev/orbis?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTMw", "urlUploadApi": "https://localhost:3000/smartoperation/orbisapi/upload/dev/orbis?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTMw", - "appTitle": "SmartOperation", - "idApp": "smartoperation", + "appTitle": "OrbisTemplate", + "idApp": "orbistemplate", "publicKey":"-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA205Ag8sXnqc0XsPa4NiS tZSca+3afzgkMdpotsIOphZxketyBLs4QOKYsAHGw51R68fbx5oLmDCn7a4n4ZtT u39ksIQg1lwQ3y7pqfb9BbYZKhtYigL8URUVrsQ5EuZxk9BOHHez59gizNzM+Vp0 zlnOuJVZdVdp3d+d1z+oE3ejsdXLGFEjAblo8GNQxTgxOXJk2VQ+4yQX5QN+mEYS FQpJqP9z5Y+/SVXlD3e943XjuNOFZwSG2uVkW3tuKsvGBOA38xLKydY9hb5y0WdM E0/hnOvB6gfIOovSmdTonDF3224iGQJa8RXss3SN+6NeLnhJQYGBri6U4sa0lNR/ 5vip/VCzaHliYERTztT2NgW6WUZAEW05gjN6Qid2eB7lKs/ND3BQkDHUKqouNDO1 xookeBqSg7fT/l3D6D7QzJE5Jc+bdZUDrr2MeYXehzbGg8sUBXJZbOu6GUkDSM5Y C8r/SnZhhA0ancQZZW/t4TmFNiLiGrqNS4uJf4UHKKsmXHCKDKB/bdlp60lTl6YF ocGzW6tBPdDFD7S5UTPqg//ob6mvuPFJ0E6t8Le60P+UiZIdmINe9dX9darS0VNH +eCVLj1J7iQNyXrelD5sE7xhAvQ3+jp3Q4mXWVgOZi1Uh/+/iNXDxrAtzKipYAOg zuyH0DDtO3E4JSiv4qr8o+UCAwEAAQ== -----END PUBLIC KEY-----", "maxMbUpload": 4, "defaultLocale": "es" diff --git a/config/www.json b/config/www.json index 9a436e4..2f5ef4c 100644 --- a/config/www.json +++ b/config/www.json @@ -1,12 +1,12 @@ { "constants": { "plataforma": "web", - "publicPath": "/smartoperation", + "publicPath": "/orbistemplate", "urlServerImages" : "https://www.via-asesores.com/smartoperation/orbisapi/dtsrv/prod/orbis?apikey=MDJmNTEwOWUtNWY2ZC00OGJlLThjZGQtNWM4NmEyNmZmN2U5", "urlWebApi": "https://www.via-asesores.com/smartoperation/orbisapi/api/prod/orbis?apikey=MDJmNTEwOWUtNWY2ZC00OGJlLThjZGQtNWM4NmEyNmZmN2U5", "urlUploadApi": "https://www.via-asesores.com/smartoperation/orbisapi/upload/prod/orbis?apikey=MDJmNTEwOWUtNWY2ZC00OGJlLThjZGQtNWM4NmEyNmZmN2U5", - "appTitle": "SmartOperation", - "idApp": "smartoperation", + "appTitle": "OrbisTemplate", + "idApp": "orbistemplate", "publicKey":"-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA205Ag8sXnqc0XsPa4NiS tZSca+3afzgkMdpotsIOphZxketyBLs4QOKYsAHGw51R68fbx5oLmDCn7a4n4ZtT u39ksIQg1lwQ3y7pqfb9BbYZKhtYigL8URUVrsQ5EuZxk9BOHHez59gizNzM+Vp0 zlnOuJVZdVdp3d+d1z+oE3ejsdXLGFEjAblo8GNQxTgxOXJk2VQ+4yQX5QN+mEYS FQpJqP9z5Y+/SVXlD3e943XjuNOFZwSG2uVkW3tuKsvGBOA38xLKydY9hb5y0WdM E0/hnOvB6gfIOovSmdTonDF3224iGQJa8RXss3SN+6NeLnhJQYGBri6U4sa0lNR/ 5vip/VCzaHliYERTztT2NgW6WUZAEW05gjN6Qid2eB7lKs/ND3BQkDHUKqouNDO1 xookeBqSg7fT/l3D6D7QzJE5Jc+bdZUDrr2MeYXehzbGg8sUBXJZbOu6GUkDSM5Y C8r/SnZhhA0ancQZZW/t4TmFNiLiGrqNS4uJf4UHKKsmXHCKDKB/bdlp60lTl6YF ocGzW6tBPdDFD7S5UTPqg//ob6mvuPFJ0E6t8Le60P+UiZIdmINe9dX9darS0VNH +eCVLj1J7iQNyXrelD5sE7xhAvQ3+jp3Q4mXWVgOZi1Uh/+/iNXDxrAtzKipYAOg zuyH0DDtO3E4JSiv4qr8o+UCAwEAAQ== -----END PUBLIC KEY-----", "maxMbUpload": 4, "defaultLocale": "es" diff --git a/next.config.js b/next.config.js index 0350b76..e3b966d 100644 --- a/next.config.js +++ b/next.config.js @@ -12,17 +12,6 @@ const rewrites = async () => { ] } -const redirects = async () => { - return [ - { - source: '/mantenimientos', - destination: constants.publicPath, - basePath: true, - permanent: false - } - ] -} - const nextConfig = { env: { ...constants diff --git a/package.json b/package.json index a222ef8..02889fd 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,21 @@ "lint": "next lint" }, "dependencies": { + "@headlessui/react": "^1.7.17", + "config": "^3.3.9", + "js-cookie": "^3.0.5", + "js-md5": "^0.8.3", "next": "14.0.4", + "node-forge": "^1.3.1", + "pristinejs": "^1.1.0", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "react-dropzone-component": "^3.2.0", + "react-icons": "^4.12.0", + "react-simple-hook-store": "^0.0.6", + "react-toastify": "^9.1.3", + "rosetta": "^1.1.0", + "vComponents": "git+https://2bdcc0300e0ed5ac01f9dcd51368f7ac74fdb85a@git.via-asesores.com/libraries/v-components.git" }, "devDependencies": { "@types/node": "^20", diff --git a/src/components/Login/FormLogin.jsx b/src/components/Login/FormLogin.jsx new file mode 100644 index 0000000..c2e15a5 --- /dev/null +++ b/src/components/Login/FormLogin.jsx @@ -0,0 +1,141 @@ +import Pristine from 'pristinejs' +import { useEffect, useState } from 'react' +import { UserIcon, EyeIcon, EyeSlashIcon, KeyIcon } from '@heroicons/react/24/solid' +import functions from 'v-functions' +import useI18n from '@/hooks/useI18n' +import presets from '@/utils/globalPresets' +import useHasMounted from '@/hooks/useHasMounted' + +let validateLogin = null + +const FormLogin = ({ onLogin }) => { + const i18n = useI18n() + const hasMounted = useHasMounted() + const [viewPassword, setViewPassword] = useState(false) + const [isInputValid, setIsInputValid] = useState(false) + + const validate = (event) => { + if (event) { + event.preventDefault() + event.stopPropagation() + } + if (validateLogin && validateLogin !== null) { + const resulValidate = validateLogin.validate() + setIsInputValid(resulValidate) + } + } + + const doLogin = (event) => { + if (event) { + event.preventDefault() + event.stopPropagation() + } + if (isInputValid === true) { + const emailLogin = document.getElementById('usuario') + const passwordLogin = document.getElementById('clave') + const datos = { + email: functions.toUpperCaseAndTrim(emailLogin.value), + password: functions.trim(passwordLogin.value) + } + setIsInputValid(false) // para prevenir doble click + onLogin(datos) + } + } + + // when page is mounted + useEffect(() => { + if (hasMounted) { + const helem = document.getElementById('frmLogin') + validateLogin = new Pristine(helem, presets.pristine, false) + const helemUsuario = document.getElementById('usuario') + helemUsuario.focus() + } + }, [hasMounted]) + + useEffect(() => { + const handleKeyDown = (event) => { + if (event.key === 'Enter') { + validate(event) + if (isInputValid === true) { + doLogin(event) + event.preventDefault() + event.stopPropagation() + } + } + } + + document.addEventListener('keydown', handleKeyDown) + return () => { + document.removeEventListener('keydown', handleKeyDown) + } + }) + + return ( +
doLogin(event)} noValidate > +
+
+
+ { i18n.t('login.user') } +
(*)
+
+
+ { validate(e) }} + /> + +
+
+
+
+ { i18n.t('login.password') } +
(*)
+
+
+ { validate(e) }} + /> + +
+
+
+ +
+
+
+ ) +} + +export default FormLogin diff --git a/src/components/SessionTimeout/index.jsx b/src/components/SessionTimeout/index.jsx new file mode 100644 index 0000000..666390e --- /dev/null +++ b/src/components/SessionTimeout/index.jsx @@ -0,0 +1,163 @@ +import React, { Fragment, useEffect, useRef, useState } from 'react' +import { Dialog, Transition } from '@headlessui/react' +import PropTypes from 'prop-types' +import useHasMounted from '@/hooks/useHasMounted' + +export default function SessionTimeout ({ i18n, user, onTimeout, onCancelTimeout }) { + const TIME = 30 + const hasMounted = useHasMounted() + const countTimerRef = useRef() + const [tick, setTick] = useState(0) + const [countTimer, setCountTimer] = useState() // contador que lleva el control de tiempo en segundos para mostrar antes de cerrar sesion + const [timerIsOn, setTimerIsOn] = useState(false) // verifica si el dialogo debe ser mostrado + const idleTimer = useRef(null) // variable de control para el proceso de conteo + + // realiza el conteo regresivo + const timedCount = () => { + if (countTimerRef.current <= 0) { + clearInterval(idleTimer.current) + setTimerIsOn(false) + setCountTimer(TIME) + onTimeout() + return + } + setCountTimer(countTimerRef.current - 1) + } + + // inicia el conteo regresivo + const startIdleMonitor = (expiracion = 0) => { + if (expiracion < TIME * 1000) { + countTimerRef.current = Math.round(expiracion / 1000) // tiempo restante + } else { + countTimerRef.current = TIME + } + setCountTimer(countTimerRef.current) + setTimerIsOn(true) + timedCount() + idleTimer.current = setInterval(timedCount, 1000) + } + + const calendarizeIdle = () => { + // const fecha_inicio_sesion = new Date(user.fecha_inicio_sesion.slice(0, -1)) // uso de localtime quita Z al final del string + const fecha_fin_sesion = new Date(user?.fecha_fin_sesion?.slice(0, -1)) // uso de localtime quita Z al final del string + // const fecha_fin_sesion = new Date(user.fecha_fin_sesion) + const expiracion = Math.round(fecha_fin_sesion.getTime() - (new Date()).getTime()) // valida cuando se realiza un F5 o reload del navegador (user.tiempo_expiracion * 60 * 1000) + if (expiracion <= 0) { + return // no debe calendarizar porque la sesion ya vencio + } + const timeInMillis = expiracion - (TIME * 1000) + const processTimer = setTimeout(startIdleMonitor, timeInMillis > 0 ? timeInMillis : 0, expiracion) + return () => clearTimeout(processTimer) + } + + // cancela el conteo regresivo aumentando el tiempo de expiracion + const stopIdleMonitor = async () => { + await onCancelTimeout() + clearInterval(idleTimer.current) + setTimerIsOn(false) + setCountTimer(TIME) + // force rerender to update view + setTick((tick) => tick + 1) + // await new Promise(resolve => setTimeout(resolve, 2000)) // espera obligada para actualizacion DB + } + + useEffect(() => { + if (timerIsOn === false && tick > 0) { + return calendarizeIdle() + } + }, [timerIsOn, tick]) + + useEffect(() => { + countTimerRef.current = countTimer + }, [countTimer]) + + useEffect(() => { + if (!user || user === null) { + if (idleTimer && idleTimer.current) { + clearInterval(idleTimer.current) + } + } + return () => clearInterval(idleTimer.current) + }, [user]) + + useEffect(() => { + if (hasMounted) { + return calendarizeIdle() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hasMounted]) + + return ( + <> + { timerIsOn && timerIsOn === true && + + { }}> + +
+ + +
+
+ + + + {i18n.t('common.sessionToFinish')} + +
+

+ {countTimer} +

+
+ +
+ +
+
+
+
+
+
+
+ } + + ) +} + +SessionTimeout.propTypes = { + i18n: PropTypes.object, + user: PropTypes.object, + onTimeout: PropTypes.func, + onCancelTimeout: PropTypes.func +} + +SessionTimeout.defaultProps = { + i18n: { t: () => { return 'txtNone' } }, + user: {}, + onTimeout: () => {}, + onCancelTimeout: () => {} +} diff --git a/src/components/widgets/UserOptionsMenu.jsx b/src/components/widgets/UserOptionsMenu.jsx new file mode 100644 index 0000000..42cfd7f --- /dev/null +++ b/src/components/widgets/UserOptionsMenu.jsx @@ -0,0 +1,115 @@ +import React from 'react' +import { Menu } from '@headlessui/react' +import { MdOutlineCheckBox, MdOutlineCheckBoxOutlineBlank, MdOutlineLightMode, MdDarkMode } from 'react-icons/md' +import { TbColorPicker, TbLanguage } from 'react-icons/tb' + +const UserOptionsMenu = ({ setPreferences, theme, i18n }) => { + return ( + <> +
+
+
+ + + + + + +
+ +
+
+ +
+ + + + + + +
+ + ) +} + +export default UserOptionsMenu diff --git a/src/hooks/useRoute.js b/src/hooks/useRoute.js index 0e620e9..1868e10 100644 --- a/src/hooks/useRoute.js +++ b/src/hooks/useRoute.js @@ -65,7 +65,7 @@ export const RouteProvider = ({ children }) => { breadcrumbsListArr, addBreadcrumb, truncateBreadcrumbs, - breadcrumbsList // Incluir breadcrumbsList en el valor del contexto + breadcrumbsList } return ( diff --git a/src/hooks/useStore.ts b/src/hooks/useStore.ts index 19fea1d..fc39c64 100644 --- a/src/hooks/useStore.ts +++ b/src/hooks/useStore.ts @@ -16,7 +16,7 @@ export const { useStore, store } = createStore( { title: '', usuarioPermisos: null, - valueEasyMDE: null + valueEasyMDE: '' }, { setTitle: (store, newState) => { diff --git a/src/layout/ResponsiveContainer.jsx b/src/layout/ResponsiveContainer.jsx index 45440a2..a847843 100644 --- a/src/layout/ResponsiveContainer.jsx +++ b/src/layout/ResponsiveContainer.jsx @@ -14,24 +14,24 @@ import { toast } from 'react-toastify' export const LayoutContext = createContext() -const Footer = dynamic(() => { return import('vComponents/dist/Footer') }, { ssr: false }) -const Sidebar = dynamic(() => { return import('vComponents/dist/Sidebar') }, { ssr: false }) -const Navbar = dynamic(() => { return import('vComponents/dist/Navbar') }, { ssr: false }) +const Footer = dynamic(() => { return import('vComponents/Footer') }, { ssr: false }) +const Sidebar = dynamic(() => { return import('vComponents/Sidebar') }, { ssr: false }) +const Navbar = dynamic(() => { return import('vComponents/Navbar') }, { ssr: false }) const ResponsiveContainer = ({ children }) => { const router = useRouter() const loading = useLoading() const hasMounted = useHasMounted() const i18n = useI18n() - const [_i18n, setI18n] = useState({ t: () => { return 'txtNone' } }) const [sidebarOpen, setSidebarOpen] = useState(true) const [menu, setMenu] = useState([]) const [title, setTitle] = useStore(s => s.title, a => a.setTitle) const [userObj, setUserObj] = useState() const [token, setToken] = useState('') - const [theme, setTheme] = useState(null) + const [theme, setTheme] = useState('light') const [constanteObj, setConstanteObj] = useState('') + const [appVersion, setAppVersion] = useState('1.0.0') const doLogout = async () => { const redirectPath = await environment.logout() @@ -84,39 +84,24 @@ const ResponsiveContainer = ({ children }) => { } } - const onBackKeyDown = () => { - if (router.asPath === '/') { - // cuando esta en la pagina principal cierra la app - if (navigator.app) { - navigator.app.exitApp() - } else if (navigator.device) { - navigator.device.exitApp() - } else { - window.close() - } - } else { - window.history.back() - } - } - - const validaPermisosRuta = async (token) => { - if (router.pathname.includes('/admin')) { - loading.start() - const tienePermiso = await environment.validaPermisos(token, 'S', 'N', 'N', 'N') - loading.stop() - if (tienePermiso === false) { - router.push(presets.locations.welcome) - } - } - if (router.pathname.includes('/mantenimientos')) { - loading.start() - const tienePermiso = await environment.validaPermisos(token, 'N', 'S', 'N', 'N') - loading.stop() - if (tienePermiso === false) { - router.push(presets.locations.welcome) - } - } - } + // const validaPermisosRuta = async (token) => { + // if (router.pathname.includes('/admin')) { + // loading.start() + // const tienePermiso = await environment.validaPermisos(token, 'S', 'N', 'N', 'N') + // loading.stop() + // if (tienePermiso === false) { + // router.push(presets.locations.welcome) + // } + // } + // if (router.pathname.includes('/mantenimientos')) { + // loading.start() + // const tienePermiso = await environment.validaPermisos(token, 'N', 'S', 'N', 'N') + // loading.stop() + // if (tienePermiso === false) { + // router.push(presets.locations.welcome) + // } + // } + // } const getMenu = async () => { loading.start() @@ -173,10 +158,6 @@ const ResponsiveContainer = ({ children }) => { setTitle }), [userObj, setUserObj, constanteObj, setConstanteObj, token, setToken, setTheme, setTitle]) - useEffect(() => { - setI18n(i18n) - }, [i18n]) - useEffect(() => { getMenu() }, [token]) @@ -187,59 +168,70 @@ const ResponsiveContainer = ({ children }) => { getEnv().then(() => { getMenu() }) + setAppVersion(process.env.NEXT_PUBLIC_VERSION) } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [hasMounted]) useEffect(() => { - if (process.browser && window.cordova) { - document.addEventListener('backbutton', onBackKeyDown, false) + const handleStart = (url) => { + // tienePermisosParaRuta(url) + loading.start() } - }) + + const handleComplete = () => { + loading.stop() + } + + router.events.on('routeChangeStart', handleStart) + router.events.on('routeChangeComplete', handleComplete) + router.events.on('routeChangeError', handleComplete) + + return () => { + router.events.off('routeChangeStart', handleStart) + router.events.off('routeChangeComplete', handleComplete) + router.events.off('routeChangeError', handleComplete) + } + }, [router]) return ( -
+
{/* Sidebar */} - { - userObj && userObj.nombre_usuario && - + { userObj && userObj.nombre_usuario && doLogout()} setTitle={setTitle} userObj={userObj} environment={environment} presets={presets} router={router} - i18n={_i18n} + i18n={i18n} /> } {/* Content area */}
- {/* Site header */} {userObj && userObj.nombre_usuario && - doLogout()} onClickProfile={() => router.push(`${presets.locations.profile}/${environment.getTime()}`)} MenuOptions={() => } @@ -247,24 +239,21 @@ const ResponsiveContainer = ({ children }) => { userObj={userObj} router={router} presets={presets} - /> - }
-
+
{children}
- { - userObj && userObj.nombre_usuario && - onTimeout()} onCancelTimeout={() => onCancelTimeout()} /> + + { userObj && userObj.nombre_usuario && + onTimeout()} onCancelTimeout={() => onCancelTimeout()} /> }
- +
-