Skip to content

Commit 9fba5d3

Browse files
committed
fix GitHub Pages frontend entrypoint
1 parent c494161 commit 9fba5d3

7 files changed

Lines changed: 265 additions & 27 deletions

File tree

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Auth System
2+
3+
Simple authentication project with a static frontend and an Express backend.
4+
5+
## Live frontend
6+
7+
GitHub Pages serves the static UI from this repository:
8+
9+
- Landing page: `https://thalesmar.github.io/auth-system/`
10+
- Sign up page: `https://thalesmar.github.io/auth-system/frontend/pages/signup.html`
11+
- Login page: `https://thalesmar.github.io/auth-system/frontend/pages/login.html`
12+
13+
## Project structure
14+
15+
- `frontend/`: static HTML, CSS, and browser JavaScript
16+
- `backend/`: Express API for sign up and login
17+
- `assets/`: shared images and icons
18+
19+
## Run locally
20+
21+
1. Install backend dependencies:
22+
23+
```bash
24+
cd backend
25+
npm install
26+
```
27+
28+
2. Start the backend:
29+
30+
```bash
31+
npm run dev
32+
```
33+
34+
3. Open the frontend in a browser:
35+
36+
- `frontend/pages/signup.html`
37+
- `frontend/pages/login.html`
38+
39+
By default, the frontend sends requests to `http://localhost:8080`.
40+
41+
## Notes
42+
43+
- GitHub Pages can only host the static frontend.
44+
- The backend must run locally or be deployed separately for form submission to work online.

frontend/css/shared.css

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ body {
2828
color: var(--color-text);
2929
}
3030

31+
.landing-page {
32+
min-height: 100vh;
33+
background:
34+
radial-gradient(circle at top left, rgba(26, 115, 232, 0.14), transparent 30%),
35+
linear-gradient(135deg, #eef4ff 0%, #f7f8fb 55%, #ffffff 100%);
36+
}
37+
3138
.container {
3239
display: flex;
3340
align-items: center;
@@ -47,6 +54,114 @@ body {
4754
overflow: hidden;
4855
}
4956

57+
.landing-shell {
58+
min-height: 100vh;
59+
display: flex;
60+
align-items: center;
61+
justify-content: center;
62+
padding: 32px;
63+
}
64+
65+
.landing-card {
66+
width: min(1120px, 100%);
67+
display: grid;
68+
grid-template-columns: 1.2fr 0.8fr;
69+
gap: 32px;
70+
align-items: center;
71+
padding: 32px;
72+
border: 1px solid rgba(26, 115, 232, 0.12);
73+
border-radius: 28px;
74+
background: rgba(255, 255, 255, 0.9);
75+
box-shadow: 0 30px 80px rgba(31, 56, 88, 0.12);
76+
backdrop-filter: blur(8px);
77+
}
78+
79+
.landing-copy {
80+
display: grid;
81+
gap: 18px;
82+
}
83+
84+
.landing-eyebrow {
85+
display: inline-flex;
86+
width: fit-content;
87+
padding: 8px 14px;
88+
border-radius: 999px;
89+
background: rgba(26, 115, 232, 0.1);
90+
color: var(--color-link);
91+
font-size: 14px;
92+
font-weight: 700;
93+
letter-spacing: 0.03em;
94+
text-transform: uppercase;
95+
}
96+
97+
.landing-copy h1 {
98+
max-width: 12ch;
99+
font-size: clamp(40px, 6vw, 68px);
100+
line-height: 0.95;
101+
}
102+
103+
.landing-text {
104+
max-width: 56ch;
105+
font-size: 18px;
106+
line-height: 1.7;
107+
color: #4b5563;
108+
}
109+
110+
.landing-actions {
111+
display: flex;
112+
flex-wrap: wrap;
113+
gap: 14px;
114+
}
115+
116+
.landing-btn {
117+
min-width: 180px;
118+
text-decoration: none;
119+
}
120+
121+
.form-btn--ghost {
122+
border: 1px solid rgba(26, 115, 232, 0.2);
123+
color: var(--color-link);
124+
background: rgba(26, 115, 232, 0.06);
125+
}
126+
127+
.form-btn--ghost:hover {
128+
background: rgba(26, 115, 232, 0.12);
129+
}
130+
131+
.landing-note {
132+
width: fit-content;
133+
padding: 14px 16px;
134+
border-radius: 16px;
135+
background: #f7f8fb;
136+
border: 1px solid #e5e7eb;
137+
line-height: 1.6;
138+
}
139+
140+
.landing-preview {
141+
position: relative;
142+
}
143+
144+
.landing-preview::before {
145+
content: "";
146+
position: absolute;
147+
inset: auto 12% -8% 12%;
148+
height: 28px;
149+
border-radius: 999px;
150+
background: rgba(31, 56, 88, 0.18);
151+
filter: blur(22px);
152+
}
153+
154+
.landing-image {
155+
position: relative;
156+
display: block;
157+
width: 100%;
158+
max-width: 420px;
159+
margin-inline: auto;
160+
border-radius: 24px;
161+
object-fit: cover;
162+
box-shadow: 0 18px 45px rgba(31, 56, 88, 0.2);
163+
}
164+
50165
.form-header {
51166
position: relative;
52167
z-index: 1;
@@ -120,6 +235,8 @@ body {
120235
display: flex;
121236
top: 50%;
122237
transform: translateY(-50%);
238+
border: 0;
239+
background: transparent;
123240
}
124241

125242
.eye-icon svg {
@@ -222,6 +339,12 @@ body {
222339
text-decoration: none;
223340
}
224341

342+
#warningMsg {
343+
min-height: 24px;
344+
color: #c62828;
345+
text-align: center;
346+
}
347+
225348
.form-blob {
226349
position: absolute;
227350
width: 240px;
@@ -346,3 +469,13 @@ span{
346469
right: -48px;
347470
}
348471
}
472+
473+
@media (max-width: 900px) {
474+
.landing-card {
475+
grid-template-columns: 1fr;
476+
}
477+
478+
.landing-copy h1 {
479+
max-width: none;
480+
}
481+
}

frontend/js/login.js

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
const usernameInput = document.getElementById("username");
22
const passwordInput = document.getElementById("password");
33
const warningMsg = document.getElementById("warningMsg");
4-
const submitBtn = document.querySelector(".form-btn");
54
const form = document.querySelector(".form-box");
5+
const togglePasswordButton = document.querySelector(".eye-icon");
6+
const API_BASE_URL = window.AUTH_API_BASE_URL || "http://localhost:8080";
7+
8+
const buildApiUrl = (path) => `${API_BASE_URL}${path}`;
9+
10+
const togglePasswordVisibility = () => {
11+
passwordInput.type = passwordInput.type === "password" ? "text" : "password";
12+
};
613

714
const handleInputForm = async (e) => {
815
e.preventDefault();
@@ -19,24 +26,30 @@ const handleInputForm = async (e) => {
1926
return;
2027
}
2128

22-
const response = await fetch("http://localhost:8000/api/login", {
23-
method: "POST",
24-
headers: {"Content-Type": 'application/json'},
25-
body: JSON.stringify({
26-
username: usernameInputValue,
27-
password: passwordInputValue,
28-
}),
29-
});
29+
try {
30+
const response = await fetch(buildApiUrl("/api/login"), {
31+
method: "POST",
32+
headers: { "Content-Type": "application/json" },
33+
body: JSON.stringify({
34+
username: usernameInputValue,
35+
password: passwordInputValue,
36+
}),
37+
});
38+
39+
const data = await response.json();
3040

31-
const data = await response.json();
41+
if (!response.ok) {
42+
warningMsg.textContent = data.message;
43+
return;
44+
}
3245

33-
if (!response.ok) {
3446
warningMsg.textContent = data.message;
35-
return;
47+
} catch (error) {
48+
warningMsg.textContent = "Unable to reach the API. Start the backend or configure AUTH_API_BASE_URL.";
49+
console.log(error);
3650
}
3751

38-
warningMsg.textContent = data.message;
39-
40-
}
52+
};
4153

4254
form.addEventListener("submit", handleInputForm);
55+
togglePasswordButton?.addEventListener("click", togglePasswordVisibility);

frontend/js/signup.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ const usernameInput = document.getElementById("username");
22
const passwordInput = document.getElementById("password");
33
const warningMsg = document.getElementById("warningMsg");
44
const emailInput = document.getElementById("email");
5-
const submitBtn = document.querySelector(".form-btn");
65
const termsInput = document.getElementById("termsInput");
76
const form = document.querySelector(".form-box");
7+
const togglePasswordButton = document.querySelector(".eye-icon");
8+
const API_BASE_URL = window.AUTH_API_BASE_URL || "http://localhost:8080";
9+
10+
const buildApiUrl = (path) => `${API_BASE_URL}${path}`;
11+
12+
const togglePasswordVisibility = () => {
13+
passwordInput.type = passwordInput.type === "password" ? "text" : "password";
14+
};
815

916
const handleInputForm = async (e) => {
1017
e.preventDefault();
@@ -28,7 +35,7 @@ const handleInputForm = async (e) => {
2835
}
2936

3037
try {
31-
const response = await fetch("http://localhost:8000/api/signup", {
38+
const response = await fetch(buildApiUrl("/api/signup"), {
3239
method: "POST",
3340
headers: { "Content-Type": "application/json" },
3441
body: JSON.stringify({
@@ -45,12 +52,13 @@ const handleInputForm = async (e) => {
4552
return;
4653
}
4754

48-
warningMsg.textContent = data.message;
55+
warningMsg.textContent = data.message;
56+
form.reset();
4957
} catch (error) {
50-
warningMsg.textContent = "Server error. Please try again.";
58+
warningMsg.textContent = "Unable to reach the API. Start the backend or configure AUTH_API_BASE_URL.";
5159
console.log(error);
52-
console.log(object);
5360
}
5461
};
5562

5663
form.addEventListener("submit", handleInputForm);
64+
togglePasswordButton?.addEventListener("click", togglePasswordVisibility);

frontend/pages/login.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ <h1>Welcome Back</h1>
3737
<div class="input-group">
3838
<input type="password" id="password" class="input-field" placeholder="" required />
3939
<label for="password" class="floating-label">Password</label>
40-
<div class="eye-icon" onclick="togglePassword()">
40+
<button type="button" class="eye-icon" aria-label="Toggle password visibility">
4141
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
4242
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"
4343
class="lucide lucide-eye-icon lucide-eye">
4444
<path
4545
d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" />
4646
<circle cx="12" cy="12" r="3" />
4747
</svg>
48-
</div>
48+
</button>
4949
</div>
5050
<div class="input-group checkbox-group">
5151
<div class="form-col remember-me">
@@ -84,5 +84,5 @@ <h1>Welcome Back</h1>
8484
</div>
8585
</div>
8686

87-
<script type="module" src="/frontend/js/login.js"></script>
87+
<script type="module" src="../js/login.js"></script>
8888
</body>

frontend/pages/signup.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ <h1>Get Started Now</h1>
4141
<div class="input-group">
4242
<input type="password" id="password" class="input-field" placeholder="" required />
4343
<label for="password" class="floating-label">Password</label>
44-
<div class="eye-icon" >
44+
<button type="button" class="eye-icon" aria-label="Toggle password visibility">
4545
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
4646
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"
4747
class="lucide lucide-eye-icon lucide-eye">
4848
<path
4949
d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" />
5050
<circle cx="12" cy="12" r="3" />
5151
</svg>
52-
</div>
52+
</button>
5353
</div>
5454
<div class="input-group checkbox-group">
5555
<div class="form-col remember-me">
@@ -80,13 +80,13 @@ <h1>Get Started Now</h1>
8080
</button>
8181
</div>
8282
<p>
83-
Don't have an account? <a href="./login.html" class="form-link">Sign In</a>
83+
Already have an account? <a href="./login.html" class="form-link">Sign In</a>
8484
</p>
8585

8686
<p id="warningMsg"></p>
8787
</div>
8888
</div>
8989
</div>
9090

91-
<script type="module" src="/frontend/js/signUp.js"></script>
91+
<script type="module" src="../js/signup.js"></script>
9292
</body>

0 commit comments

Comments
 (0)