diff --git a/.env.example b/.env.example
index b0e0288..ec05419 100644
--- a/.env.example
+++ b/.env.example
@@ -1,6 +1,9 @@
# API Configuration
# Base URL da API do HGTX
VITE_API_BASE_URL=https://prod-hgtx-intelligence-n8n.hgtx.com.br
+VITE_BASE_URL_OPEN_CODEX_APIs=https://codex-api.hgtx.com.br/api/
+VITE_BASE_URL_HGTX_CORE_API=https://core-api.hgtx.com.br/api/
+VITE_BASE_URL_HGTX_CORE=https://core.hgtx.com.br/
# API Key para autenticação
# IMPORTANTE: Mantenha esta chave segura e não compartilhe publicamente
diff --git a/index.html b/index.html
index 3b041b8..1513c1c 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,5 @@
-
+
@@ -10,11 +10,11 @@
-
+
-
-
+
+
diff --git a/package-lock.json b/package-lock.json
index fc7bedc..6a27f24 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,6 +44,7 @@
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
+ "jwt-decode": "^4.0.0",
"lucide-react": "^0.462.0",
"next-themes": "^0.3.0",
"react": "^18.3.1",
@@ -4828,6 +4829,14 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/jwt-decode": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
+ "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
diff --git a/package.json b/package.json
index 2ecde5e..e7982a7 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
+ "jwt-decode": "^4.0.0",
"lucide-react": "^0.462.0",
"next-themes": "^0.3.0",
"react": "^18.3.1",
diff --git a/public/favicon.ico b/public/favicon.ico
index dd5a126..70c2a8f 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000..3808375
Binary files /dev/null and b/public/favicon.png differ
diff --git a/public/favicon2.ico b/public/favicon2.ico
new file mode 100644
index 0000000..dd5a126
Binary files /dev/null and b/public/favicon2.ico differ
diff --git a/src/App.tsx b/src/App.tsx
index c06f45b..3603675 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,11 +2,13 @@ import { Toaster } from "@/components/ui/toaster";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
-import { BrowserRouter, Routes, Route } from "react-router-dom";
+import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import { ThemeProvider } from "next-themes";
import Index from "./pages/Index";
import NotFound from "./pages/NotFound";
import Redirect from "./pages/Redirect";
+import { GlobalFunctions } from "./GlobalFunctions";
+import React from "react";
const queryClient = new QueryClient();
@@ -23,7 +25,7 @@ const App = () => (
element={}
/>
- } />
+ : } />
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
} />
} />
@@ -35,3 +37,13 @@ const App = () => (
);
export default App;
+
+
+const HGTXLogin = () =>{
+
+ React.useEffect(() => {
+ window.location.replace(import.meta.env.VITE_BASE_URL_HGTX_CORE);
+ });
+
+ return(<>>);
+}
\ No newline at end of file
diff --git a/src/GlobalFunctions.ts b/src/GlobalFunctions.ts
new file mode 100644
index 0000000..71834f3
--- /dev/null
+++ b/src/GlobalFunctions.ts
@@ -0,0 +1,286 @@
+import { jwtDecode } from 'jwt-decode';
+import { RedirectService } from './pages/RedirectService';
+
+export class GlobalFunctions {
+
+ public static getTranferAreaObj(): TransferAreaResponse {
+ let objRetorno: TransferAreaResponse = {
+ aplicativoID: 0,
+ aplicativoNome: "",
+ areaTransferenciaID: 0,
+ dataRegistro: "",
+ estabelecimentoID: 0,
+ usuarioID: 0,
+ usuarioEmail: "",
+ usuarioNome: "",
+ aplicativoShareCode: "",
+ nivelAcesso: 0
+ };
+ try {
+ const objTransferStr = sessionStorage.getItem("TRANSFER_AREA");
+ if (
+ objTransferStr != null &&
+ objTransferStr != undefined &&
+ objTransferStr.trim() != ""
+ ) {
+ const objTransfer = JSON.parse(objTransferStr);
+ objRetorno = objTransfer;
+ }
+ } catch (error) {}
+
+ return objRetorno;
+ }
+
+ public static getRedirectComponent(): string {
+ let objRetorno = "";
+ try {
+ const objTransfer = GlobalFunctions.getTranferAreaObj();
+ if (objTransfer != null) {
+ // let objRedir = objTransfer.find(x => x.name == 'REDIRECT');
+ // objRetorno = objRedir?.value ?? '';
+ objRetorno = objTransfer.urlDestino ?? "";
+ if (objRetorno.startsWith("/")) objRetorno = objRetorno.substring(1);
+ } else {
+ objRetorno = "";
+ }
+ } catch (error) {
+ //console.log(error);
+ objRetorno = "";
+ }
+
+ return objRetorno;
+ }
+
+ public static getTransferProperty(propertyName: TransferAreaProperties): any {
+ let objRetorno: any = "";
+ try {
+ const objTransfer = this.getTranferAreaObj();
+ if (objTransfer != null) {
+ //let obj: any = objTransfer[propertyName];
+ const element = objTransfer[propertyName];
+ objRetorno = element;
+ } else {
+ objRetorno = null;
+ }
+ } catch (error) {
+ objRetorno = null;
+ }
+
+ return objRetorno;
+ }
+
+ public static isUsuarioLogado(): boolean {
+ let jsonUsuario = sessionStorage.getItem('usuarioLogado');
+ if (jsonUsuario) {
+ let tokenDecode: any = GlobalFunctions.getUsuarioLogado();
+ let d: Date = new Date();
+ let dateAtual: number = Date.UTC(d.getFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes() + 5, d.getUTCSeconds()) / 1000;
+ if (dateAtual > tokenDecode.exp) return false;
+ return true;
+ }
+ return false;
+ }
+
+ public static tokenExpired(tokenDecode: any): boolean {
+ let d: Date = new Date();
+ let dateAtual: number = Date.UTC(d.getFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes() + 5, d.getUTCSeconds()) / 1000;
+ if (dateAtual > tokenDecode.exp) return true;
+ return false;
+ }
+
+ public static handleNavigateBack(): void {
+ try {
+ // Verifica se existe histórico de navegação
+ if (window.history && window.history.length > 1) {
+ window.history.back();
+ return;
+ }
+
+ // Tenta fechar a janela
+ if (!window.closed) {
+ try {
+ const windowRef = window.open('', '_self');
+ if (windowRef) {
+ windowRef.close();
+
+ // Pequeno timeout para verificar se a janela foi fechada
+ setTimeout(() => {
+ // Se ainda estiver aberta, redireciona
+ if (!windowRef.closed) {
+ window.location.href = "https://core.hgtx.com.br/aplicativos/";
+ }
+ }, 100);
+ return;
+ }
+ } catch (closeError) {
+ console.warn("Não foi possível fechar a janela:", closeError);
+ }
+ }
+
+ // Se não conseguiu fechar, redireciona
+ window.location.href = "https://core.hgtx.com.br/aplicativos/";
+ } catch (error) {
+ // Em caso de qualquer erro, garante o redirecionamento
+ console.error("Erro ao tentar navegar:", error);
+ window.location.href = "https://core.hgtx.com.br/aplicativos/";
+ }
+ }
+
+ public static getUsuarioLogado(): UsuarioLogadoData {
+ const jsonUsuario = sessionStorage.getItem("usuarioLogado") ?? "";
+ try {
+ const objJwt = JSON.parse(jsonUsuario);
+ //return jwt_decode(objJwt.token);
+ return jwtDecode(objJwt.token);
+ } catch (error) {}
+
+ return {
+ EID: "0",
+ email: "",
+ exp: 0,
+ iat: 0,
+ jti: "",
+ name: "",
+ nbf: 0,
+ UID: "0",
+ };
+ }
+
+ public static getUsuarioLogadoToken(): string {
+ let retorno = "";
+ const jsonUsuario = sessionStorage.getItem("usuarioLogado") ?? "";
+ try {
+ const objJwt = JSON.parse(jsonUsuario);
+ retorno = objJwt.token;
+ } catch (error) {}
+
+ return retorno;
+ }
+
+ public static getUsuarioLogadoRefreshToken(): string {
+ let retorno = "";
+ const jsonUsuario = sessionStorage.getItem("usuarioLogado") ?? "";
+ try {
+ const objJwt = JSON.parse(jsonUsuario);
+ retorno = objJwt.refreshToken;
+ } catch (error) {}
+
+ return retorno;
+ }
+
+ public static getPerfilUsuario(): PerfilUsuario | null {
+ let retorno: PerfilUsuario | null = null;
+ const jsonUsuario = sessionStorage.getItem("perfilUsuario") ?? "";
+ try {
+ const objJwt = JSON.parse(jsonUsuario);
+ retorno = objJwt;
+ } catch (error) {
+ retorno = null;
+ }
+
+ return retorno;
+ }
+
+ public static getHighUserProfile(): number {
+ let retorno = 6;
+ const objPerfil = GlobalFunctions.getPerfilUsuario();
+
+ if (objPerfil) {
+ const tiposPerfil: number[] = objPerfil.results.map((v) => v.tipoPerfil);
+ retorno = Math.min(...tiposPerfil);
+ }
+
+ return retorno;
+ }
+
+ public static async getToken(): Promise {
+ let token: string = GlobalFunctions.getUsuarioLogadoToken();
+
+ const tokenDecode: any = GlobalFunctions.getUsuarioLogado();
+
+ let currentDate = new Date();
+
+ // JWT exp is in seconds
+ if ((tokenDecode.exp * 1000) < currentDate.getTime()) {
+ //console.log("Token expired.");
+ let gsikey: number = parseInt(sessionStorage.getItem('gsikey') ?? '0');
+ RedirectService.loadTransferArea(gsikey).then((response) => {
+ if(response.data.errorCode == 0){
+ sessionStorage.setItem('TRANSFER_AREA',JSON.stringify(response.data.areTrs));
+ sessionStorage.setItem('usuarioLogado',JSON.stringify({
+ token: response.data.jwt.token,
+ refreshToken: response.data.jwt.refreshToken
+ }));
+
+ token = response.data.jwt.token;
+ }
+ // else if(error !== 1401){
+ // navigate('/',{replace: true});
+ // }
+ });
+ }
+ // else {
+ // //console.log("Valid token");
+ // result = true;
+ // }
+
+ return token;
+ }
+}
+
+export interface UsuarioLogadoData {
+ UID: string;
+ EID: string;
+ name: string;
+ email: string;
+ jti: string;
+ nbf: number;
+ exp: number;
+ iat: number;
+}
+
+export interface TransferAreaResponse {
+ estabelecimentoID: number;
+ nivelAcesso: number;
+ aplicativoID: number;
+ usuarioID: number;
+ areaTransferenciaID: number;
+ dataRegistro: string;
+ urlBase?: string;
+ urlDestino?: string;
+ aplicativoNome: string;
+ usuarioNome: string;
+ usuarioEmail: string;
+ aplicativoShareCode: string;
+}
+
+export enum TransferAreaProperties {
+ EstabelecimentoCodigo = "estabelecimentoID",
+ UsuarioCodigo = "usuarioID",
+ UsuarioNome = "usuarioNome",
+ UsuarioEmail = "usuarioEmail",
+ APP_COD = "aplicativoID",
+ APP_TITULO = "aplicativoNome",
+ areaTransferenciaID = "areaTransferenciaID",
+ urlBase = "urlBase",
+ urlDestino = "urlDestino",
+ aplicativoShareCode = "aplicativoShareCode",
+ nivelAcesso = "nivelAcesso",
+}
+
+type PerfilUsuario = {
+ errorCode: number;
+ errorMessage: string;
+ results: PerfilUsuarioResult[];
+};
+
+export type PerfilUsuarioResult = {
+ tipoPerfil: number;
+ itens: PerfilUsuarioItem[];
+};
+
+type PerfilUsuarioItem = {
+ id: number;
+ descricao: string;
+ identificador: string;
+};
diff --git a/src/components/FullScreenLoader.tsx b/src/components/FullScreenLoader.tsx
index aed2a98..ff4ad25 100644
--- a/src/components/FullScreenLoader.tsx
+++ b/src/components/FullScreenLoader.tsx
@@ -27,7 +27,7 @@ export default function FullScreenLoader({ show, text = "Carregando..." }: FullS
}`}
>
diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx
index cdf0350..08eaa8b 100644
--- a/src/components/Layout.tsx
+++ b/src/components/Layout.tsx
@@ -3,6 +3,7 @@ import { MessageSquare, Image, AudioLines, Mic, ArrowLeft, Plus, ChevronLeft, Ch
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { ThemeToggle } from "@/components/ThemeToggle";
+import { GlobalFunctions } from "@/GlobalFunctions";
interface LayoutProps {
children: React.ReactNode;
@@ -75,7 +76,7 @@ export const Layout = ({ children, activeTab, onTabChange }: LayoutProps) => {
Tema
-