fix: migrate inline styles to CSS modules per review feedback

This commit is contained in:
Marko (Hermes Implementer)
2026-05-26 17:04:58 +00:00
parent e6e6c92c28
commit 9846f823b3
6 changed files with 380 additions and 312 deletions
+83
View File
@@ -0,0 +1,83 @@
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.card {
background-color: #fff;
padding: 2.5rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
text-align: center;
}
.heading {
margin: 0 0 0.5rem;
}
.welcomeText {
color: #666;
margin-bottom: 1.5rem;
}
.signedInText {
margin-bottom: 0.5rem;
}
.emailStrong {
font-weight: 600;
}
.logoutButton {
padding: 0.5rem 1.25rem;
background-color: #b91c1c;
color: #fff;
border: none;
border-radius: 6px;
font-size: 0.9rem;
cursor: pointer;
}
.logoutButton:hover {
background-color: #991616;
}
.authLinks {
display: flex;
gap: 0.75rem;
justify-content: center;
}
.signInLink {
padding: 0.5rem 1.25rem;
background-color: #1a73e8;
color: #fff;
text-decoration: none;
border-radius: 6px;
font-size: 0.9rem;
display: inline-block;
}
.signInLink:hover {
background-color: #1557b0;
}
.registerLink {
padding: 0.5rem 1.25rem;
background-color: #fff;
color: #1a73e8;
text-decoration: none;
border: 1px solid #1a73e8;
border-radius: 6px;
font-size: 0.9rem;
display: inline-block;
}
.registerLink:hover {
background-color: #f0f5ff;
}
+14 -61
View File
@@ -1,83 +1,36 @@
import { Link } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import styles from "./HomePage.module.css";
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" }}>
<div className={styles.container}>
<div className={styles.card}>
<h1 className={styles.heading}>Job Tracker</h1>
<p className={styles.welcomeText}>
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 className={styles.signedInText}>
Signed in as{" "}
<strong className={styles.emailStrong}>
{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",
}}
>
<button onClick={logout} className={styles.logoutButton}>
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",
}}
>
<div className={styles.authLinks}>
<Link to="/login" className={styles.signInLink}>
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",
}}
>
<Link to="/register" className={styles.registerLink}>
Register
</Link>
</div>
+114
View File
@@ -0,0 +1,114 @@
.container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.card {
background-color: #fff;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
}
.title {
margin: 0 0 0.25rem;
font-size: 1.5rem;
font-weight: 600;
}
.subtitle {
margin: 0 0 1.5rem;
color: #666;
font-size: 0.9rem;
}
.form {
display: flex;
flex-direction: column;
gap: 1rem;
}
.field {
display: flex;
flex-direction: column;
gap: 0.35rem;
}
.label {
font-size: 0.85rem;
font-weight: 500;
color: #333;
}
.input {
padding: 0.6rem 0.75rem;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 0.95rem;
outline: none;
transition: border-color 0.15s;
}
.input:focus {
border-color: #1a73e8;
}
.button {
padding: 0.65rem;
background-color: #1a73e8;
color: #fff;
border: none;
border-radius: 6px;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
margin-top: 0.5rem;
}
.button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.error {
background-color: #fef2f2;
color: #b91c1c;
border: 1px solid #fecaca;
border-radius: 6px;
padding: 0.5rem 0.75rem;
font-size: 0.85rem;
margin-bottom: 0.5rem;
}
.success {
background-color: #f0fdf4;
color: #166534;
border: 1px solid #bbf7d0;
border-radius: 6px;
padding: 0.5rem 0.75rem;
font-size: 0.85rem;
margin-bottom: 0.5rem;
}
.footer {
margin-top: 1.25rem;
text-align: center;
font-size: 0.85rem;
color: #666;
}
.link {
color: #1a73e8;
text-decoration: none;
font-weight: 500;
}
.link:hover {
text-decoration: underline;
}
+19 -118
View File
@@ -1,6 +1,7 @@
import { useState, type FormEvent, type ChangeEvent } from "react";
import { useNavigate, useLocation, Link } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import styles from "./LoginPage.module.css";
export default function LoginPage() {
const navigate = useNavigate();
@@ -33,17 +34,17 @@ export default function LoginPage() {
};
return (
<div style={styles.container}>
<div style={styles.card}>
<h1 style={styles.title}>Sign In</h1>
<p style={styles.subtitle}>Welcome back to Job Tracker</p>
<div className={styles.container}>
<div className={styles.card}>
<h1 className={styles.title}>Sign In</h1>
<p className={styles.subtitle}>Welcome back to Job Tracker</p>
{state.error && <div style={styles.error}>{state.error}</div>}
{successMessage && <div style={styles.success}>{successMessage}</div>}
{state.error && <div className={styles.error}>{state.error}</div>}
{successMessage && <div className={styles.success}>{successMessage}</div>}
<form onSubmit={handleSubmit} style={styles.form}>
<div style={styles.field}>
<label htmlFor="email" style={styles.label}>
<form onSubmit={handleSubmit} className={styles.form}>
<div className={styles.field}>
<label htmlFor="email" className={styles.label}>
Email
</label>
<input
@@ -51,14 +52,14 @@ export default function LoginPage() {
type="email"
value={email}
onChange={handleEmailChange}
style={styles.input}
className={styles.input}
placeholder="you@example.com"
required
/>
</div>
<div style={styles.field}>
<label htmlFor="password" style={styles.label}>
<div className={styles.field}>
<label htmlFor="password" className={styles.label}>
Password
</label>
<input
@@ -66,8 +67,8 @@ export default function LoginPage() {
type="password"
value={password}
onChange={handlePasswordChange}
style={styles.input}
placeholder="&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;&#xb7;"
className={styles.input}
placeholder="\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7"
required
/>
</div>
@@ -75,119 +76,19 @@ export default function LoginPage() {
<button
type="submit"
disabled={state.isLoading}
style={{
...styles.button,
...(state.isLoading ? styles.buttonDisabled : {}),
}}
className={styles.button}
>
{state.isLoading ? "Signing in..." : "Sign In"}
</button>
</form>
<p style={styles.footer}>
<p className={styles.footer}>
Don't have an account?{" "}
<Link to="/register" style={styles.link}>
<Link to="/register" className={styles.link}>
Create one
</Link>
</p>
</div>
</div>
);
}
const styles: Record<string, React.CSSProperties> = {
container: {
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f5f5f5",
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
},
card: {
backgroundColor: "#fff",
padding: "2rem",
borderRadius: "8px",
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
width: "100%",
maxWidth: "400px",
},
title: {
margin: "0 0 0.25rem",
fontSize: "1.5rem",
fontWeight: 600,
},
subtitle: {
margin: "0 0 1.5rem",
color: "#666",
fontSize: "0.9rem",
},
form: {
display: "flex",
flexDirection: "column",
gap: "1rem",
},
field: {
display: "flex",
flexDirection: "column",
gap: "0.35rem",
},
label: {
fontSize: "0.85rem",
fontWeight: 500,
color: "#333",
},
input: {
padding: "0.6rem 0.75rem",
border: "1px solid #ccc",
borderRadius: "6px",
fontSize: "0.95rem",
outline: "none",
transition: "border-color 0.15s",
},
button: {
padding: "0.65rem",
backgroundColor: "#1a73e8",
color: "#fff",
border: "none",
borderRadius: "6px",
fontSize: "1rem",
fontWeight: 500,
cursor: "pointer",
marginTop: "0.5rem",
},
buttonDisabled: {
opacity: 0.6,
cursor: "not-allowed",
},
error: {
backgroundColor: "#fef2f2",
color: "#b91c1c",
border: "1px solid #fecaca",
borderRadius: "6px",
padding: "0.5rem 0.75rem",
fontSize: "0.85rem",
marginBottom: "0.5rem",
},
success: {
backgroundColor: "#f0fdf4",
color: "#166534",
border: "1px solid #bbf7d0",
borderRadius: "6px",
padding: "0.5rem 0.75rem",
fontSize: "0.85rem",
marginBottom: "0.5rem",
},
footer: {
marginTop: "1.25rem",
textAlign: "center",
fontSize: "0.85rem",
color: "#666",
},
link: {
color: "#1a73e8",
textDecoration: "none",
fontWeight: 500,
},
};
}
+120
View File
@@ -0,0 +1,120 @@
.container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.card {
background-color: #fff;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 440px;
}
.title {
margin: 0 0 0.25rem;
font-size: 1.5rem;
font-weight: 600;
}
.subtitle {
margin: 0 0 1.5rem;
color: #666;
font-size: 0.9rem;
}
.form {
display: flex;
flex-direction: column;
gap: 1rem;
}
.row {
display: flex;
gap: 0.75rem;
}
.field {
display: flex;
flex-direction: column;
gap: 0.35rem;
}
.halfField {
display: flex;
flex-direction: column;
gap: 0.35rem;
flex: 1;
}
.label {
font-size: 0.85rem;
font-weight: 500;
color: #333;
}
.required {
color: #b91c1c;
}
.input {
padding: 0.6rem 0.75rem;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 0.95rem;
outline: none;
transition: border-color 0.15s;
}
.input:focus {
border-color: #1a73e8;
}
.button {
padding: 0.65rem;
background-color: #1a73e8;
color: #fff;
border: none;
border-radius: 6px;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
margin-top: 0.5rem;
}
.button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.error {
background-color: #fef2f2;
color: #b91c1c;
border: 1px solid #fecaca;
border-radius: 6px;
padding: 0.5rem 0.75rem;
font-size: 0.85rem;
margin-bottom: 0.5rem;
}
.footer {
margin-top: 1.25rem;
text-align: center;
font-size: 0.85rem;
color: #666;
}
.link {
color: #1a73e8;
text-decoration: none;
font-weight: 500;
}
.link:hover {
text-decoration: underline;
}
+30 -133
View File
@@ -1,6 +1,7 @@
import { useState, type FormEvent, type ChangeEvent } from "react";
import { useNavigate, Link } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import styles from "./RegisterPage.module.css";
export default function RegisterPage() {
const navigate = useNavigate();
@@ -32,17 +33,17 @@ export default function RegisterPage() {
};
return (
<div style={styles.container}>
<div style={styles.card}>
<h1 style={styles.title}>Create Account</h1>
<p style={styles.subtitle}>Get started with Job Tracker</p>
<div className={styles.container}>
<div className={styles.card}>
<h1 className={styles.title}>Create Account</h1>
<p className={styles.subtitle}>Get started with Job Tracker</p>
{state.error && <div style={styles.error}>{state.error}</div>}
{state.error && <div className={styles.error}>{state.error}</div>}
<form onSubmit={handleSubmit} style={styles.form}>
<div style={styles.row}>
<div style={styles.halfField}>
<label htmlFor="firstName" style={styles.label}>
<form onSubmit={handleSubmit} className={styles.form}>
<div className={styles.row}>
<div className={styles.halfField}>
<label htmlFor="firstName" className={styles.label}>
First Name
</label>
<input
@@ -52,11 +53,11 @@ export default function RegisterPage() {
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setFirstName(e.target.value)
}
style={styles.input}
className={styles.input}
/>
</div>
<div style={styles.halfField}>
<label htmlFor="lastName" style={styles.label}>
<div className={styles.halfField}>
<label htmlFor="lastName" className={styles.label}>
Last Name
</label>
<input
@@ -66,14 +67,14 @@ export default function RegisterPage() {
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setLastName(e.target.value)
}
style={styles.input}
className={styles.input}
/>
</div>
</div>
<div style={styles.field}>
<label htmlFor="email" style={styles.label}>
Email <span style={styles.required}>*</span>
<div className={styles.field}>
<label htmlFor="email" className={styles.label}>
Email <span className={styles.required}>*</span>
</label>
<input
id="email"
@@ -82,15 +83,15 @@ export default function RegisterPage() {
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setEmail(e.target.value)
}
style={styles.input}
className={styles.input}
placeholder="you@example.com"
required
/>
</div>
<div style={styles.field}>
<label htmlFor="password" style={styles.label}>
Password <span style={styles.required}>*</span>
<div className={styles.field}>
<label htmlFor="password" className={styles.label}>
Password <span className={styles.required}>*</span>
</label>
<input
id="password"
@@ -99,16 +100,16 @@ export default function RegisterPage() {
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setPassword(e.target.value)
}
style={styles.input}
className={styles.input}
placeholder="Min. 8 characters"
required
minLength={8}
/>
</div>
<div style={styles.field}>
<label htmlFor="passwordConfirm" style={styles.label}>
Confirm Password <span style={styles.required}>*</span>
<div className={styles.field}>
<label htmlFor="passwordConfirm" className={styles.label}>
Confirm Password <span className={styles.required}>*</span>
</label>
<input
id="passwordConfirm"
@@ -117,7 +118,7 @@ export default function RegisterPage() {
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setPasswordConfirm(e.target.value)
}
style={styles.input}
className={styles.input}
placeholder="Repeat your password"
required
minLength={8}
@@ -127,123 +128,19 @@ export default function RegisterPage() {
<button
type="submit"
disabled={state.isLoading}
style={{
...styles.button,
...(state.isLoading ? styles.buttonDisabled : {}),
}}
className={styles.button}
>
{state.isLoading ? "Creating Account..." : "Create Account"}
</button>
</form>
<p style={styles.footer}>
<p className={styles.footer}>
Already have an account?{" "}
<Link to="/login" style={styles.link}>
<Link to="/login" className={styles.link}>
Sign in
</Link>
</p>
</div>
</div>
);
}
const styles: Record<string, React.CSSProperties> = {
container: {
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#f5f5f5",
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
},
card: {
backgroundColor: "#fff",
padding: "2rem",
borderRadius: "8px",
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
width: "100%",
maxWidth: "440px",
},
title: {
margin: "0 0 0.25rem",
fontSize: "1.5rem",
fontWeight: 600,
},
subtitle: {
margin: "0 0 1.5rem",
color: "#666",
fontSize: "0.9rem",
},
form: {
display: "flex",
flexDirection: "column",
gap: "1rem",
},
row: {
display: "flex",
gap: "0.75rem",
},
field: {
display: "flex",
flexDirection: "column",
gap: "0.35rem",
},
halfField: {
display: "flex",
flexDirection: "column",
gap: "0.35rem",
flex: 1,
},
label: {
fontSize: "0.85rem",
fontWeight: 500,
color: "#333",
},
required: {
color: "#b91c1c",
},
input: {
padding: "0.6rem 0.75rem",
border: "1px solid #ccc",
borderRadius: "6px",
fontSize: "0.95rem",
outline: "none",
transition: "border-color 0.15s",
},
button: {
padding: "0.65rem",
backgroundColor: "#1a73e8",
color: "#fff",
border: "none",
borderRadius: "6px",
fontSize: "1rem",
fontWeight: 500,
cursor: "pointer",
marginTop: "0.5rem",
},
buttonDisabled: {
opacity: 0.6,
cursor: "not-allowed",
},
error: {
backgroundColor: "#fef2f2",
color: "#b91c1c",
border: "1px solid #fecaca",
borderRadius: "6px",
padding: "0.5rem 0.75rem",
fontSize: "0.85rem",
marginBottom: "0.5rem",
},
footer: {
marginTop: "1.25rem",
textAlign: "center",
fontSize: "0.85rem",
color: "#666",
},
link: {
color: "#1a73e8",
textDecoration: "none",
fontWeight: 500,
},
};
}