import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import useAuthStore from '../../store/auth'; import useSettingsStore from '../../store/settings'; import { Paper, Title, TextInput, Button, Center, Stack, Text, Image, Group, Divider, Modal, Anchor, Code, Checkbox, } from '@mantine/core'; import logo from '../../assets/logo.png'; const LoginForm = () => { const login = useAuthStore((s) => s.login); const logout = useAuthStore((s) => s.logout); const isAuthenticated = useAuthStore((s) => s.isAuthenticated); const initData = useAuthStore((s) => s.initData); const fetchVersion = useSettingsStore((s) => s.fetchVersion); const storedVersion = useSettingsStore((s) => s.version); const navigate = useNavigate(); // Hook to navigate to other routes const [formData, setFormData] = useState({ username: '', password: '' }); const [rememberMe, setRememberMe] = useState(false); const [savePassword, setSavePassword] = useState(false); const [forgotPasswordOpened, setForgotPasswordOpened] = useState(false); const [isLoading, setIsLoading] = useState(false); // Simple base64 encoding/decoding for localStorage // Note: This is obfuscation, not encryption. Use browser's password manager for real security. const encodePassword = (password) => { try { return btoa(password); } catch (error) { console.error('Encoding error:', error); return null; } }; const decodePassword = (encoded) => { try { return atob(encoded); } catch (error) { console.error('Decoding error:', error); return ''; } }; useEffect(() => { // Fetch version info using the settings store (will skip if already loaded) fetchVersion(); }, [fetchVersion]); useEffect(() => { // Load saved username if it exists const savedUsername = localStorage.getItem( 'dispatcharr_remembered_username' ); const savedPassword = localStorage.getItem('dispatcharr_saved_password'); if (savedUsername) { setFormData((prev) => ({ ...prev, username: savedUsername })); setRememberMe(true); if (savedPassword) { try { const decrypted = decodePassword(savedPassword); if (decrypted) { setFormData((prev) => ({ ...prev, password: decrypted })); setSavePassword(true); } } catch { // If decoding fails, just skip } } } }, []); useEffect(() => { if (isAuthenticated) { navigate('/channels'); } }, [isAuthenticated, navigate]); const handleInputChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value, }); }; const handleSubmit = async (e) => { e.preventDefault(); setIsLoading(true); try { await login(formData); // Save username if remember me is checked if (rememberMe) { localStorage.setItem( 'dispatcharr_remembered_username', formData.username ); // Save password if save password is checked if (savePassword) { const encoded = encodePassword(formData.password); if (encoded) { localStorage.setItem('dispatcharr_saved_password', encoded); } } else { localStorage.removeItem('dispatcharr_saved_password'); } } else { localStorage.removeItem('dispatcharr_remembered_username'); localStorage.removeItem('dispatcharr_saved_password'); } await initData(); // Navigation will happen automatically via the useEffect or route protection } catch (e) { console.log(`Failed to login: ${e}`); await logout(); setIsLoading(false); } }; return (
docker exec <container_name> python manage.py changepassword
<username>
python manage.py changepassword <username>
<container_name> with your Docker container name
and <username> with the account username.