/* * Copyright (c) 2026 by Christian Kellner. * Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause */ import React, { useEffect } from 'react'; import cityBackground from '../../assets/city_background.jpg'; import Logo from '../../components/logo/Logo'; import { xhrPost } from '../../services/xhr'; import { useNavigate } from 'react-router-dom'; import { useActions, useSelector } from '../../services/state/store'; import { Input, Button, Banner } from '@douyinfe/semi-ui-19'; import './login.less'; import { IconUser, IconLock } from '@douyinfe/semi-icons'; export default function Login() { const actions = useActions(); const [username, setUserName] = React.useState(''); const [password, setPassword] = React.useState(''); const [error, setError] = React.useState(null); const demoMode = useSelector((state) => state.demoMode.demoMode || false); const navigate = useNavigate(); useEffect(() => { async function init() { await actions.demoMode.getDemoMode(); } init(); }, []); const tryLogin = async () => { if (!username?.trim() || !password) { setError('Username and password are mandatory.'); return; } setError(null); try { await xhrPost('/api/login', { username: username.trim(), password, }); /* eslint-disable no-unused-vars */ } catch (ignored) { setError('Login unsuccessful. Please check your username and password.'); return; } await actions.user.getCurrentUser(); navigate('/dashboard'); }; return (
{demoMode && ( )}
e.preventDefault()}> {error && }
} placeholder="Username" value={username} showClear autoFocus onChange={(value) => setUserName(value)} onKeyPress={async (e) => { if (e.key === 'Enter') { await tryLogin(); } }} />
} value={password} placeholder="Password" onChange={(value) => setPassword(value)} onKeyPress={async (e) => { if (e.key === 'Enter') { await tryLogin(); } }} />
); } Login.displayName = 'Login';