import React, { useState, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import { loginUser, clearError, updateCacheInfo } from '../store/reducers/authSlice'; const Login = () => { const dispatch = useDispatch(); const navigate = useNavigate(); const { isAuthenticated, loading, error } = useSelector(state => { console.log('Redux auth state updated:', state.auth); return state.auth; }); const [formData, setFormData] = useState({ email: '', password: '' }); const [showPassword, setShowPassword] = useState(false); const [rememberMe, setRememberMe] = useState(false); const [isFocused, setIsFocused] = useState({ email: false, password: false }); // Auto-fill remember me preference if available useEffect(() => { const rememberPref = localStorage.getItem('rememberMePreference'); if (rememberPref === 'true') { setRememberMe(true); } }, []); useEffect(() => { if (isAuthenticated) { navigate('/dashboard'); return; } // Only check for cached auth if not already loading if (loading === 'idle') { const checkAuthStatus = async () => { const token = localStorage.getItem('token'); if (!token) { return; // No token, nothing to check } try { // Check if token is expired const tokenData = JSON.parse(atob(token.split('.')[1])); const isExpired = tokenData.exp * 1000 < Date.now(); if (isExpired) { localStorage.removeItem('token'); } } catch (error) { // Invalid token format, remove it localStorage.removeItem('token'); } }; checkAuthStatus(); } }, [isAuthenticated, loading, navigate, dispatch]); const handleChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }); // Clear error when user starts typing if (error) { dispatch(clearError()); } }; const handleFocus = (field) => { setIsFocused({ ...isFocused, [field]: true }); }; const handleBlur = (field) => { setIsFocused({ ...isFocused, [field]: false }); }; const handleSubmit = async (e) => { e.preventDefault(); // Prevent form submission if already loading if (loading === 'pending') { return; } // Clear any existing errors before attempting login if (error) { dispatch(clearError()); } try { const result = await dispatch(loginUser({ ...formData, rememberMe: rememberMe // Pass remember me flag })).unwrap(); // Update Redux store with cache info dispatch(updateCacheInfo({ isRemembered: rememberMe, expiresAt: result.expiresAt, deviceFingerprint: result.deviceFingerprint })); navigate('/dashboard'); } catch (err) { // Error is handled by the Redux slice console.error('Login failed:', err); } }; const togglePasswordVisibility = () => { setShowPassword(!showPassword); }; const toggleForm = () => { dispatch(clearError()); navigate('/register'); }; if (isAuthenticated) { return null; // Redirect handled by useEffect } return (
Sign in to your Lin account
Don't have an account?{' '}
© 2024 Lin. All rights reserved.