Skip to content

Commit 01c56d9

Browse files
authored
Backend Integration PR ( #52 )
Completed routes in frontend and server setup for login and register functionality
2 parents e19cc52 + 46e413c commit 01c56d9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2858
-548
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/server/node_modules
2+
/server/.env
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

Diff for: client/src/css/alert.css

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#custom-alert {
2+
position: fixed;
3+
top: 5%;
4+
left: 50%;
5+
transform: translateX(-50%);
6+
padding: 15px;
7+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
8+
z-index: 1000;
9+
border: 2px solid #6c6ceb;
10+
background: #000042;
11+
color: #6c6ceb;
12+
border-radius: 9px;
13+
transition: all 0.5s ease;
14+
}
15+
16+
#custom-alert-content {
17+
display: flex;
18+
align-items: center;
19+
gap: 10px;
20+
}
21+
22+
#custom-alert-close {
23+
color: #6c6ceb;
24+
background: none;
25+
padding: 0;
26+
border: none;
27+
cursor: pointer;
28+
}
29+
.animated-element {
30+
animation-name: alert;
31+
animation-duration: 1s;
32+
animation-timing-function: linear;
33+
animation-delay: 0s;
34+
}
35+
@keyframes alert {
36+
0% {
37+
transform: translateX(-50%) scale(0.5);
38+
}
39+
10% {
40+
transform: translateX(-50%) scale(0.5);
41+
}
42+
20% {
43+
transform: translateX(-50%) scale(1);
44+
}
45+
30% {
46+
transform: translateX(-50%) scale(0.5);
47+
}
48+
40% {
49+
transform: translateX(-50%) scale(1);
50+
}
51+
50% {
52+
transform: translateX(-50%) scale(0.5);
53+
}
54+
60% {
55+
transform: translateX(-50%) scale(1);
56+
}
57+
70% {
58+
transform: translateX(-50%) scale(0.5);
59+
}
60+
100% {
61+
transform: translateX(-50%) scale(0);
62+
}
63+
}

Diff for: src/css/contact.css renamed to client/src/css/contact.css

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
--color-primary: black;
99
--color-secondary: white;
1010
}
11+
1112
.main-container {
1213
color: var(--color-secondary);
1314
display: flex;
File renamed without changes.

Diff for: src/css/login.css renamed to client/src/css/login.css

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
--font-small: 1.25rem;
1616
--font-ex-small: 0.8rem;
1717
}
18+
a {
19+
text-decoration: none;
20+
}
1821
.material-symbols-outlined {
1922
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
2023
color: var(--color-secondary);
@@ -51,6 +54,7 @@
5154
font-size: var(--font-large);
5255
}
5356
.blue-btn {
57+
border-color: var(--color-primary);
5458
padding: 20px;
5559
height: 10vh;
5660
background-color: var(--color-primary);
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

Diff for: client/src/js/alert.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
fetch('alert.html')
3+
.then((response) => response.text())
4+
.then((data) => {
5+
document.body.insertAdjacentHTML('beforeend', data)
6+
setupCustomAlert()
7+
})
8+
})
9+
10+
function setupCustomAlert() {
11+
const alertBox = document.getElementById('custom-alert')
12+
const alertClose = document.getElementById('custom-alert-close')
13+
14+
alertClose.addEventListener('click', () => {
15+
alertBox.classList.add('animated-element')
16+
})
17+
}
18+
// function to show the alert message
19+
export function showCustomAlert(message) {
20+
const alertMessage = document.getElementById('custom-alert-message')
21+
const alertBox = document.getElementById('custom-alert')
22+
alertMessage.textContent = message
23+
}

Diff for: client/src/js/api.js

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { CONFIG } from '../../../config.js'
2+
3+
export async function sendUserData(userData) {
4+
try {
5+
const response = await fetch(`${CONFIG.API_ENDPOINT}/api/register`, {
6+
method: 'POST',
7+
headers: {
8+
'Content-Type': 'application/json'
9+
},
10+
body: JSON.stringify(userData)
11+
})
12+
13+
if (!response.ok) {
14+
const errorData = await response.json()
15+
alert(errorData.message || 'Network response was not ok')
16+
throw new Error(errorData.message || 'Network response was not ok')
17+
}
18+
19+
const data = await response.json()
20+
return data
21+
} catch (error) {
22+
console.error(
23+
'There was a problem with the fetch operation:',
24+
error.message
25+
)
26+
throw error
27+
}
28+
}
29+
30+
export async function login(userData) {
31+
try {
32+
const response = await fetch(`${CONFIG.API_ENDPOINT}/api/login`, {
33+
method: 'POST',
34+
headers: {
35+
'Content-Type': 'application/json'
36+
},
37+
body: JSON.stringify(userData)
38+
})
39+
40+
const data = await response.json()
41+
if (response.ok) {
42+
localStorage.setItem('accessToken', data.accessToken)
43+
document.cookie = `refreshToken=${data.refreshToken}; HttpOnly`
44+
alert('Login successful!')
45+
} else {
46+
alert(data.message)
47+
}
48+
} catch (e) {
49+
console.error(
50+
'There was a problem with the fetch operation:',
51+
error.message
52+
)
53+
throw error
54+
}
55+
}
56+
57+
async function fetchProtectedData() {
58+
let accessToken = localStorage.getItem('accessToken')
59+
const response = await fetch(`${CONFIG.API_ENDPOINT}/api/protected`, {
60+
headers: {
61+
Authorization: `Bearer ${accessToken}`
62+
}
63+
})
64+
65+
if (response.status === 401) {
66+
// Access token expired, try to refresh it
67+
const refreshToken = document.cookie
68+
.split('; ')
69+
.find((row) => row.startsWith('refreshToken'))
70+
.split('=')[1]
71+
const tokenResponse = await fetch(`${CONFIG.API_ENDPOINT}/api/token`, {
72+
method: 'POST',
73+
headers: {
74+
'Content-Type': 'application/json'
75+
},
76+
body: JSON.stringify({ token: refreshToken })
77+
})
78+
79+
if (tokenResponse.ok) {
80+
const tokenData = await tokenResponse.json()
81+
accessToken = tokenData.accessToken
82+
localStorage.setItem('accessToken', accessToken)
83+
84+
// Retry the original request with the new access token
85+
const retryResponse = await fetch(
86+
`${CONFIG.API_ENDPOINT}/api/protected`,
87+
{
88+
headers: {
89+
Authorization: `Bearer ${accessToken}`
90+
}
91+
}
92+
)
93+
94+
if (retryResponse.ok) {
95+
const data = await retryResponse.json()
96+
} else {
97+
alert('Failed to fetch protected data')
98+
}
99+
} else {
100+
alert('Failed to refresh token')
101+
}
102+
} else if (response.ok) {
103+
const data = await response.json()
104+
} else {
105+
alert('Failed to fetch protected data')
106+
}
107+
}

0 commit comments

Comments
 (0)