Compare commits
3 Commits
2b2886a75c
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5099311373 | |||
| 8cc5954563 | |||
| f0b86641b6 |
+18
-2
@@ -1,3 +1,19 @@
|
|||||||
VITE_ESTABELECIMENTO_ID=27
|
# API Configuration
|
||||||
VITE_USER_EMAIL=your-email@example.com
|
# Base URL da API do HGTX
|
||||||
VITE_API_BASE_URL=https://prod-hgtx-intelligence-n8n.hgtx.com.br
|
VITE_API_BASE_URL=https://prod-hgtx-intelligence-n8n.hgtx.com.br
|
||||||
|
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
|
||||||
|
VITE_API_KEY=zp01m-pmn5q-0l2eg-aj5vy
|
||||||
|
|
||||||
|
# User Configuration
|
||||||
|
# Configure com os dados do usuário/estabelecimento
|
||||||
|
VITE_USER_EMAIL=suporte@hightechx.com
|
||||||
|
VITE_ESTABELECIMENTO_ID=27
|
||||||
|
|
||||||
|
# Instruções:
|
||||||
|
# 1. Copie este arquivo para .env
|
||||||
|
# 2. Substitua os valores acima com as configurações reais
|
||||||
|
# 3. NUNCA commite o arquivo .env no git
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# API Configuration
|
||||||
|
# Base URL da API do HGTX
|
||||||
|
VITE_API_BASE_URL=https://prod-hgtx-intelligence-n8n.hgtx.com.br
|
||||||
|
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
|
||||||
|
VITE_API_KEY=zp01m-pmn5q-0l2eg-aj5vy
|
||||||
|
|
||||||
|
# User Configuration
|
||||||
|
# Configure com os dados do usuário/estabelecimento
|
||||||
|
VITE_USER_EMAIL=suporte@hightechx.com
|
||||||
|
VITE_ESTABELECIMENTO_ID=1
|
||||||
|
|
||||||
|
# Instruções:
|
||||||
|
# 1. Copie este arquivo para .env
|
||||||
|
# 2. Substitua os valores acima com as configurações reais
|
||||||
|
# 3. NUNCA commite o arquivo .env no git
|
||||||
+3
-2
@@ -2,6 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/x-icon" href="/ficon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>HGTX PromptLab - Laboratório de Prompts de IA</title>
|
<title>HGTX PromptLab - Laboratório de Prompts de IA</title>
|
||||||
<meta name="description" content="Crie, edite, teste e versione prompts para agentes de IA de forma profissional e eficiente" />
|
<meta name="description" content="Crie, edite, teste e versione prompts para agentes de IA de forma profissional e eficiente" />
|
||||||
@@ -13,11 +14,11 @@
|
|||||||
<meta property="og:title" content="HGTX PromptLab - Laboratório de Prompts de IA" />
|
<meta property="og:title" content="HGTX PromptLab - Laboratório de Prompts de IA" />
|
||||||
<meta property="og:description" content="Crie, edite, teste e versione prompts para agentes de IA de forma profissional e eficiente" />
|
<meta property="og:description" content="Crie, edite, teste e versione prompts para agentes de IA de forma profissional e eficiente" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
|
<meta property="og:image" content="/favicon.png" />
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:site" content="@lovable_dev" />
|
<meta name="twitter:site" content="@lovable_dev" />
|
||||||
<meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
|
<meta name="twitter:image" content="/favicon.png" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Generated
+9
@@ -44,6 +44,7 @@
|
|||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
"lucide-react": "^0.462.0",
|
"lucide-react": "^0.462.0",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
@@ -4828,6 +4829,14 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/keyv": {
|
||||||
"version": "4.5.4",
|
"version": "4.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
"lucide-react": "^0.462.0",
|
"lucide-react": "^0.462.0",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
+19
-5
@@ -10,6 +10,8 @@ import AgentDetails from "./pages/AgentDetails";
|
|||||||
import TestPrompt from "./pages/TestPrompt";
|
import TestPrompt from "./pages/TestPrompt";
|
||||||
import History from "./pages/History";
|
import History from "./pages/History";
|
||||||
import NotFound from "./pages/NotFound";
|
import NotFound from "./pages/NotFound";
|
||||||
|
import Redirect from "./pages/Redirect";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
@@ -21,14 +23,26 @@ const App = () => (
|
|||||||
<Sonner />
|
<Sonner />
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route element={<AppLayout />}>
|
<Route
|
||||||
<Route path="/" element={<Agents />} />
|
path="/redir/:gsikey"
|
||||||
<Route path="/agents/:id" element={<AgentDetails />} />
|
element={<Redirect />}
|
||||||
<Route path="/test" element={<TestPrompt />} />
|
/>
|
||||||
<Route path="/history" element={<History />} />
|
{/* Layout principal para /prompt-labs */}
|
||||||
|
<Route path="/prompt-labs" element={<AppLayout />}>
|
||||||
|
{/* Página inicial: /prompt-labs */}
|
||||||
|
<Route index element={<Agents />} />
|
||||||
|
|
||||||
|
{/* Rotas internas */}
|
||||||
|
<Route path="agents/:id" element={<AgentDetails />} />
|
||||||
|
<Route path="test" element={<TestPrompt />} />
|
||||||
|
<Route path="history" element={<History />} />
|
||||||
|
|
||||||
|
{/* Catch-all exclusivo para o contexto de /prompt-labs */}
|
||||||
|
<Route path="*" element={<NotFound />} />
|
||||||
</Route>
|
</Route>
|
||||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
|
<Route path="/404" element={<NotFound />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|||||||
@@ -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 = <TransferAreaResponse>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 = <PerfilUsuario>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<string> {
|
||||||
|
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;
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
interface FullScreenLoaderProps {
|
||||||
|
show: boolean;
|
||||||
|
text?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FullScreenLoader({ show, text = "Carregando..." }: FullScreenLoaderProps) {
|
||||||
|
const [visible, setVisible] = useState(show);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (show) setVisible(true);
|
||||||
|
else {
|
||||||
|
// adiciona um pequeno atraso para suavizar o fade-out
|
||||||
|
const timeout = setTimeout(() => setVisible(false), 200);
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
}, [show]);
|
||||||
|
|
||||||
|
if (!visible && !show) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`fixed inset-0 z-[9999] flex items-center justify-center bg-background/80 backdrop-blur-sm transition-opacity duration-200 ${
|
||||||
|
show ? "opacity-100" : "opacity-0 pointer-events-none"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col items-center gap-3 p-6 rounded-2xl bg-card shadow-lg border border-border transition-all duration-200">
|
||||||
|
<Loader2 className="h-10 w-10 animate-spin text-primary" />
|
||||||
|
<p className="text-card-foreground text-sm font-medium">{text}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@@ -19,8 +19,7 @@ import {
|
|||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import { createAgent } from "@/lib/api/agents";
|
import { createAgent, getAIModels } from "@/lib/api/agents";
|
||||||
import { AI_MODELS, getModelIdByValue } from "@/lib/constants/aiModels";
|
|
||||||
|
|
||||||
interface CreateAgentDialogProps {
|
interface CreateAgentDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -32,7 +31,13 @@ export function CreateAgentDialog({ open, onOpenChange }: CreateAgentDialogProps
|
|||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
const [selectedModel, setSelectedModel] = useState("");
|
const [selectedModelId, setSelectedModelId] = useState("");
|
||||||
|
|
||||||
|
// Buscar modelos da API
|
||||||
|
const { data: aiModels = [], isLoading: isLoadingModels } = useQuery({
|
||||||
|
queryKey: ["aiModels"],
|
||||||
|
queryFn: getAIModels,
|
||||||
|
});
|
||||||
|
|
||||||
const createAgentMutation = useMutation({
|
const createAgentMutation = useMutation({
|
||||||
mutationFn: ({ name, modelId }: { name: string; modelId: number }) =>
|
mutationFn: ({ name, modelId }: { name: string; modelId: number }) =>
|
||||||
@@ -49,11 +54,11 @@ export function CreateAgentDialog({ open, onOpenChange }: CreateAgentDialogProps
|
|||||||
onOpenChange(false);
|
onOpenChange(false);
|
||||||
|
|
||||||
// Navegar para a tela de detalhes do novo agente
|
// Navegar para a tela de detalhes do novo agente
|
||||||
navigate(`/agents/${data.agent_id}`);
|
navigate(`/prompt-labs/agents/${data.agent_id}`);
|
||||||
|
|
||||||
// Reset form
|
// Reset form
|
||||||
setName("");
|
setName("");
|
||||||
setSelectedModel("");
|
setSelectedModelId("");
|
||||||
},
|
},
|
||||||
onError: (error: any) => {
|
onError: (error: any) => {
|
||||||
toast({
|
toast({
|
||||||
@@ -65,17 +70,16 @@ export function CreateAgentDialog({ open, onOpenChange }: CreateAgentDialogProps
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleCreate = () => {
|
const handleCreate = () => {
|
||||||
const modelId = getModelIdByValue(selectedModel);
|
if (!selectedModelId) {
|
||||||
if (!modelId) {
|
|
||||||
toast({
|
toast({
|
||||||
title: "Erro",
|
title: "Erro",
|
||||||
description: "Modelo de IA inválido.",
|
description: "Selecione um modelo de IA.",
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
createAgentMutation.mutate({ name, modelId });
|
createAgentMutation.mutate({ name, modelId: parseInt(selectedModelId) });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -101,13 +105,13 @@ export function CreateAgentDialog({ open, onOpenChange }: CreateAgentDialogProps
|
|||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="model">Modelo de IA</Label>
|
<Label htmlFor="model">Modelo de IA</Label>
|
||||||
<Select value={selectedModel} onValueChange={setSelectedModel}>
|
<Select value={selectedModelId} onValueChange={setSelectedModelId} disabled={isLoadingModels}>
|
||||||
<SelectTrigger id="model">
|
<SelectTrigger id="model">
|
||||||
<SelectValue placeholder="Selecione um modelo" />
|
<SelectValue placeholder={isLoadingModels ? "Carregando modelos..." : "Selecione um modelo"} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{AI_MODELS.map((model) => (
|
{aiModels.filter(model => model.is_active === 1).map((model) => (
|
||||||
<SelectItem key={model.value} value={model.value}>
|
<SelectItem key={model.id} value={model.id.toString()}>
|
||||||
{model.name}
|
{model.name}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
@@ -121,7 +125,7 @@ export function CreateAgentDialog({ open, onOpenChange }: CreateAgentDialogProps
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleCreate}
|
onClick={handleCreate}
|
||||||
disabled={!name || !selectedModel || createAgentMutation.isPending}
|
disabled={!name || !selectedModelId || createAgentMutation.isPending || isLoadingModels}
|
||||||
>
|
>
|
||||||
{createAgentMutation.isPending ? "Criando..." : "Criar Agente"}
|
{createAgentMutation.isPending ? "Criando..." : "Criar Agente"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,8 +1,23 @@
|
|||||||
|
import React from "react";
|
||||||
import { AppSidebar } from "./AppSidebar";
|
import { AppSidebar } from "./AppSidebar";
|
||||||
import { MobileNav } from "./MobileNav";
|
import { MobileNav } from "./MobileNav";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet, useLocation } from "react-router-dom";
|
||||||
|
import { GlobalFunctions } from "@/GlobalFunctions";
|
||||||
|
|
||||||
export function AppLayout() {
|
export function AppLayout() {
|
||||||
|
|
||||||
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
|
// ignora layout se for redirecionamento
|
||||||
|
if (pathname.startsWith("/redir")) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
console.log('Aqui');
|
||||||
|
if(!GlobalFunctions.isUsuarioLogado())window.location.replace(import.meta.env.VITE_BASE_URL_HGTX_CORE);
|
||||||
|
},[]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen w-full bg-background overflow-hidden">
|
<div className="flex h-screen w-full bg-background overflow-hidden">
|
||||||
<MobileNav />
|
<MobileNav />
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ import {
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import { ThemeToggle } from "./ThemeToggle";
|
import { ThemeToggle } from "./ThemeToggle";
|
||||||
|
import { GlobalFunctions } from "@/GlobalFunctions";
|
||||||
|
|
||||||
const menuItems = [
|
const menuItems = [
|
||||||
{ title: "Agentes", url: "/", icon: Bot },
|
{ title: "Agentes", url: "/prompt-labs", icon: Bot },
|
||||||
{ title: "Testar Prompt", url: "/test", icon: TestTube },
|
{ title: "Testar Prompt", url: "/prompt-labs/test", icon: TestTube },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function AppSidebar() {
|
export function AppSidebar() {
|
||||||
@@ -134,6 +135,7 @@ export function AppSidebar() {
|
|||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
onClick={GlobalFunctions.handleNavigateBack}
|
||||||
className="w-full justify-start gap-2 text-sidebar-foreground"
|
className="w-full justify-start gap-2 text-sidebar-foreground"
|
||||||
>
|
>
|
||||||
<ArrowLeft className="w-4 h-4" />
|
<ArrowLeft className="w-4 h-4" />
|
||||||
|
|||||||
+13
-2
@@ -1,8 +1,8 @@
|
|||||||
import api from "./axios";
|
import api from "./axios";
|
||||||
import type {
|
import type {
|
||||||
Agent,
|
|
||||||
AgentDetails,
|
AgentDetails,
|
||||||
AgentVersion,
|
AgentVersion,
|
||||||
|
AIModel,
|
||||||
CreateAgentRequest,
|
CreateAgentRequest,
|
||||||
CreateAgentResponse,
|
CreateAgentResponse,
|
||||||
EditAgentRequest,
|
EditAgentRequest,
|
||||||
@@ -13,8 +13,9 @@ import type {
|
|||||||
ToggleAgentStatusResponse,
|
ToggleAgentStatusResponse,
|
||||||
ListAgentsResponse,
|
ListAgentsResponse,
|
||||||
} from "../types/agent";
|
} from "../types/agent";
|
||||||
|
import { GlobalFunctions, TransferAreaProperties } from "@/GlobalFunctions";
|
||||||
|
|
||||||
const estabelecimentoId = import.meta.env.VITE_ESTABELECIMENTO_ID;
|
const estabelecimentoId = GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo) ?? import.meta.env.VITE_ESTABELECIMENTO_ID;
|
||||||
const userEmail = import.meta.env.VITE_USER_EMAIL;
|
const userEmail = import.meta.env.VITE_USER_EMAIL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,3 +149,13 @@ export const getAgentVersions = async (
|
|||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtém todos os modelos de IA disponíveis
|
||||||
|
*/
|
||||||
|
export const getAIModels = async (): Promise<AIModel[]> => {
|
||||||
|
const response = await api.get<AIModel[]>(
|
||||||
|
"/webhook/codex/get_models_ia"
|
||||||
|
);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|||||||
+2
-1
@@ -5,8 +5,9 @@ import type {
|
|||||||
TestAgentRequest,
|
TestAgentRequest,
|
||||||
TestAgentResponse,
|
TestAgentResponse,
|
||||||
} from "../types/chat";
|
} from "../types/chat";
|
||||||
|
import { GlobalFunctions, TransferAreaProperties } from "@/GlobalFunctions";
|
||||||
|
|
||||||
const estabelecimentoId = import.meta.env.VITE_ESTABELECIMENTO_ID;
|
const estabelecimentoId = GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo) ?? import.meta.env.VITE_ESTABELECIMENTO_ID;
|
||||||
const userEmail = import.meta.env.VITE_USER_EMAIL;
|
const userEmail = import.meta.env.VITE_USER_EMAIL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,33 +1,30 @@
|
|||||||
import { AIModel } from "../types/agent";
|
import { AIModel } from "../types/agent";
|
||||||
|
|
||||||
// Mapeamento de modelos de IA conforme a API
|
/**
|
||||||
// Nota: Os IDs precisam ser confirmados com a API real
|
* Este arquivo contém funções auxiliares para trabalhar com modelos de IA.
|
||||||
export const AI_MODELS: AIModel[] = [
|
* Os modelos agora são buscados dinamicamente da API através da função getAIModels() em @/lib/api/agents
|
||||||
{ id: 1, name: "Google Gemini 2.5 Pro", value: "google/gemini-2.5-pro" },
|
*
|
||||||
{ id: 2, name: "Google Gemini 2.5 Flash", value: "google/gemini-2.5-flash" },
|
* @deprecated AI_MODELS - Use getAIModels() da API ao invés disso
|
||||||
{ id: 3, name: "Google Gemini 2.5 Flash Lite", value: "google/gemini-2.5-flash-lite" },
|
*/
|
||||||
{ id: 4, name: "OpenAI GPT-5", value: "openai/gpt-5" },
|
|
||||||
{ id: 5, name: "OpenAI GPT-5 Mini", value: "openai/gpt-5-mini" },
|
|
||||||
{ id: 6, name: "OpenAI GPT-5 Nano", value: "openai/gpt-5-nano" },
|
|
||||||
{ id: 7, name: "Anthropic Claude Sonnet 4.5", value: "anthropic/claude-sonnet-4.5" },
|
|
||||||
{ id: 8, name: "Anthropic Claude Haiku 4.5", value: "anthropic/claude-haiku-4.5" },
|
|
||||||
{ id: 9, name: "Anthropic Claude Opus 4.5", value: "anthropic/claude-opus-4.5" },
|
|
||||||
{ id: 10, name: "Claude Haiku 4.5", value: "claude/haiku-4.5" },
|
|
||||||
];
|
|
||||||
|
|
||||||
// Função auxiliar para obter o nome do modelo pelo ID
|
// Função auxiliar para obter o nome do modelo pelo ID
|
||||||
export const getModelNameById = (id: number): string => {
|
export const getModelNameById = (models: AIModel[], id: number): string => {
|
||||||
const model = AI_MODELS.find((m) => m.id === id);
|
const model = models.find((m) => m.id === id);
|
||||||
return model?.name || "Modelo Desconhecido";
|
return model?.name || "Modelo Desconhecido";
|
||||||
};
|
};
|
||||||
|
|
||||||
// Função auxiliar para obter o modelo pelo value
|
// Função auxiliar para obter o modelo pelo identifier
|
||||||
export const getModelByValue = (value: string): AIModel | undefined => {
|
export const getModelByIdentifier = (models: AIModel[], identifier: string): AIModel | undefined => {
|
||||||
return AI_MODELS.find((m) => m.value === value);
|
return models.find((m) => m.model_identifier === identifier);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Função auxiliar para obter o ID pelo value
|
// Função auxiliar para obter o ID pelo identifier
|
||||||
export const getModelIdByValue = (value: string): number | undefined => {
|
export const getModelIdByIdentifier = (models: AIModel[], identifier: string): number | undefined => {
|
||||||
const model = getModelByValue(value);
|
const model = getModelByIdentifier(models, identifier);
|
||||||
return model?.id;
|
return model?.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Função auxiliar para filtrar apenas modelos ativos
|
||||||
|
export const getActiveModels = (models: AIModel[]): AIModel[] => {
|
||||||
|
return models.filter((m) => m.is_active === 1);
|
||||||
|
};
|
||||||
|
|||||||
@@ -115,6 +115,12 @@ export interface ListAgentsResponse {
|
|||||||
|
|
||||||
export interface AIModel {
|
export interface AIModel {
|
||||||
id: number;
|
id: number;
|
||||||
|
provider_id: number;
|
||||||
name: string;
|
name: string;
|
||||||
value: string;
|
model_identifier: string;
|
||||||
|
cost_input_per_million: string;
|
||||||
|
cost_output_per_million: string;
|
||||||
|
is_active: number;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-14
@@ -27,8 +27,8 @@ import {
|
|||||||
editAgentName,
|
editAgentName,
|
||||||
toggleAgentStatus,
|
toggleAgentStatus,
|
||||||
getAgentVersions,
|
getAgentVersions,
|
||||||
|
getAIModels,
|
||||||
} from "@/lib/api/agents";
|
} from "@/lib/api/agents";
|
||||||
import { AI_MODELS, getModelIdByValue } from "@/lib/constants/aiModels";
|
|
||||||
|
|
||||||
export default function AgentDetails() {
|
export default function AgentDetails() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -40,9 +40,15 @@ export default function AgentDetails() {
|
|||||||
const [isDeactivateDialogOpen, setIsDeactivateDialogOpen] = useState(false);
|
const [isDeactivateDialogOpen, setIsDeactivateDialogOpen] = useState(false);
|
||||||
const [isEditingName, setIsEditingName] = useState(false);
|
const [isEditingName, setIsEditingName] = useState(false);
|
||||||
const [tempName, setTempName] = useState("");
|
const [tempName, setTempName] = useState("");
|
||||||
const [selectedModel, setSelectedModel] = useState("");
|
const [selectedModelId, setSelectedModelId] = useState<number | undefined>();
|
||||||
const [systemPrompt, setSystemPrompt] = useState("");
|
const [systemPrompt, setSystemPrompt] = useState("");
|
||||||
|
|
||||||
|
// Fetch AI models
|
||||||
|
const { data: aiModels = [], isLoading: isLoadingModels } = useQuery({
|
||||||
|
queryKey: ["aiModels"],
|
||||||
|
queryFn: getAIModels,
|
||||||
|
});
|
||||||
|
|
||||||
// Fetch agent details
|
// Fetch agent details
|
||||||
const {
|
const {
|
||||||
data: agentDetails,
|
data: agentDetails,
|
||||||
@@ -68,8 +74,7 @@ export default function AgentDetails() {
|
|||||||
// Update local state when agent details are loaded
|
// Update local state when agent details are loaded
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (agentDetails) {
|
if (agentDetails) {
|
||||||
const model = AI_MODELS.find((m) => m.id === agentDetails.model_id);
|
setSelectedModelId(agentDetails.model_id);
|
||||||
setSelectedModel(model?.value || "");
|
|
||||||
setSystemPrompt(agentDetails.system_prompt);
|
setSystemPrompt(agentDetails.system_prompt);
|
||||||
setTempName(agentDetails.name);
|
setTempName(agentDetails.name);
|
||||||
}
|
}
|
||||||
@@ -148,18 +153,17 @@ export default function AgentDetails() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSave = (versionType: "major" | "minor" | "patch", notes: string) => {
|
const handleSave = (versionType: "major" | "minor" | "patch", notes: string) => {
|
||||||
const modelId = getModelIdByValue(selectedModel);
|
if (!selectedModelId) {
|
||||||
if (!modelId) {
|
|
||||||
toast({
|
toast({
|
||||||
title: "Erro",
|
title: "Erro",
|
||||||
description: "Modelo de IA inválido.",
|
description: "Selecione um modelo de IA.",
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
editAgentMutation.mutate({
|
editAgentMutation.mutate({
|
||||||
model_id: modelId,
|
model_id: selectedModelId,
|
||||||
system_prompt: systemPrompt,
|
system_prompt: systemPrompt,
|
||||||
version_type: versionType,
|
version_type: versionType,
|
||||||
notes,
|
notes,
|
||||||
@@ -236,7 +240,7 @@ export default function AgentDetails() {
|
|||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
className="mb-4 gap-2"
|
className="mb-4 gap-2"
|
||||||
onClick={() => navigate("/")}
|
onClick={() => navigate("/prompt-labs")}
|
||||||
>
|
>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Voltar para Agentes
|
Voltar para Agentes
|
||||||
@@ -341,15 +345,16 @@ export default function AgentDetails() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Select
|
<Select
|
||||||
value={selectedModel}
|
value={selectedModelId?.toString()}
|
||||||
onValueChange={setSelectedModel}
|
onValueChange={(value) => setSelectedModelId(parseInt(value))}
|
||||||
|
disabled={isLoadingModels}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue />
|
<SelectValue placeholder={isLoadingModels ? "Carregando modelos..." : "Selecione um modelo"} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{AI_MODELS.map((model) => (
|
{aiModels.filter(model => model.is_active === 1).map((model) => (
|
||||||
<SelectItem key={model.value} value={model.value}>
|
<SelectItem key={model.id} value={model.id.toString()}>
|
||||||
{model.name}
|
{model.name}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ export default function Agents() {
|
|||||||
<Card
|
<Card
|
||||||
key={agent.agente_id}
|
key={agent.agente_id}
|
||||||
className="group relative overflow-hidden border-2 transition-all duration-300 hover:shadow-lg hover:scale-[1.02] bg-gradient-to-br from-card to-card/50 cursor-pointer"
|
className="group relative overflow-hidden border-2 transition-all duration-300 hover:shadow-lg hover:scale-[1.02] bg-gradient-to-br from-card to-card/50 cursor-pointer"
|
||||||
onClick={() => navigate(`/agents/${agent.agente_id}`)}
|
onClick={() => navigate(`/prompt-labs/agents/${agent.agente_id}`)}
|
||||||
>
|
>
|
||||||
{/* Glow effect on hover */}
|
{/* Glow effect on hover */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-primary/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-primary/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
import { GlobalFunctions } from "@/GlobalFunctions";
|
||||||
|
|
||||||
const NotFound = () => {
|
const NotFound = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -13,9 +14,15 @@ const NotFound = () => {
|
|||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h1 className="mb-4 text-4xl font-bold">404</h1>
|
<h1 className="mb-4 text-4xl font-bold">404</h1>
|
||||||
<p className="mb-4 text-xl text-gray-600">Oops! Page not found</p>
|
<p className="mb-4 text-xl text-gray-600">Oops! Page not found</p>
|
||||||
<a href="/" className="text-blue-500 underline hover:text-blue-700">
|
{/* <a href="/" className="text-blue-500 underline hover:text-blue-700">
|
||||||
Return to Home
|
Return to Home
|
||||||
</a>
|
</a> */}
|
||||||
|
<button
|
||||||
|
className="text-blue-500 underline hover:text-blue-700"
|
||||||
|
onClick={GlobalFunctions.handleNavigateBack}
|
||||||
|
>
|
||||||
|
Return to Home
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
import { GlobalFunctions } from "@/GlobalFunctions";
|
||||||
|
import { RedirectService } from "./RedirectService";
|
||||||
|
import React from "react";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import FullScreenLoader from "@/components/FullScreenLoader";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function Redirect() {
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
let { gsikey } = useParams();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
let error: number = 0;
|
||||||
|
sessionStorage.setItem('gsikey', gsikey ?? '0');
|
||||||
|
RedirectService.loadTransferArea(parseInt(gsikey ?? '0')).then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
error = response.data.errorCode;
|
||||||
|
//msg = response.data.errorMessage;
|
||||||
|
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
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// else if(error !== 1401){
|
||||||
|
// navigate('/',{replace: true});
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
.catch((_err) => {
|
||||||
|
navigate('/404',{replace: true});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if(error == 0 || error === 1401){
|
||||||
|
//navigate(`/${GlobalFunctions.getRedirectComponent()}`,{replace: true});
|
||||||
|
window.location.replace(`/${GlobalFunctions.getRedirectComponent()}`);
|
||||||
|
}
|
||||||
|
// else if(error === 1401){
|
||||||
|
// navigate({pathname: '/',search:`?p=${window.btoa(msg)}`},{replace: true});
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FullScreenLoader show={true} text="Carregando...Aguarde..." />
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { GlobalFunctions, TransferAreaProperties } from "@/GlobalFunctions";
|
||||||
|
import axios from "axios";
|
||||||
|
const endPoint: string = 'v1/redirect/';
|
||||||
|
|
||||||
|
export class RedirectService{
|
||||||
|
|
||||||
|
public static loadTransferArea(gsikey: number): Promise<any>{
|
||||||
|
return axios.get(`${import.meta.env.VITE_BASE_URL_HGTX_CORE_API}${endPoint}get_component/${gsikey}/S`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async validaAcessoApp(urlDestino: string): Promise<any>{
|
||||||
|
//let token = await GlobalFunctions.getToken();
|
||||||
|
let usuLogado = GlobalFunctions.getUsuarioLogado();
|
||||||
|
let usuCod: string = GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioCodigo);
|
||||||
|
let estCod: string = usuLogado.EID;
|
||||||
|
|
||||||
|
let urlDestinoPost: string = urlDestino;//urlDestino.trim().length < 1 ? GlobalFunctions.getTransferProperty(TransferAreaProperties.urlDestino) : urlDestino;
|
||||||
|
if(urlDestinoPost.trim().length < 1){
|
||||||
|
try {
|
||||||
|
let pathSplit = window.location.pathname.split('/');
|
||||||
|
|
||||||
|
urlDestinoPost = `/${pathSplit[pathSplit.length-2]}/${pathSplit[pathSplit.length-1]}`;
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//const heads = { headers: {'Content-Type':'application/json; charset=utf-8','Authorization': `Bearer ${token}`} };
|
||||||
|
const heads = { headers: {'Content-Type':'application/json; charset=utf-8'} };
|
||||||
|
return axios.post(`${import.meta.env.VITE_BASE_URL_HGTX_CORE_API}v1/aplicativos/validar_acesso_app?usuCod=${usuCod}&estCod=${estCod}`,{
|
||||||
|
"urlDestino": urlDestinoPost
|
||||||
|
},heads);
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+12
@@ -1 +1,13 @@
|
|||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_API_BASE_URL: string
|
||||||
|
readonly VITE_API_KEY: string
|
||||||
|
readonly VITE_USER_EMAIL: string
|
||||||
|
readonly VITE_ESTABELECIMENTO_ID: string
|
||||||
|
readonly VITE_BASE_URL_HGTX_CORE_API: string
|
||||||
|
readonly VITE_BASE_URL_HGTX_CORE: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user