This commit is contained in:
2026-08-22 02:59:16 +02:00
commit 6a5bb1d699
100 changed files with 17409 additions and 0 deletions
+82
View File
@@ -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">&#8599;</span>
</button>
</form>
<p className="auth-card__footer">
New to Northline? <Link to="/register">Create an account</Link>
</p>
</div>
</AuthLayout>
);
}