shop + cart + user login with school

This commit is contained in:
Claudio 2025-04-13 21:33:59 +02:00
parent 296d7dbb2a
commit 16ff34419e
22 changed files with 1931 additions and 590 deletions

4
.env
View File

@ -1,7 +1,7 @@
APP_ENV=production
APP_DEBUG=false
APP_DEBUG=true
APP_KEY=base64:RWTN8ZDkeItU6xmobXjl6sRn8ph0XoAHgDpX4+wCdlE=
APP_URL=http://vanguard.test
APP_URL=http://localhost/yogiboook
LOG_CHANNEL=stack

View File

@ -16,6 +16,7 @@ use Vanguard\Repositories\Session\SessionRepository;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Services\Auth\ThrottlesLogins;
use Vanguard\User;
use Vanguard\Models\School;
class LoginController extends Controller
{
@ -30,17 +31,30 @@ class LoginController extends Controller
/**
* Show the application login form.
*/
public function show(): View
public function show($school = null): View
{
// Debug: aggiungiamo un log per verificare se arriviamo qui
\Log::info('LoginController::show chiamato con school = ' . ($school ?? 'null'));
// Cerca la scuola in base allo slug
$schoolData = null;
if ($school) {
$schoolData = School::where('slug', $school)->first();
}
return view('auth.login', [
'socialProviders' => config('auth.social.providers'),
'school_slug' => $school,
'school_logo' => $schoolData ? $schoolData->logo : null,
]);
}
public function login(LoginRequest $request, SessionRepository $sessions): Response|RedirectResponse
{
// Debug: aggiungiamo un log per verificare se arriviamo qui
\Log::info('LoginController::login chiamato con input: ' . json_encode($request->all()));
// In case that request throttling is enabled, we have to check if user can perform this request.
// We'll key this by the username and the IP address of the client making these requests into this application.
$throttles = (bool) setting('throttle_enabled');
// Redirect URL that can be passed as hidden field.
@ -50,12 +64,25 @@ class LoginController extends Controller
return $this->sendLockoutResponse($request);
}
// Validazione del campo school
$schoolSlug = $request->input('school');
if ($schoolSlug) {
$school = School::where('slug', $schoolSlug)->first();
if (!$school) {
return redirect()->to('login' . $to)
->withErrors(['school' => trans('auth.school_not_found')]);
}
// Salva lo school_id nella sessione
$request->session()->put('school_id', $school->id);
} else {
// Se il campo school è vuoto, possiamo gestire il caso di default
return redirect()->to('login' . $to)
->withErrors(['school' => trans('auth.school_required')]);
}
$credentials = $request->getCredentials();
if (! Auth::validate($credentials)) {
// If the login attempt was unsuccessful we will increment the number of attempts
// to log in and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles) {
$this->incrementLoginAttempts($request);
}
@ -94,7 +121,7 @@ class LoginController extends Controller
$this->clearLoginAttempts($request);
}
// Redirezione basata sul ruolo con la prima lettera maiuscola e prefisso 'userarea/'
// Redirezione basata sul ruolo
if ($user->hasRole('Admin')) {
return redirect()->to('userarea/admin.php');
} elseif ($user->hasRole('User')) {
@ -105,11 +132,9 @@ class LoginController extends Controller
return redirect()->to('userarea/school_dashboard.php');
}
// Fallback nel caso il ruolo non corrisponda
return redirect()->intended('userarea/default.php');
}
protected function logoutAndRedirectToTokenPage(Request $request, $user, ?string $redirectPage): RedirectResponse
{
Auth::logout();

33
app/Models/School.php Normal file
View File

@ -0,0 +1,33 @@
<?php
namespace Vanguard\Models;
use Illuminate\Database\Eloquent\Model;
class School extends Model
{
protected $table = 'schools';
protected $connection = 'mysql_no_prefix'; // Usa la connessione senza prefisso
protected $fillable = [
'owner_id',
'name',
'website',
'email',
'phone',
'description',
'address_street',
'address_city',
'address_postal_code',
'address_province',
'address_country',
'latitude',
'longitude',
'owner_name',
'vat_number',
'logo',
'status',
'slug'
];
}

View File

@ -68,7 +68,20 @@ return [
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql_no_prefix' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '', // Nessun prefisso per questa connessione
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
],
'mariadb' => [
'driver' => 'mariadb',
'url' => env('DB_URL'),

View File

@ -86,7 +86,7 @@ return [
|
*/
'prefix' => '',
'prefix' => 'auth',
'domain' => null,

View File

@ -0,0 +1,40 @@
<?php
session_start();
// Inizializza il carrello se non esiste
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
// Recupera i dati dal POST
$product_id = $_POST['product_id'] ?? 0;
$variation_id = $_POST['variation_id'] ?? 0;
$class_type_id = $_POST['class_type_id'] ?? 0;
$quantity = $_POST['quantity'] ?? 1;
// Validazione
if ($product_id <= 0 || $variation_id <= 0 || $class_type_id <= 0) {
echo json_encode(['success' => false, 'message' => 'Dati non validi']);
exit;
}
// Chiave univoca per l'elemento nel carrello
$cart_key = $product_id . '-' . $variation_id . '-' . $class_type_id;
// Aggiungi o aggiorna il prodotto nel carrello
if (isset($_SESSION['cart'][$cart_key])) {
$_SESSION['cart'][$cart_key]['quantity'] += $quantity;
} else {
$_SESSION['cart'][$cart_key] = [
'product_id' => $product_id,
'variation_id' => $variation_id,
'class_type_id' => $class_type_id,
'quantity' => $quantity
];
}
// Calcola il numero totale di elementi nel carrello
$cart_count = array_sum(array_column($_SESSION['cart'], 'quantity'));
// Rispondi con successo
echo json_encode(['success' => true, 'cart_count' => $cart_count]);

View File

@ -0,0 +1,358 @@
<?php
// Inizia la sessione e includi i file necessari
session_start();
require_once('include/headscript.php');
// Debug: verifica il contenuto della sessione
\Log::info('Contenuto della sessione:', $_SESSION);
// Ottieni l'istanza del DBHandlerSelect
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Recupera lo school_id e user_id dalla sessione
$school_id = session('school_id');
$user_id = $iduserlogin;
// Debug: verifica il valore di iduserlogin
\Log::info('Valore di iduserlogin: ' . $user_id);
// Controlla se l'utente è loggato
if (empty($user_id)) {
// Reindirizza alla pagina di login se l'utente non è loggato
header('Location: login.php?error=not_logged_in');
exit;
}
$school = null;
$school_name = 'Nessuna scuola selezionata';
$school_logo_path = url('userarea/photoschool/yogibook_logo.png'); // Default logo
if ($school_id) {
$school = \Vanguard\Models\School::find($school_id);
if ($school) {
$school_name = $school->name;
$school_logo_path = $school->logo ? url('userarea/photoschool/' . $school->logo) : $school_logo_path;
}
}
// Inizializza il carrello se non esiste
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
// Recupera i prodotti nel carrello
$cart_items = [];
$total_price = 0;
if (!empty($_SESSION['cart'])) {
foreach ($_SESSION['cart'] as $cart_key => $item) {
$product_id = $item['product_id'];
$variation_id = $item['variation_id'];
$class_type_id = $item['class_type_id'];
$quantity = $item['quantity'];
// Query per ottenere i dettagli del prodotto, variazione e classe
$stmt = $pdo->prepare("
SELECT p.id AS product_id, p.name AS product_name, pv.id AS variation_id, pv.name AS variation_name, pv.price, c.id AS class_id, c.name AS class_name, c.photo AS class_photo,
ct.id AS class_type_id, ct.level, ct.day_of_week
FROM products p
JOIN product_variations pv ON pv.id = ?
LEFT JOIN product_class_types pct ON p.id = pct.product_id AND pct.variation_id IS NULL
LEFT JOIN class_types ct ON ct.id = ?
LEFT JOIN classes c ON ct.class_id = c.id
WHERE p.id = ?
");
$stmt->execute([$variation_id, $class_type_id, $product_id]);
$cart_item = $stmt->fetch(PDO::FETCH_ASSOC);
if ($cart_item) {
$cart_items[$cart_key] = [
'product_id' => $cart_item['product_id'],
'product_name' => $cart_item['product_name'],
'variation_id' => $cart_item['variation_id'],
'variation_name' => $cart_item['variation_name'],
'class_id' => $cart_item['class_id'],
'class_name' => $cart_item['class_name'],
'class_type_id' => $cart_item['class_type_id'],
'level' => $cart_item['level'],
'day_of_week' => $cart_item['day_of_week'],
'photo' => $cart_item['class_photo'] ?: 'default_class_image.jpg',
'price' => $cart_item['price'],
'quantity' => $quantity,
'subtotal' => $cart_item['price'] * $quantity
];
$total_price += $cart_item['price'] * $quantity;
}
}
}
// Calcola il numero totale di elementi nel carrello
$cart_count = array_sum(array_column($_SESSION['cart'], 'quantity'));
// Gestione della conferma dell'acquisto
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['confirm_purchase'])) {
// Assicurati che non ci siano output prima di questo punto
ob_start(); // Avvia il buffer per catturare eventuali output indesiderati
if (empty($cart_items)) {
$response = ['success' => false, 'message' => 'Il carrello è vuoto.'];
} else {
try {
// Verifica che user_id non sia NULL (dovrebbe essere già garantito dal controllo sopra)
if (empty($user_id)) {
throw new Exception("L'ID utente non è definito nella sessione.");
}
// Genera un order_number unico
$stmt = $pdo->query("SELECT MAX(order_number) AS max_order FROM orders");
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$order_number = ($result['max_order'] ?? 0) + 1;
// Inserisci ogni elemento del carrello come un ordine
foreach ($cart_items as $item) {
$total_entries = null; // Da calcolare in base alla variazione
if (preg_match('/(\d+) Ticket/i', $item['variation_name'], $matches)) {
$total_entries = (int)$matches[1];
}
$available_entries = $total_entries;
$available_recoveries = 0; // Da definire
$expiration_date = null; // Da definire
$activation_date = date('Y-m-d'); // Oggi
$stmt = $pdo->prepare("
INSERT INTO orders (
order_number, school_id, user_id, product_id, variation_id, class_id, class_type_id,
created_at, payment_method, price, status, total_entries, available_entries,
available_recoveries, expiration_date, activation_date
) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), 'direct', ?, 'completed', ?, ?, ?, ?, ?)
");
$stmt->execute([
$order_number,
$school_id,
$user_id,
$item['product_id'],
$item['variation_id'],
$item['class_id'],
$item['class_type_id'],
$item['subtotal'],
$total_entries,
$available_entries,
$available_recoveries,
$expiration_date,
$activation_date
]);
}
// Svuota il carrello
$_SESSION['cart'] = [];
// Reindirizza alla pagina di ringraziamento con l'order_number
$response = ['success' => true, 'redirect' => 'thank_you.php?order_number=' . $order_number];
} catch (Exception $e) {
$response = ['success' => false, 'message' => 'Errore durante l\'acquisto: ' . $e->getMessage()];
}
}
// Pulisci il buffer e invia la risposta JSON
ob_end_clean();
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
.page-content {
background-color: #f0f4f5;
}
.card-pastel {
background-color: rgb(149, 217, 248);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
border: none;
}
.cart-item-card {
background-color: #fff;
border: 1px solid #c8e6c9;
border-radius: 8px;
margin-bottom: 15px;
padding: 15px;
}
.cart-item-image {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 50%;
}
.btn-pastel {
background-color: rgb(148, 186, 204);
border: none;
transition: background-color 0.3s ease;
}
.btn-pastel:hover {
background-color: rgb(155, 189, 221);
}
h5,
h6 {
font-family: 'Poppins', sans-serif;
color: #333;
}
.cart-item-details p {
margin: 0;
font-size: 0.9rem;
color: #555;
}
.cart-item-details .price {
font-weight: bold;
color: #28a745;
}
.total-section {
background-color: rgb(148, 186, 204);
color: #fff;
padding: 10px;
border-radius: 8px;
}
.swal2-pastel {
background-color: #f0f4f5;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
.swal2-title {
font-family: 'Poppins', sans-serif;
color: #333;
}
.swal2-content {
font-family: 'Poppins', sans-serif;
color: #333;
}
</style>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card card-pastel radius-10 mb-4">
<div class="card-body text-center">
<?php if ($school): ?>
<h5 class="mb-3">Checkout - Scuola: <?php echo htmlspecialchars($school_name); ?></h5>
<img src="<?php echo $school_logo_path; ?>" alt="School Logo" style="max-height: 100px;">
<?php else: ?>
<h5 class="mb-3">Nessuna scuola selezionata</h5>
<img src="<?php echo $school_logo_path; ?>" alt="Default Logo" style="max-height: 100px;">
<?php endif; ?>
</div>
</div>
<div class="card card-pastel radius-10">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0">Riepilogo Carrello</h6>
</div>
</div>
</div>
<div class="card-body">
<?php if (empty($cart_items)): ?>
<p class="text-center text-muted">Il carrello è vuoto.</p>
<?php else: ?>
<div class="cart-items-list">
<?php foreach ($cart_items as $item): ?>
<div class="cart-item-card d-flex align-items-center">
<img src="<?php echo htmlspecialchars($item['photo']); ?>" class="cart-item-image me-3" alt="product image">
<div class="cart-item-details flex-grow-1">
<h6 class="mb-1"><?php echo htmlspecialchars($item['product_name']); ?></h6>
<p><strong>Variazione:</strong> <?php echo htmlspecialchars($item['variation_name']); ?></p>
<p><strong>Classe:</strong> <?php echo htmlspecialchars($item['class_name'] . ' - ' . $item['level'] . ' (' . $item['day_of_week'] . ')'); ?></p>
<p><strong>Quantità:</strong> <?php echo $item['quantity']; ?></p>
<p><strong>Prezzo Unitario:</strong> <?php echo number_format($item['price'], 2); ?></p>
<p class="price"><strong>Subtotale:</strong> <?php echo number_format($item['subtotal'], 2); ?></p>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="total-section mt-3 d-flex justify-content-between align-items-center">
<h5 class="mb-0">Totale</h5>
<h5 class="mb-0"><?php echo number_format($total_price, 2); ?></h5>
</div>
<div class="text-center mt-4">
<button id="confirm_purchase" class="btn btn-pastel">Conferma Acquisto</button>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<div class="overlay toggle-icon"></div>
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$('#confirm_purchase').on('click', function() {
$.ajax({
url: 'checkout.php',
method: 'POST',
data: {
confirm_purchase: true
},
dataType: 'json', // Specifica che ci aspettiamo JSON
success: function(response) {
// Non c'è bisogno di JSON.parse(), response è già un oggetto
console.log('Risposta AJAX:', response); // Debug
if (response.success) {
// Reindirizza alla pagina di ringraziamento
window.location.href = response.redirect;
} else {
Swal.fire({
icon: 'error',
title: 'Errore',
text: response.message,
confirmButtonText: 'OK',
confirmButtonColor: '#94bacc',
customClass: {
popup: 'swal2-pastel',
title: 'swal2-title',
content: 'swal2-content'
}
});
}
},
error: function(xhr, status, error) {
console.log('Errore AJAX:', xhr.responseText); // Debug
Swal.fire({
icon: 'error',
title: 'Errore',
text: 'Errore di connessione: ' + xhr.responseText,
confirmButtonColor: '#94bacc'
});
}
});
});
});
</script>
</body>
</html>

View File

@ -1,3 +1,3 @@
<footer class="page-footer">
<p class="mb-0">C.E. Soft srl © 2025. All right reserved.</p>
<p class="mb-0">YogiBook © 2025. All right reserved.</p>
</footer>

View File

@ -0,0 +1,13 @@
<?php
session_start();
// Recupera la chiave dell'elemento da rimuovere
$cart_key = $_POST['cart_key'] ?? '';
if ($cart_key && isset($_SESSION['cart'][$cart_key])) {
// Rimuovi l'elemento dal carrello
unset($_SESSION['cart'][$cart_key]);
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'message' => 'Elemento non trovato']);
}

View File

@ -1,275 +1,241 @@
<?php
// Ottieni l'istanza del DBHandlerSelect
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Inizializza il carrello se non esiste
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
// Recupera i prodotti nel carrello
$cart_items = [];
$total_price = 0;
if (!empty($_SESSION['cart'])) {
foreach ($_SESSION['cart'] as $cart_key => $item) {
$product_id = $item['product_id'];
$variation_id = $item['variation_id'];
$class_type_id = $item['class_type_id'];
$quantity = $item['quantity'];
// Query per ottenere i dettagli del prodotto, variazione e classe
$stmt = $pdo->prepare("
SELECT p.name AS product_name, pv.name AS variation_name, pv.price, c.name AS class_name, c.photo AS class_photo,
ct.level, ct.day_of_week
FROM products p
JOIN product_variations pv ON pv.id = ?
LEFT JOIN product_class_types pct ON p.id = pct.product_id AND pct.variation_id IS NULL
LEFT JOIN class_types ct ON ct.id = ?
LEFT JOIN classes c ON ct.class_id = c.id
WHERE p.id = ?
");
$stmt->execute([$variation_id, $class_type_id, $product_id]);
$cart_item = $stmt->fetch(PDO::FETCH_ASSOC);
if ($cart_item) {
$cart_items[$cart_key] = [
'product_name' => $cart_item['product_name'],
'variation_name' => $cart_item['variation_name'],
'class_name' => $cart_item['class_name'],
'level' => $cart_item['level'],
'day_of_week' => $cart_item['day_of_week'],
'photo' => $cart_item['class_photo'] ?: 'default_class_image.jpg',
'price' => $cart_item['price'],
'quantity' => $quantity,
'subtotal' => $cart_item['price'] * $quantity
];
$total_price += $cart_item['price'] * $quantity;
}
}
}
// Calcola il numero totale di elementi nel carrello
$cart_count = array_sum(array_column($_SESSION['cart'], 'quantity'));
?>
<header>
<div class="topbar d-flex align-items-center">
<nav class="navbar navbar-expand gap-3">
<div class="mobile-toggle-menu"><i class='bx bx-menu'></i>
</div>
<div class="mobile-toggle-menu"><i class='bx bx-menu'></i></div>
<div class="search-bar d-lg-block d-none" data-bs-toggle="modal" data-bs-target="#SearchModal">
<a href="avascript:;" class="btn d-flex align-items-center"><i class='bx bx-search'></i>Search</a>
<a href="javascript:;" class="btn d-flex align-items-center"><i class='bx bx-search'></i>Search</a>
</div>
<div class="top-menu ms-auto">
<ul class="navbar-nav align-items-center gap-1">
<li class="nav-item mobile-search-icon d-flex d-lg-none" data-bs-toggle="modal" data-bs-target="#SearchModal">
<a class="nav-link" href="avascript:;"><i class='bx bx-search'></i>
</a>
<a class="nav-link" href="javascript:;"><i class='bx bx-search'></i></a>
</li>
<li class="nav-item dropdown dropdown-laungauge d-none d-sm-flex">
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret" href="avascript:;" data-bs-toggle="dropdown"><img src="assets/images/county/02.png" width="22" alt="">
</a>
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret" href="javascript:;" data-bs-toggle="dropdown"><img src="assets/images/county/02.png" width="22" alt=""></a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/01.png" width="20" alt=""><span class="ms-2">English</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/02.png" width="20" alt=""><span class="ms-2">Catalan</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/03.png" width="20" alt=""><span class="ms-2">French</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/04.png" width="20" alt=""><span class="ms-2">Belize</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/05.png" width="20" alt=""><span class="ms-2">Colombia</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/06.png" width="20" alt=""><span class="ms-2">Spanish</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/07.png" width="20" alt=""><span class="ms-2">Georgian</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/08.png" width="20" alt=""><span class="ms-2">Hindi</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/01.png" width="20" alt=""><span class="ms-2">English</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/02.png" width="20" alt=""><span class="ms-2">Catalan</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/03.png" width="20" alt=""><span class="ms-2">French</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/04.png" width="20" alt=""><span class="ms-2">Belize</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/05.png" width="20" alt=""><span class="ms-2">Colombia</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/06.png" width="20" alt=""><span class="ms-2">Spanish</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/07.png" width="20" alt=""><span class="ms-2">Georgian</span></a></li>
<li><a class="dropdown-item d-flex align-items-center py-2" href="javascript:;"><img src="assets/images/county/08.png" width="20" alt=""><span class="ms-2">Hindi</span></a></li>
</ul>
</li>
<li class="nav-item dark-mode d-none d-sm-flex">
<a class="nav-link dark-mode-icon" href="javascript:;"><i class='bx bx-moon'></i>
</a>
<a class="nav-link dark-mode-icon" href="javascript:;"><i class='bx bx-moon'></i></a>
</li>
<li class="nav-item dropdown dropdown-app">
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret" data-bs-toggle="dropdown" href="javascript:;"><i class='bx bx-grid-alt'></i></a>
<div class="dropdown-menu dropdown-menu-end p-0">
<div class="app-container p-2 my-2">
<div class="row gx-0 gy-2 row-cols-3 justify-content-center p-2">
<div class="col">
<a href="javascript:;">
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/slack.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/slack.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Slack</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/behance.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/behance.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Behance</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/google-drive.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/google-drive.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Dribble</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/outlook.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/outlook.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Outlook</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/github.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/github.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">GitHub</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/stack-overflow.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/stack-overflow.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Stack</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/figma.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/figma.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Stack</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/twitter.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/twitter.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Twitter</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/google-calendar.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/google-calendar.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Calendar</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/spotify.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/spotify.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Spotify</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/google-photos.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/google-photos.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Photos</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/pinterest.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/pinterest.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Photos</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/linkedin.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/linkedin.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">linkedin</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/dribble.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/dribble.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Dribble</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/youtube.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/youtube.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">YouTube</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/google.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/google.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">News</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/envato.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/envato.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Envato</p>
</div>
</div>
</a>
</div>
<div class="col">
<a href="javascript:;">
</a></div>
<div class="col"><a href="javascript:;">
<div class="app-box text-center">
<div class="app-icon">
<img src="assets/images/app/safari.png" width="30" alt="">
</div>
<div class="app-icon"><img src="assets/images/app/safari.png" width="30" alt=""></div>
<div class="app-name">
<p class="mb-0 mt-1">Safari</p>
</div>
</div>
</a>
</a></div>
</div>
</div><!--end row-->
</div>
</div>
</li>
<li class="nav-item dropdown dropdown-large">
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret position-relative" href="#" data-bs-toggle="dropdown"><span class="alert-count">7</span>
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret position-relative" href="#" data-bs-toggle="dropdown"><span class="alert-count cart-count"><?php echo $cart_count; ?></span>
<i class='bx bx-bell'></i>
</a>
<div class="dropdown-menu dropdown-menu-end">
@ -286,105 +252,12 @@
<img src="assets/images/avatars/avatar-1.png" class="msg-avatar" alt="user avatar">
</div>
<div class="flex-grow-1">
<h6 class="msg-name">Daisy Anderson<span class="msg-time float-end">5 sec
ago</span></h6>
<h6 class="msg-name">Daisy Anderson<span class="msg-time float-end">5 sec ago</span></h6>
<p class="msg-info">The standard chunk of lorem</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="notify bg-light-danger text-danger">dc
</div>
<div class="flex-grow-1">
<h6 class="msg-name">New Orders <span class="msg-time float-end">2 min
ago</span></h6>
<p class="msg-info">You have recived new orders</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="user-online">
<img src="assets/images/avatars/avatar-2.png" class="msg-avatar" alt="user avatar">
</div>
<div class="flex-grow-1">
<h6 class="msg-name">Althea Cabardo <span class="msg-time float-end">14
sec ago</span></h6>
<p class="msg-info">Many desktop publishing packages</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="notify bg-light-success text-success">
<img src="assets/images/app/outlook.png" width="25" alt="user avatar">
</div>
<div class="flex-grow-1">
<h6 class="msg-name">Account Created<span class="msg-time float-end">28 min
ago</span></h6>
<p class="msg-info">Successfully created new email</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="notify bg-light-info text-info">Ss
</div>
<div class="flex-grow-1">
<h6 class="msg-name">New Product Approved <span
class="msg-time float-end">2 hrs ago</span></h6>
<p class="msg-info">Your new product has approved</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="user-online">
<img src="assets/images/avatars/avatar-4.png" class="msg-avatar" alt="user avatar">
</div>
<div class="flex-grow-1">
<h6 class="msg-name">Katherine Pechon <span class="msg-time float-end">15
min ago</span></h6>
<p class="msg-info">Making this the first true generator</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="notify bg-light-success text-success"><i class='bx bx-check-square'></i>
</div>
<div class="flex-grow-1">
<h6 class="msg-name">Your item is shipped <span class="msg-time float-end">5 hrs
ago</span></h6>
<p class="msg-info">Successfully shipped your item</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="notify bg-light-primary">
<img src="assets/images/app/github.png" width="25" alt="user avatar">
</div>
<div class="flex-grow-1">
<h6 class="msg-name">New 24 authors<span class="msg-time float-end">1 day
ago</span></h6>
<p class="msg-info">24 new authors joined last week</p>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center">
<div class="user-online">
<img src="assets/images/avatars/avatar-8.png" class="msg-avatar" alt="user avatar">
</div>
<div class="flex-grow-1">
<h6 class="msg-name">Peter Costanzo <span class="msg-time float-end">6 hrs
ago</span></h6>
<p class="msg-info">It was popularised in the 1960s</p>
</div>
</div>
</a>
<!-- Altre notifiche... -->
</div>
<a href="javascript:;">
<div class="text-center msg-footer">
@ -394,187 +267,53 @@
</div>
</li>
<li class="nav-item dropdown dropdown-large">
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret position-relative" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> <span class="alert-count">8</span>
<a class="nav-link dropdown-toggle dropdown-toggle-nocaret position-relative" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<span class="alert-count cart-count"><?php echo $cart_count; ?></span>
<i class='bx bx-shopping-bag'></i>
</a>
<div class="dropdown-menu dropdown-menu-end">
<a href="javascript:;">
<div class="msg-header">
<p class="msg-header-title">My Cart</p>
<p class="msg-header-badge">10 Items</p>
<p class="msg-header-badge"><?php echo $cart_count; ?> Items</p>
</div>
</a>
<div class="header-message-list">
<?php if (empty($cart_items)): ?>
<p class="text-center text-muted p-3">Il carrello è vuoto.</p>
<?php else: ?>
<?php foreach ($cart_items as $cart_key => $item): ?>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/11.png" class="" alt="product image">
<img src="<?php echo htmlspecialchars($item['photo']); ?>" class="rounded-circle" width="50" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
<h6 class="cart-product-title mb-0"><?php echo htmlspecialchars($item['product_name']); ?></h6>
<p class="cart-product-price mb-0"><?php echo htmlspecialchars($item['variation_name']); ?></p>
<p class="cart-product-price mb-0"><?php echo htmlspecialchars($item['class_name'] . ' - ' . $item['level'] . ' (' . $item['day_of_week'] . ')'); ?></p>
<p class="cart-product-price mb-0"><?php echo $item['quantity']; ?> x €<?php echo number_format($item['price'], 2); ?></p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
<p class="cart-price mb-0"><?php echo number_format($item['subtotal'], 2); ?></p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/02.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/03.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/04.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/05.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/06.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/07.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/08.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
</div>
</div>
</a>
<a class="dropdown-item" href="javascript:;">
<div class="d-flex align-items-center gap-3">
<div class="position-relative">
<div class="cart-product rounded-circle bg-light">
<img src="assets/images/products/09.png" class="" alt="product image">
</div>
</div>
<div class="flex-grow-1">
<h6 class="cart-product-title mb-0">Men White T-Shirt</h6>
<p class="cart-product-price mb-0">1 X $29.00</p>
</div>
<div class="">
<p class="cart-price mb-0">$250</p>
</div>
<div class="cart-product-cancel"><i class="bx bx-x"></i>
<div class="cart-product-cancel">
<a href="javascript:;" class="remove-cart-item" data-key="<?php echo $cart_key; ?>"><i class="bx bx-x"></i></a>
</div>
</div>
</a>
<?php endforeach; ?>
<?php endif; ?>
</div>
<a href="javascript:;">
<div class="text-center msg-footer">
<div class="d-flex align-items-center justify-content-between mb-3">
<h5 class="mb-0">Total</h5>
<h5 class="mb-0 ms-auto">$489.00</h5>
<h5 class="mb-0 ms-auto"><?php echo number_format($total_price, 2); ?></h5>
</div>
<button class="btn btn-primary w-100">Checkout</button>
<a href="checkout.php" class="btn btn-primary w-100">Checkout</a>
</div>
</a>
</div>
@ -604,3 +343,32 @@
</nav>
</div>
</header>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// Rimuovi un elemento dal carrello
$('.remove-cart-item').on('click', function(e) {
e.preventDefault();
const cartKey = $(this).data('key');
$.ajax({
url: 'remove_from_cart.php',
method: 'POST',
data: {
cart_key: cartKey
},
success: function(response) {
const result = JSON.parse(response);
if (result.success) {
location.reload(); // Ricarica la pagina per aggiornare il carrello
} else {
alert('Errore durante la rimozione del prodotto dal carrello.');
}
},
error: function() {
alert('Errore di connessione.');
}
});
});
});
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -1,12 +1,26 @@
<?php include('include/headscript.php'); ?>
<?php
include('include/headscript.php');
// Ottieni l'istanza del DBHandlerSelect
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Recupera lo school_id dalla sessione
$school_id = session('school_id');
$school = null;
$school_name = 'Nessuna scuola selezionata';
$school_logo_path = url('userarea/photoschool/yogibook_logo.png'); // Default logo
if ($school_id) {
$school = \Vanguard\Models\School::find($school_id);
if ($school) {
$school_name = $school->name;
$school_logo_path = $school->logo ? url('userarea/photoschool/' . $school->logo) : $school_logo_path;
}
}
$product_id = $_GET['product_id'] ?? 0;
// Recupera i dettagli del prodotto
// Recupera i dettagli del prodotto, verificando che appartenga alla scuola selezionata
$stmt = $pdo->prepare("
SELECT p.id, p.name AS product_name,
c.name AS class_name, c.description AS class_description, c.photo AS class_photo
@ -14,14 +28,14 @@ $stmt = $pdo->prepare("
LEFT JOIN product_class_types pct ON p.id = pct.product_id AND pct.variation_id IS NULL
LEFT JOIN class_types ct ON pct.class_type_id = ct.id
LEFT JOIN classes c ON ct.class_id = c.id
WHERE p.id = ?
WHERE p.id = ? AND p.school_id = ?
GROUP BY p.id
");
$stmt->execute([$product_id]);
$stmt->execute([$product_id, $school_id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
die("Prodotto non trovato.");
die("Prodotto non trovato o non appartiene alla scuola selezionata.");
}
// Recupera le variazioni del prodotto
@ -43,16 +57,29 @@ $stmt = $pdo->prepare("
$stmt->execute([$product_id]);
$class_types = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="it">
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dettaglio Prodotto - <?php echo htmlspecialchars($product['product_name']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--favicon-->
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
.page-content {
background-color: #f0f4f5;
}
.card-pastel {
background-color: rgb(149, 217, 248);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
border: none;
}
.product-image {
width: 100%;
height: 300px;
@ -60,25 +87,88 @@ $class_types = $stmt->fetchAll(PDO::FETCH_ASSOC);
border-radius: 8px;
}
.btn-pastel {
background-color: rgb(148, 186, 204);
border: none;
transition: background-color 0.3s ease;
}
.btn-pastel:hover {
background-color: rgb(155, 189, 221);
}
h5,
h6 {
font-family: 'Poppins', sans-serif;
color: #333;
}
.price-display {
font-size: 1.5rem;
color: #28a745;
margin-top: 10px;
}
.form-label {
font-family: 'Poppins', sans-serif;
color: #333;
}
.form-select {
border: 1px solid #c8e6c9;
}
.swal2-pastel {
background-color: #f0f4f5;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
.swal2-title {
font-family: 'Poppins', sans-serif;
color: #333;
}
.swal2-content {
font-family: 'Poppins', sans-serif;
color: #333;
}
</style>
</head>
<body>
<div class="container mt-5">
<h1 class="mb-4"><?php echo htmlspecialchars($product['product_name']); ?></h1>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card card-pastel radius-10 mb-4">
<div class="card-body text-center">
<?php if ($school): ?>
<h5 class="mb-3">Dettagli Prodotto - Scuola: <?php echo htmlspecialchars($school_name); ?></h5>
<img src="<?php echo $school_logo_path; ?>" alt="School Logo" style="max-height: 100px;">
<?php else: ?>
<h5 class="mb-3">Nessuna scuola selezionata</h5>
<img src="<?php echo $school_logo_path; ?>" alt="Default Logo" style="max-height: 100px;">
<?php endif; ?>
</div>
</div>
<div class="card card-pastel radius-10">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0"><?php echo htmlspecialchars($product['product_name']); ?></h6>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="col-md-6 mb-3">
<img src="<?php echo htmlspecialchars($product['class_photo'] ?: 'default_class_image.jpg'); ?>" alt="<?php echo htmlspecialchars($product['class_name']); ?>" class="product-image">
</div>
<div class="col-md-6">
<h3><?php echo htmlspecialchars($product['class_name']); ?></h3>
<h5><?php echo htmlspecialchars($product['class_name']); ?></h5>
<p><?php echo htmlspecialchars($product['class_description']); ?></p>
<div class="mb-3">
<label for="variation_select" class="form-label">Seleziona Variazione Prodotto:</label>
<select id="variation_select" class="form-select">
@ -90,7 +180,6 @@ $class_types = $stmt->fetchAll(PDO::FETCH_ASSOC);
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="class_type_select" class="form-label">Seleziona Variazione Classe:</label>
<select id="class_type_select" class="form-select">
@ -102,16 +191,20 @@ $class_types = $stmt->fetchAll(PDO::FETCH_ASSOC);
<?php endforeach; ?>
</select>
</div>
<div class="price-display" id="price_display">Prezzo: -- </div>
<button id="add_to_cart" class="btn btn-success mt-3" disabled>Aggiungi al Carrello</button>
<button id="add_to_cart" class="btn btn-pastel mt-3" disabled>Aggiungi al Carrello</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="overlay toggle-icon"></div>
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
$(document).ready(function() {
const variationSelect = $('#variation_select');
@ -139,9 +232,64 @@ $class_types = $stmt->fetchAll(PDO::FETCH_ASSOC);
addToCartButton.on('click', function() {
const variationId = variationSelect.val();
const classTypeId = classTypeSelect.val();
alert(`Prodotto aggiunto al carrello!\nVariazione: ${variationSelect.find('option:selected').text()}\nClasse: ${classTypeSelect.find('option:selected').text()}`);
// Qui puoi aggiungere una chiamata AJAX per aggiungere al carrello
const variationText = variationSelect.find('option:selected').text();
const classText = classTypeSelect.find('option:selected').text();
// Chiamata AJAX per aggiungere al carrello
$.ajax({
url: 'add_to_cart.php',
method: 'POST',
data: {
product_id: <?php echo $product_id; ?>,
variation_id: variationId,
class_type_id: classTypeId,
quantity: 1
},
success: function(response) {
const result = JSON.parse(response);
if (result.success) {
Swal.fire({
icon: 'success',
title: 'Prodotto Aggiunto!',
html: `
<p><strong>Variazione:</strong> ${variationText}</p>
<p><strong>Classe:</strong> ${classText}</p>
`,
confirmButtonText: 'OK',
confirmButtonColor: '#94bacc',
customClass: {
popup: 'swal2-pastel',
title: 'swal2-title',
content: 'swal2-content'
}
}).then(() => {
// Ricarica il conteggio del carrello nella topbar
updateCartCount(result.cart_count);
});
} else {
Swal.fire({
icon: 'error',
title: 'Errore',
text: 'Impossibile aggiungere il prodotto al carrello.',
confirmButtonColor: '#94bacc'
});
}
},
error: function() {
Swal.fire({
icon: 'error',
title: 'Errore',
text: 'Errore di connessione.',
confirmButtonColor: '#94bacc'
});
}
});
});
// Funzione per aggiornare il conteggio del carrello nella topbar
function updateCartCount(count) {
$('.alert-count.cart-count').text(count);
}
});
</script>
</body>

View File

@ -53,12 +53,23 @@ if ($is_new) {
'status' => 'active',
'created_at' => '',
'updated_at' => '',
'slug' => '',
'first_name' => $school['first_name'],
'last_name' => $school['last_name'],
'email' => $school['email']
];
}
// Funzione per generare uno slug valido
function generateSlug($string)
{
$slug = strtolower($string); // Converti in minuscolo
$slug = preg_replace('/[^a-z0-9-]+/', '-', $slug); // Sostituisci caratteri non validi con trattini
$slug = preg_replace('/-+/', '-', $slug); // Rimuovi trattini multipli
$slug = trim($slug, '-'); // Rimuovi trattini all'inizio e alla fine
return $slug;
}
// Gestione del form
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
@ -76,6 +87,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$owner_name = $_POST['owner_name'] ?? '';
$vat_number = $_POST['vat_number'] ?? '';
$status = in_array($_POST['status'], ['active', 'inactive', 'suspended']) ? $_POST['status'] : 'active';
$slug = isset($_POST['slug']) ? generateSlug($_POST['slug']) : '';
// Validazione dello slug
if (empty($slug)) {
$error = "Errore: Lo slug non può essere vuoto.";
} else {
// Controlla se lo slug è univoco
$stmt = $pdo->prepare("SELECT COUNT(*) FROM schools WHERE slug = ? AND id != ?");
$stmt->execute([$slug, $school['id'] ?? 0]);
$slug_exists = $stmt->fetchColumn();
if ($slug_exists) {
$error = "Errore: Lo slug '$slug' è già in uso. Scegli un altro slug.";
}
}
// Gestione del caricamento del logo
$logo = $school['logo'];
@ -101,14 +127,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
// Se non ci sono errori, procedi con il salvataggio
if (!isset($error)) {
// Aggiorna auth_users (opzionale, se vuoi aggiornare first_name e last_name)
$stmt = $pdo->prepare("UPDATE auth_users SET first_name = ?, last_name = ? WHERE id = ?");
$stmt->execute([$school['first_name'], $school['last_name'], $iduserlogin]);
if ($is_new) {
$stmt = $pdo->prepare("
INSERT INTO schools (owner_id, name, website, email, phone, description, address_street, address_city, address_postal_code, address_province, address_country, latitude, longitude, owner_name, vat_number, logo, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
INSERT INTO schools (owner_id, name, website, email, phone, description, address_street, address_city, address_postal_code, address_province, address_country, latitude, longitude, owner_name, vat_number, logo, status, slug)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$success = $stmt->execute([
$iduserlogin,
@ -127,7 +155,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$owner_name,
$vat_number,
$logo,
$status
$status,
$slug
]);
if ($success) {
@ -149,7 +178,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
UPDATE schools
SET name = ?, website = ?, email = ?, phone = ?, description = ?, address_street = ?, address_city = ?,
address_postal_code = ?, address_province = ?, address_country = ?, latitude = ?, longitude = ?,
owner_name = ?, vat_number = ?, logo = ?, status = ?
owner_name = ?, vat_number = ?, logo = ?, status = ?, slug = ?
WHERE owner_id = ?
");
$success = $stmt->execute([
@ -169,6 +198,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$vat_number,
$logo,
$status,
$slug,
$iduserlogin
]);
@ -187,6 +217,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
}
}
?>
<!doctype html>
@ -238,6 +269,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<label for="name" class="form-label">Nome Scuola</label>
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($school['name'] ?? ''); ?>" required>
</div>
<div class="mb-3">
<label for="slug" class="form-label">Slug (URL personalizzato, es. yogiboook.com/slug)</label>
<input type="text" class="form-control" id="slug" name="slug" value="<?php echo htmlspecialchars($school['slug'] ?? ''); ?>" required>
<small class="form-text text-muted">Usa solo lettere minuscole, numeri e trattini (es. yoga-milano).</small>
</div>
<div class="mb-3">
<label for="website" class="form-label">Sito Web</label>
<input type="url" class="form-control" id="website" name="website" value="<?php echo htmlspecialchars($school['website'] ?? ''); ?>">
@ -327,6 +363,45 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
<!-- Script per validazione e suggerimento dello slug -->
<script>
// Funzione per generare uno slug valido
function generateSlug(string) {
return string
.toLowerCase() // Converti in minuscolo
.replace(/[^a-z0-9-]+/g, '-') // Sostituisci caratteri non validi con trattini
.replace(/-+/g, '-') // Rimuovi trattini multipli
.replace(/^-|-$/g, ''); // Rimuovi trattini all'inizio e alla fine
}
// Riferimenti ai campi
const nameInput = document.getElementById('name');
const slugInput = document.getElementById('slug');
let isUserTypingSlug = false; // Flag per tracciare se l'utente sta modificando lo slug manualmente
// Suggerimento dello slug basato sul nome
nameInput.addEventListener('input', function(e) {
if (!isUserTypingSlug) { // Aggiorna lo slug solo se l'utente non lo sta modificando manualmente
const name = e.target.value;
const generatedSlug = generateSlug(name);
slugInput.value = generatedSlug;
}
});
// Validazione dello slug in tempo reale
slugInput.addEventListener('input', function(e) {
isUserTypingSlug = true; // L'utente sta modificando lo slug manualmente
let value = e.target.value;
value = generateSlug(value); // Applica le regole di validazione
e.target.value = value; // Aggiorna il campo con il valore validato
});
// Ripristina il flag quando l'utente smette di modificare lo slug
slugInput.addEventListener('blur', function() {
isUserTypingSlug = false; // L'utente ha finito di modificare lo slug
});
</script>
</body>
</html>

View File

@ -0,0 +1,200 @@
<?php include('include/headscript.php'); ?>
<?php
// Ottieni l'istanza del DBHandlerSelect
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Recupera lo school_id dalla sessione
$school_id = session('school_id');
$school = null;
$school_name = 'Nessuna scuola selezionata';
$school_logo_path = url('userarea/photoschool/yogibook_logo.png'); // Default logo
if ($school_id) {
// Usa il modello School per recuperare i dati della scuola
$school = \Vanguard\Models\School::find($school_id);
if ($school) {
$school_name = $school->name;
$school_logo_path = $school->logo ? url('userarea/' . $school->logo) : $school_logo_path;
}
}
// Recupera i prodotti con le variazioni e le classi associate, filtrati per scuola
$products = [];
if ($school_id) {
$stmt = $pdo->prepare("
SELECT p.id, p.name AS product_name,
MIN(pv.price) AS min_price,
MAX(pv.price) AS max_price,
c.name AS class_name,
c.photo AS class_photo
FROM products p
LEFT JOIN product_variations pv ON p.id = pv.product_id
LEFT JOIN product_class_types pct ON p.id = pct.product_id AND pct.variation_id IS NULL
LEFT JOIN class_types ct ON pct.class_type_id = ct.id
LEFT JOIN classes c ON ct.class_id = c.id
WHERE p.school_id = ? AND p.status = 'active'
GROUP BY p.id
");
$stmt->execute([$school_id]);
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
?>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--favicon-->
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<style>
.page-content {
background-color: #f0f4f5;
/* Sfondo pastello chiaro (grigio-azzurro) */
}
.card-pastel {
background-color: rgb(149, 217, 248);
/* Celeste pastello */
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
/* Ombra leggera */
border: none;
}
.product-card {
background-color: #ffffff;
border-left: 4px solid #c8e6c9;
/* Verde pastello per il bordo */
transition: transform 0.2s ease;
}
.product-card:hover {
transform: translateY(-3px);
}
.product-card img {
width: 100%;
height: 200px;
object-fit: cover;
}
.btn-pastel {
background-color: rgb(148, 186, 204);
/* Celeste pastello */
border: none;
transition: background-color 0.3s ease;
}
.btn-pastel:hover {
background-color: rgb(155, 189, 221);
/* Celeste più scuro */
}
h5,
h6 {
font-family: 'Poppins', sans-serif;
color: #333;
}
.price-range {
font-size: 1.1rem;
color: #28a745;
margin-bottom: 10px;
}
</style>
</head>
<body>
<!--wrapper-->
<div class="wrapper">
<!--sidebar wrapper -->
<?php include('include/navbar.php'); ?>
<!--end sidebar wrapper -->
<!--start header -->
<?php include('include/topbar.php'); ?>
<!--end header -->
<!--start page wrapper -->
<div class="page-wrapper">
<div class="page-content">
<!-- Sezione Scuola -->
<div class="card card-pastel radius-10 mb-4">
<div class="card-body text-center">
<?php if ($school): ?>
<h5 class="mb-3">Shop della scuola: <?php echo htmlspecialchars($school_name); ?></h5>
<img src="<?php echo $school_logo_path; ?>" alt="School Logo" style="max-height: 100px;">
<?php else: ?>
<h5 class="mb-3">Nessuna scuola selezionata</h5>
<img src="<?php echo $school_logo_path; ?>" alt="Default Logo" style="max-height: 100px;">
<?php endif; ?>
</div>
</div>
<!-- Sezione Prodotti -->
<div class="card card-pastel radius-10">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0">Acquista un Prodotto</h6>
</div>
</div>
</div>
<div class="card-body">
<?php if (empty($products)): ?>
<p class="text-center text-muted">Nessun prodotto disponibile per questa scuola.</p>
<?php else: ?>
<div class="row">
<?php foreach ($products as $product): ?>
<div class="col-12 col-md-6 col-lg-4 mb-3">
<div class="card product-card radius-10">
<img src="<?php echo htmlspecialchars($product['class_photo'] ?: 'default_class_image.jpg'); ?>" alt="<?php echo htmlspecialchars($product['class_name']); ?>">
<div class="card-body text-center">
<h6 class="card-title"><?php echo htmlspecialchars($product['product_name']); ?></h6>
<p class="price-range">
<?php
if ($product['min_price'] == $product['max_price']) {
echo htmlspecialchars($product['min_price']) . '€';
} else {
echo htmlspecialchars($product['min_price']) . '€ - ' . htmlspecialchars($product['max_price']) . '€';
}
?>
</p>
<p class="text-muted"><?php echo htmlspecialchars($product['class_name'] ?: 'Classe non specificata'); ?></p>
<a href="product_detail.php?product_id=<?php echo $product['id']; ?>" class="btn btn-pastel btn-sm">Dettagli</a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<!--end page wrapper -->
<!--start overlay-->
<div class="overlay toggle-icon"></div>
<!--end overlay-->
<!--Start Back To Top Button-->
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<!--End Back To Top Button-->
<?php include('include/footer.php'); ?>
</div>
<!--end wrapper-->
<!-- search modal -->
<?php //include('include/searchmodal.php');
?>
<!-- end search modal -->
<!--start switcher-->
<?php //include('include/themeswitcher.php');
?>
<!--end switcher-->
<?php include('jsinclude.php'); ?>
</body>
</html>

View File

@ -0,0 +1,192 @@
<?php include('include/headscript.php'); ?>
<?php
// Ottieni l'istanza del DBHandlerSelect
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Recupera lo school_id e user_id dalla sessione
$school_id = session('school_id');
$user_id = session('iduserlogin'); // Cambiato da 'user_id' a 'iduserlogin'
// Recupera l'order_number dai parametri GET
$order_number = $_GET['order_number'] ?? 0;
$school = null;
$school_name = 'Nessuna scuola selezionata';
$school_logo_path = url('userarea/photoschool/yogibook_logo.png'); // Default logo
if ($school_id) {
$school = \Vanguard\Models\School::find($school_id);
if ($school) {
$school_name = $school->name;
$school_logo_path = $school->logo ? url('userarea/photoschool/' . $school->logo) : $school_logo_path;
}
}
// Recupera i dettagli dell'ordine
$order_items = [];
$total_price = 0;
if ($order_number) {
$stmt = $pdo->prepare("
SELECT o.order_number, o.created_at, o.price, o.total_entries, o.available_entries, o.activation_date,
p.name AS product_name, pv.name AS variation_name, c.name AS class_name, ct.level, ct.day_of_week, c.photo AS class_photo
FROM orders o
JOIN products p ON o.product_id = p.id
JOIN product_variations pv ON o.variation_id = pv.id
LEFT JOIN class_types ct ON o.class_type_id = ct.id
LEFT JOIN classes c ON ct.class_id = c.id
WHERE o.order_number = ? AND o.user_id = ?
");
$stmt->execute([$order_number, $user_id]);
$order_items = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Calcola il totale
$total_price = array_sum(array_column($order_items, 'price'));
}
// Se non ci sono ordini, reindirizza (opzionale)
if (empty($order_items)) {
header('Location: index.php');
exit;
}
// Prendi la data di creazione dal primo elemento
$order_date = $order_items[0]['created_at'];
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<style>
.page-content {
background-color: #f0f4f5;
}
.card-pastel {
background-color: rgb(149, 217, 248);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
border: none;
}
.order-item-card {
background-color: #fff;
border: 1px solid #c8e6c9;
border-radius: 8px;
margin-bottom: 15px;
padding: 15px;
}
.order-item-image {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 50%;
}
.btn-pastel {
background-color: rgb(148, 186, 204);
border: none;
transition: background-color 0.3s ease;
}
.btn-pastel:hover {
background-color: rgb(155, 189, 221);
}
h5,
h6 {
font-family: 'Poppins', sans-serif;
color: #333;
}
.order-item-details p {
margin: 0;
font-size: 0.9rem;
color: #555;
}
.order-item-details .price {
font-weight: bold;
color: #28a745;
}
.total-section {
background-color: rgb(148, 186, 204);
color: #fff;
padding: 10px;
border-radius: 8px;
}
.success-icon {
font-size: 3rem;
color: #28a745;
}
</style>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card card-pastel radius-10 mb-4">
<div class="card-body text-center">
<?php if ($school): ?>
<h5 class="mb-3">Grazie per il tuo acquisto! - Scuola: <?php echo htmlspecialchars($school_name); ?></h5>
<img src="<?php echo $school_logo_path; ?>" alt="School Logo" style="max-height: 100px;">
<?php else: ?>
<h5 class="mb-3">Grazie per il tuo acquisto!</h5>
<img src="<?php echo $school_logo_path; ?>" alt="Default Logo" style="max-height: 100px;">
<?php endif; ?>
</div>
</div>
<div class="card card-pastel radius-10">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0">Riepilogo Ordine #<?php echo $order_number; ?></h6>
</div>
</div>
</div>
<div class="card-body text-center">
<i class="bx bx-check-circle success-icon mb-3"></i>
<h5 class="mb-3">Acquisto Completato con Successo!</h5>
<p class="text-muted">Ordine effettuato il <?php echo date('d/m/Y H:i', strtotime($order_date)); ?></p>
<div class="order-items-list">
<?php foreach ($order_items as $item): ?>
<div class="order-item-card d-flex align-items-center">
<img src="<?php echo htmlspecialchars($item['class_photo'] ?: 'default_class_image.jpg'); ?>" class="order-item-image me-3" alt="product image">
<div class="order-item-details flex-grow-1">
<h6 class="mb-1"><?php echo htmlspecialchars($item['product_name']); ?></h6>
<p><strong>Variazione:</strong> <?php echo htmlspecialchars($item['variation_name']); ?></p>
<p><strong>Classe:</strong> <?php echo htmlspecialchars($item['class_name'] . ' - ' . $item['level'] . ' (' . $item['day_of_week'] . ')'); ?></p>
<p><strong>Entrate Totali:</strong> <?php echo $item['total_entries']; ?></p>
<p class="price"><strong>Prezzo:</strong> <?php echo number_format($item['price'], 2); ?></p>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="total-section mt-3 d-flex justify-content-between align-items-center">
<h5 class="mb-0">Totale</h5>
<h5 class="mb-0"><?php echo number_format($total_price, 2); ?></h5>
</div>
<div class="text-center mt-4">
<a href="index.php" class="btn btn-pastel">Torna alla Home</a>
</div>
</div>
</div>
</div>
</div>
<div class="overlay toggle-icon"></div>
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
</body>
</html>

View File

@ -0,0 +1,295 @@
<?php include('include/headscript.php'); ?>
<?php
// Ottieni l'istanza del DBHandlerSelect
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Recupera lo school_id dalla sessione
$school_id = session('school_id');
$school = null;
// Costruisci manualmente l'URL assoluto per il logo di default
$base_url = rtrim(env('APP_URL'), '/') . '/public/userarea/';
$school_logo_path = $base_url . 'yogibook_logo.png'; // Default logo
if ($school_id) {
// Usa il modello School per recuperare i dati della scuola
$school = \Vanguard\Models\School::find($school_id);
if ($school) {
// Se la scuola esiste, aggiorna il percorso del logo
$school_logo_path = $school->logo ? $base_url . $school->logo : $school_logo_path;
}
}
// Query per i dati dell'utente
$stmt = $pdo->prepare("SELECT first_name, last_name, avatar FROM auth_users WHERE id = ?");
$stmt->execute([$iduserlogin]);
$user = $stmt->fetch();
// Dopo aver recuperato i dati dell'utente
$avatar = !empty($user['avatar']) ? '../upload/users/' . $user['avatar'] : '../assets/images/default-avatar.png';
?>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--favicon-->
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<style>
.page-content {
background-color: #f0f4f5;
/* Sfondo pastello chiaro (grigio-azzurro) */
}
.card-pastel {
background-color: rgb(149, 217, 248);
/* Verde menta pastello */
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
/* Ombra leggera */
border: none;
/* Rimuoviamo il bordo predefinito */
}
.avatar-border {
border: 3px solid #a3d9b1;
/* Bordo verde pastello intorno all'avatar */
}
.btn-pastel {
background-color: rgb(148, 186, 204);
/* Colore pulsante coordinato */
border: none;
transition: background-color 0.3s ease;
/* Effetto hover */
}
.btn-pastel:hover {
background-color: rgb(155, 189, 221);
/* Colore più scuro al passaggio del mouse */
}
h5 {
font-family: 'Poppins', sans-serif;
/* Font moderno e morbido, se disponibile */
color: #333;
/* Colore testo scuro per contrasto */
}
.calendar-header {
display: flex;
flex-wrap: wrap;
/* Permette ai filtri di andare a capo su schermi piccoli */
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
gap: 10px;
/* Spazio tra gli elementi */
}
.lesson-card {
background-color: #ffffff;
border-left: 4px solid #c8e6c9;
/* Verde per le lezioni programmate */
transition: transform 0.2s ease;
}
.lesson-card:hover {
transform: translateY(-3px);
}
.filter-btn {
background-color: #f8bbd0;
border: none;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 0.9rem;
margin: 0 5px;
/* Spazio tra i pulsanti */
}
.filter-btn.active {
background-color: #bbdefb;
}
.reschedule-btn {
background-color: #c8e6c9;
border: none;
color: white;
font-size: 0.85rem;
padding: 5px 10px;
border-radius: 15px;
}
.lesson-details p {
margin-bottom: 0.2rem;
/* Spazio ridotto tra le righe */
font-size: 0.85rem;
/* Testo più piccolo per adattarsi meglio */
}
</style>
</head>
<body>
<!--wrapper-->
<div class="wrapper">
<!--sidebar wrapper -->
<?php include('include/navbar.php'); ?>
<!--end sidebar wrapper -->
<!--start header -->
<?php include('include/topbar.php'); ?>
<!--end header -->
<!--start page wrapper -->
<div class="page-wrapper">
<div class="page-content">
<!-- Sezione Scuola -->
<div class="card card-pastel radius-10 mb-4">
<div class="card-body text-center">
<?php if ($school): ?>
<h5 class="mb-3">Sei loggato nella scuola: <?php echo htmlspecialchars($school->name); ?></h5>
<img src="<?php echo $school_logo_path; ?>" alt="School Logo" style="max-height: 100px;">
<?php else: ?>
<h5 class="mb-3">Nessuna scuola selezionata</h5>
<img src="<?php echo $school_logo_path; ?>" alt="Default Logo" style="max-height: 100px;">
<?php endif; ?>
</div>
</div>
<!-- Sezione Profilo -->
<div class="card card-pastel radius-10">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0">Stato Utente</h6>
</div>
</div>
</div>
<div class="card-body">
<div class="d-flex flex-column align-items-center text-center">
<!-- Saluto e Nome -->
<h5 class="mb-3">Ciao, <?php echo htmlspecialchars($user['first_name']); ?>!</h5>
</div>
<!-- Sezione dei box -->
<div class="row">
<!-- Lezioni programmate -->
<div class="col-12 col-md-4 mb-3">
<div class="card card-pastel radius-10 text-center" style="background-color: #c8e6c9;">
<div class="card-body">
<h6 class="mb-2">Lezioni Programmate</h6>
<h3 class="mb-0 text-primary">5</h3>
</div>
</div>
</div>
<!-- Ticket da programmare -->
<div class="col-12 col-md-4 mb-3">
<div class="card card-pastel radius-10 text-center" style="background-color: #f8bbd0;">
<div class="card-body">
<h6 class="mb-2">Ticket da Programmare</h6>
<h3 class="mb-0 text-primary">3</h3>
</div>
</div>
</div>
<!-- Lezioni da confermare -->
<div class="col-12 col-md-4 mb-3">
<div class="card card-pastel radius-10 text-center" style="background-color: #bbdefb;">
<div class="card-body">
<h6 class="mb-2">Lezioni da Confermare</h6>
<h3 class="mb-0 text-primary">2</h3>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Sezione delle lezioni future -->
<div class="card card-pastel radius-10 mt-4">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0">Le tue Lezioni Future</h6>
</div>
</div>
</div>
<div class="card-body">
<!-- Header con calendario e filtri -->
<div class="calendar-header">
<!-- Calendario per cambiare mese -->
<div>
<input type="month" id="monthPicker" value="2025-04" class="form-control" style="width: 150px;">
</div>
<!-- Filtri -->
<div>
<button class="filter-btn active">Programmate</button>
<button class="filter-btn">Effettuate</button>
<button class="filter-btn">Perse</button>
</div>
</div>
<!-- Lista delle lezioni -->
<div class="row">
<!-- Lezione 1 -->
<div class="col-12 col-md-6 mb-3">
<div class="card lesson-card radius-10">
<div class="card-body d-flex justify-content-between align-items-center">
<div class="lesson-details">
<h6 class="mb-1">Yoga Flow</h6>
<p class="text-muted">15 Apr 2025, 18:00</p>
<p class="text-muted">Scuola: Yoga Harmony</p>
<p class="text-muted">Via Roma 12, Milano</p>
</div>
<button class="reschedule-btn">Riprogramma</button>
</div>
</div>
</div>
<!-- Lezione 2 -->
<div class="col-12 col-md-6 mb-3">
<div class="card lesson-card radius-10">
<div class="card-body d-flex justify-content-between align-items-center">
<div class="lesson-details">
<h6 class="mb-1">Hatha Yoga</h6>
<p class="text-muted">20 Apr 2025, 09:00</p>
<p class="text-muted">Scuola: Zen Studio</p>
<p class="text-muted">Corso Italia 45, Torino</p>
</div>
<button class="reschedule-btn">Riprogramma</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--end page wrapper -->
<!--start overlay-->
<div class="overlay toggle-icon"></div>
<!--end overlay-->
<!--Start Back To Top Button-->
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<!--End Back To Top Button-->
<?php include('include/footer.php'); ?>
</div>
<!--end wrapper-->
<!-- search modal -->
<?php //include('include/searchmodal.php');
?>
<!-- end search modal -->
<!--start switcher-->
<?php //include('include/themeswitcher.php');
?>
<!--end switcher-->
<?php include('jsinclude.php'); ?>
</body>
</html>

View File

@ -17,6 +17,8 @@ return [
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'banned' => 'Your account is banned by administrator.',
'max_sessions_reached' => 'You reached the maximum number of active sessions allowed. Please log out on other devices and try again.',
'school_not_found' => 'The specified school was not found.',
'school_required' => 'Please specify a school.',
'2fa' => [
'enabled_successfully' => 'Two-Factor Authentication enabled successfully.',

View File

@ -0,0 +1,88 @@
@extends('layouts.auth')
@section('page-title', trans('Login'))
@section('content')
<div class="col-md-8 col-lg-6 col-xl-5 mx-auto my-10p" id="login">
<div class="text-center">
<x-logo />
</div>
<div class="card mt-5">
<div class="card-body">
<h5 class="card-title text-center mt-4 text-uppercase">
@lang('Login')
</h5>
<div class="p-4">
@include('auth.social.buttons')
@include('partials.messages')
<form role="form" action="<?= url('login') ?>" method="POST" id="login-form" autocomplete="off" class="mt-3">
<input type="hidden" value="<?= csrf_token() ?>" name="_token">
@if (Request::has('to'))
<input type="hidden" value="{{ Request::get('to') }}" name="to">
@endif
<div class="form-group">
<label for="username" class="sr-only">@lang('Email or Username')</label>
<input type="text"
name="username"
id="username"
class="form-control input-solid"
placeholder="@lang('Email or Username')"
value="{{ old('username') }}">
</div>
<div class="form-group password-field">
<label for="password" class="sr-only">@lang('Password')</label>
<input type="password"
name="password"
id="password"
class="form-control input-solid"
placeholder="@lang('Password')">
</div>
@if (setting('remember_me'))
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="remember" id="remember" value="1"/>
<label class="custom-control-label font-weight-normal" for="remember">
@lang('Remember me?')
</label>
</div>
@endif
<div class="form-group mt-4">
<button type="submit" class="btn btn-primary btn-lg btn-block" id="btn-login">
@lang('Log In')
</button>
</div>
</form>
@if (setting('forgot_password'))
<a href="<?= route('password.request') ?>" class="forgot">@lang('I forgot my password')</a>
@endif
</div>
</div>
</div>
<div class="text-center text-muted">
@if (setting('reg_enabled'))
@lang("Don't have an account?")
<a class="font-weight-bold" href="<?= url("register") ?>">@lang('Sign Up')</a>
@endif
</div>
</div>
@stop
@section('scripts')
<script src="{{ asset('assets/js/as/login.js') }}"></script>
{!! JsValidator::formRequest('Vanguard\Http\Requests\Auth\LoginRequest', '#login-form') !!}
@stop

View File

@ -6,7 +6,11 @@
<div class="col-md-8 col-lg-6 col-xl-5 mx-auto my-10p" id="login">
<div class="text-center">
<x-logo />
@if (isset($school_logo) && $school_logo)
<img src="{{ asset('userarea/' . $school_logo) }}" alt="School Logo" style="max-height: 100px;">
@else
<img src="{{ asset('userarea/photoschool/yogibook_logo.png') }}" alt="Default Logo" style="max-height: 100px;">
@endif
</div>
<div class="card mt-5">
@ -28,6 +32,17 @@
<input type="hidden" value="{{ Request::get('to') }}" name="to">
@endif
<div class="form-group">
<label for="school" class="sr-only">@lang('School')</label>
<input type="text"
name="school"
id="school"
class="form-control input-solid"
placeholder="@lang('School')"
value="{{ $school_slug ?? '' }}"
{{ $school_slug ? 'readonly' : '' }}>
</div>
<div class="form-group">
<label for="username" class="sr-only">@lang('Email or Username')</label>
<input type="text"
@ -47,7 +62,6 @@
placeholder="@lang('Password')">
</div>
@if (setting('remember_me'))
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" name="remember" id="remember" value="1" />
@ -57,7 +71,6 @@
</div>
@endif
<div class="form-group mt-4">
<button type="submit" class="btn btn-primary btn-lg btn-block" id="btn-login">
@lang('Log In')

View File

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="{{ asset('assets/images/favicon-32x32.png') }}" type="image/png" />
<!-- Plugins -->
<link href="{{ asset('assets/plugins/simplebar/css/simplebar.css') }}" rel="stylesheet" />
<link href="{{ asset('assets/plugins/perfect-scrollbar/css/perfect-scrollbar.css') }}" rel="stylesheet" />
<link href="{{ asset('assets/plugins/metismenu/css/metisMenu.min.css') }}" rel="stylesheet" />
<!-- Loader -->
<link href="{{ asset('assets/css/pace.min.css') }}" rel="stylesheet" />
<script src="{{ asset('assets/js/pace.min.js') }}"></script>
<!-- Bootstrap CSS -->
<link href="{{ asset('assets/css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ asset('assets/css/bootstrap-extended.css') }}" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
<link href="{{ asset('assets/css/app.css') }}" rel="stylesheet">
<link href="{{ asset('assets/css/icons.css') }}" rel="stylesheet">
<title>@yield('page-title', 'Rocker - Bootstrap 5 Admin Dashboard Template')</title>
</head>
<body class="">
<!-- Wrapper -->
<div class="wrapper">
<div class="section-authentication-cover">
<div class="">
<div class="row g-0">
<div class="col-12 col-xl-7 col-xxl-8 auth-cover-left align-items-center justify-content-center d-none d-xl-flex">
<div class="card shadow-none bg-transparent shadow-none rounded-0 mb-0">
<div class="card-body">
<img src="{{ asset('assets/images/login-images/login-cover.svg') }}" class="img-fluid auth-img-cover-login" width="650" alt="" />
</div>
</div>
</div>
<div class="col-12 col-xl-5 col-xxl-4 auth-cover-right align-items-center justify-content-center">
<div class="card rounded-0 m-3 shadow-none bg-transparent mb-0">
<div class="card-body p-sm-5">
@yield('content')
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="{{ asset('assets/js/bootstrap.bundle.min.js') }}"></script>
<!-- Plugins -->
<script src="{{ asset('assets/js/jquery.min.js') }}"></script>
<script src="{{ asset('assets/plugins/simplebar/js/simplebar.min.js') }}"></script>
<script src="{{ asset('assets/plugins/metismenu/js/metisMenu.min.js') }}"></script>
<script src="{{ asset('assets/plugins/perfect-scrollbar/js/perfect-scrollbar.js') }}"></script>
<!-- Password show & hide JS -->
<script>
$(document).ready(function() {
$("#show_hide_password a").on('click', function(event) {
event.preventDefault();
if ($('#show_hide_password input').attr("type") == "text") {
$('#show_hide_password input').attr('type', 'password');
$('#show_hide_password i').addClass("bx-hide");
$('#show_hide_password i').removeClass("bx-show");
} else if ($('#show_hide_password input').attr("type") == "password") {
$('#show_hide_password input').attr('type', 'text');
$('#show_hide_password i').removeClass("bx-hide");
$('#show_hide_password i').addClass("bx-show");
}
});
});
</script>
<!-- App JS -->
<script src="{{ asset('assets/js/app.js') }}"></script>
@yield('scripts')
</body>
</html>

View File

@ -3,7 +3,7 @@
/**
* Authentication
*/
Route::get('login', 'Auth\LoginController@show');
Route::get('login/{school?}', 'Auth\LoginController@show'); // Aggiunto {school?}
Route::post('login', 'Auth\LoginController@login');
Route::get('logout', 'Auth\LoginController@logout')->name('auth.logout');