Design: neues Login (weiss, Logo, Code-Schritte), Glitch-Hintergrund entfernt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
988934552f
commit
47a26fb9b2
3 files changed
+84
-397
No files matched your search
+82
-150
@@ -1,7 +1,7 @@
|
||||
import { useState } from 'react'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import { useAuth } from '../context/AuthContext'
|
||||
import LetterGlitch from '../components/LetterGlitch'
|
||||
import Logo from '../components/Logo'
|
||||
import { safeReturnPath } from '../lib/returnPath'
|
||||
import { NO_STAFF_ACCESS } from '../lib/staffAccess'
|
||||
|
||||
@@ -83,167 +83,99 @@ export default function LoginPage() {
|
||||
setPassword('')
|
||||
}
|
||||
|
||||
const linkButton = {
|
||||
background: 'none',
|
||||
border: 0,
|
||||
padding: 0,
|
||||
color: '#e2e8f0',
|
||||
textDecoration: 'underline',
|
||||
cursor: 'pointer',
|
||||
font: 'inherit',
|
||||
}
|
||||
|
||||
const codeStep = mfaPending && (
|
||||
<form onSubmit={handleCode}>
|
||||
{error && (
|
||||
<div className="bg-red text-white p-1 mb-2" style={{ borderRadius: '4px' }}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
<p style={{ marginTop: 0 }}>
|
||||
<>
|
||||
<h1>Code eingeben</h1>
|
||||
<p className="sub">
|
||||
{!mfaPending.challengeId
|
||||
? 'Wir schicken dir einen Code an deine E-Mail-Adresse.'
|
||||
: `Wir haben dir einen Code an ${mfaPending.email || 'deine E-Mail-Adresse'} geschickt.`}
|
||||
</p>
|
||||
{notice && <p style={{ marginTop: 0 }}>{notice}</p>}
|
||||
{mfaPending.challengeId ? (
|
||||
<>
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="mfa-code">Code aus der E-Mail</label>
|
||||
<input
|
||||
id="mfa-code"
|
||||
type="text"
|
||||
className="form-control"
|
||||
value={code}
|
||||
onChange={(e) => setCode(e.target.value.replace(/\D/g, ''))}
|
||||
inputMode="numeric"
|
||||
autoComplete="one-time-code"
|
||||
maxLength={6}
|
||||
required
|
||||
autoFocus
|
||||
style={{ letterSpacing: '0.3em' }}
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="btn btn-green" style={{ width: '100%' }} disabled={loading}>
|
||||
{loading ? 'Prüfe…' : 'Anmelden'}
|
||||
</button>
|
||||
<p style={{ textAlign: 'center', marginBottom: 0 }}>
|
||||
<button type="button" style={linkButton} onClick={handleSend} disabled={loading}>Code erneut senden</button>
|
||||
{' · '}
|
||||
<button type="button" style={linkButton} onClick={handleCancel}>Abbrechen</button>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<button type="button" className="btn btn-green" style={{ width: '100%' }} onClick={handleSend} disabled={loading}>
|
||||
<form onSubmit={handleCode}>
|
||||
{error && <div className="msg err" role="alert">{error}</div>}
|
||||
{notice && <div className="msg ok">{notice}</div>}
|
||||
{mfaPending.challengeId ? (
|
||||
<>
|
||||
<div className="field">
|
||||
<label htmlFor="mfa-code">Code aus der E-Mail</label>
|
||||
<input
|
||||
id="mfa-code"
|
||||
type="text"
|
||||
className="input code-input"
|
||||
value={code}
|
||||
onChange={(e) => setCode(e.target.value.replace(/\D/g, ''))}
|
||||
inputMode="numeric"
|
||||
autoComplete="one-time-code"
|
||||
maxLength={6}
|
||||
required
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="btn btn-primary btn-block" disabled={loading}>
|
||||
{loading ? 'Prüfe…' : 'Anmelden'}
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<button type="button" className="btn btn-primary btn-block" onClick={handleSend} disabled={loading}>
|
||||
{loading ? 'Sende…' : 'Code senden'}
|
||||
</button>
|
||||
<p style={{ textAlign: 'center', marginBottom: 0 }}>
|
||||
<button type="button" style={linkButton} onClick={handleCancel}>Abbrechen</button>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
</form>
|
||||
<div className="login-links">
|
||||
{mfaPending.challengeId && (
|
||||
<button type="button" className="link" onClick={handleSend} disabled={loading}>Code erneut senden</button>
|
||||
)}
|
||||
<button type="button" className="link" onClick={handleCancel}>Abbrechen</button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
position: 'relative',
|
||||
minHeight: '100vh',
|
||||
width: '100%',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
{/* LetterGlitch Hintergrund */}
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
zIndex: 0
|
||||
}}>
|
||||
<LetterGlitch
|
||||
glitchSpeed={50}
|
||||
centerVignette={true}
|
||||
outerVignette={false}
|
||||
smooth={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Login-Formular */}
|
||||
<div style={{
|
||||
position: 'relative',
|
||||
zIndex: 1,
|
||||
minHeight: '100vh',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
<div style={{
|
||||
width: '400px',
|
||||
boxShadow: '0 10px 40px rgba(0,0,0,0.5)',
|
||||
backdropFilter: 'blur(10px)',
|
||||
WebkitBackdropFilter: 'blur(10px)',
|
||||
background: 'transparent',
|
||||
border: '1px solid rgba(255, 255, 255, 0.2)',
|
||||
borderRadius: '8px',
|
||||
marginBottom: '16px'
|
||||
}}>
|
||||
<div style={{
|
||||
padding: '12px 16px',
|
||||
background: 'transparent',
|
||||
color: '#fff',
|
||||
fontWeight: 'bold',
|
||||
borderBottom: '1px solid rgba(255, 255, 255, 0.2)',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
<h2>Webklar WOMS 2.0</h2>
|
||||
</div>
|
||||
<div style={{ padding: '16px', color: '#e2e8f0' }}>
|
||||
{codeStep || <form onSubmit={handleSubmit}>
|
||||
{error && (
|
||||
<div className="bg-red text-white p-1 mb-2" style={{ borderRadius: '4px' }}>
|
||||
{error}
|
||||
<>
|
||||
<div className="login">
|
||||
<div className="login-box">
|
||||
<Logo size={40} />
|
||||
{codeStep || (
|
||||
<>
|
||||
<h1>Anmelden</h1>
|
||||
<p className="sub">Ticketsystem für das WEBklar-Team</p>
|
||||
<form onSubmit={handleSubmit}>
|
||||
{error && <div className="msg err" role="alert">{error}</div>}
|
||||
<div className="field">
|
||||
<label htmlFor="login-email">E-Mail</label>
|
||||
<input
|
||||
id="login-email"
|
||||
type="email"
|
||||
className="input"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
autoComplete="username"
|
||||
required
|
||||
placeholder="deine@email.com"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Email</label>
|
||||
<input
|
||||
type="email"
|
||||
className="form-control"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
placeholder="deine@email.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
className="form-control"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
placeholder="••••••••"
|
||||
minLength={8}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-green"
|
||||
style={{ width: '100%' }}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? 'Login läuft...' : 'Login'}
|
||||
</button>
|
||||
</form>}
|
||||
</div>
|
||||
<div className="field">
|
||||
<label htmlFor="login-password">Passwort</label>
|
||||
<input
|
||||
id="login-password"
|
||||
type="password"
|
||||
className="input"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
autoComplete="current-password"
|
||||
required
|
||||
minLength={8}
|
||||
/>
|
||||
</div>
|
||||
<button type="submit" className="btn btn-primary btn-block" disabled={loading}>
|
||||
{loading ? 'Login läuft...' : 'Weiter'}
|
||||
</button>
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="login-foot">Webklar Ticket-Plattform · © {new Date().getFullYear()}</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user