feat: add user authentication with separate login and register pages

- Custom User model with email as unique identifier (AUTH_USER_MODEL)

- POST /api/auth/register/ with email validation, password min 8 chars, duplicate rejection

- POST /api/auth/login/ returning JWT (access + refresh) tokens

- Passwords hashed via Django's make_password

- React LoginPage and RegisterPage with form validation

- AuthContext with useReducer for auth state management

- Axios API client with JWT token injection

- TypeScript conversion of frontend scaffold
This commit is contained in:
Marko (Hermes Implementer)
2026-05-26 00:54:27 +00:00
parent b91b7c364e
commit 6867a91b67
28 changed files with 3313 additions and 55 deletions
+88
View File
@@ -0,0 +1,88 @@
import { Link } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
export default function HomePage() {
const { state, logout } = useAuth();
return (
<div
style={{
minHeight: "100vh",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f5f5f5",
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
}}
>
<div
style={{
backgroundColor: "#fff",
padding: "2.5rem",
borderRadius: "8px",
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
textAlign: "center",
}}
>
<h1 style={{ margin: "0 0 0.5rem" }}>Job Tracker</h1>
<p style={{ color: "#666", marginBottom: "1.5rem" }}>
Welcome to the Job Tracker application.
</p>
{state.isAuthenticated && state.user ? (
<div>
<p style={{ marginBottom: "0.5rem" }}>
Signed in as <strong>{state.user.email}</strong>
</p>
<button
onClick={logout}
style={{
padding: "0.5rem 1.25rem",
backgroundColor: "#b91c1c",
color: "#fff",
border: "none",
borderRadius: "6px",
fontSize: "0.9rem",
cursor: "pointer",
}}
>
Sign Out
</button>
</div>
) : (
<div style={{ display: "flex", gap: "0.75rem", justifyContent: "center" }}>
<Link
to="/login"
style={{
padding: "0.5rem 1.25rem",
backgroundColor: "#1a73e8",
color: "#fff",
textDecoration: "none",
borderRadius: "6px",
fontSize: "0.9rem",
}}
>
Sign In
</Link>
<Link
to="/register"
style={{
padding: "0.5rem 1.25rem",
backgroundColor: "#fff",
color: "#1a73e8",
textDecoration: "none",
border: "1px solid #1a73e8",
borderRadius: "6px",
fontSize: "0.9rem",
}}
>
Register
</Link>
</div>
)}
</div>
</div>
);
}