import React, {useCallback, useEffect, useState} from 'react'; import logo from '../../Flaticon_circle.png' import {Alert, Card, Col, Row} from "react-bootstrap-v5"; import {Link, useNavigate} from "react-router-dom"; import {useTranslation} from "react-i18next"; import {FontAwesomeIcon as Fa} from "@fortawesome/react-fontawesome"; import {faPalette} from "@fortawesome/free-solid-svg-icons"; import {useTheme} from "../../hooks/themeHook"; import ColorSelectorModal from "../../components/modal/ColorSelectorModal"; import drawSine from "../../util/loginSineRenderer"; import {fetchLogin} from "../../service/authenticationService"; import ForgotPasswordModal from "../../components/modal/ForgotPasswordModal"; import {useAuth} from "../../hooks/authenticationHook"; const Logo = () => { return ( logo ) }; const LoginCard = ({children}) => { return (
{children}
) } const LoginForm = ({login}) => { const {t} = useTranslation(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const onLogin = useCallback(event => { event.preventDefault(); login(username, password).then(() => setPassword('')); }, [username, password, setPassword, login]); return (
setUsername(event.target.value)}/>
setPassword(event.target.value)}/>
); } const ColorChooserButton = () => { const {t} = useTranslation(); const {toggleColorChooser} = useTheme(); return (
) } const ForgotPasswordButton = ({onClick}) => { const {t} = useTranslation(); return (
) } const CreateAccountLink = () => { const {t} = useTranslation(); return (
{t('html.login.register')}
) } const Decoration = () => { useEffect(() => { drawSine('decoration'); }) return ( ); } const LoginPage = () => { const {t} = useTranslation(); const navigate = useNavigate(); const {authLoaded, authRequired, loggedIn, updateLoginDetails} = useAuth(); const [forgotPasswordModalOpen, setForgotPasswordModalOpen] = useState(false); const [successMessage, setSuccessMessage] = useState('') const [failMessage, setFailMessage] = useState(''); const [redirectTo, setRedirectTo] = useState(undefined); const togglePasswordModal = useCallback(() => setForgotPasswordModalOpen(!forgotPasswordModalOpen), [setForgotPasswordModalOpen, forgotPasswordModalOpen]) useEffect(() => { document.body.classList.add("bg-theme", "plan-bg-gradient"); const urlParams = new URLSearchParams(window.location.search); const cameFrom = urlParams.get('from'); if (cameFrom) setRedirectTo(cameFrom); const registerSuccess = urlParams.get('registerSuccess'); if (registerSuccess) setSuccessMessage(t('html.register.success')) return () => { document.body.classList.remove("bg-theme", "plan-bg-gradient"); } }, [setRedirectTo, setSuccessMessage, t]) const login = async (username, password) => { if (!username || username.length < 1) { return setFailMessage(t('html.register.error.noUsername')); } if (username.length > 50) { return setFailMessage(t('html.register.error.usernameLength') + username.length); } if (!password || password.length < 1) { return setFailMessage(t('html.register.error.noPassword')); } const {data, error} = await fetchLogin(username, password); if (error) { if (error.message === 'Request failed with status code 403') { // Too many logins, reload browser to show forbidden page window.location.reload(); } else { setFailMessage(t('html.login.failed') + (error.data && error.data.error ? error.data.error : error.message)); } } else if (data && data.success) { await updateLoginDetails(); if (redirectTo && !redirectTo.startsWith('http') && !redirectTo.startsWith('file') && !redirectTo.startsWith('javascript')) { navigate(redirectTo.substring(redirectTo.indexOf('/')) + (window.location.hash ? window.location.hash : '')); } else { navigate('/'); } } else { setFailMessage(t('html.login.failed') + data ? data.error : t('generic.noData')); } } if (!authLoaded) { return <> } if (!authRequired || loggedIn) { navigate('../'); } return ( <>
{failMessage && {failMessage}} {successMessage && {successMessage}}
) }; export default LoginPage