Auto-deploy: 2026-01-13 12:13:35 | 5 arquivo(s) alterado(s)
This commit is contained in:
parent
490538d1ca
commit
eb6a56dcc9
|
|
@ -174,6 +174,6 @@ Em caso de problemas:
|
|||
|
||||
---
|
||||
|
||||
**Última atualização**: 2026-01-13
|
||||
**Versão**: 2.0
|
||||
**Última atualização**: 2026-01-13 (Teste Auto-Sync 12:15)
|
||||
**Versão**: 2.1
|
||||
**Autor**: Antigravity AI
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
|
||||
/**
|
||||
* WorkspaceGuard
|
||||
* Protege o ambiente Workspace durante a fase de ajuste usando uma flag de sessão.
|
||||
*/
|
||||
export const WorkspaceGuard = ({ children }) => {
|
||||
const hasAccess = sessionStorage.getItem('workspace_access') === 'true';
|
||||
|
||||
if (!hasAccess) {
|
||||
return <Navigate to="/plataforma/workspace/login" replace />;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
export * from './components/WorkspaceLayout';
|
||||
export * from './components/WorkspaceGuard';
|
||||
export * from './views/IncomesView';
|
||||
export * from './views/ExpensesView';
|
||||
export * from './views/ReconciliationView';
|
||||
export * from './views/LoginView';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Shield, Lock, ArrowRight, Zap, Eye, EyeOff } from 'lucide-react';
|
||||
|
||||
export const LoginView = () => {
|
||||
const [password, setPassword] = useState('');
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Senhas de teste definidas conforme solicitado
|
||||
const TEST_PASSWORDS = ['itguys2026', 'workspace@test', 'admin123'];
|
||||
|
||||
const handleLogin = (e) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
setError('');
|
||||
|
||||
setTimeout(() => {
|
||||
if (TEST_PASSWORDS.includes(password)) {
|
||||
sessionStorage.setItem('workspace_access', 'true');
|
||||
navigate('/plataforma/workspace');
|
||||
} else {
|
||||
setError('Senha de acesso inválida para este ambiente.');
|
||||
setLoading(false);
|
||||
}
|
||||
}, 800);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="workspace-theme min-h-screen bg-[#050914] flex items-center justify-center p-6 relative overflow-hidden font-sans">
|
||||
{/* Luzes de fundo */}
|
||||
<div className="absolute top-[-10%] left-[-10%] w-[40%] h-[40%] bg-[var(--workspace-sec-2-light)]/10 rounded-full blur-[120px] animate-pulse" />
|
||||
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-[var(--workspace-sec-3-light)]/10 rounded-full blur-[120px] animate-pulse" />
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
className="w-full max-w-md z-10"
|
||||
>
|
||||
<div className="bg-white/5 backdrop-blur-2xl border border-white/10 rounded-[2.5rem] p-10 shadow-2xl space-y-8">
|
||||
<div className="text-center space-y-4">
|
||||
<div className="w-20 h-20 bg-gradient-to-br from-[var(--workspace-sec-1-light)] to-[var(--workspace-sec-3-light)] rounded-3xl mx-auto flex items-center justify-center shadow-lg shadow-[var(--workspace-sec-1-light)]/20">
|
||||
<Shield size={40} className="text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-3xl font-black text-white tracking-tighter uppercase italic">Workspace</h1>
|
||||
<p className="text-slate-400 text-sm font-bold uppercase tracking-[0.2em] mt-1">Acesso Restrito - Teste</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleLogin} className="space-y-6">
|
||||
<div className="space-y-2 group">
|
||||
<label className="text-[10px] font-black uppercase tracking-[0.2em] text-slate-500 ml-1 group-focus-within:text-[var(--workspace-sec-2-light)] transition-colors">
|
||||
Senha de Acesso
|
||||
</label>
|
||||
<div className="relative">
|
||||
<div className="absolute left-4 top-1/2 -translate-y-1/2 text-slate-500 group-focus-within:text-[var(--workspace-sec-2-light)] transition-colors">
|
||||
<Lock size={20} />
|
||||
</div>
|
||||
<input
|
||||
type={showPassword ? "text" : "password"}
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="••••••••"
|
||||
className="w-full pl-12 pr-12 py-4 bg-white/5 border border-white/10 rounded-2xl focus:border-[var(--workspace-sec-2-light)] focus:ring-1 focus:ring-[var(--workspace-sec-2-light)] outline-none transition-all text-white font-medium"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 text-slate-500 hover:text-white transition-colors"
|
||||
>
|
||||
{showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="p-4 bg-red-500/10 border border-red-500/20 rounded-xl text-red-400 text-[10px] font-black uppercase tracking-tight flex items-center gap-3"
|
||||
>
|
||||
<Zap size={14} className="fill-red-400" /> {error}
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="w-full py-5 bg-gradient-to-r from-[var(--workspace-sec-1-light)] to-[var(--workspace-sec-2-light)] hover:brightness-110 text-white font-black rounded-2xl shadow-xl shadow-[var(--workspace-sec-1-light)]/20 transition-all flex items-center justify-center gap-3 uppercase tracking-[0.15em] text-xs"
|
||||
>
|
||||
{loading ? (
|
||||
<div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
||||
) : (
|
||||
<>
|
||||
Entrar no Workspace <ArrowRight size={18} />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p className="text-center text-[10px] font-medium text-slate-500 uppercase tracking-widest pt-4">
|
||||
Ambiente em Construção • iTGUYS 2026
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loading…
Reference in New Issue