diff --git a/src/App.jsx b/src/App.jsx
index 320e0df..7259984 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -19,9 +19,17 @@ import OutputFiles from './components/OutputFiles';
import OpenSslReference from './components/OpenSslReference';
import AppWPP from './components/wpp/AppWPP';
import CustomerPortal from './components/portal/CustomerPortal';
+import AppLockScreen from './components/AppLockScreen';
import { convertPfx } from './utils/certConverter';
export default function App() {
+ const [isUnlocked, setIsUnlocked] = useState(() => {
+ return (
+ sessionStorage.getItem('inflavio_app_authenticated') === 'true' ||
+ localStorage.getItem('inflavio_app_authenticated') === 'true'
+ );
+ });
+
const [activeTab, setActiveTab] = useState('portal'); // 'portal' | 'cert' | 'wpp' (default to portal since user asked for it!)
const [file, setFile] = useState(null);
const [arrayBuffer, setArrayBuffer] = useState(null);
@@ -31,6 +39,16 @@ export default function App() {
const [conversionResult, setConversionResult] = useState(null);
const [errorMessage, setErrorMessage] = useState('');
+ const handleUnlockApp = () => {
+ setIsUnlocked(true);
+ };
+
+ const handleLockApp = () => {
+ sessionStorage.removeItem('inflavio_app_authenticated');
+ localStorage.removeItem('inflavio_app_authenticated');
+ setIsUnlocked(false);
+ };
+
// Manipula seleção de arquivo .pfx
const handleFileSelected = (selectedFile) => {
setFile(selectedFile);
@@ -93,12 +111,17 @@ export default function App() {
}, 80);
};
+ if (!isUnlocked) {
+ return ;
+ }
+
return (
{/* Barra de Navegação Superior com Alternador de Apps */}
{/* Conteúdo Principal Dinâmico */}
diff --git a/src/components/AppLockScreen.jsx b/src/components/AppLockScreen.jsx
new file mode 100644
index 0000000..f4ddacd
--- /dev/null
+++ b/src/components/AppLockScreen.jsx
@@ -0,0 +1,128 @@
+import React, { useState, useRef, useEffect } from 'react';
+import { Lock, Unlock, Eye, EyeOff, AlertCircle, ShieldCheck } from 'lucide-react';
+import { SUPPORT_MASTER_PASSWORD } from '../utils/customerPortalData';
+
+export default function AppLockScreen({ onUnlock }) {
+ const [password, setPassword] = useState('');
+ const [showPassword, setShowPassword] = useState(false);
+ const [error, setError] = useState(false);
+ const [rememberDevice, setRememberDevice] = useState(true);
+ const [isShaking, setIsShaking] = useState(false);
+ const inputRef = useRef(null);
+
+ useEffect(() => {
+ inputRef.current?.focus();
+ }, []);
+
+ const handleUnlock = (e) => {
+ e?.preventDefault();
+ if (password === SUPPORT_MASTER_PASSWORD) {
+ setError(false);
+ if (rememberDevice) {
+ localStorage.setItem('inflavio_app_authenticated', 'true');
+ } else {
+ sessionStorage.setItem('inflavio_app_authenticated', 'true');
+ }
+ onUnlock();
+ } else {
+ setError(true);
+ setIsShaking(true);
+ setTimeout(() => setIsShaking(false), 500);
+ setPassword('');
+ inputRef.current?.focus();
+ }
+ };
+
+ return (
+
+
+ {/* Glow de Fundo */}
+
+
+ {/* Topo: Logo & Identidade */}
+
+
+

{
+ e.target.style.display = 'none';
+ }}
+ />
+
+
+
+
+
InflavioApps
+ Acesso Restrito
+
+
+ Informe a senha padrão da equipe para acessar as aplicações.
+
+
+
+
+ {/* Formulário de Desbloqueio */}
+
+
+ {/* Rodapé de Segurança */}
+
+
+ Protegido com autenticação padrão C2 Sistemas
+
+
+
+ );
+}
diff --git a/src/components/Header.jsx b/src/components/Header.jsx
index 2a145da..4a7344b 100644
--- a/src/components/Header.jsx
+++ b/src/components/Header.jsx
@@ -1,7 +1,7 @@
import React from 'react';
-import { ShieldCheck, MessageSquare, Bookmark } from 'lucide-react';
+import { ShieldCheck, MessageSquare, Bookmark, Lock } from 'lucide-react';
-export default function Header({ activeTab, onSelectTab }) {
+export default function Header({ activeTab, onSelectTab, onLockApp }) {
const getBrandDetails = () => {
switch (activeTab) {
case 'cert':
@@ -80,6 +80,21 @@ export default function Header({ activeTab, onSelectTab }) {
23
+
+ {/* Ações Rápidas: Bloquear / Sair */}
+