mirror of
https://github.com/dat515-2025/Group-8.git
synced 2026-03-22 15:12:08 +01:00
108 lines
4.3 KiB
TypeScript
108 lines
4.3 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { login, register } from '../api';
|
|
import { BACKEND_URL } from '../config';
|
|
|
|
// Minimal helper to start OAuth: fetch authorization_url and redirect
|
|
async function startOauth(provider: 'mojeid' | 'bankid') {
|
|
const base = BACKEND_URL.replace(/\/$/, '');
|
|
const url = `${base}/auth/${provider}/authorize`;
|
|
try {
|
|
const res = await fetch(url, { credentials: 'include' });
|
|
const data = await res.json();
|
|
if (data && typeof data.authorization_url === 'string') {
|
|
window.location.assign(data.authorization_url);
|
|
} else {
|
|
alert('Cannot start OAuth.');
|
|
}
|
|
} catch (e) {
|
|
alert('Cannot start OAuth.');
|
|
}
|
|
}
|
|
|
|
export default function LoginRegisterPage({ onLoggedIn }: { onLoggedIn: () => void }) {
|
|
const [mode, setMode] = useState<'login' | 'register'>('login');
|
|
const [email, setEmail] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [firstName, setFirstName] = useState('');
|
|
const [lastName, setLastName] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
async function handleSubmit(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
setError(null);
|
|
try {
|
|
if (mode === 'login') {
|
|
await login(email, password);
|
|
onLoggedIn();
|
|
} else {
|
|
await register(email, password, firstName || undefined, lastName || undefined);
|
|
// After register, prompt login automatically
|
|
await login(email, password);
|
|
onLoggedIn();
|
|
}
|
|
} catch (err: any) {
|
|
setError(err?.message || 'Operation failed');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
// Add this useEffect hook
|
|
useEffect(() => {
|
|
// When the component mounts, add a class to the body
|
|
document.body.classList.add('auth-page');
|
|
|
|
// When the component unmounts, remove the class
|
|
return () => {
|
|
document.body.classList.remove('auth-page');
|
|
};
|
|
}, []); // The empty array ensures this runs only once
|
|
|
|
// The JSX no longer needs the wrapper div
|
|
return (
|
|
<div className="card" style={{ width: 420 }}>
|
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
|
|
<h2 style={{ margin: 0 }}>{mode === 'login' ? 'Welcome back' : 'Create your account'}</h2>
|
|
<div className="segmented">
|
|
<button className={mode === 'login' ? 'active' : ''} type="button" onClick={() => setMode('login')}>Login</button>
|
|
<button className={mode === 'register' ? 'active' : ''} type="button" onClick={() => setMode('register')}>Register</button>
|
|
</div>
|
|
</div>
|
|
<form onSubmit={handleSubmit} className="space-y">
|
|
<div>
|
|
<label className="muted">Email</label>
|
|
<input className="input" type="email" required value={email} onChange={(e) => setEmail(e.target.value)} />
|
|
</div>
|
|
<div>
|
|
<label className="muted">Password</label>
|
|
<input className="input" type="password" required value={password} onChange={(e) => setPassword(e.target.value)} />
|
|
</div>
|
|
{mode === 'register' && (
|
|
<div className="form-row">
|
|
<div>
|
|
<label className="muted">First name (optional)</label>
|
|
<input className="input" type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} />
|
|
</div>
|
|
<div>
|
|
<label className="muted">Last name (optional)</label>
|
|
<input className="input" type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
{error && <div style={{ color: 'crimson' }}>{error}</div>}
|
|
<div className="actions" style={{ justifyContent: 'space-between' }}>
|
|
<div className="muted">Or continue with</div>
|
|
<div className="actions">
|
|
<button type="button" className="btn" onClick={() => startOauth('mojeid')}>MojeID</button>
|
|
<button type="button" className="btn" onClick={() => startOauth('bankid')}>BankID</button>
|
|
<button className="btn primary" type="submit" disabled={loading}>{loading ? 'Please wait…' : (mode === 'login' ? 'Login' : 'Register')}</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
|