feat: Add admin toggle and dark mode to login page

- Add admin toggle switch to switch between user/admin login modes
- Implement dark mode toggle button in top-right corner
- Style dark mode toggle with adaptive colors and hover effects

Enhances login page with flexible authentication modes and
improved visual customization options for better user experience.
This commit is contained in:
Johannes
2025-09-14 17:18:01 +02:00
parent c9160136cb
commit bae5afa73f

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { Form, Input, Button, Typography, Alert, message } from 'antd';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { Form, Input, Button, Typography, Alert, message, Switch } from 'antd';
import { LockOutlined, UserOutlined, SettingOutlined, SunOutlined, MoonOutlined } from '@ant-design/icons';
import { preserveFullUrl } from '../utils/urlUtils';
const { Title } = Typography;
@@ -9,7 +9,30 @@ const { Title } = Typography;
export default function LoginPage({ onLogin }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const darkMode = typeof window !== 'undefined' && localStorage.getItem('darkMode') === 'true';
const [isAdminMode, setIsAdminMode] = useState(false);
const [darkMode, setDarkMode] = useState(
typeof window !== 'undefined' && localStorage.getItem('darkMode') === 'true'
);
const toggleDarkMode = () => {
const newDarkMode = !darkMode;
setDarkMode(newDarkMode);
localStorage.setItem('darkMode', newDarkMode.toString());
// Update HTML class for immediate visual feedback
const htmlElement = document.documentElement;
const bodyElement = document.body;
if (newDarkMode) {
htmlElement.classList.add('dark-mode');
htmlElement.style.backgroundColor = '#181818';
bodyElement.style.backgroundColor = '#181818';
} else {
htmlElement.classList.remove('dark-mode');
htmlElement.style.backgroundColor = '#f5f5f5';
bodyElement.style.backgroundColor = '#f5f5f5';
}
};
const onFinish = async (values) => {
setLoading(true);
@@ -53,8 +76,27 @@ export default function LoginPage({ onLogin }) {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'relative'
}}
>
{/* Dark Mode Toggle in der oberen rechten Ecke */}
<Button
type="text"
shape="circle"
icon={darkMode ? <SunOutlined /> : <MoonOutlined />}
onClick={toggleDarkMode}
style={{
position: 'absolute',
top: 16,
right: 16,
color: darkMode ? '#fff' : '#666',
backgroundColor: darkMode ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)',
border: 'none',
width: 40,
height: 40
}}
title={darkMode ? 'Light Mode aktivieren' : 'Dark Mode aktivieren'}
/>
<div
style={{
width: 350,
@@ -62,20 +104,61 @@ export default function LoginPage({ onLogin }) {
background: darkMode ? '#1f1f1f' : '#fff',
borderRadius: 8,
boxShadow: darkMode ? '0 2px 8px #222' : '0 2px 8px #eee',
color: darkMode ? '#fff' : undefined
color: darkMode ? '#fff' : '#1f1f1f'
}}
>
<Title level={3} style={{ textAlign: 'center', color: darkMode ? '#fff' : undefined }}>Anmeldung</Title>
<Title level={3} style={{ textAlign: 'center', color: darkMode ? '#fff' : '#1f1f1f' }}>
{isAdminMode ? 'Admin-Anmeldung' : 'Benutzer-Anmeldung'}
</Title>
{/* Admin-Mode Toggle */}
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 24,
gap: 8
}}>
<SettingOutlined style={{ color: darkMode ? '#888' : '#666' }} />
<span style={{ color: darkMode ? '#888' : '#666', fontSize: 14 }}>Admin-Login</span>
<Switch
checked={isAdminMode}
onChange={setIsAdminMode}
size="small"
/>
</div>
{error && <Alert type="error" message={error} showIcon style={{ marginBottom: 16 }} />}
<Form name="login" onFinish={onFinish} layout="vertical">
<Form.Item name="username" label={<span style={{ color: darkMode ? '#fff' : undefined }}>Benutzername (nur Admin)</span>} >
<Input prefix={<UserOutlined />} placeholder="Benutzername" autoComplete="username" style={darkMode ? { background: '#222', color: '#fff' } : {}} />
</Form.Item>
<Form.Item name="password" label={<span style={{ color: darkMode ? '#fff' : undefined }}>Passwort</span>} rules={[{ required: true, message: 'Bitte Passwort eingeben!' }]}>
<Input.Password prefix={<LockOutlined />} placeholder="Passwort" autoComplete="current-password" style={darkMode ? { background: '#222', color: '#fff' } : {}} />
{/* Benutzername-Feld nur im Admin-Mode */}
{isAdminMode && (
<Form.Item
name="username"
label={<span style={{ color: darkMode ? '#fff' : '#1f1f1f' }}>Benutzername</span>}
rules={[{ required: isAdminMode, message: 'Bitte Benutzername eingeben!' }]}
>
<Input
prefix={<UserOutlined />}
placeholder="Admin-Benutzername"
autoComplete="username"
style={darkMode ? { background: '#222', color: '#fff' } : {}}
/>
</Form.Item>
)}
<Form.Item
name="password"
label={<span style={{ color: darkMode ? '#fff' : '#1f1f1f' }}>Passwort</span>}
rules={[{ required: true, message: 'Bitte Passwort eingeben!' }]}
>
<Input.Password
prefix={<LockOutlined />}
placeholder={isAdminMode ? "Admin-Passwort" : "Passwort"}
autoComplete="current-password"
style={darkMode ? { background: '#222', color: '#fff' } : {}}
/>
</Form.Item>
<Button type="primary" htmlType="submit" block loading={loading}>
Einloggen
{isAdminMode ? 'Als Admin einloggen' : 'Einloggen'}
</Button>
</Form>
</div>