login in registracija
This commit is contained in:
40
login.html
Normal file
40
login.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sl_SI">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Prijava</title>
|
||||||
|
<script src="./scripts/preload.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./styles/main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="page-header"></div>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="page-title-container">
|
||||||
|
<h3 class="page-title" id="page-title">Prijava</h3>
|
||||||
|
</div>
|
||||||
|
<form class="page-login-form" id="login-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Uporabniško ime:</label><br>
|
||||||
|
<input type="text" id="username" name="username" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Geslo:</label><br>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="page-btn">Prijavi se</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<p>Še nimate računa? <a href="/register.html" class="page-link">Registrirajte se</a></p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="page-footer"></div>
|
||||||
|
|
||||||
|
<script src="./scripts/login.js"></script>
|
||||||
|
<script src="./scripts/main.js" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
48
register.html
Normal file
48
register.html
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="sl_SI">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Registracija</title>
|
||||||
|
<script src="./scripts/preload.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./styles/main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="page-header"></div>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="page-title-container">
|
||||||
|
<h3 class="page-title" id="page-title">Registracija</h3>
|
||||||
|
</div>
|
||||||
|
<form class="page-login-form" id="login-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Uporabniško ime:</label><br>
|
||||||
|
<input type="text" id="username" name="username" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">E-pošta:</label><br>
|
||||||
|
<input type="email" id="email" name="email" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Geslo:</label><br>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="confirm-password">Potrdite geslo:</label><br>
|
||||||
|
<input type="password" id="confirm-password" name="confirm-password" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="page-btn">Registriraj se</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<p>Že imate račun? <a href="/login.html" class="page-link">Prijavite se</a></p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="page-footer"></div>
|
||||||
|
|
||||||
|
<script src="./scripts/register.js"></script>
|
||||||
|
<script src="./scripts/main.js" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
45
scripts/login.js
Normal file
45
scripts/login.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
const errmsg = `
|
||||||
|
<div class="form-group">
|
||||||
|
<p class="page-paragraph-error">Napaka pri prijavi! Preverite uporabniško ime in geslo oz. poskusite kasneje.</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById("login-form").addEventListener("submit", async function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Izbriši prejšnje napake
|
||||||
|
const previousErrors = document.querySelectorAll(".page-paragraph-error");
|
||||||
|
previousErrors.forEach(error => error.remove());
|
||||||
|
|
||||||
|
const username = document.getElementById("username").value;
|
||||||
|
const password = document.getElementById("password").value;
|
||||||
|
const form = document.getElementById("login-form");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("http://localhost:3000/prijava", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ "username": username, "password": password })
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json().catch(() => ({}));
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
// Nastavi cookie, 3 ure veljaven
|
||||||
|
document.cookie = `token=${data.token}; max-age=${3 * 60 * 60}; path=/; secure; samesite=strict`;
|
||||||
|
|
||||||
|
window.location.href = "/";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = data.message || "Napaka pri prijavi! Preverite uporabniško ime in geslo oz. poskusite kasneje.";
|
||||||
|
form.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="form-group"><p class="page-paragraph-error">${message}</p></div>`
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
form.insertAdjacentHTML("beforeend", errmsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -8,6 +8,7 @@ const headerHtml = `
|
|||||||
<a class="nav-btn" href="/about.html">O projektu</a>
|
<a class="nav-btn" href="/about.html">O projektu</a>
|
||||||
<a class="nav-btn" href="/contact.html">Kontakt</a>
|
<a class="nav-btn" href="/contact.html">Kontakt</a>
|
||||||
<a class="nav-btn" href="/extras.html">Dodatki</a>
|
<a class="nav-btn" href="/extras.html">Dodatki</a>
|
||||||
|
<div id="nav-login-holder"></div>
|
||||||
|
|
||||||
<button id="theme-toggle" class="toggle-btn" onclick="toggleTheme()" aria-label="Toggle colour scheme" aria-pressed="false">
|
<button id="theme-toggle" class="toggle-btn" onclick="toggleTheme()" aria-label="Toggle colour scheme" aria-pressed="false">
|
||||||
<div class="track"><div class="knob"></div></div>
|
<div class="track"><div class="knob"></div></div>
|
||||||
@@ -38,7 +39,12 @@ function updateToggleState(theme) {
|
|||||||
|
|
||||||
icon.textContent = theme === 'dark' ? '🌙' : '☀';
|
icon.textContent = theme === 'dark' ? '🌙' : '☀';
|
||||||
toggleButton.setAttribute('aria-pressed', theme === 'dark' ? 'true' : 'false');
|
toggleButton.setAttribute('aria-pressed', theme === 'dark' ? 'true' : 'false');
|
||||||
toggleButton.setAttribute('aria-label', theme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme');
|
toggleButton.setAttribute('aria-label', theme === 'dark' ? 'Svetli način' : 'Temni način');
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
// Odstrani cookie tako, da ga nastaviš z max-age=0
|
||||||
|
document.cookie = 'token=; max-age=0; path=/; secure; samesite=strict';
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
@@ -50,6 +56,27 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||||||
element.innerHTML = headerHtml;
|
element.innerHTML = headerHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dodaj gumb za prijavo, če uporabnik ni prijavljen
|
||||||
|
const isLoggedIn = document.cookie.split(';').some(cookie => cookie.trim().startsWith('token='));
|
||||||
|
if (!isLoggedIn) {
|
||||||
|
const navRight = document.querySelector('.nav-right');
|
||||||
|
if (navRight) {
|
||||||
|
const loginBtn = `<a class="nav-btn nav-btn-primary" href="/login.html">Prijava</a>`;
|
||||||
|
// Najdi zadnji <a> element in dodaj gumb za njim
|
||||||
|
const lastLink = navRight.querySelector('a:last-child');
|
||||||
|
document.getElementById("nav-login-holder").innerHTML = loginBtn;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const navRight = document.querySelector('.nav-right');
|
||||||
|
if (navRight) {
|
||||||
|
const logoutBtn = `<a class="nav-btn nav-btn-primary" href="/">Odjava</a>`;
|
||||||
|
// Najdi zadnji <a> element in dodaj gumb za njim
|
||||||
|
const lastLink = navRight.querySelector('a:last-child');
|
||||||
|
document.getElementById("nav-login-holder").innerHTML = logoutBtn;
|
||||||
|
document.querySelector('.nav-btn-primary').addEventListener('click', logout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let element of document.getElementsByClassName("page-footer")) {
|
for (let element of document.getElementsByClassName("page-footer")) {
|
||||||
element.innerHTML = footerHtml;
|
element.innerHTML = footerHtml;
|
||||||
}
|
}
|
||||||
|
|||||||
78
scripts/register.js
Normal file
78
scripts/register.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
const errmsg = `
|
||||||
|
<div class="form-group">
|
||||||
|
<p class="page-paragraph-error">Napaka pri registraciji! Preverite vnešene podatke oz. poskusite kasneje.</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById("login-form").addEventListener("submit", async function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Izbriši prejšnje napake
|
||||||
|
const previousErrors = document.querySelectorAll(".page-paragraph-error");
|
||||||
|
previousErrors.forEach(error => error.remove());
|
||||||
|
// Izbriši prejšnje uspehe
|
||||||
|
const previousSuccesses = document.querySelectorAll(".page-paragraph-success");
|
||||||
|
previousSuccesses.forEach(success => success.remove());
|
||||||
|
|
||||||
|
const username = document.getElementById("username").value;
|
||||||
|
const email = document.getElementById("email").value;
|
||||||
|
const password = document.getElementById("password").value;
|
||||||
|
const confirmPassword = document.getElementById("confirm-password").value;
|
||||||
|
const form = document.getElementById("login-form");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Veljavnost vnosa
|
||||||
|
if (!username || !email || !password || !confirmPassword) {
|
||||||
|
form.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="form-group"><p class="page-paragraph-error">Vsa polja so obvezna!</p></div>`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!email.includes("@")) {
|
||||||
|
form.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="form-group"><p class="page-paragraph-error">Neveljaven email naslov!</p></div>`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password !== confirmPassword) {
|
||||||
|
form.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="form-group"><p class="page-paragraph-error">Gesli se ne ujemata!</p></div>`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch("http://localhost:3000/registracija", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ "username": username, "email": email, "password": password })
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json().catch(() => ({}));
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
setTimeout(() => {
|
||||||
|
form.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="form-group"><p class="page-paragraph-success">Uspešna registracija! Preusmerjanje na prijavo...</p></div>`
|
||||||
|
);
|
||||||
|
}, 500);
|
||||||
|
window.location.href = "/login.html";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = data.message || "Napaka pri registraciji! Preverite vnešene podatke oz. poskusite kasneje.";
|
||||||
|
form.insertAdjacentHTML(
|
||||||
|
"beforeend",
|
||||||
|
`<div class="form-group"><p class="page-paragraph-error">${message}</p></div>`
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
form.insertAdjacentHTML("beforeend", errmsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -12,6 +12,8 @@
|
|||||||
--toggle-track: #4a4a4a;
|
--toggle-track: #4a4a4a;
|
||||||
--toggle-knob: #f4f4f4;
|
--toggle-knob: #f4f4f4;
|
||||||
--toggle-icon-color: #f5f5f5;
|
--toggle-icon-color: #f5f5f5;
|
||||||
|
--nav-btn-primary-bg: #007acc;
|
||||||
|
--nav-btn-primary-hover-bg: #006bb3;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme="light"] {
|
:root[data-theme="light"] {
|
||||||
@@ -26,6 +28,8 @@
|
|||||||
--toggle-track: #d3d3d3;
|
--toggle-track: #d3d3d3;
|
||||||
--toggle-knob: #ffffff;
|
--toggle-knob: #ffffff;
|
||||||
--toggle-icon-color: #444;
|
--toggle-icon-color: #444;
|
||||||
|
--nav-btn-primary-bg: #007acc;
|
||||||
|
--nav-btn-primary-hover-bg: #006bb3;
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@@ -158,6 +162,26 @@ nav {
|
|||||||
margin-right: 23px;
|
margin-right: 23px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-paragraph-error {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #e74c3c;
|
||||||
|
|
||||||
|
/* Smooth Theme Transition */
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-paragraph-success {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #27ae60;
|
||||||
|
|
||||||
|
/* Smooth Theme Transition */
|
||||||
|
transition: color 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
.page-input {
|
.page-input {
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
border: 1px solid var(--nav-btn-border);
|
border: 1px solid var(--nav-btn-border);
|
||||||
@@ -171,6 +195,40 @@ nav {
|
|||||||
transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
|
transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-login-form {
|
||||||
|
margin-top: 10px;
|
||||||
|
border: 1px solid var(--nav-btn-border);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--nav-btn-bg);
|
||||||
|
color: var(--text-color);
|
||||||
|
transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
|
||||||
|
padding-top: 12px;
|
||||||
|
width: max-content;
|
||||||
|
margin-left: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input {
|
||||||
|
padding: 8px 10px;
|
||||||
|
border: 1px solid var(--nav-btn-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--nav-btn-bg);
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 0.92rem;
|
||||||
|
font-family: inherit;
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
/* Smooth Theme Transition */
|
||||||
|
transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-login-form .form-group {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 0 23px;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-left,
|
.nav-left,
|
||||||
.nav-right {
|
.nav-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -224,6 +282,20 @@ nav {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-btn-primary {
|
||||||
|
background: var(--nav-btn-primary-bg);
|
||||||
|
border-color: var(--nav-btn-primary-bg);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-btn-primary:hover,
|
||||||
|
.nav-btn-primary:focus-visible {
|
||||||
|
background: var(--nav-btn-primary-hover-bg);
|
||||||
|
border-color: var(--nav-btn-primary-hover-bg);
|
||||||
|
color: #fff;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
@media (max-width: 720px) {
|
||||||
header {
|
header {
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
|
|||||||
Reference in New Issue
Block a user