This commit is contained in:
Lheorvine 2025-05-26 19:24:45 +02:00
parent 8f7799cc28
commit b857c644f7
10 changed files with 364 additions and 184 deletions

View file

@ -253,21 +253,46 @@ async fn get_ksiazka(
}
}
#[derive(Serialize)]
struct UserInfo {
id: i32,
imie: String,
}
#[get("/api/check-auth")]
async fn check_auth(req: HttpRequest) -> impl Responder {
async fn check_auth(
req: HttpRequest,
pool: web::Data<sqlx::PgPool>, // Dodajemy pool jako parametr
) -> impl Responder {
let token = req.headers().get("Authorization")
.and_then(|h| h.to_str().ok());
match validate_token(token).await {
Ok(user_id) => HttpResponse::Ok().json(json!({
Ok(user_id) => {
match sqlx::query!(
"SELECT imie FROM uzytkownicy WHERE id = $1",
user_id
)
.fetch_one(pool.get_ref()) // Używamy pool z parametru
.await {
Ok(u) => HttpResponse::Ok().json(json!({
"authenticated": true,
"user": {"id": user_id}
"user": {
"id": user_id,
"imie": u.imie
}
})),
Err(_) => HttpResponse::Ok().json(json!({
"authenticated": false,
"user": null
}))
}
},
Err(_) => HttpResponse::Ok().json(json!({
"authenticated": false,
"user": null
}))
}
}
#[derive(serde::Serialize)]

View file

@ -10,36 +10,36 @@
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<a class="navbar-brand" href="/">DARK ATHENAEUM</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<div class="navbar-nav gap-3">
<!-- Dodaj pole wyszukiwania -->
<form class="d-flex" id="searchForm">
<input class="form-control me-2 dark-input" type="search" placeholder="Szukaj książek..." aria-label="Search">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
aria-label="Search"
id="searchInput">
</form>
<!-- Linki -->
<div class="anonymous-links d-flex gap-3">
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links d-flex gap-3" style="display: none;">
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
</div>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<main class="container py-5">

View file

@ -12,6 +12,40 @@
<link href="https://fonts.googleapis.com/css2?family=Lobster&family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
aria-label="Search"
id="searchInput">
</form>
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<main class="container py-5">
<h2 class="neon-title mb-4">Twój koszyk</h2>
<div id="cart-items" class="row g-4"></div>

View file

@ -255,3 +255,72 @@ footer a {
.order-item:last-child {
margin-bottom: 0;
}
.hidden {
display: none !important;
}
/* Pokazywanie elementów */
.visible {
display: flex !important;
}
.auth-links {
display: flex;
gap: 1rem;
}
.anonymous-links,
.user-links {
display: none;
}
.anonymous-links.visible,
.user-links.visible {
display: flex !important;
gap: 1rem;
}
.navbar-brand {
font-size: 1.8rem;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
@media (max-width: 991px) {
.navbar-brand {
position: static;
transform: none;
order: 0 !important;
margin: 0.5rem 0;
}
.navbar-toggler {
order: 1;
}
#searchForm {
order: 2;
width: 100%;
margin-top: 1rem;
}
.auth-links {
order: 3;
width: 100%;
justify-content: center;
margin-top: 1rem;
}
}
/* Responsywność formularza wyszukiwania */
@media (min-width: 992px) {
#searchForm {
max-width: 400px;
}
.navbar-brand {
position: absolute;
}
}

View file

@ -13,15 +13,8 @@
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<a class="navbar-brand" href="/">DARK ATHENAEUM</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<div class="navbar-nav gap-3">
<form class="d-flex" id="searchForm">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
@ -29,22 +22,27 @@
id="searchInput">
</form>
<div class="anonymous-links d-flex gap-3">
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links d-flex gap-3" style="display: none !important;">
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
</div>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<main class="container py-5">

View file

@ -51,6 +51,54 @@
document.addEventListener('DOMContentLoaded', loadBooks);
})();
async function updateAuthUI() {
const token = localStorage.getItem('token');
const authContainers = document.querySelectorAll('.auth-links');
try {
const response = await fetch('/api/check-auth', {
headers: token ? { 'Authorization': `Bearer ${token}` } : {}
});
const data = await response.json();
authContainers.forEach(container => {
const anonymous = container.querySelector('.anonymous-links');
const user = container.querySelector('.user-links');
const cart = container.querySelector('a[href="/cart.html"]');
if (data.authenticated) {
anonymous?.classList.remove('visible');
user?.classList.add('visible');
cart?.classList.add('visible');
} else {
anonymous?.classList.add('visible');
user?.classList.remove('visible');
cart?.classList.remove('visible');
localStorage.removeItem('token');
}
});
} catch (error) {
console.error('Błąd autentykacji:', error);
}
}
// Obsługa wylogowania
function setupLogout() {
document.getElementById('logoutLink')?.addEventListener('click', async (e) => {
e.preventDefault();
localStorage.removeItem('token');
await updateAuthUI();
window.location.href = '/';
});
}
// Inicjalizacja na każdej stronie
document.addEventListener('DOMContentLoaded', () => {
updateAuthUI();
setupLogout();
});
document.addEventListener('DOMContentLoaded', () => {
updateNavVisibility();
checkAuthStatus();
@ -94,30 +142,27 @@ document.getElementById('logoutLink')?.addEventListener('click', (e) => {
document.getElementById('loginForm')?.addEventListener('submit', async (e) => {
e.preventDefault();
const email = document.getElementById('loginEmail').value;
const password = document.getElementById('loginPassword').value;
try {
const response = await fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, haslo: password }),
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: document.getElementById('loginEmail').value,
haslo: document.getElementById('loginPassword').value
})
});
const data = await response.json();
if (response.ok) {
localStorage.setItem('token', data.token);
localStorage.setItem('imie', data.imie);
updateNavVisibility();
const { token } = await response.json();
localStorage.setItem('token', token);
await updateAuthUI();
window.location.href = '/';
} else {
alert(data.message || 'Logowanie nieudane');
alert('Błąd logowania!');
}
} catch (error) {
console.error('Błąd logowania:', error);
alert('Wystąpił błąd podczas logowania');
console.error('Błąd:', error);
}
});
@ -276,29 +321,5 @@ function getAuthHeaders() {
};
}
async function updateNavbar() {
try {
const response = await fetch('/api/check-auth', {
headers: getAuthHeaders()
});
const authInfo = await response.json();
const userLinks = document.querySelector('.user-links');
const anonLinks = document.querySelector('.anonymous-links');
if (authInfo.authenticated) {
userLinks.style.display = 'flex';
anonLinks.style.display = 'none';
} else {
userLinks.style.display = 'none';
anonLinks.style.display = 'flex';
}
} catch (error) {
console.error('Error checking auth:', error);
}
}
// Wywołaj przy każdym załadowaniu strony
document.addEventListener('DOMContentLoaded', updateNavbar);
localStorage.setItem('token', response.token);

View file

@ -12,36 +12,36 @@
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<a class="navbar-brand" href="/">DARK ATHENAEUM</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<div class="navbar-nav gap-3">
<!-- Dodaj pole wyszukiwania -->
<form class="d-flex" id="searchForm">
<input class="form-control me-2 dark-input" type="search" placeholder="Szukaj książek..." aria-label="Search">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
aria-label="Search"
id="searchInput">
</form>
<!-- Linki -->
<div class="anonymous-links d-flex gap-3">
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links d-flex gap-3" style="display: none;">
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
</div>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<div class="auth-container">

View file

@ -13,15 +13,8 @@
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<a class="navbar-brand" href="/">DARK ATHENAEUM</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<div class="navbar-nav gap-3">
<form class="d-flex" id="searchForm">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
@ -29,23 +22,29 @@
id="searchInput">
</form>
<div class="anonymous-links d-flex gap-3">
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links d-flex gap-3" style="display: none !important;">
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
</div>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<main class="container py-5">
<h2 class="neon-title mb-4">Twój profil</h2>

View file

@ -11,36 +11,36 @@
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<a class="navbar-brand" href="/">DARK ATHENAEUM</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<div class="navbar-nav gap-3">
<!-- Dodaj pole wyszukiwania -->
<form class="d-flex" id="searchForm">
<input class="form-control me-2 dark-input" type="search" placeholder="Szukaj książek..." aria-label="Search">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
aria-label="Search"
id="searchInput">
</form>
<!-- Linki -->
<div class="anonymous-links d-flex gap-3">
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links d-flex gap-3" style="display: none;">
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
</div>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<div class="auth-container">

View file

@ -7,6 +7,40 @@
<link href="/css/styles.css" rel="stylesheet">
</head>
<body class="dark-theme">
<nav class="navbar navbar-expand-lg navbar-dark bg-black">
<div class="container">
<!-- Lewa strona - wyszukiwanie -->
<form class="d-flex me-lg-3 flex-grow-1" id="searchForm">
<input class="form-control me-2 dark-input"
type="search"
placeholder="Szukaj książek..."
aria-label="Search"
id="searchInput">
</form>
<!-- Środek - logo -->
<a class="navbar-brand mx-lg-auto order-lg-1" href="/">DARK ATHENAEUM</a>
<!-- Prawa strona - przyciski -->
<div class="d-flex align-items-center order-lg-2">
<div class="auth-links">
<div class="anonymous-links">
<a class="nav-link" href="/login.html">Logowanie</a>
<a class="nav-link" href="/register.html">Rejestracja</a>
</div>
<div class="user-links">
<a class="nav-link" href="/profile.html">Profil</a>
<a class="nav-link" href="#" id="logoutLink">Wyloguj</a>
<a class="nav-link" href="/cart.html">
<i class="bi bi-basket"></i> Koszyk
</a>
</div>
</div>
</div>
</div>
</nav>
<main class="container py-5 text-center">
<h1 class="neon-title mb-4">Dziękujemy za zakup!</h1>
<p class="inter-font fs-5">Twoje zamówienie zostało pomyślnie zrealizowane.</p>