diff --git a/src/features/workspace/views/LoginView.jsx b/src/features/workspace/views/LoginView.jsx index 171cd27..acd3996 100644 --- a/src/features/workspace/views/LoginView.jsx +++ b/src/features/workspace/views/LoginView.jsx @@ -23,9 +23,12 @@ export const LoginView = () => { const [showPassword, setShowPassword] = useState(false); const [error, setError] = useState(''); const [isLoading, setIsLoading] = useState(false); - const [step, setStep] = useState(1); // 1: Login, 2: Verification (Visual Demo) + const [step, setStep] = useState(1); // 1: Login, 2: OTP const navigate = useNavigate(); + const [otp, setOtp] = useState(['', '', '', '', '', '']); + const otpRefs = React.useRef([]); + const handleLogin = async (e) => { e.preventDefault(); setIsLoading(true); @@ -37,7 +40,7 @@ export const LoginView = () => { setTimeout(() => { if (allowedPasswords.includes(password)) { sessionStorage.setItem('workspace_access', 'granted'); - setStep(2); // Muda para o passo de verificação visual + setStep(2); setIsLoading(false); } else { setError('Chave de acesso inválida ou expirada.'); @@ -46,6 +49,30 @@ export const LoginView = () => { }, 800); }; + const handleOtpChange = (index, value) => { + if (!/^\d*$/.test(value)) return; + + const newOtp = [...otp]; + newOtp[index] = value.slice(-1); + setOtp(newOtp); + + // Auto focus next + if (value && index < 5) { + otpRefs.current[index + 1]?.focus(); + } + + // Auto submit if full + if (newOtp.every(digit => digit !== '')) { + setTimeout(() => handleFinalize(), 600); + } + }; + + const handleKeyDown = (index, e) => { + if (e.key === 'Backspace' && !otp[index] && index > 0) { + otpRefs.current[index - 1]?.focus(); + } + }; + const handleFinalize = () => { navigate('/plataforma/workspace'); window.location.reload(); @@ -95,7 +122,7 @@ export const LoginView = () => { {/* Right Panel - Interactive Form */} -
+
{/* Decorative Grid */}
{
) : ( - /* Verification Step (Image 1 reference) */ + /* Step 2 - Digite o Código (Reference Image 1 style) */ -
- -
-

Chave Confirmada

-

O ambiente de teste do Workspace está liberado para o seu perfil administrativo.

+

Digite o Código

- {/* Decorative numeric placeholders (Image 1 style) */} -
- {[1,2,3,4,5,6].map(i => ( -
-
-
+
+ {otp.map((digit, i) => ( + otpRefs.current[i] = el} + type="text" + maxLength={1} + value={digit} + onChange={(e) => handleOtpChange(i, e.target.value)} + onKeyDown={(e) => handleKeyDown(i, e)} + autoFocus={i === 0} + className="w-16 h-20 bg-white rounded-[20px] text-[#002137] text-4xl font-black text-center outline-none focus:ring-4 focus:ring-[#22bb6c]/50 transition-all shadow-lg" + /> ))}
)}