293 lines
19 KiB
PHP
293 lines
19 KiB
PHP
<?php
|
|
session_start();
|
|
$roleName = isset($_SESSION['role_name']) ? $_SESSION['role_name'] : null;
|
|
$isLogged = isset($_SESSION['user_id']);
|
|
$username = isset($_SESSION['username']) ? $_SESSION['username'] : null;
|
|
// Flag di sessione: mostra l'effetto solo una volta per sessione
|
|
$alessioCandidate = $isLogged && $username && stripos($username, 'alessio') !== false;
|
|
$showBlessingOnce = false;
|
|
if ($alessioCandidate && empty($_SESSION['alessio_blessed'])) {
|
|
$showBlessingOnce = true;
|
|
$_SESSION['alessio_blessed'] = true;
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="it">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Biblioteca | Home</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<style>
|
|
#alessioBlessing{position:fixed;left:50%;transform:translateX(-50%);top:-300px;width:220px;height:220px;pointer-events:none;z-index:9999;opacity:0;}
|
|
#alessioBlessing .halo{position:absolute;top:-20px;left:50%;transform:translateX(-50%);width:150px;height:150px;border-radius:50%;box-shadow:0 0 30px 15px rgba(255,215,0,0.7) inset,0 0 25px 10px rgba(255,215,0,0.6);background:radial-gradient(circle, rgba(255,238,169,0.7) 0%, rgba(255,204,0,0.4) 60%, rgba(255,204,0,0.1) 100%);}
|
|
#alessioBlessing .photo{position:absolute;bottom:0;left:50%;transform:translateX(-50%);width:120px;height:160px;border-radius:10px;object-fit:cover;box-shadow:0 10px 25px rgba(0,0,0,0.15);}
|
|
#alessioBlessing .sparkles{position:absolute;inset:0;}
|
|
#alessioBlessing .sparkles span{position:absolute;width:6px;height:6px;background:#ffd700;border-radius:50%;box-shadow:0 0 10px #ffd700;opacity:.9;animation:twinkle 1.2s infinite ease-in-out;}
|
|
@keyframes twinkle{0%,100%{transform:translateY(0) scale(1);opacity:.3;}50%{transform:translateY(-6px) scale(1.2);opacity:1;}}
|
|
@keyframes descendTop{0%{top:-300px;opacity:0;}30%{top:18%;opacity:1;}60%{top:35%;opacity:1;}85%{top:60%;opacity:.9;}100%{top:110%;opacity:0;}}
|
|
#alessioBlessing.run{animation:descendTop 4.8s ease-in-out forwards;}
|
|
</style>
|
|
</head>
|
|
<body class="bg-[#f8fafc] text-[#545454]">
|
|
<nav class="w-full bg-[#545454] text-white shadow">
|
|
<div class="max-w-7xl mx-auto px-4">
|
|
<div class="flex justify-between items-center h-16">
|
|
<div class="flex items-center gap-6">
|
|
<a href="#" class="font-semibold text-lg">Biblioteca Online</a>
|
|
<div class="hidden md:flex items-center gap-4">
|
|
<a href="#" class="hover:text-[#cbff4d]">Catalogo</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Recensioni</a>
|
|
</div>
|
|
</div>
|
|
<!-- Menu basato sul ruolo -->
|
|
<div class="hidden md:flex items-center gap-4">
|
|
<?php if ($isLogged && $roleName === 'admin'): ?>
|
|
<a href="#" class="hover:text-[#cbff4d]">Gestione Utenti</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Ruoli & Permessi</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Gestione Bibliotecari</a>
|
|
<?php elseif ($isLogged && $roleName === 'bibliotecario'): ?>
|
|
<a href="#" class="hover:text-[#cbff4d]">Elenco Libri</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Elenco Film</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Elenco Documentari</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Prenotazioni</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Utenti Registrati</a>
|
|
<?php elseif ($isLogged && $roleName === 'utente'): ?>
|
|
<a href="#" class="hover:text-[#cbff4d]">Prenota</a>
|
|
<a href="#" class="hover:text-[#cbff4d]">Le mie Prenotazioni</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<?php if ($isLogged): ?>
|
|
<span class="hidden md:inline text-sm">Ciao, <?php echo htmlspecialchars($username); ?></span>
|
|
<a href="./php/auth/logout.php" class="px-4 py-2 bg-[#84dd63] text-[#1f2937] rounded hover:bg-[#cbff4d]">Logout</a>
|
|
<?php else: ?>
|
|
<button id="openLogin" class="px-4 py-2 bg-[#84dd63] text-[#1f2937] rounded hover:bg-[#cbff4d]">Login</button>
|
|
<button id="openRegister" class="px-4 py-2 bg-[#69747c] text-white rounded hover:bg-[#545454]">Registrati</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Hero/Intro -->
|
|
<section class="max-w-7xl mx-auto px-4 py-10">
|
|
<div class="grid md:grid-cols-2 gap-8 items-center">
|
|
<div>
|
|
<h1 class="text-3xl md:text-4xl font-bold text-[#6baa75]">Benvenuto nella Biblioteca Online</h1>
|
|
<p class="mt-3 text-[#69747c]">Esplora libri, film e documentari. Prenota facilmente e gestisci le tue recensioni. In base al tuo ruolo vedrai azioni diverse.</p>
|
|
<div class="mt-6 flex gap-3">
|
|
<a href="#" class="px-5 py-2 bg-[#6baa75] text-white rounded hover:bg-[#84dd63]">Sfoglia Catalogo</a>
|
|
<?php if (!$isLogged): ?>
|
|
<button id="openLogin2" class="px-5 py-2 bg-[#545454] text-white rounded hover:bg-[#69747c]">Accedi</button>
|
|
<button id="openRegister2" class="px-5 py-2 bg-[#69747c] text-white rounded hover:bg-[#545454]">Registrati</button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow p-6 border border-[#e5e7eb]">
|
|
<h2 class="text-xl font-semibold text-[#545454]">Cosa puoi fare</h2>
|
|
<ul class="mt-3 space-y-2 text-[#69747c] list-disc list-inside">
|
|
<li>Utente: prenotare e gestire le tue prenotazioni</li>
|
|
<li>Bibliotecario: gestire catalogo, prenotazioni e recensioni</li>
|
|
<li>Admin: gestire utenti, ruoli e permessi</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Modal Login -->
|
|
<div id="loginModal" class="fixed inset-0 bg-black/40 hidden items-center justify-center">
|
|
<div class="bg-white w-full max-w-md rounded-lg shadow-lg p-6">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h3 class="text-lg font-semibold text-[#545454]">Accedi</h3>
|
|
<button id="closeLogin" class="text-[#69747c] hover:text-[#545454]">✕</button>
|
|
</div>
|
|
<form id="loginForm" class="space-y-4">
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Username</label>
|
|
<input type="text" name="username" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]" placeholder="username">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Password</label>
|
|
<input type="password" name="password" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]" placeholder="••••••••">
|
|
</div>
|
|
<div id="loginError" class="hidden text-red-600 text-sm"></div>
|
|
<button type="submit" class="w-full bg-[#6baa75] text-white rounded py-2 hover:bg-[#84dd63]">Login</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Registrazione -->
|
|
<div id="registerModal" class="fixed inset-0 bg-black/40 hidden items-center justify-center">
|
|
<div class="bg-white w-full max-w-2xl rounded-lg shadow-lg p-6">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<h3 class="text-lg font-semibold text-[#545454]">Registrazione Utente</h3>
|
|
<button id="closeRegister" class="text-[#69747c] hover:text-[#545454]">✕</button>
|
|
</div>
|
|
<form id="registerForm" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Nome</label>
|
|
<input type="text" name="nome" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Cognome</label>
|
|
<input type="text" name="cognome" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Data di nascita</label>
|
|
<input type="date" name="data_nascita" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Luogo di nascita</label>
|
|
<input type="text" name="luogo_nascita" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Codice Fiscale</label>
|
|
<input type="text" name="cod_fiscale" maxlength="16" required class="mt-1 w-full border rounded px-3 py-2 uppercase focus:outline-none focus:ring-2 focus:ring-[#84dd63]">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Telefono</label>
|
|
<input type="tel" name="telefono" maxlength="10" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]">
|
|
</div>
|
|
<div class="md:col-span-2 mt-2 border-t pt-4">
|
|
<h2 class="text-lg font-semibold text-[#545454]">Credenziali di accesso</h2>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Username</label>
|
|
<input type="text" name="username" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]" placeholder="username">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-[#69747c]">Password</label>
|
|
<input type="password" name="password" required class="mt-1 w-full border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[#84dd63]" placeholder="Almeno 8 caratteri, maiuscola, minuscola, speciale">
|
|
</div>
|
|
<div id="registerError" class="md:col-span-2 hidden text-red-600 text-sm"></div>
|
|
<div id="registerOk" class="md:col-span-2 hidden text-green-700 text-sm"></div>
|
|
<div class="md:col-span-2 mt-2">
|
|
<button type="submit" class="w-full bg-[#6baa75] text-white rounded py-2 hover:bg-[#84dd63]">Registrati</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
$(function() {
|
|
const $modal = $('#loginModal');
|
|
$('#openLogin, #openLogin2').on('click', function() { $modal.removeClass('hidden').addClass('flex'); });
|
|
$('#closeLogin').on('click', function() { $modal.addClass('hidden').removeClass('flex'); $('#loginError').addClass('hidden').text(''); });
|
|
$(document).on('keydown', function(e){ if(e.key === 'Escape'){ $('#closeLogin').click(); } });
|
|
|
|
$('#loginForm').on('submit', function(e) {
|
|
e.preventDefault();
|
|
const formData = $(this).serialize();
|
|
$.ajax({
|
|
url: './php/auth/login.php',
|
|
method: 'POST',
|
|
data: formData,
|
|
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
|
success: function(resp) {
|
|
try { resp = typeof resp === 'string' ? JSON.parse(resp) : resp; } catch (_) {}
|
|
if (resp && resp.status === 'ok') {
|
|
location.reload();
|
|
} else {
|
|
$('#loginError').removeClass('hidden').text(resp && resp.message ? resp.message : 'Accesso non riuscito.');
|
|
}
|
|
},
|
|
error: function() {
|
|
$('#loginError').removeClass('hidden').text('Errore di rete. Riprovare.');
|
|
}
|
|
});
|
|
});
|
|
|
|
const $regModal = $('#registerModal');
|
|
$('#openRegister, #openRegister2').on('click', function(){ $regModal.removeClass('hidden').addClass('flex'); });
|
|
$('#closeRegister').on('click', function(){ $regModal.addClass('hidden').removeClass('flex'); $('#registerError').addClass('hidden').text(''); $('#registerOk').addClass('hidden').text(''); });
|
|
|
|
function clientValidate(pwd){
|
|
if(/\s/.test(pwd)) return 'La password non deve contenere spazi';
|
|
if(pwd.length < 8) return 'La password deve avere almeno 8 caratteri';
|
|
if(!/[a-z]/.test(pwd)) return 'La password deve contenere almeno una minuscola';
|
|
if(!/[A-Z]/.test(pwd)) return 'La password deve contenere almeno una maiuscola';
|
|
if(!/[^a-zA-Z0-9]/.test(pwd)) return 'La password deve contenere almeno un carattere speciale';
|
|
return null;
|
|
}
|
|
|
|
$('#registerForm').on('submit', function(e){
|
|
e.preventDefault();
|
|
const $err = $('#registerError');
|
|
const $ok = $('#registerOk');
|
|
$err.addClass('hidden').text('');
|
|
$ok.addClass('hidden').text('');
|
|
|
|
const pwd = $(this).find('input[name="password"]').val();
|
|
const v = clientValidate(pwd);
|
|
if (v) { $err.removeClass('hidden').text(v); return; }
|
|
|
|
$.ajax({
|
|
url: './php/auth/register.php',
|
|
method: 'POST',
|
|
data: $(this).serialize(),
|
|
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
|
success: function(resp){
|
|
try { resp = typeof resp === 'string' ? JSON.parse(resp) : resp; } catch(_) {}
|
|
if (resp && resp.status === 'ok') {
|
|
$ok.removeClass('hidden').text('Registrazione completata. Reindirizzamento...');
|
|
setTimeout(function(){ window.location.reload(); }, 800);
|
|
} else {
|
|
const msg = resp && resp.errors ? resp.errors.join(' | ') : 'Registrazione non riuscita';
|
|
$err.removeClass('hidden').text(msg);
|
|
}
|
|
},
|
|
error: function(){
|
|
$err.removeClass('hidden').text('Errore di rete. Riprovare.');
|
|
}
|
|
});
|
|
});
|
|
|
|
const isAlessioOnce = <?php echo ($showBlessingOnce ? 'true' : 'false'); ?>;
|
|
if (isAlessioOnce) {
|
|
const $b = $(
|
|
'<div id="alessioBlessing">\
|
|
<div class="halo"></div>\
|
|
<img class="photo" src="./assets/santino.png" alt="Santino" onerror="this.style.display=\'none\'" />\
|
|
<div class="sparkles"></div>\
|
|
</div>'
|
|
);
|
|
$('body').append($b);
|
|
$b.find('.photo').attr('src','./assets/img/santino.png').attr('alt','Santino Alessio');
|
|
const $s = $b.find('.sparkles');
|
|
for (let i = 0; i < 18; i++) {
|
|
const $sp = $('<span/>');
|
|
$sp.css({
|
|
left: (Math.random() * 200) + 'px',
|
|
top: (Math.random() * 200) + 'px',
|
|
animationDelay: (Math.random() * 1.2) + 's'
|
|
});
|
|
$s.append($sp);
|
|
}
|
|
// Avvia animazione, riproduce l'MP3 celestiale e rimuove
|
|
function playHeavenly(){
|
|
try {
|
|
const audio = new Audio('./assets/sound/heavenly.mp3');
|
|
audio.volume = 0.7;
|
|
audio.play().catch(() => {
|
|
const once = function(){
|
|
audio.play().catch(()=>{});
|
|
document.removeEventListener('click', once);
|
|
document.removeEventListener('keydown', once);
|
|
document.removeEventListener('touchstart', once);
|
|
};
|
|
document.addEventListener('click', once, { once: true });
|
|
document.addEventListener('keydown', once, { once: true });
|
|
document.addEventListener('touchstart', once, { once: true });
|
|
});
|
|
} catch(e){}
|
|
}
|
|
setTimeout(function(){ $b.addClass('run'); playHeavenly(); }, 150);
|
|
setTimeout(function(){ $b.remove(); }, 5200);
|
|
}
|
|
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|