From 35321e9955c3e334c7903e63e458f60549b13999 Mon Sep 17 00:00:00 2001 From: dehernandezm Date: Thu, 31 Aug 2023 09:01:31 -0600 Subject: [PATCH] =?UTF-8?q?=20ejercicio=20tarjeta=20de=20cr=C3=A9dito=20co?= =?UTF-8?q?mpletado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 0 .eslintrc.json | 3 + config/default.json | 14 + helper/clientApi.js | 83 + hooks/useGlobalContainer.js | 9 + hooks/useHasMounted.js | 15 + hooks/useI18n.js | 9 + hooks/useLoading.js | 9 + layout/ResponsiveContainer.jsx | 192 ++ models/CreditCardModel.js | 35 + models/CreditCardProps.js | 372 +++ next.config.js | 45 + package.json | 66 + pages/_app.jsx | 24 + pages/index.jsx | 107 + pages/welcome.jsx | 16 + plugins/LoadingContext.jsx | 27 + plugins/i18nContext.jsx | 81 + postcss.config.js | 6 + public/favicon.ico | Bin 0 -> 25931 bytes public/vercel.svg | 4 + styles/additional-styles/toastify.css | 7 + styles/component-styles/datatable.css | 15 + styles/component-styles/loading.css | 102 + styles/component-styles/navbar.css | 18 + styles/component-styles/sidebar.css | 11 + styles/globals.css | 36 + styles/page-styles/common.css | 38 + styles/page-styles/eventos_colores.css | 28 + styles/page-styles/login.css | 23 + tailwind.config.js | 79 + utils/environment.js | 160 ++ utils/globalPresets.js | 81 + yarn.lock | 3632 ++++++++++++++++++++++++ 34 files changed, 5347 insertions(+) create mode 100644 .env.development create mode 100644 .eslintrc.json create mode 100644 config/default.json create mode 100644 helper/clientApi.js create mode 100644 hooks/useGlobalContainer.js create mode 100644 hooks/useHasMounted.js create mode 100644 hooks/useI18n.js create mode 100644 hooks/useLoading.js create mode 100644 layout/ResponsiveContainer.jsx create mode 100644 models/CreditCardModel.js create mode 100644 models/CreditCardProps.js create mode 100644 next.config.js create mode 100644 package.json create mode 100644 pages/_app.jsx create mode 100644 pages/index.jsx create mode 100644 pages/welcome.jsx create mode 100644 plugins/LoadingContext.jsx create mode 100644 plugins/i18nContext.jsx create mode 100644 postcss.config.js create mode 100644 public/favicon.ico create mode 100644 public/vercel.svg create mode 100644 styles/additional-styles/toastify.css create mode 100644 styles/component-styles/datatable.css create mode 100644 styles/component-styles/loading.css create mode 100644 styles/component-styles/navbar.css create mode 100644 styles/component-styles/sidebar.css create mode 100644 styles/globals.css create mode 100644 styles/page-styles/common.css create mode 100644 styles/page-styles/eventos_colores.css create mode 100644 styles/page-styles/login.css create mode 100644 tailwind.config.js create mode 100644 utils/environment.js create mode 100644 utils/globalPresets.js create mode 100644 yarn.lock diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..e69de29 diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/config/default.json b/config/default.json new file mode 100644 index 0000000..4816cd5 --- /dev/null +++ b/config/default.json @@ -0,0 +1,14 @@ +{ + "constants": { + "plataforma": "web", + "publicPath": "/smartcollector", + "urlServerImages" : "https://gt.via-asesores.com/smartcollector/orbisapi/dtsrv/dev/smartcollector?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTsc", + "urlWebApi": "https://gt.via-asesores.com/smartcollector/orbisapi/api/dev/smartcollector?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTsc", + "urlUploadApi": "https://gt.via-asesores.com/smartcollector/orbisapi/upload/dev/smartcollector?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTsc", + "appTitle": "SmartCollector", + "idApp": "smartcollector", + "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" + } +} \ No newline at end of file diff --git a/helper/clientApi.js b/helper/clientApi.js new file mode 100644 index 0000000..7a0ad8e --- /dev/null +++ b/helper/clientApi.js @@ -0,0 +1,83 @@ +import forge from 'node-forge' + +const constants = { + urlWebApi: process.env.urlWebApi, + urlUploadApi: process.env.urlUploadApi, + publicKey: process.env.publicKey +} + +const uris = { + procedure: '', + upload: '/upload' +} + +const encryptRsa = function (obj) { + const encoded = forge.util.encodeUtf8(obj) + const publicKey = forge.pki.publicKeyFromPem(constants.publicKey) + const encrypted = publicKey.encrypt(encoded, 'RSA-OAEP', { + md: forge.md.sha256.create(), + mgf1: forge.mgf1.create() + }) + const base64 = forge.util.encode64(encrypted) + return base64 +} + + +const callWs = async (uri, json) => { + // Send the form data to our API and get a response. + const response = await fetch(uri, { + // Body of the request is the JSON data we created above. + body: JSON.stringify(json), + // Tell the server we're sending JSON. + headers: { + 'Content-Type': 'application/json', + }, + // The method is POST because we are sending data. + method: 'POST', + }) + + // Get the response data from server as JSON. + // If server returns the name submitted, that means the form works. + const result = await response.json() + return result.data // return data rows +} + +const execute = async (spName, params, encriptado = 0, loading = false, connInfo = undefined) => { + let model = {} + if (typeof spName === 'string') { + model.nombre = spName + model.loading = loading + // verifica que los parametros vengan como Array + model.parametros = params ?? [] + // si la información se envía encriptada + if (encriptado === 1) { + const paramsToEncrypt = { + nombre: spName, + parametros: params + } + const paramsEncryptedString = encryptRsa(JSON.stringify(paramsToEncrypt)) + + model.nombre = '' + model.encriptado = 1 + model.parametros = paramsEncryptedString + } + } else if(typeof spName === 'object') { + if (encriptado === 1) { + const paramsEncryptedString = encryptRsa(JSON.stringify(spName)) + model.parametros = paramsEncryptedString + model.encriptado = 1 + model.loading = loading + } else { + model = spName + model.loading = loading + } + } + + if (connInfo) { + return await callWs(connInfo.api + '/' + connInfo.env + '/' + connInfo.exposeRoute + '?apikey=' + connInfo.apikey, model) + } + return await callWs(constants.urlWebApi + uris.procedure, model) +} + + +export { execute } diff --git a/hooks/useGlobalContainer.js b/hooks/useGlobalContainer.js new file mode 100644 index 0000000..045763e --- /dev/null +++ b/hooks/useGlobalContainer.js @@ -0,0 +1,9 @@ +import { useContext } from "react" +import { LayoutContext } from '../layout/ResponsiveContainer' + +const useGlobalContainer = () => { + const container = useContext(LayoutContext) + return container +} + +export default useGlobalContainer diff --git a/hooks/useHasMounted.js b/hooks/useHasMounted.js new file mode 100644 index 0000000..5570e8e --- /dev/null +++ b/hooks/useHasMounted.js @@ -0,0 +1,15 @@ + +import { useEffect, useState } from "react" + +const useHasMounted = () => { + const [hasMounted, setHasMounted] = useState(false) + + useEffect(() => { + setHasMounted(true) + // console.log('page is mounted') + }, []) + + return hasMounted +} + +export default useHasMounted diff --git a/hooks/useI18n.js b/hooks/useI18n.js new file mode 100644 index 0000000..1e68be0 --- /dev/null +++ b/hooks/useI18n.js @@ -0,0 +1,9 @@ +import { useContext } from 'react' +import { I18nContext } from '../plugins/i18nContext' + +const useI18n = () => { + const i18n = useContext(I18nContext) + return i18n +} + +export default useI18n diff --git a/hooks/useLoading.js b/hooks/useLoading.js new file mode 100644 index 0000000..55b69ec --- /dev/null +++ b/hooks/useLoading.js @@ -0,0 +1,9 @@ +import { useContext } from "react" +import { LoadingContext } from "../plugins/LoadingContext" + +const useLoading = () => { + const loading = useContext(LoadingContext) + return loading +} + +export default useLoading diff --git a/layout/ResponsiveContainer.jsx b/layout/ResponsiveContainer.jsx new file mode 100644 index 0000000..fb296b8 --- /dev/null +++ b/layout/ResponsiveContainer.jsx @@ -0,0 +1,192 @@ +import { useEffect, useState, createContext } from 'react' +import { useRouter } from 'next/router' +import { execute } from "../helper/clientApi" +import environment from '../utils/environment' +import presets from '../utils/globalPresets' +import dynamic from 'next/dynamic' +import useLoading from '../hooks/useLoading' +import useHasMounted from '../hooks/useHasMounted' +import useI18n from '../hooks/useI18n' + +export const LayoutContext = createContext() + +const Footer = dynamic(() => { return import("vComponents/dist/Footer") }, { ssr: false }) +const Navbar = dynamic(() => { return import("vComponents/dist/Navbar") }, { ssr: false }) +const Sidebar = dynamic(() => { return import("vComponents/dist/Sidebar") }, { ssr: false }) + +const ResponsiveContainer = ({ children }) => { + const router = useRouter() + const loading = useLoading() + const i18n = useI18n() + const hasMounted = useHasMounted() + const [sidebarOpen, setSidebarOpen] = useState(true) + const [menu, setMenu] = useState([]) + const [title, setTitle] = useState('') + const [userObj, setUserObj] = useState() + const [token, setToken] = useState('') + + const doLogout = async () => { + const redirectPath = await environment.logout() + setUserObj(null) + router.push(redirectPath) + } + + 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 getMenu = async (token) => { + loading.start() + setMenu([]) + if (token && token !== null) { + console.log('Responsive Container - getMenu - token', token) + let options = await execute('SPR_MENU_S', [token, 'SC', null]) + setMenu(options) + console.log('Responsive Container - getMenu - options', options) + if (environment.validaResultadoDB(options) === false) { + options = await execute('SPR_MENU_S', [token, 'SC', null]) + setMenu(options) + console.log('Responsive Container - getMenu - reoptions', options) + } + } + loading.stop() + } + + const getEnv = async () => { + try { + const env = await environment.getEnvUser() + if (!env || !env.token) { + toast.error(i18n.t('common.inactiveSession'), presets.toaster) + router.push(presets.locations.login) + return + } + setUserObj(env.user) + setToken(env.token) + validaPermisosRuta(env.token) + getMenu(token) + } catch (error) { + router.push(presets.locations.login) + } + } + + const containerWrapper = { + userObj: userObj, + setUserObj: setUserObj, + token: token, + setToken: setToken + } + + useEffect(() => { + console.log('Responsive Container - getMenu - useEffect token', token) + getMenu(token) + }, [token]) + + + // when page is mounted + useEffect(() => { + if (hasMounted) { + getEnv() + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hasMounted]) + + useEffect(() => { + if (process.browser && window.cordova) { + document.addEventListener("backbutton", onBackKeyDown, false) + } + }) + + + return ( + +
+ + {/* Sidebar */} + { + userObj && userObj.nombre_usuario && + + doLogout()} + setTitle={setTitle} + userObj={userObj} + environment={environment} + presets={presets} + router={router} + i18n={i18n} + /> + } + + {/* Content area */} +
+ + {/* Site header */} + {userObj && userObj.nombre_usuario && + + doLogout()} + onClickProfile={() => router.push(`${presets.locations.profile}`)} + title={title} + userObj={userObj} + router={router} + presets={presets} + /> + } + + +
+
+ {children} +
+
+
+ +
+