129 lines
4.0 KiB
TypeScript
129 lines
4.0 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { useNavigate, Link } from 'react-router-dom';
|
|
import { authService, LoginData } from '../services/membershipService';
|
|
|
|
const Login: React.FC = () => {
|
|
const navigate = useNavigate();
|
|
const [formData, setFormData] = useState<LoginData>({
|
|
email: '',
|
|
password: ''
|
|
});
|
|
const [error, setError] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
setFormData({
|
|
...formData,
|
|
[e.target.name]: e.target.value
|
|
});
|
|
};
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setError('');
|
|
setLoading(true);
|
|
|
|
try {
|
|
await authService.login(formData);
|
|
navigate('/dashboard');
|
|
} catch (err: any) {
|
|
console.error('Login error:', err.response?.data); // Debug log
|
|
const errorDetail = err.response?.data?.detail;
|
|
if (typeof errorDetail === 'string') {
|
|
setError(errorDetail);
|
|
} else if (errorDetail && typeof errorDetail === 'object') {
|
|
// Handle validation error objects
|
|
setError('Login failed. Please check your credentials.');
|
|
} else {
|
|
setError('Login failed. Please check your credentials.');
|
|
}
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="auth-container" style={{ gap: '40px', padding: '20px' }}>
|
|
<div className="welcome-section" style={{
|
|
flex: '1',
|
|
maxWidth: '400px',
|
|
textAlign: 'center',
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
padding: '30px',
|
|
borderRadius: '12px',
|
|
boxShadow: '0 4px 16px rgba(0, 0, 0, 0.1)'
|
|
}}>
|
|
<h1 style={{ color: '#333', marginBottom: '16px', fontSize: '2.2rem' }}>Welcome to SASA</h1>
|
|
<p style={{ fontSize: '1.1rem', color: '#666', lineHeight: '1.6', marginBottom: '20px' }}>
|
|
REPLACE WITH BOB WORDS: Swansea Airport Stakeholder's Association (SASA) is a community interest company run by volunteers, which holds the lease of Swansea Airport.
|
|
</p>
|
|
<p style={{ fontSize: '1rem', color: '#555', lineHeight: '1.5' }}>
|
|
Join our community of aviation enthusiasts and support the future of Swansea Airport.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="auth-card" style={{ flex: '1', maxWidth: '400px' }}>
|
|
<h2>SASA Member Portal</h2>
|
|
<p style={{ textAlign: 'center', marginBottom: '24px', color: '#666' }}>
|
|
Log in to your membership account
|
|
</p>
|
|
|
|
{error && <div className="alert alert-error">{error}</div>}
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
<div className="form-group">
|
|
<label htmlFor="email">Email Address</label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
value={formData.email}
|
|
onChange={handleChange}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="form-group">
|
|
<label htmlFor="password">Password</label>
|
|
<input
|
|
type="password"
|
|
id="password"
|
|
name="password"
|
|
value={formData.password}
|
|
onChange={handleChange}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
className="btn btn-primary"
|
|
disabled={loading}
|
|
style={{ width: '100%', marginTop: '16px' }}
|
|
>
|
|
{loading ? 'Logging in...' : 'Log In'}
|
|
</button>
|
|
</form>
|
|
|
|
<div className="form-footer">
|
|
<div style={{ marginBottom: '16px' }}>
|
|
<Link to="/forgot-password" style={{ color: '#0066cc', textDecoration: 'none' }}>
|
|
Forgot your password?
|
|
</Link>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="btn btn-secondary"
|
|
onClick={() => navigate('/register')}
|
|
style={{ width: '100%' }}
|
|
>
|
|
Join SASA
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Login;
|