init
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { useState } from 'react';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
import { AuthLayout } from '../components/app/AuthLayout';
|
||||
import { useAuth } from '../features/auth/useAuth';
|
||||
import { login } from '../lib/api';
|
||||
|
||||
export default function LoginPage() {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { setUser } = useAuth();
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
async function submit(event: React.FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault();
|
||||
setSubmitting(true);
|
||||
setError('');
|
||||
try {
|
||||
const user = await login(email, password);
|
||||
setUser(user);
|
||||
const destination = (location.state as { from?: string } | null)?.from || '/dashboard';
|
||||
navigate(destination, { replace: true });
|
||||
} catch (reason) {
|
||||
setError(reason instanceof Error ? reason.message : 'Could not sign in.');
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthLayout>
|
||||
<div className="auth-card">
|
||||
<div className="auth-card__heading">
|
||||
<p className="platform-kicker platform-kicker--accent">Welcome back</p>
|
||||
<h2 className="platform-display">
|
||||
Your work,
|
||||
<br />
|
||||
<em>waiting.</em>
|
||||
</h2>
|
||||
<p>Sign in to keep shaping the way your clients experience their photographs.</p>
|
||||
</div>
|
||||
<form className="auth-form" onSubmit={submit}>
|
||||
<label>
|
||||
Email address
|
||||
<input
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
value={email}
|
||||
onChange={(event) => setEmail(event.target.value)}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Password
|
||||
<input
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
value={password}
|
||||
onChange={(event) => setPassword(event.target.value)}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
{error && <p className="form-error">{error}</p>}
|
||||
<button
|
||||
className="platform-button platform-button--dark"
|
||||
type="submit"
|
||||
disabled={submitting}
|
||||
>
|
||||
<span>{submitting ? 'Opening studio...' : 'Sign in'}</span>
|
||||
<span aria-hidden="true">↗</span>
|
||||
</button>
|
||||
</form>
|
||||
<p className="auth-card__footer">
|
||||
New to Northline? <Link to="/register">Create an account</Link>
|
||||
</p>
|
||||
</div>
|
||||
</AuthLayout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user