diff --git a/.vscode/settings.json b/.vscode/settings.json index f677a92..ecc0a38 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,6 +19,10 @@ "cSpell.words": [ "headlessui", "orbis", - "Orbis" + "Orbis", + "orbisapi", + "esnext", + "tailwindcss", + "unoptimized", ], } \ No newline at end of file diff --git a/config/default.json b/config/default.json index 8222035..1d10d83 100644 --- a/config/default.json +++ b/config/default.json @@ -2,9 +2,9 @@ "constants": { "plataforma": "web", "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", + "urlServerImages" : "https://gt.via-asesores.com/smartoperation-api/dtsrv/dev/operation?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTso", + "urlWebApi": "https://gt.via-asesores.com/smartoperation-api/api/dev/operation?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTso", + "urlUploadApi": "https://gt.via-asesores.com/smartoperation-api/upload/dev/operation?apikey=NTAzYzZlOTItMDcwZC00Zjg4LTljODMtNzBkNGQ5YjZhZTso", "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-----", diff --git a/package.json b/package.json index 9e76478..432f7ab 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "license": "ISC", "private": true, "scripts": { + "clean": "rimraf .next && cls && yarn dev", "dev": "next dev", "build": "next build", "generate": "next build && next export", diff --git a/src/components/Login/FormLogin.jsx b/src/components/Login/FormLogin.jsx index cda3be3..cb66e60 100644 --- a/src/components/Login/FormLogin.jsx +++ b/src/components/Login/FormLogin.jsx @@ -127,7 +127,7 @@ const FormLogin = ({ onLogin }) => { - - - - - - -
-
- -
- - - - - - -
- - ) -} - -export default UserOptionsMenu diff --git a/src/hooks/useGlobalFilters.js b/src/hooks/useGlobalFilters.js deleted file mode 100644 index 44d0adf..0000000 --- a/src/hooks/useGlobalFilters.js +++ /dev/null @@ -1,54 +0,0 @@ -import { useState, useEffect } from 'react' -import functions from 'v-functions' - -const safeGetPathname = () => { - return typeof window !== 'undefined' ? window.location.pathname : '' -} - -const useGlobalFilters = () => { - const [rutaActual, setRutaActual] = useState(safeGetPathname()) - - useEffect(() => { - setRutaActual(safeGetPathname()) - }, [safeGetPathname()]) - - const getFiltersFromLocalStorage = () => { - const storedFilters = functions.getDecodeStorage('globalFilters') - const parsedFilters = storedFilters ? JSON.parse(storedFilters) : {} - return parsedFilters[rutaActual] || {} - } - - const setFilters = (keyOrObject, value) => { - const prevFilters = getFiltersFromLocalStorage() - let updatedFilters - - if (typeof keyOrObject === 'object' && value === undefined) { - updatedFilters = { ...prevFilters, ...keyOrObject } - } else { - updatedFilters = { ...prevFilters, [keyOrObject]: value } - } - - const storedFilters = functions.getDecodeStorage('globalFilters') - const globalFilters = storedFilters ? JSON.parse(storedFilters) : {} - functions.setEncodeStorage( - 'globalFilters', - JSON.stringify({ ...globalFilters, [rutaActual]: updatedFilters }) - ) - } - - const clearFiltersForRoute = () => { - const storedFilters = functions.getDecodeStorage('globalFilters') - const globalFilters = storedFilters ? JSON.parse(storedFilters) : {} - functions.setEncodeStorage('globalFilters', JSON.stringify({ ...globalFilters, [rutaActual]: {} })) - } - - const clearAllFilters = () => { - functions.setEncodeStorage('globalFilters', JSON.stringify({})) - } - - const filters = getFiltersFromLocalStorage() - - return [filters, setFilters, clearFiltersForRoute, clearAllFilters] -} - -export default useGlobalFilters diff --git a/src/hooks/useLocalStorage.js b/src/hooks/useLocalStorage.js deleted file mode 100644 index 5fa2f7c..0000000 --- a/src/hooks/useLocalStorage.js +++ /dev/null @@ -1,120 +0,0 @@ -import { useState, useEffect, useCallback } from 'react' -import PropTypes from 'prop-types' -import functions from 'v-functions' - -/** - * Función para parsear JSON. Maneja los valores 'undefined' y errores de parseo. - * @param {string | null} value - El valor JSON como string para parsear. - * @returns {any} El objeto JavaScript parseado o undefined si hay un error. - */ -function parseJSON (value) { - try { - return value === 'undefined' ? undefined : JSON.parse(value ?? '') - } catch { - console.error('Error al parsear', { value }) - return undefined - } -} - -/** - * Hook personalizado para interactuar con el localStorage del navegador. - * Permite almacenar, actualizar y recuperar un valor de localStorage. - * - * @param {string} key - La clave bajo la cual almacenar el valor en localStorage. - * @param {any} initialValue - El valor inicial a usar si no hay nada en localStorage. - * @returns {Array} Un array con el valor almacenado y la función para actualizarlo. - * - * @example - * - * // Uso en un componente React funcional - * const MyComponent = () => { - * // Utiliza el hook para almacenar un valor en localStorage - * const [name, setName] = useLocalStorage('name', 'Nombre inicial'); - * - * return ( - *
- * setName(e.target.value)} - * /> - *

El nombre es: {name}

- *
- * ); - * } - */ -const useLocalStorage = (key, initialValue) => { - const [storedValue, setStoredValue] = useState(initialValue) - const [initialized, setInitialized] = useState(false) - - const readValue = useCallback(() => { - if (typeof window === 'undefined') { - return initialValue - } - - try { - // const item = window.localStorage.getItem(key) - const item = functions.getDecodeStorage(key) - return item ? parseJSON(item) : initialValue - } catch (error) { - console.warn(`Error al leer la clave ${key} del localStorage:`, error) - return initialValue - } - }, [key, initialValue]) - - useEffect(() => { - setInitialized(true) - setStoredValue(readValue()) - }, [readValue]) - - useEffect(() => { - if (!initialized) { - return - } - - const handleStorageChange = (event) => { - if (event.key && event.key !== key) { - return - } - setStoredValue(readValue()) - } - - window.addEventListener('storage', handleStorageChange) - window.addEventListener('local-storage', handleStorageChange) - - return () => { - window.removeEventListener('storage', handleStorageChange) - window.removeEventListener('local-storage', handleStorageChange) - } - }, [key, readValue, initialized]) - - const setValue = (value) => { - if (typeof window === 'undefined' || !initialized) { - console.warn(`Intentando establecer la clave ${key} del localStorage en un entorno no cliente.`) - return - } - - try { - const newValue = value instanceof Function ? value(storedValue) : value - // window.localStorage.setItem(key, JSON.stringify(newValue)) - functions.setEncodeStorage(key, JSON.stringify(newValue)) - setStoredValue(newValue) - window.dispatchEvent(new Event('local-storage')) - } catch (error) { - console.warn(`Error al establecer la clave ${key} en el localStorage:`, error) - } - } - - return [storedValue, setValue] -} - -useLocalStorage.propTypes = { - key: PropTypes.string.isRequired, - initialValue: PropTypes.any -} - -useLocalStorage.defaultProps = { - initialValue: null -} - -export default useLocalStorage diff --git a/src/hooks/useRoute.js b/src/hooks/useRoute.js deleted file mode 100644 index 1868e10..0000000 --- a/src/hooks/useRoute.js +++ /dev/null @@ -1,76 +0,0 @@ -import { createContext, useContext, useState, useEffect } from 'react' -import environment from '@/utils/environment' - -export const RouteContext = createContext() - -export const useRoute = () => { - return useContext(RouteContext) -} - -export const RouteProvider = ({ children }) => { - const [breadcrumbsList, setBreadcrumbsList] = useState([]) - - useEffect(() => { - const storedBreadcrumbs = JSON.parse(sessionStorage.getItem('breadcrumbsList')) || [] - if (storedBreadcrumbs.length !== 0) { - setBreadcrumbsList(storedBreadcrumbs) - } - }, []) - - useEffect(() => { - sessionStorage.setItem('breadcrumbsList', JSON.stringify(breadcrumbsList)) - }, [breadcrumbsList]) - - const addBreadcrumb = (title, location) => { - const timestamp = '/' + environment.getTime() - if (location.endsWith(timestamp)) { - location = location.replace(timestamp, '') - } else if (location.endsWith('[...index]')) { - location = location.replace('/[...index]', '') - } - - setBreadcrumbsList(prev => { - const lastBreadcrumb = prev[prev.length - 1] - if (lastBreadcrumb && lastBreadcrumb.location === location && lastBreadcrumb.title === title) { - return prev - } - return [...prev, { title, location }] - }) - } - - const breadcrumbsListArr = () => { - return breadcrumbsList.slice(0, breadcrumbsList.length - 1) - } - - const truncateBreadcrumbs = (index) => { - setBreadcrumbsList(prev => prev.slice(0, index)) - } - - useEffect(() => { - const handlePopState = () => { - setBreadcrumbsList(prev => { - const newArr = [...prev] - newArr.pop() - return newArr - }) - } - - window.addEventListener('popstate', handlePopState) - return () => { - window.removeEventListener('popstate', handlePopState) - } - }, []) - - const value = { - breadcrumbsListArr, - addBreadcrumb, - truncateBreadcrumbs, - breadcrumbsList - } - - return ( - - {children} - - ) -} diff --git a/src/hooks/useScreenType.js b/src/hooks/useScreenType.js deleted file mode 100644 index c2696ba..0000000 --- a/src/hooks/useScreenType.js +++ /dev/null @@ -1,35 +0,0 @@ -import { useEffect, useState } from 'react' -import mq from 'js-mq' - -const useScreenType = () => { - const [isMobile, setIsMobile] = useState(null) - - useEffect(() => { - if (typeof window !== 'undefined' && typeof document !== 'undefined') { - try { - mq.register([ - { name: 'mobile', query: '(max-width: 767px)' }, - { name: 'desktop', query: '(min-width: 768px)' } - ]) - mq.on('mobile', (e) => { - setIsMobile(true) - }) - mq.on('desktop', (e) => { - setIsMobile(false) - }) - const arrayEstadoMq = mq.getState() - if (arrayEstadoMq.length && (arrayEstadoMq[0] === 'not-mobile' || arrayEstadoMq[0] === 'desktop')) { - setIsMobile(false) - } else { - setIsMobile(true) - } - } catch (e) { - console.error(`Error al registrar mq breackpoints - ${e.message}`) - } - } - }, []) - - return isMobile -} - -export default useScreenType diff --git a/src/layout/ResponsiveContainer.jsx b/src/layout/ResponsiveContainer.jsx index 0195b33..f6ac7d1 100644 --- a/src/layout/ResponsiveContainer.jsx +++ b/src/layout/ResponsiveContainer.jsx @@ -9,7 +9,7 @@ import { useStore } from '@/hooks/useStore' import useHasMounted from '@/hooks/useHasMounted' import useI18n from '@/hooks/useI18n' import SessionTimeout from '@/components/SessionTimeout' -import UserOptionsMenu from '@/components/widgets/UserOptionsMenu' +// import UserOptionsMenu from '@/components/widgets/UserOptionsMenu' import { toast } from 'react-toastify' import { useTheme } from 'next-themes' @@ -191,7 +191,7 @@ const ResponsiveContainer = ({ children }) => { return ( -
+
{/* Sidebar */} {userObj && userObj.nombre_usuario && { doLogout()} onClickProfile={() => router.push(`${presets.locations.profile}/${environment.getTime()}`)} - MenuOptions={() => } + // MenuOptions={() => } + i18n={i18n} + theme={theme} + setPreferences={setPreferences} title={title} userObj={userObj} router={router} @@ -230,10 +228,8 @@ const ResponsiveContainer = ({ children }) => { /> } -
-
- {children} -
+
+ {children}
{userObj && userObj.nombre_usuario && diff --git a/src/pages/404.jsx b/src/pages/404.jsx index 933e30b..ebfdfbb 100644 --- a/src/pages/404.jsx +++ b/src/pages/404.jsx @@ -22,7 +22,7 @@ const NotFound = () => { return (
-
+
{stars.map((_, index) => (
))} diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index f957ce3..97eb34f 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,23 +1,21 @@ -import { RouteProvider } from '@/hooks/useRoute' +// Estilos globales +import '@/styles/globals.css' + +// Dependencias import { ThemeProvider } from '@/components/theme-provider' import ResponsiveContainer from '@/layout/ResponsiveContainer' import LoadingProvider from '@/plugins/LoadingContext' import I18nProvider from '@/plugins/i18nContext' -import Head from 'next/head' - -// Estilos globales -import '@/styles/globals.css' -import 'vComponents/styles/generated/output.css' - -import { Portal } from '@headlessui/react' -import { ToastContainer } from 'react-toastify' import presets from '@/utils/globalPresets' +import { Portal } from '@headlessui/react' +import Head from 'next/head' +import { ToastContainer } from 'react-toastify' export default function App ({ Component, pageProps }) { return ( <> - + Orbis Template @@ -36,9 +34,7 @@ export default function App ({ Component, pageProps }) { /> - - - + diff --git a/src/pages/dashboard/index.jsx b/src/pages/dashboard/index.jsx index fe5c2ca..49761b6 100644 --- a/src/pages/dashboard/index.jsx +++ b/src/pages/dashboard/index.jsx @@ -2,7 +2,29 @@ import React from 'react' const DashboardPage = () => { return ( -
DashboardPage
+ <> +
+

Texto normal (font-normal - 400)

+

Texto semibold (font-semibold - 600)

+

Texto bold (font-bold - 700)

+

Texto extrabold (font-extrabold - 800)

+
+
+

Texto normal (font-normal - 400)

+

Texto semibold (font-semibold - 600)

+

Texto bold (font-bold - 700)

+

Texto extrabold (font-extrabold - 800)

+
+ +
+ + Texto de prueba + +

Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim, nobis.

+
+ + {/*
Hello
*/} + ) } diff --git a/src/styles/component-styles/navbar.css b/src/styles/component-styles/navbar.css index f30db22..e69de29 100644 --- a/src/styles/component-styles/navbar.css +++ b/src/styles/component-styles/navbar.css @@ -1,19 +0,0 @@ -.via-navbar { - @apply bg-white dark:bg-[#222222] border-slate-200 text-theme-app-500 dark:text-theme-app-50 font-semibold transition-colors duration-300 ease-in-out !important; -} - -.via-menu-btn-navbar { - @apply text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-slate-200 transition-colors duration-300 ease-in-out !important; -} - -.via-user-menu-btn-navbar { - @apply bg-slate-700 text-white transition-colors duration-300 ease-in-out !important; -} - -.via-user-options-navbar { - @apply text-gray-900 bg-transparent transition-colors duration-300 ease-in-out !important; -} - -.via-user-options-selected-navbar { - @apply bg-slate-700 dark:bg-slate-800 text-white transition-colors duration-300 ease-in-out !important; -} diff --git a/src/styles/globals.css b/src/styles/globals.css index 14087a2..8bdc523 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -16,13 +16,29 @@ } } +/* * { + @apply border-pink-500; +} */ + /* Additional Styles */ @import 'additional-styles/toastify.css'; +@import 'additional-styles/dropzone.css'; @import 'additional-styles/404.css'; + +/* Component Styles */ +/* @import 'component-styles/navbar.css'; → use vComponents styles instead */ @import 'component-styles/loading.css'; @import 'component-styles/sidebar.css'; -@import 'component-styles/navbar.css'; @import 'component-styles/datatable.css'; +/* @import 'component-styles/via-ui.css'; */ + +/* Page Styles */ @import 'page-styles/common.css'; @import 'page-styles/login.css'; -@import 'ui-styles/via-ui.css'; \ No newline at end of file + +/* vComponent Styles */ +@import 'vComponents/styles/generated/globals.min.css'; +@import 'vComponents/styles/generated/component-styles/navbar.min.css'; + +/* Analytics Lib Styles */ +/* @import 'analytics-lib/styles/generated/output.css'; */ \ No newline at end of file diff --git a/src/styles/page-styles/common.css b/src/styles/page-styles/common.css index f77604f..65475ce 100644 --- a/src/styles/page-styles/common.css +++ b/src/styles/page-styles/common.css @@ -7,23 +7,35 @@ } .via-input { - @apply w-full text-sm text-gray-900 dark:text-neutral-900 rounded-lg border-l-gray-100 border border-gray-300 focus:ring-stone-500 focus:border-stone-500 dark:border-stone-600 dark:placeholder-gray-400 dark:focus:border-stone-500 !important; + @apply w-full text-md bg-background text-foreground rounded-lg border-l-gray-100 border border-gray-300 focus:ring-stone-500 focus:border-stone-500 dark:border-stone-600 dark:placeholder-gray-400 dark:focus:border-stone-500 !important; +} + +.via-input:disabled { + @apply bg-gray-300 text-gray-700 dark:bg-gray-800 dark:text-gray-300 cursor-not-allowed !important; +} + +.via-input:not(div) { + @apply px-2 !important; } .via-input:not(textarea) { - @apply h-7 !important; + @apply h-8 !important; } select.via-input { @apply py-0 !important; } +.via-input-focus { + @apply border-stone-500 border-[2px] !important; +} + .invalid-feedback { @apply h-2; } .via-input-prepend { - @apply w-full text-sm text-gray-900 dark:text-neutral-900 rounded-l-lg border-l-gray-100 border border-gray-300 focus:ring-stone-500 focus:border-stone-500 dark:border-stone-600 dark:placeholder-gray-400 dark:focus:border-stone-500 !important; + @apply w-full text-sm text-foreground rounded-l-lg border border-gray-300 focus:ring-stone-500 focus:border-stone-500 dark:border-stone-600 dark:placeholder-gray-400 dark:focus:border-stone-500 !important; } .via-append-input { @@ -38,12 +50,13 @@ select.via-input { } .via-append-input-extra { - @apply w-8 absolute top-0 -right-1 h-full mr-7 text-sm font-medium text-white bg-theme-app-700 rounded-r-lg border border-theme-app-700 hover:bg-theme-app-600 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800; + @apply absolute top-0 right-0 py-1 px-3 mr-[1.7rem] w-auto h-full text-sm font-medium text-white rounded-full bg-red-700 rounded-r-md hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-800; } .via-button { @apply cursor-pointer inline-flex items-center h-8 px-2 m-1 text-white ease-linear transition-colors duration-150 rounded-md border border-gray-300 dark:border-gray-700; } + .via-div-actions { @apply flex w-full justify-center flex-wrap; } diff --git a/src/utils/globalPresets.js b/src/utils/globalPresets.js index 50647d9..408cf65 100644 --- a/src/utils/globalPresets.js +++ b/src/utils/globalPresets.js @@ -3,7 +3,7 @@ const theme = 'blue' const presets = { appTitle: 'Orbis Template', theme: `${theme}`, - svgIconUrl: 'https://www.via-asesores.com/svgicons/smartoperation/', + svgIconUrl: 'https://www.via-asesores.com/logos/logo_icons/orbisprocess_icon.svg', images: { loginFondo: 'https://www.via-asesores.com/backgrounds/smartoperation/SmartOperation_background.png', welcomeFondo: 'https://www.via-asesores.com/backgrounds/smartoperation/SmartOperation_background.png', diff --git a/tailwind.config.ts b/tailwind.config.ts index 906ddd8..fc3345c 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,34 +1,48 @@ import type { Config } from 'tailwindcss' -import standard from 'via-tailwind' +import { standard, standardThemes } from 'via-tailwind' + +const themeAppColors = { + 50: '#DDE3EB', + 100: '#B0C4D6', + 200: '#83A5C1', + 300: '#5686AC', + 400: '#296897', + 500: '#1E507B', + 600: '#1B4870', + 700: '#183F64', + 800: '#153758', + 900: '#112F4D', + 950: '#0E2741' +} + +const themeTextColors = { + principal: '#334155', + disabled: '#cbd5e1' +} const config: Config = { darkMode: 'class', content: [ - './src/**/*.{js,ts,jsx,tsx,mdx}' + './src/**/*.{js,ts,jsx,tsx,mdx}', + './node_modules/analytics-lib/dist/**/*.{js,ts,jsx,tsx}', + './node_modules/vComponents/dist/**/*.{js,ts,jsx,tsx}', + './node_modules/via-ui/dist/**/*.{js,ts,jsx,tsx}' ], theme: { extend: { colors: { - 'theme-text': { - principal: '#334155', - disabled: '#cbd5e1' - }, - 'theme-app': { - 50: '#DDE3EB', - 100: '#B0C4D6', - 200: '#83A5C1', - 300: '#5686AC', - 400: '#296897', - 500: '#1E507B', - 600: '#1B4870', - 700: '#183F64', - 800: '#153758', - 900: '#112F4D', - 950: '#0E2741' - } + 'theme-text': themeTextColors, + 'theme-app': themeAppColors } } }, - plugins: [standard] + plugins: [ + standard, + standardThemes({ + 'theme-app': themeAppColors, + 'theme-text': themeTextColors + }) + ] } + export default config