fixed promemoria and timing cancellation

This commit is contained in:
Claudio 2025-10-09 21:46:29 +02:00
parent 26fb165c98
commit 754c5f93f0
4 changed files with 1017 additions and 512 deletions

View File

@ -1,5 +1,5 @@
<?php <?php
// Abilita visualizzazione errori PHP // Abilita visualizzazione errori PHP (solo per debug)
ini_set('display_errors', 1); ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);
@ -15,125 +15,304 @@ if ($conn->connect_error) {
die("Connessione al database fallita: " . $conn->connect_error); die("Connessione al database fallita: " . $conn->connect_error);
} }
// Inizializza log
$logFile = 'cancella_prenotazione_log.txt';
$logMessage = "Esecuzione cancellazione: " . date('Y-m-d H:i:s') . "\n";
// Recupera parametri GET: idbookingclass e token // Recupera parametri GET: idbookingclass e token
if (isset($_GET['idbookingclass']) && isset($_GET['token'])) { if (!isset($_GET['idbookingclass']) || !isset($_GET['token'])) {
$idbookingclass = $_GET['idbookingclass']; $logMessage .= "Parametri mancanti: idbookingclass o token\n";
$token = $_GET['token']; file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Cancellazione non possibile</h1>";
echo "<p>Parametri mancanti.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$conn->close();
exit;
}
// Verifica validità: token corrisponde, lezione futura e prima delle 12:00 del giorno // Sanitizza idbookingclass
$query = "SELECT * FROM bookingclass $idbookingclass = filter_var($_GET['idbookingclass'], FILTER_VALIDATE_INT);
WHERE idbookingclass = ? $token = $_GET['token'];
AND cancellation_token = ?
AND status = 'booked'
AND bookingstart > NOW()
AND NOW() <= DATE_ADD(DATE(bookingstart), INTERVAL 12 HOUR)";
$stmt = $conn->prepare($query);
if ($stmt) { if (!$idbookingclass) {
$stmt->bind_param("is", $idbookingclass, $token); $logMessage .= "Errore: idbookingclass non valido: " . $_GET['idbookingclass'] . "\n";
$stmt->execute(); file_put_contents($logFile, $logMessage, FILE_APPEND);
$result = $stmt->get_result(); echo "<h1>Cancellazione non possibile</h1>";
echo "<p>Parametro idbookingclass non valido.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$conn->close();
exit;
}
if ($result->num_rows > 0) { // Verifica validità: token corrisponde, lezione futura
$row = $result->fetch_assoc(); $query = "SELECT bc.*, ob.expireon, au.email, au.first_name, s.servicename
$bookingstart = $row['bookingstart']; FROM bookingclass bc
$newtimeformat = date("d-m-Y H:i", strtotime($bookingstart)); LEFT JOIN orderbook ob ON bc.idorder = ob.order_id
LEFT JOIN auth_users au ON bc.iduser = au.id
LEFT JOIN service s ON bc.idservice = s.idservice
WHERE bc.idbookingclass = ?
AND bc.cancellation_token = ?
AND bc.status = 'booked'
AND bc.bookingstart > NOW()";
$stmt = $conn->prepare($query);
// Aggiorna status a 'cancelled' e invalida token if (!$stmt) {
$updateQuery = "UPDATE bookingclass $logMessage .= "Errore preparazione query per ID $idbookingclass: " . $conn->error . "\n";
SET status = 'cancelled', cancellation_token = NULL file_put_contents($logFile, $logMessage, FILE_APPEND);
WHERE idbookingclass = ?"; echo "<h1>Cancellazione non possibile</h1>";
$updateStmt = $conn->prepare($updateQuery); echo "<p>Errore nella preparazione della query.</p>";
$updateStmt->bind_param("i", $idbookingclass); echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$updateStmt->execute(); $conn->close();
exit;
}
// Recupera dati utente e servizio $stmt->bind_param("is", $idbookingclass, $token);
$dataQuery = "SELECT bookingclass.*, auth_users.*, service.* $stmt->execute();
FROM bookingclass $result = $stmt->get_result();
LEFT JOIN auth_users ON bookingclass.iduser = auth_users.id
LEFT JOIN service ON bookingclass.idservice = service.idservice
WHERE bookingclass.idbookingclass = ?";
$dataStmt = $conn->prepare($dataQuery);
$dataStmt->bind_param("i", $idbookingclass);
$dataStmt->execute();
$dataResult = $dataStmt->get_result();
$dataRow = $dataResult->fetch_assoc();
$emailuser = $dataRow['email']; if ($result->num_rows === 0) {
$firstname = $dataRow['first_name'] ?? 'Utente'; $checkQuery = "SELECT * FROM bookingclass
WHERE idbookingclass = ?
AND cancellation_token = ?
AND status = 'booked'
AND bookingstart > NOW()";
$checkStmt = $conn->prepare($checkQuery);
$checkStmt->bind_param("is", $idbookingclass, $token);
$checkStmt->execute();
$checkResult = $checkStmt->get_result();
// Prepara messaggio email if ($checkResult->num_rows > 0) {
$messagecancel = "<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 18px; line-height: 34.2px;'><strong><span style='line-height: 34.2px; font-size: 18px;'> Ciao $firstname , </span></strong></span></p> $row = $checkResult->fetch_assoc();
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>La tua lezione è stata cancellata con successo! </span></p> $bookingstart = $row['bookingstart'];
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Dettaglio: $newtimeformat</span></p> $lessonTime = new DateTime($bookingstart);
<br> $hour = (int)$lessonTime->format('H');
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Per vedere e gestire le tue lezioni clicca qui: https://yogibook.yogasoul.it </span></p> $minute = (int)$lessonTime->format('i');
<br> $isBefore1700 = ($hour < 17) || ($hour === 17 && $minute === 0);
$logMessage .= "Tentativo di cancellazione fallito per ID $idbookingclass: orario oltre il limite (" . ($isBefore1700 ? "00:01" : "12:00") . ")\n";
echo "<h1>Cancellazione non possibile</h1>";
echo "<p>Non è possibile cancellare la lezione dopo le " . ($isBefore1700 ? "00:01" : "12:00") . " del giorno della lezione.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
} else {
$logMessage .= "Tentativo di cancellazione fallito per ID $idbookingclass: link non valido o lezione non prenotata\n";
echo "<h1>Cancellazione non possibile</h1>";
echo "<p>Il link non è valido o la lezione non è prenotata.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
}
file_put_contents($logFile, $logMessage, FILE_APPEND);
$checkStmt->close();
$stmt->close();
$conn->close();
exit;
}
$row = $result->fetch_assoc();
$bookingstart = $row['bookingstart'];
$newtimeformat = date("d-m-Y H:i", strtotime($bookingstart));
$expireon = $row['expireon'] ? date("d-m-Y", strtotime($row['expireon'])) : "sconosciuta";
$emailuser = $row['email'];
$firstname = $row['first_name'] ?? 'Utente';
$servicename = $row['servicename'] ?? 'Sconosciuta';
$iduser = $row['iduser'];
$idservice = $row['idservice'];
$idorderbook = $row['idorder'];
// Verifica il limite di cancellazione
$lessonTime = new DateTime($bookingstart);
$hour = (int)$lessonTime->format('H');
$minute = (int)$lessonTime->format('i');
$isBefore1700 = ($hour < 17) || ($hour === 17 && $minute === 0);
$currentTime = new DateTime();
$lessonDate = $lessonTime->format('Y-m-d');
if ($isBefore1700) {
$deadline = new DateTime("$lessonDate 00:01:00");
} else {
$deadline = new DateTime("$lessonDate 12:00:00");
}
if ($currentTime > $deadline) {
$logMessage .= "Tentativo di cancellazione fallito per ID $idbookingclass: orario oltre il limite (" . $deadline->format('Y-m-d H:i:s') . ")\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Cancellazione non possibile</h1>";
echo "<p>Non è possibile cancellare la lezione dopo le " . ($isBefore1700 ? "00:01" : "12:00") . " del giorno della lezione.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$stmt->close();
$conn->close();
exit;
}
// Gestisci azione di cancellazione
if (isset($_GET['action']) && $_GET['action'] === 'cancel') {
$updateQuery = "UPDATE bookingclass
SET status = 'cancelled'
WHERE idbookingclass = ? AND cancellation_token = ?";
$updateStmt = $conn->prepare($updateQuery);
$updateStmt->bind_param("is", $idbookingclass, $token);
$updateStmt->execute();
if (!filter_var($emailuser, FILTER_VALIDATE_EMAIL)) {
$logMessage .= "Email non valida per ID $idbookingclass: $emailuser\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Cancellazione confermata</h1>";
echo "<p>La lezione del $newtimeformat è stata cancellata con successo, ma non è stato possibile inviare l'email di conferma.</p>";
echo "<p>Ricordati di riprenotare entro la scadenza del tuo abbonamento ($expireon).</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$stmt->close();
$conn->close();
exit;
}
$cancellationDeadline = $isBefore1700 ? "00:01" : "12:00";
$messagecancel = "<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 18px; line-height: 34.2px;'><strong>Ciao $firstname,</strong></span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>La tua lezione ($servicename) del $newtimeformat è stata cancellata con successo!</span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Hai cancellato la lezione entro il limite delle $cancellationDeadline del giorno della lezione.</span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Ricordati di riprenotare entro la scadenza del tuo abbonamento ($expireon).</span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Per vedere e gestire le tue lezioni clicca qui: <a href='https://yogibook.yogasoul.it'>YogiBook</a></span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Ci vediamo sul tappetino!</span></p> <p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Ci vediamo sul tappetino!</span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Il Team Yogasoul</span></p>"; <p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Il Team Yogasoul</span></p>";
// Definisci $messageedit per il template $messageedit = $messagecancel;
$messageedit = $messagecancel; $buttonedit = "<a href='https://yogibook.yogasoul.it/' target='_blank' class='v-button v-font-size' style='box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #3AAEE0; border-radius: 4px;-webkit-border-radius: 4px; -moz-border-radius: 4px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;'>
// Definisci $buttonedit (pulsante generico)
$buttonedit = "<a href='https://yogibook.yogasoul.it/' target='_blank' class='v-button v-font-size' style='box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #3AAEE0; border-radius: 4px;-webkit-border-radius: 4px; -moz-border-radius: 4px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;'>
<span style='display:block;padding:10px 20px;line-height:120%;'><span style='line-height: 16.8px;'>YogiBook - YogaSoul</span></span> <span style='display:block;padding:10px 20px;line-height:120%;'><span style='line-height: 16.8px;'>YogiBook - YogaSoul</span></span>
</a>"; </a>";
require 'phpmailer/src/Exception.php'; require_once 'phpmailer/src/Exception.php';
require 'phpmailer/src/PHPMailer.php'; require_once 'phpmailer/src/PHPMailer.php';
require 'phpmailer/src/SMTP.php'; require_once 'phpmailer/src/SMTP.php';
$mail = new PHPMailer(true); $mail = new PHPMailer(true);
try { try {
$mail->isSMTP(); $mail->isSMTP();
$mail->Host = 'mail.yogasoul.it'; $mail->Host = 'mail.yogasoul.it';
$mail->SMTPAuth = true; $mail->SMTPAuth = true;
$mail->Username = 'info@yogasoul.it'; $mail->Username = 'info@yogasoul.it';
$mail->Password = '!Testolina88'; $mail->Password = '!Testolina88';
$mail->SMTPSecure = 'tls'; $mail->SMTPSecure = 'tls';
$mail->Port = 587; $mail->Port = 587;
// Verifica esistenza file template if (!file_exists('mail/emailtemplate2.php')) {
if (!file_exists('mail/emailtemplate2.php')) { throw new Exception("File emailtemplate2.php non trovato.");
throw new Exception("File emailtemplate2.php non trovato.");
}
include('mail/emailtemplate2.php');
// Verifica che $mailmessage1 esista
if (!isset($mailmessage1)) {
throw new Exception("Variabile \$mailmessage1 non definita in emailtemplate2.php.");
}
// Sostituisci placeholder (per compatibilità)
$htmlContent = str_replace('{message}', $messagecancel, $mailmessage1);
$mail->From = 'info@yogasoul.it';
$mail->FromName = 'YogiBook [YogaSoul]';
$mail->addAddress($emailuser);
$mail->Subject = "YogiBook - Lezione cancellata con successo!";
$mail->Body = $htmlContent;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
// Mostra landing di conferma
echo "<h1>Cancellazione confermata</h1>";
echo "<p>La lezione del $newtimeformat è stata cancellata con successo.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
} catch (Exception $e) {
echo "Errore invio email: " . $mail->ErrorInfo;
}
} else {
echo "Link non valido o scaduto.";
} }
$stmt->close(); include('mail/emailtemplate2.php');
} else {
echo "Errore nella preparazione della query: " . $conn->error; if (!isset($mailmessage1)) {
throw new Exception("Variabile \$mailmessage1 non definita in emailtemplate2.php.");
}
$htmlContent = str_replace('{message}', $messagecancel, $mailmessage1);
$mail->From = 'info@yogasoul.it';
$mail->FromName = 'YogiBook [YogaSoul]';
$mail->addAddress($emailuser);
$mail->Subject = "YogiBook - Lezione cancellata con successo!";
$mail->Body = $htmlContent;
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
$logMessage .= "Cancellazione confermata per ID $idbookingclass ($newtimeformat), email inviata a $emailuser\n";
echo "<h1>Cancellazione confermata</h1>";
echo "<p>La lezione del $newtimeformat è stata cancellata con successo.</p>";
echo "<p>Ricordati di riprenotare entro la scadenza del tuo abbonamento ($expireon).</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
} catch (Exception $e) {
$logMessage .= "Cancellazione confermata per ID $idbookingclass ($newtimeformat), ma errore invio email a $emailuser: " . $mail->ErrorInfo . "\n";
echo "<h1>Cancellazione confermata</h1>";
echo "<p>La lezione del $newtimeformat è stata cancellata con successo, ma non è stato possibile inviare l'email di conferma.</p>";
echo "<p>Ricordati di riprenotare entro la scadenza del tuo abbonamento ($expireon).</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
} }
} else { file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "Parametri mancanti."; $updateStmt->close();
$stmt->close();
$conn->close();
exit;
} }
$conn->close(); $logMessage .= "Accesso a modale per ID $idbookingclass, token: $token, opzione riprogrammazione: rebook-from-cancel.php?idbookingclass=$idbookingclass&token=" . urlencode($token) . "\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8" />
<title>YogiBook - Cancellazione Lezione</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
<link href="assets/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<h1>Gestione Lezione</h1>
<p>Lezione: <?php echo htmlspecialchars($servicename); ?> del <?php echo htmlspecialchars($newtimeformat); ?></p>
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log("Modale SweetAlert2 avviato per ID <?php echo $idbookingclass; ?>, token: <?php echo urlencode($token); ?>");
Swal.fire({
title: "Cosa vuoi fare?",
html: "Puoi cancellare la lezione del <?php echo htmlspecialchars($newtimeformat); ?> o riprogrammarla.<br>Scadenza abbonamento: <?php echo htmlspecialchars($expireon); ?><br><br><strong>Debug:</strong> Reindirizzamento previsto: rebook-from-cancel.php?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>",
icon: "question",
showCancelButton: true,
confirmButtonColor: "#d33",
cancelButtonColor: "#3085d6",
confirmButtonText: "Cancella Lezione",
cancelButtonText: "Riprogramma Lezione",
showDenyButton: true,
denyButtonText: "Torna al Portale",
denyButtonColor: "#6c757d"
}).then((result) => {
if (result.isConfirmed) {
console.log("Cliccato 'Cancella Lezione' per ID <?php echo $idbookingclass; ?>");
Swal.fire({
title: "Attenzione!",
text: "La lezione sarà cancellata. Ricordati di riprenotare entro la scadenza del tuo abbonamento (<?php echo htmlspecialchars($expireon); ?>)!",
icon: "warning",
confirmButtonText: "Conferma Cancellazione",
showCancelButton: true,
cancelButtonText: "Annulla"
}).then((confirmResult) => {
if (confirmResult.isConfirmed) {
console.log("Conferma cancellazione, reindirizzamento a: ?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>&action=cancel");
window.location.replace("?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>&action=cancel");
} else {
console.log("Cancellazione annullata");
}
});
} else if (result.isCancel) {
console.log("Cliccato 'Riprogramma Lezione' per ID <?php echo $idbookingclass; ?>, reindirizzamento a: rebook-from-cancel.php?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>");
try {
window.location.replace("rebook-from-cancel.php?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>");
} catch (e) {
console.error("Errore durante il reindirizzamento: ", e);
alert("Errore: impossibile reindirizzare a rebook-from-cancel.php. Controlla la console del browser.");
}
} else if (result.isDenied) {
console.log("Cliccato 'Torna al Portale', reindirizzamento a: https://yogibook.yogasoul.it");
window.location.replace("rebook-from-cancel.php?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>");
}
});
});
</script>
</div>
</body>
</html>
<?php
$stmt->close();
$conn->close();
?>

View File

@ -1,5 +1,5 @@
<?php <?php
// Abilita visualizzazione errori PHP // Abilita visualizzazione errori PHP (solo per debug)
ini_set('display_errors', 1); ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);
@ -9,6 +9,11 @@ use PHPMailer\PHPMailer\Exception;
include('include/headscript.php'); include('include/headscript.php');
// Includi PHPMailer una sola volta, all'inizio dello script
require 'phpmailer/src/Exception.php';
require 'phpmailer/src/PHPMailer.php';
require 'phpmailer/src/SMTP.php';
// Verifica connessione al database // Verifica connessione al database
$conn = new mysqli($servername, $username, $password, $dbname); $conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) { if ($conn->connect_error) {
@ -21,13 +26,32 @@ $errors = [];
$logFile = 'promemoria_cron_log.txt'; $logFile = 'promemoria_cron_log.txt';
$logMessage = "Esecuzione cron: " . date('Y-m-d H:i:s') . "\n"; $logMessage = "Esecuzione cron: " . date('Y-m-d H:i:s') . "\n";
// Seleziona prenotazioni per domani // Genera UUID per tutti i record senza token
$updateQuery = "UPDATE bookingclass
SET cancellation_token = UUID()
WHERE status = 'booked'
AND cancellation_token IS NULL";
$updateStmt = $conn->prepare($updateQuery);
if ($updateStmt) {
$updateStmt->execute();
$affectedRows = $updateStmt->affected_rows;
$logMessage .= "Generati $affectedRows token UUID per prenotazioni senza token.\n";
} else {
$errors[] = "Errore preparazione query per generazione token: " . $conn->error;
$logMessage .= "Errore generazione token: " . $conn->error . "\n";
}
// Seleziona prenotazioni per domani (dalle 17:00 in poi) e dopodomani (fino alle 16:59)
$tomorrow = date('Y-m-d', strtotime('+1 day')); $tomorrow = date('Y-m-d', strtotime('+1 day'));
$dayAfterTomorrow = date('Y-m-d', strtotime('+2 days'));
$query = "SELECT bc.*, au.email, au.first_name, s.servicename $query = "SELECT bc.*, au.email, au.first_name, s.servicename
FROM bookingclass bc FROM bookingclass bc
LEFT JOIN auth_users au ON bc.iduser = au.id LEFT JOIN auth_users au ON bc.iduser = au.id
LEFT JOIN service s ON bc.idservice = s.idservice LEFT JOIN service s ON bc.idservice = s.idservice
WHERE DATE(bc.bookingstart) = ? AND bc.status = 'booked'"; WHERE bc.status = 'booked' AND (
(DATE(bc.bookingstart) = ? AND TIME(bc.bookingstart) >= '17:00:00') OR
(DATE(bc.bookingstart) = ? AND TIME(bc.bookingstart) <= '16:59:59')
)";
$stmt = $conn->prepare($query); $stmt = $conn->prepare($query);
if (!$stmt) { if (!$stmt) {
@ -37,14 +61,14 @@ if (!$stmt) {
exit; exit;
} }
$stmt->bind_param("s", $tomorrow); $stmt->bind_param("ss", $tomorrow, $dayAfterTomorrow);
$stmt->execute(); $stmt->execute();
$result = $stmt->get_result(); $result = $stmt->get_result();
if ($result->num_rows === 0) { if ($result->num_rows === 0) {
$logMessage .= "Nessuna prenotazione trovata per domani.\n"; $logMessage .= "Nessuna prenotazione trovata per domani (dalle 17:00) o dopodomani (fino alle 16:59).\n";
file_put_contents($logFile, $logMessage, FILE_APPEND); file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "Nessuna prenotazione trovata per domani.\n"; echo "Nessuna prenotazione trovata.\n";
exit; exit;
} }
@ -52,17 +76,11 @@ while ($row = $result->fetch_assoc()) {
$idbookingclass = $row['idbookingclass']; $idbookingclass = $row['idbookingclass'];
$token = $row['cancellation_token']; $token = $row['cancellation_token'];
// Genera token se assente // Verifica che il token esista
if (empty($token)) { if (empty($token)) {
$token = bin2hex(random_bytes(32)); $errors[] = "Token mancante per ID $idbookingclass dopo aggiornamento UUID.";
$updateQuery = "UPDATE bookingclass SET cancellation_token = ? WHERE idbookingclass = ?"; $logMessage .= "Token mancante per ID $idbookingclass dopo aggiornamento UUID.\n";
$updateStmt = $conn->prepare($updateQuery); continue;
if ($updateStmt) {
$updateStmt->bind_param("si", $token, $idbookingclass);
$updateStmt->execute();
} else {
$errors[] = "Errore preparazione query token per ID $idbookingclass: " . $conn->error;
}
} }
$firstname = $row['first_name'] ?? 'Utente'; $firstname = $row['first_name'] ?? 'Utente';
@ -71,6 +89,14 @@ while ($row = $result->fetch_assoc()) {
$bookingstart = $row['bookingstart']; $bookingstart = $row['bookingstart'];
$dataformat = date("d-m-Y H:i", strtotime($bookingstart)); $dataformat = date("d-m-Y H:i", strtotime($bookingstart));
// Determina il limite di cancellazione in base all'orario della lezione
$lessonTime = new DateTime($bookingstart);
$isTomorrow = $lessonTime->format('Y-m-d') === $tomorrow;
$hour = (int)$lessonTime->format('H');
$minute = (int)$lessonTime->format('i');
$isBefore1700 = ($hour < 17) || ($hour === 17 && $minute === 0);
$cancellationDeadline = $isBefore1700 ? "00:01" : "12:00";
// Verifica email valida // Verifica email valida
if (!filter_var($emailuser, FILTER_VALIDATE_EMAIL)) { if (!filter_var($emailuser, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Email non valida per ID $idbookingclass: $emailuser"; $errors[] = "Email non valida per ID $idbookingclass: $emailuser";
@ -83,8 +109,8 @@ while ($row = $result->fetch_assoc()) {
// Messaggio email // Messaggio email
$message = "<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 18px; line-height: 34.2px;'><strong>Ciao $firstname,</strong></span></p> $message = "<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 18px; line-height: 34.2px;'><strong>Ciao $firstname,</strong></span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Promemoria: domani hai la lezione $servicename del $dataformat.</span></p> <p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Promemoria: hai la lezione $servicename del $dataformat.</span></p>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Puoi cancellarla fino alle 12:00 cliccando qui:</span></p> <p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Puoi cancellarla fino alle $cancellationDeadline del giorno della lezione cliccando qui:</span></p>
<a href='$link' target='_blank'>Cancella prenotazione</a> <a href='$link' target='_blank'>Cancella prenotazione</a>
<br> <br>
<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Ci vediamo sul tappetino!</span></p> <p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>Ci vediamo sul tappetino!</span></p>
@ -93,15 +119,11 @@ while ($row = $result->fetch_assoc()) {
// Definisci $messageedit per il template // Definisci $messageedit per il template
$messageedit = $message; $messageedit = $message;
// Definisci $buttonedit (vuoto o pulsante generico) // Definisci $buttonedit
$buttonedit = "<a href='https://yogibook.yogasoul.it/' target='_blank' class='v-button v-font-size' style='box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #3AAEE0; border-radius: 4px;-webkit-border-radius: 4px; -moz-border-radius: 4px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;'> $buttonedit = "<a href='https://yogibook.yogasoul.it/' target='_blank' class='v-button v-font-size' style='box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: center;color: #FFFFFF; background-color: #3AAEE0; border-radius: 4px;-webkit-border-radius: 4px; -moz-border-radius: 4px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-size: 14px;'>
<span style='display:block;padding:10px 20px;line-height:120%;'><span style='line-height: 16.8px;'>YogiBook - YogaSoul</span></span> <span style='display:block;padding:10px 20px;line-height:120%;'><span style='line-height: 16.8px;'>YogiBook - YogaSoul</span></span>
</a>"; </a>";
require 'phpmailer/src/Exception.php';
require 'phpmailer/src/PHPMailer.php';
require 'phpmailer/src/SMTP.php';
$mail = new PHPMailer(true); $mail = new PHPMailer(true);
try { try {
$mail->isSMTP(); $mail->isSMTP();
@ -112,24 +134,21 @@ while ($row = $result->fetch_assoc()) {
$mail->SMTPSecure = 'tls'; $mail->SMTPSecure = 'tls';
$mail->Port = 587; $mail->Port = 587;
// Verifica esistenza file template
if (!file_exists('mail/emailtemplate2.php')) { if (!file_exists('mail/emailtemplate2.php')) {
throw new Exception("File emailtemplate2.php non trovato."); throw new Exception("File emailtemplate2.php non trovato.");
} }
include('mail/emailtemplate2.php'); include('mail/emailtemplate2.php');
// Verifica che $mailmessage1 esista
if (!isset($mailmessage1)) { if (!isset($mailmessage1)) {
throw new Exception("Variabile \$mailmessage1 non definita in emailtemplate2.php."); throw new Exception("Variabile \$mailmessage1 non definita in emailtemplate2.php.");
} }
// Sostituisci placeholder (anche se non usato, per compatibilità)
$htmlContent = str_replace('{message}', $message, $mailmessage1); $htmlContent = str_replace('{message}', $message, $mailmessage1);
$mail->From = 'info@yogasoul.it'; $mail->From = 'info@yogasoul.it';
$mail->FromName = 'YogiBook [YogaSoul]'; $mail->FromName = 'YogiBook [YogaSoul]';
$mail->addAddress($emailuser); $mail->addAddress($emailuser);
$mail->Subject = "YogiBook - Promemoria lezione domani!"; $mail->Subject = "YogiBook - Promemoria lezione!";
$mail->Body = $htmlContent; $mail->Body = $htmlContent;
$mail->AltBody = 'Promemoria lezione.'; $mail->AltBody = 'Promemoria lezione.';
@ -141,7 +160,7 @@ while ($row = $result->fetch_assoc()) {
$logMessage .= "Errore invio a $emailuser (ID $idbookingclass): " . $mail->ErrorInfo . "\n"; $logMessage .= "Errore invio a $emailuser (ID $idbookingclass): " . $mail->ErrorInfo . "\n";
} }
sleep(2); // Delay 2 secondi sleep(2);
} }
// Scrivi log // Scrivi log

View File

@ -0,0 +1,484 @@
<?php
// Abilita visualizzazione errori PHP (solo per debug)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Includi headscript.php
require_once('include/headscript.php');
// Connessione al database
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connessione al database fallita: " . $conn->connect_error);
}
// Inizializza log
$logFile = 'rebook_from_cancel_log.txt';
$logMessage = "Esecuzione riprogrammazione: " . date('Y-m-d H:i:s') . "\n";
// Recupera parametri GET
if (!isset($_GET['idbookingclass']) || !isset($_GET['token'])) {
$logMessage .= "Parametri mancanti: idbookingclass o token\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Riprogrammazione non possibile</h1>";
echo "<p>Parametri mancanti.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$conn->close();
exit;
}
$idbookingclass = filter_var($_GET['idbookingclass'], FILTER_VALIDATE_INT);
$token = $_GET['token'];
if (!$idbookingclass) {
$logMessage .= "Errore: idbookingclass non valido: " . $_GET['idbookingclass'] . "\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Riprogrammazione non possibile</h1>";
echo "<p>Parametro idbookingclass non valido.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$conn->close();
exit;
}
// Verifica validità della prenotazione
$query = "SELECT bc.*, ob.expireon, au.email, au.first_name, s.servicename
FROM bookingclass bc
LEFT JOIN orderbook ob ON bc.idorder = ob.order_id
LEFT JOIN auth_users au ON bc.iduser = au.id
LEFT JOIN service s ON bc.idservice = s.idservice
WHERE bc.idbookingclass = ?
AND bc.cancellation_token = ?
AND bc.status = 'booked'
AND bc.bookingstart > NOW()";
$stmt = $conn->prepare($query);
if (!$stmt) {
$logMessage .= "Errore preparazione query per ID $idbookingclass: " . $conn->error . "\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Riprogrammazione non possibile</h1>";
echo "<p>Errore nella preparazione della query.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$conn->close();
exit;
}
$stmt->bind_param("is", $idbookingclass, $token);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
$logMessage .= "Tentativo di riprogrammazione fallito per ID $idbookingclass: link non valido o lezione non prenotata\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Riprogrammazione non possibile</h1>";
echo "<p>Il link non è valido o la lezione non è prenotata.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$stmt->close();
$conn->close();
exit;
}
$row = $result->fetch_assoc();
$bookingstart = $row['bookingstart'];
$newtimeformat = date("d-m-Y H:i", strtotime($bookingstart));
$expireon = $row['expireon'] ? date("d-m-Y", strtotime($row['expireon'])) : "sconosciuta";
$emailuser = $row['email'];
$firstname = $row['first_name'] ?? 'Utente';
$servicename = $row['servicename'] ?? 'Sconosciuta';
$iduser = $row['iduser'];
$idserviceordered = $row['idservice'];
$idorder = $row['idorder'];
// Verifica il limite di cancellazione/riprogrammazione
$lessonTime = new DateTime($bookingstart);
$hour = (int)$lessonTime->format('H');
$minute = (int)$lessonTime->format('i');
$isBefore1700 = ($hour < 17) || ($hour === 17 && $minute === 0);
$currentTime = new DateTime();
$lessonDate = $lessonTime->format('Y-m-d');
if ($isBefore1700) {
$deadline = new DateTime("$lessonDate 00:01:00");
} else {
$deadline = new DateTime("$lessonDate 12:00:00");
}
if ($currentTime > $deadline) {
$logMessage .= "Tentativo di riprogrammazione fallito per ID $idbookingclass: orario oltre il limite (" . $deadline->format('Y-m-d H:i:s') . ")\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
echo "<h1>Riprogrammazione non possibile</h1>";
echo "<p>Non è possibile riprogrammare la lezione dopo le " . ($isBefore1700 ? "00:01" : "12:00") . " del giorno della lezione.</p>";
echo "<a href='https://yogibook.yogasoul.it'>Torna al portale</a>";
$stmt->close();
$conn->close();
exit;
}
// Recupera la data di scadenza dell'ordine
$expiryDate = new DateTime($row['expireon']);
// Query sulla tabella associateclass
$sql = "SELECT idassociateservice FROM associateclass WHERE idmainservice = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $idserviceordered);
$stmt->execute();
$result = $stmt->get_result();
$idassociateservices = array();
array_push($idassociateservices, $idserviceordered);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$idassociateservices[] = $row['idassociateservice'];
}
}
$stmt->close();
// Verifica se è stata specificata una richiesta per cambiare il mese
if (isset($_GET['prev_month'])) {
$currentMonthStart = $_GET['prev_month'] . '-01';
} elseif (isset($_GET['next_month'])) {
$currentMonthStart = $_GET['next_month'] . '-01';
} else {
$currentMonthStart = date("Y-m-01");
}
$currentMonthEnd = date("Y-m-t", strtotime($currentMonthStart));
// Aggiungi filtro per la data di scadenza
$expiryCondition = '';
if ($expiryDate) {
$expiryCondition = "AND serviceschedule.dateschedule <= '{$expiryDate->format('Y-m-d 23:59:59')}'";
}
// Query per le lezioni disponibili
$placeholders = implode(',', array_fill(0, count($idassociateservices), '?'));
$query = "SELECT ss.*, s.servicename, s.colorclass, s.maxcapacity
FROM serviceschedule ss
LEFT JOIN service s ON ss.idservice = s.idservice
WHERE ss.dateschedule BETWEEN ? AND DATE_ADD(?, INTERVAL 1 DAY)
$expiryCondition
AND ss.idservice IN ($placeholders)
ORDER BY ss.dateschedule";
$stmt = $conn->prepare($query);
$types = 'ss' . str_repeat('i', count($idassociateservices));
$params = array_merge([$currentMonthStart, $currentMonthEnd], $idassociateservices);
$stmt->bind_param($types, ...$params);
$stmt->execute();
$bookedclass = $stmt->get_result();
// Mappa dei mesi in italiano
$italianMonths = [
"January" => "Gennaio",
"February" => "Febbraio",
"March" => "Marzo",
"April" => "Aprile",
"May" => "Maggio",
"June" => "Giugno",
"July" => "Luglio",
"August" => "Agosto",
"September" => "Settembre",
"October" => "Ottobre",
"November" => "Novembre",
"December" => "Dicembre"
];
$logMessage .= "Caricata pagina di riprogrammazione per ID $idbookingclass, mese: $currentMonthStart\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8" />
<title>YogiBook - Riprogramma Lezione</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="YogiBook - Prenotazione facile YogaSOul" name="description" />
<meta content="Advanced Creative Solutions" author />
<link rel="shortcut icon" href="assets/images/favicon.ico">
<link href="assets/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
<link href="assets/css/app.min.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
<style>
.custom-card {
margin: 10px auto;
display: flex;
width: 90%;
max-width: 700px;
background-color: white;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 8px;
overflow: hidden;
cursor: pointer;
transition: transform 0.2s;
}
.custom-card:hover {
transform: translateY(-5px);
}
.custom-date-box {
flex: 1;
background-color: red;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0;
font-size: 60px;
font-weight: bold;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
.custom-day {
line-height: 1;
}
.custom-month {
font-size: 28px;
}
.custom-event-details {
flex: 2;
display: flex;
flex-direction: column;
padding: 10px 20px;
background-color: lightblue;
}
.custom-heading {
margin-top: 0;
font-size: 24px;
}
.custom-paragraph {
margin-bottom: 5px;
}
.custom-actions {
display: none;
flex-direction: row;
justify-content: space-between;
margin-top: 10px;
}
.custom-card.expanded .custom-actions {
display: flex;
}
.custom-action-button {
background-color: #f0f0f0;
border: none;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}
.custom-action-button:hover {
background-color: #e0e0e0;
}
@media (max-width: 768px) {
.custom-card {
flex-direction: column;
}
.custom-date-box,
.custom-event-details {
width: 100%;
border-radius: 0;
}
.custom-event-time {
font-size: 24px;
}
}
.month-navigation {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.month-nav-button {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
}
.current-month {
font-size: 24px;
margin: 0 20px;
}
.booking-details {
margin-top: 10px;
border-top: 1px solid #ccc;
padding-top: 10px;
}
.booking-button {
background-color: #1ebf73;
color: #fff;
border: none;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
}
.booking-button:hover {
background-color: #17a663;
}
</style>
</head>
<body>
<div id="layout-wrapper">
<header id="page-topbar" class="isvertical-topbar">
<div class="navbar-header">
<div class="d-flex">
<?php include('include/logoarea.php'); ?>
<button type="button" class="btn btn-sm px-3 font-size-24 header-item waves-effect vertical-menu-btn">
<i class="bx bx-menu align-middle"></i>
</button>
<div class="page-title-box align-self-center d-none d-md-block">
<h4 class="page-title mb-0">Riprogramma la tua lezione</h4>
</div>
</div>
<div class="d-flex">
<?php include('include/languageselection.php'); ?>
<?php include('include/profiletopbar.php'); ?>
</div>
</div>
</header>
<?php include('include/sidebar.php'); ?>
<div class="main-content">
<div class="page-content">
<div class="container-fluid">
<div class="row">
<div class="col-xl-12">
<div class="card">
<div class="card-body">
<h3>Riprogrammazione Lezione</h3>
<p>Lezione attuale: <?php echo htmlspecialchars($servicename); ?> del <?php echo htmlspecialchars($newtimeformat); ?></p>
<p>Scadenza abbonamento: <?php echo htmlspecialchars($expireon); ?></p>
</div>
</div>
</div>
</div>
<div class="month-navigation">
<a href="?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>&prev_month=<?php echo date('Y-m', strtotime('-1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-left fa-2x"></i>
</a>
<h2><?php echo $italianMonths[date("F", strtotime($currentMonthStart))] . ' ' . date("Y", strtotime($currentMonthStart)); ?></h2>
<a href="?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>&next_month=<?php echo date('Y-m', strtotime('+1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-right fa-2x"></i>
</a>
</div>
<?php if ($bookedclass->num_rows == 0): ?>
<p>Classi non presenti per questo mese o oltre la data di scadenza.</p>
<a href="https://yogibook.yogasoul.it" class="btn btn-primary">Torna al portale</a>
<?php else: ?>
<?php while ($row = $bookedclass->fetch_assoc()): ?>
<?php
$dateschedule = $row['dateschedule'];
$dateObj = new DateTime($dateschedule);
$dayInItalian = $dateObj->format("d");
$monthInItalian = $italianMonths[$dateObj->format("F")];
$newDateFormat = $dateObj->format("d-m-Y H:i");
$eventId = $row['idserviceschedule'];
$bookingQuery = "SELECT iduser FROM bookingclass WHERE idserviceschedule = ? AND status='booked'";
$stmtBooking = $conn->prepare($bookingQuery);
$stmtBooking->bind_param("i", $eventId);
$stmtBooking->execute();
$bookingResult = $stmtBooking->get_result();
$countPersons = $bookingResult->num_rows;
$stmtBooking->close();
$maxcapacity = $row['maxcapacity'];
$freeplace = $maxcapacity - $countPersons;
$idcheckservice = $row['idserviceschedule'];
$query = "SELECT * FROM bookingclass WHERE idserviceschedule = ? AND iduser = ?";
$stmtCheck = $conn->prepare($query);
$stmtCheck->bind_param("ii", $idcheckservice, $iduser);
$stmtCheck->execute();
$resultcheck = $stmtCheck->get_result();
$alreadybooked = $resultcheck->num_rows > 0 ? 'Y' : 'N';
$stmtCheck->close();
?>
<div class="custom-card" onclick="toggleCard(this)">
<?php if ($alreadybooked == 'Y'): ?>
<div class="custom-date-box" style="background-color:#FF6609">
<?php elseif ($freeplace > 0): ?>
<div class="custom-date-box" style="background-color:#1ebf73">
<?php else: ?>
<div class="custom-date-box" style="background-color:#9C9C9C">
<?php endif; ?>
<div class="custom-day"><?php echo $dayInItalian; ?></div>
<div class="custom-month"><?php echo $monthInItalian; ?></div>
</div>
<?php if ($alreadybooked == 'Y'): ?>
<div class="custom-event-details" style="background-color:#FFAC7A">
<?php elseif ($freeplace > 0): ?>
<div class="custom-event-details" style="background-color:<?php echo htmlspecialchars($row['colorclass']); ?>">
<?php else: ?>
<div class="custom-event-details" style="background-color:#CDCDCD">
<?php endif; ?>
<h2 class="custom-heading"><?php echo htmlspecialchars($row['servicename']); ?> - <?php echo $countPersons; ?>/<?php echo $maxcapacity; ?></h2>
<p class="custom-paragraph">Quando: <?php echo $newDateFormat; ?></p>
<p class="custom-paragraph">Luogo: via Valassina 62/B Seregno - Sala Contesto Yoga</p>
<div class="booking-details">
<?php if ($alreadybooked == 'Y'): ?>
<button class="booking-button"><i class="fa fa-check"></i> Sei già prenotata/o</button>
<?php elseif ($freeplace > 0): ?>
<a href="rebookandgo.php?idpreviousbooking=<?php echo $idbookingclass; ?>&idservicenew=<?php echo $row['idservice']; ?>&idnewbooking=<?php echo $row['idserviceschedule']; ?>&iduser=<?php echo $iduser; ?>">
<button class="booking-button"><i class="fas fa-arrow-circle-right"></i> Riprogramma Classe</button>
</a>
<?php else: ?>
<button class="booking-button"><i class="fa fa-stop"></i> Classe Piena</button>
<?php endif; ?>
</div>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
<div class="month-navigation">
<a href="?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>&prev_month=<?php echo date('Y-m', strtotime('-1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-left fa-2x"></i>
</a>
<h2><?php echo $italianMonths[date("F", strtotime($currentMonthStart))] . ' ' . date("Y", strtotime($currentMonthStart)); ?></h2>
<a href="?idbookingclass=<?php echo $idbookingclass; ?>&token=<?php echo urlencode($token); ?>&next_month=<?php echo date('Y-m', strtotime('+1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-right fa-2x"></i>
</a>
</div>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
</div>
<script>
function toggleCard(card) {
card.classList.toggle("expanded");
}
</script>
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="assets/libs/metismenujs/metismenujs.min.js"></script>
<script src="assets/libs/simplebar/simplebar.min.js"></script>
<script src="assets/libs/eva-icons/eva.min.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>
<?php
$stmt->close();
$conn->close();
?>

View File

@ -11,7 +11,6 @@ $optionquery->setQuery("SELECT * FROM option");
$optionquery->execute(); $optionquery->execute();
?> ?>
<?php <?php
$bookedclass = new WA_MySQLi_RS("bookedclass", $bkngstm, 0); $bookedclass = new WA_MySQLi_RS("bookedclass", $bkngstm, 0);
// Verifica se è stata specificata una richiesta per cambiare il mese // Verifica se è stata specificata una richiesta per cambiare il mese
@ -38,11 +37,9 @@ $bookedclass->setQuery("SELECT * FROM bookingclass
WHERE bookingclass.iduser = '$iduserlogin' AND bookingclass.status = 'booked' WHERE bookingclass.iduser = '$iduserlogin' AND bookingclass.status = 'booked'
AND serviceschedule.dateschedule BETWEEN '$currentMonthStart' AND DATE_ADD('$currentMonthEnd', INTERVAL 1 DAY) ORDER BY serviceschedule.dateschedule"); AND serviceschedule.dateschedule BETWEEN '$currentMonthStart' AND DATE_ADD('$currentMonthEnd', INTERVAL 1 DAY) ORDER BY serviceschedule.dateschedule");
$bookedclass->execute(); $bookedclass->execute();
?> ?>
<?php <?php
$conn = new mysqli($servername, $username, $password, $dbname); $conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) { if ($conn->connect_error) {
@ -98,10 +95,6 @@ $query = "SELECT COUNT(*) AS total,
LEFT JOIN serviceschedule ON bookingclass.idserviceschedule = serviceschedule.idserviceschedule LEFT JOIN serviceschedule ON bookingclass.idserviceschedule = serviceschedule.idserviceschedule
WHERE bookingclass.iduser = $iduser"; WHERE bookingclass.iduser = $iduser";
$result = $conn->query($query); $result = $conn->query($query);
if ($result) { if ($result) {
$row = $result->fetch_assoc(); $row = $result->fetch_assoc();
@ -119,7 +112,6 @@ $conn->close();
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>YogiBook - Prenotazioni YogaSoul</title> <title>YogiBook - Prenotazioni YogaSoul</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -214,7 +206,6 @@ $conn->close();
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
transition: background-color 0.2s; transition: background-color 0.2s;
} }
.custom-action-button:hover { .custom-action-button:hover {
@ -261,6 +252,48 @@ $conn->close();
width: 100%; width: 100%;
} }
</style> </style>
<style>
.pastel-color {
border: 1px solid #D1C4CC;
padding: 0px;
text-align: center;
border-radius: 10px;
margin-right: 20px;
font-size: 18px;
}
.pastel-color.acquistate {
background-color: #E2C4FB;
}
.pastel-color.praticate {
background-color: #C4E1FB;
}
.pastel-color.prenotate {
background-color: #CDFBC4;
}
.pastel-color.conferma {
background-color: #FBFAC4;
}
.pastel-color.programmare {
background-color: #FBE4C4;
}
.pastel-color.perse {
background-color: #FBC7C4;
}
@media (max-width: 768px) {
.pastel-color {
margin-right: 0;
margin-bottom: 20px;
}
}
</style>
<script> <script>
function confirmDelete(id, idservice, deletePageUrl) { function confirmDelete(id, idservice, deletePageUrl) {
Swal.fire({ Swal.fire({
@ -274,163 +307,52 @@ $conn->close();
cancelButtonText: "Annulla" cancelButtonText: "Annulla"
}).then((result) => { }).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
// Reindirizza direttamente alla pagina di cancellazione con l'ID e l'ID del servizio come parametri.
window.location.href = `${deletePageUrl}?id=${id}&idserviceordered=${idservice}`; window.location.href = `${deletePageUrl}?id=${id}&idserviceordered=${idservice}`;
} }
}); });
} }
</script> </script>
<style>
.pastel-color {
border: 1px solid #D1C4CC;
padding: 0px;
text-align: center;
border-radius: 10px;
margin-right: 20px;
/* Spazio tra i box */
font-size: 18px;
}
.pastel-color.acquistate {
background-color: #E2C4FB;
/* Azzurro pastello */
}
.pastel-color.praticate {
background-color: #C4E1FB;
/* Verde pastello */
}
.pastel-color.prenotate {
background-color: #CDFBC4;
/* Rosa pastello */
}
.pastel-color.conferma {
background-color: #FBFAC4;
/* Arancio pastello */
}
.pastel-color.programmare {
background-color: #FBE4C4;
/* Arancio pastello */
}
.pastel-color.perse {
background-color: #FBC7C4;
/* Arancio pastello */
}
}
@media (max-width: 768px) {
.pastel-color {
margin-right: 0;
/* Rimuovi lo spazio tra i box */
margin-bottom: 20px;
/* Spazio tra i box */
}
}
</style>
<body> <body>
<!-- <body data-layout="horizontal"> -->
<!-- Begin page -->
<div id="layout-wrapper"> <div id="layout-wrapper">
<!-- Top Bar -->
<header id="page-topbar" class="isvertical-topbar"> <header id="page-topbar" class="isvertical-topbar">
<div class="navbar-header"> <div class="navbar-header">
<div class="d-flex"> <div class="d-flex">
<!-- LOGO -->
<?php include('include/logoarea.php'); ?> <?php include('include/logoarea.php'); ?>
<button type="button" class="btn btn-sm px-3 font-size-24 header-item waves-effect vertical-menu-btn"> <button type="button" class="btn btn-sm px-3 font-size-24 header-item waves-effect vertical-menu-btn">
<i class="bx bx-menu align-middle"></i> <i class="bx bx-menu align-middle"></i>
</button> </button>
<!-- start page title -->
<div class="page-title-box align-self-center d-none d-md-block"> <div class="page-title-box align-self-center d-none d-md-block">
<h4 class="page-title mb-0">Prenotazione Classi</h4> <h4 class="page-title mb-0">Prenotazione Classi</h4>
</div> </div>
<!-- end page title -->
</div> </div>
<div class="d-flex"> <div class="d-flex">
<?php include('include/languageselection.php'); ?> <?php include('include/languageselection.php'); ?>
<!-- /searh on topbar
<div class="dropdown d-inline-block">
<button type="button" class="btn header-item noti-icon"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="bx bx-search icon-sm align-middle"></i>
</button>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-end p-0">
<form class="p-2">
<div class="search-box">
<div class="position-relative">
<input type="text" class="form-control rounded bg-light border-0" placeholder="Search...">
<i class="bx bx-search search-icon"></i>
</div>
</div>
</form>
</div>
</div> -->
<?php include('include/profiletopbar.php'); ?> <?php include('include/profiletopbar.php'); ?>
</div> </div>
</div> </div>
</header> </header>
<?php include('include/sidebar.php'); ?> <?php include('include/sidebar.php'); ?>
<header class="ishorizontal-topbar"> <header class="ishorizontal-topbar">
<div class="navbar-header"> <div class="navbar-header">
<div class="d-flex"> <div class="d-flex"></div>
<div class="topnav">
<div class="container-fluid">
<nav class="navbar navbar-light navbar-expand-lg topnav-menu"></nav>
</div>
</div>
</div>
<div class="topnav">
<div class="container-fluid">
<nav class="navbar navbar-light navbar-expand-lg topnav-menu">
</nav>
</div> </div>
</div> </div>
</header> </header>
<!-- ============================================================== -->
<!-- Start right Content here -->
<!-- ============================================================== -->
<div class="main-content"> <div class="main-content">
<div class="page-content"> <div class="page-content">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-xl-12"> <div class="col-xl-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5>Benvenuta/o </h5> <h5>Benvenuta/o </h5>
<p>Di seguito puoi vedere lo stato delle tue prenotazioni</p> <p>Di seguito puoi vedere lo stato delle tue prenotazioni</p>
<?php <?php
$toprogram = $totalTickets - $passedRecords - $futureRecords - $pending - $lost; $toprogram = $totalTickets - $passedRecords - $futureRecords - $pending - $lost;
?> ?>
@ -486,292 +408,193 @@ $conn->close();
</div> </div>
<div class="alert alert-warning alert-dismissible fade show" role="alert" style="text-align: center;"> <div class="alert alert-warning alert-dismissible fade show" role="alert" style="text-align: center;">
<i class="mdi mdi-alert-outline me-2"></i> <i class="mdi mdi-alert-outline me-2"></i>
Car* Yogi, ti ricordiamo che il pacchetto 4 lezioni ha validità entro le 5 settimane dall'acquisto e il pacchetto da 12 lezioni entro il <strong>20 dicembre 2025</strong> 🙏 Car* Yogi, ti ricordiamo che il pacchetto 4 lezioni ha validità entro le 5 settimane dall'acquisto e il pacchetto da 12 lezioni entro il <strong>20 dicembre 2025</strong> 🙏
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- container-fluid -->
</div>
<?php if (isset($_GET['reprogram'])) { ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="mdi mdi-check-all me-2"></i>
Richiesta di riprogrammazione inviata con successo!
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php } ?>
<div class="container-fluid">
<?php if (isset($_GET['reprogram'])) { ?>
<div class="row"> <div class="alert alert-success alert-dismissible fade show" role="alert">
<div class="col-xl-12"> <i class="mdi mdi-check-all me-2"></i>
<div class="card"> Richiesta di riprogrammazione inviata con successo!
<div class="card-body"> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<div class="">
<div class="row mb-2">
<div class="col-xl-3 col-md-12">
<div class="pb-3 pb-xl-0">
<form class="email-search">
<div class="position-relative">
<h3>Lezioni Programmate</h3>
</div>
</form>
</div>
</div>
<div class="col-xl-9 col-md-12">
<div class="text-sm-end">
<?php if ($toprogram > 0) { ?>
<a href="selectorder.php">
<button type="button" class="btn btn-primary btn-rounded waves-effect waves-light mb-2 me-2" data-bs-toggle="modal" data-bs-target=".create-task">
<i class="mdi mdi-plus me-1"></i> Programma lezioni rimanenti
</button>
</a>
<?php } ?>
<a href="https://yogasoul.it/shop-completo/">
<button type="button" class="btn btn-success btn-rounded waves-effect waves-light mb-2 me-2" data-bs-toggle="modal" data-bs-target=".create-task">
<i class="mdi mdi-plus me-1"></i> Acquista Pacchetto Lezioni
</button>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<?php } ?>
</div>
<!-- container-fluid -->
<div class="container-fluid"> <div class="container-fluid">
<!-- starts cards -->
<!-- Aggiungi le frecce per la navigazione tra i mesi -->
<?php
$italianMonths = [
"January" => "Gennaio",
"February" => "Febbraio",
"March" => "Marzo",
"April" => "Aprile",
"May" => "Maggio",
"June" => "Giugno",
"July" => "Luglio",
"August" => "Agosto",
"September" => "Settembre",
"October" => "Ottobre",
"November" => "Novembre",
"December" => "Dicembre"
];
?>
<div class="month-navigation">
<a href="?prev_month=<?php echo date('Y-m', strtotime('-1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-left fa-2x"></i>
</a>
<h2><?php echo $italianMonths[date("F", strtotime($currentMonthStart))] . ' ' . date("Y", strtotime($currentMonthStart)); ?></h2>
<a href="?next_month=<?php echo date('Y-m', strtotime('+1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-right fa-2x"></i>
</a>
</div>
<div class="row"> <div class="row">
<div class="col-xl-12"> <div class="col-xl-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<div class="">
<div class="row mb-2">
<?php <div class="col-xl-3 col-md-12">
$wa_startindex = 0; <div class="pb-3 pb-xl-0">
<form class="email-search">
if ($bookedclass->TotalRows == 0) { <div class="position-relative">
echo "<p>Prenotazioni non presenti per questo mese</p>"; <h3>Lezioni Programmate</h3>
} else { </div>
while (!$bookedclass->atEnd()) { </form>
$wa_startindex = $bookedclass->Index;
?>
<?php
// Data dalla variabile $bookedclass->getColumnVal("dateschedule")
$dateschedule = $bookedclass->getColumnVal("dateschedule");
// Converti la data in un oggetto DateTime
$dateObj = new DateTime($dateschedule);
// Estrai il giorno e il mese in italiano
$dayInItalian = $dateObj->format("d");
$monthInItalian = $dateObj->format("F");
// Mappa dei nomi dei mesi in italiano
$italianMonths = [
"January" => "Gennaio",
"February" => "Febbraio",
"March" => "Marzo",
"April" => "Aprile",
"May" => "Maggio",
"June" => "Giugno",
"July" => "Luglio",
"August" => "Agosto",
"September" => "Settembre",
"October" => "Ottobre",
"November" => "Novembre",
"December" => "Dicembre"
];
// Sostituisci il nome del mese con la versione italiana
$monthInItalian = $italianMonths[$monthInItalian];
?>
<?php
// Data dalla variabile $bookedclass->getColumnVal("dateschedule")
$dateschedule = $bookedclass->getColumnVal("dateschedule");
// Converti la data in un oggetto DateTime
$dateObj = new DateTime($dateschedule);
// Formatta la data nel nuovo formato desiderato
$newDateFormat = $dateObj->format("d-m-Y H:i");
// Calculate the time difference in hours
$currentTime = new DateTime();
$classTime = new DateTime($dateschedule);
$timeDifference = $classTime->diff($currentTime);
$hoursDifference = $timeDifference->h + $timeDifference->days * 24;
// Check if the time difference is less than 6 hours
$timetocancel = $optionquery->getColumnVal("maxbeforetimecancell");
$canBeDeleted = ($hoursDifference > $timetocancel);
?>
<div class="custom-card" onclick="toggleCard(this)">
<div class="custom-date-box" style="background-color:#1ebf73">
<div class="custom-day"><?php echo $dayInItalian; ?></div>
<div class="custom-month"><?php echo $monthInItalian; ?></div>
</div>
<div class="custom-event-details" style="background-color:<?php echo ($bookedclass->getColumnVal("colorclass")); ?>">
<h2 class="custom-heading"><?php echo ($bookedclass->getColumnVal("servicename")); ?></h2>
<p class="custom-paragraph">Quando: <?php echo $newDateFormat; ?></p>
<p class="custom-paragraph">Luogo: via Valassina 62/B Seregno - Sala Contesto Yoga</p>
<div class="custom-actions">
<button class="custom-action-button" onclick="addToCalendar(this)" data-eventname="<?php echo ($bookedclass->getColumnVal("servicename")); ?>" data-eventdate="<?php echo $newDateFormat; ?>">
<i class="far fa-calendar-plus"></i> Cal
</button>
<!-- <button class="custom-action-button"><i class="fas fa-edit"></i> Riprogramma</button> -->
<?php $idbookingclass = $bookedclass->getColumnVal("idbookingclass");
$idservice = $bookedclass->getColumnVal("idservice");
?>
<?php if ($canBeDeleted) : ?>
<button class="custom-action-button" onclick="confirmDelete(<?php echo $idbookingclass; ?>, <?php echo $idservice; ?>, 'bookingpanel.php')">
<i class="fas fa-calendar-alt"></i> Riprogramma
</button>
<?php else : ?>
<button class="custom-action-button"> <i class="fas fa-exclamation-circle"></i> Non puoi riprogrammare</button>
<?php endif; ?>
</div>
</div> </div>
</div> </div>
<div class="col-xl-9 col-md-12">
<?php <div class="text-sm-end">
$bookedclass->moveNext(); <?php if ($toprogram > 0) { ?>
} <a href="selectorder.php">
} <button type="button" class="btn btn-primary btn-rounded waves-effect waves-light mb-2 me-2" data-bs-toggle="modal" data-bs-target=".create-task">
<i class="mdi mdi-plus me-1"></i> Programma lezioni rimanenti
$bookedclass->moveFirst(); // Ritorna all'inizio del recordset </button>
unset($wa_startindex); </a>
unset($wa_repeatcount); <?php } ?>
?> <a href="https://yogasoul.it/shop-completo/">
<button type="button" class="btn btn-success btn-rounded waves-effect waves-light mb-2 me-2" data-bs-toggle="modal" data-bs-target=".create-task">
<i class="mdi mdi-plus me-1"></i> Acquista Pacchetto Lezioni
</button>
</a>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div><br><br> </div>
<!-- Aggiungi altre card qui con le stesse classi -->
<div class="container-fluid">
<div class="month-navigation">
<?php
$italianMonths = [
"January" => "Gennaio",
"February" => "Febbraio",
"March" => "Marzo",
"April" => "Aprile",
"May" => "Maggio",
"June" => "Giugno",
"July" => "Luglio",
"August" => "Agosto",
"September" => "Settembre",
"October" => "Ottobre",
"November" => "Novembre",
"December" => "Dicembre"
];
?>
<a href="?prev_month=<?php echo date('Y-m', strtotime('-1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-left fa-2x"></i>
</a>
<h2><?php echo $italianMonths[date("F", strtotime($currentMonthStart))] . ' ' . date("Y", strtotime($currentMonthStart)); ?></h2>
<a href="?next_month=<?php echo date('Y-m', strtotime('+1 month', strtotime($currentMonthStart))); ?>" class="arrow-link">
<i class="fas fa-chevron-right fa-2x"></i>
</a>
</div>
<div class="row">
<div class="col-xl-12">
<div class="card">
<div class="card-body">
<?php
$wa_startindex = 0;
if ($bookedclass->TotalRows == 0) {
echo "<p>Prenotazioni non presenti per questo mese</p>";
} else {
while (!$bookedclass->atEnd()) {
$wa_startindex = $bookedclass->Index;
$dateschedule = $bookedclass->getColumnVal("dateschedule");
$dateObj = new DateTime($dateschedule);
$dayInItalian = $dateObj->format("d");
$monthInItalian = $dateObj->format("F");
$monthInItalian = $italianMonths[$monthInItalian];
$newDateFormat = $dateObj->format("d-m-Y H:i");
<script> // Calcola se la lezione può essere riprogrammata
function toggleCard(card) { $currentTime = new DateTime();
card.classList.toggle("expanded"); $classTime = new DateTime($dateschedule);
} $isSameDay = $classTime->format('Y-m-d') === $currentTime->format('Y-m-d');
</script> $classHour = (int)$classTime->format('H');
$classMinute = (int)$classTime->format('i');
$isBefore1700 = ($classHour < 17) || ($classHour === 17 && $classMinute === 0);
// Definisci il limite per la riprogrammazione
if ($isSameDay) {
if ($isBefore1700) {
// Lezioni prima delle 17:00: cancellazione valida fino alle 00:01 dello stesso giorno
$deadline = new DateTime($classTime->format('Y-m-d 00:01:00'));
} else {
// Lezioni alle 17:00 o dopo: cancellazione valida fino alle 12:00 dello stesso giorno
$deadline = new DateTime($classTime->format('Y-m-d 12:00:00'));
}
$canBeDeleted = $currentTime <= $deadline;
} else {
// Per lezioni in giorni futuri, la riprogrammazione è sempre consentita
$canBeDeleted = true;
}
?>
<div class="custom-card" onclick="toggleCard(this)">
<div class="custom-date-box" style="background-color:#1ebf73">
<div class="custom-day"><?php echo $dayInItalian; ?></div>
<div class="custom-month"><?php echo $monthInItalian; ?></div>
</div>
<div class="custom-event-details" style="background-color:<?php echo ($bookedclass->getColumnVal("colorclass")); ?>">
<h2 class="custom-heading"><?php echo ($bookedclass->getColumnVal("servicename")); ?></h2>
<p class="custom-paragraph">Quando: <?php echo $newDateFormat; ?></p>
<p class="custom-paragraph">Luogo: via Valassina 62/B Seregno - Sala Contesto Yoga</p>
<div class="custom-actions">
<button class="custom-action-button" onclick="addToCalendar(this)" data-eventname="<?php echo ($bookedclass->getColumnVal("servicename")); ?>" data-eventdate="<?php echo $newDateFormat; ?>">
<i class="far fa-calendar-plus"></i> Cal
</button>
<?php $idbookingclass = $bookedclass->getColumnVal("idbookingclass"); ?>
<?php $idservice = $bookedclass->getColumnVal("idservice"); ?>
<?php if ($canBeDeleted) : ?>
<button class="custom-action-button" onclick="confirmDelete(<?php echo $idbookingclass; ?>, <?php echo $idservice; ?>, 'bookingpanel.php')">
<i class="fas fa-calendar-alt"></i> Riprogramma
</button>
<?php else : ?>
<button class="custom-action-button"> <i class="fas fa-exclamation-circle"></i> Non puoi riprogrammare</button>
<?php endif; ?>
</div>
</div>
</div>
<?php
$bookedclass->moveNext();
}
}
$bookedclass->moveFirst();
unset($wa_startindex);
unset($wa_repeatcount);
?>
</div>
</div>
</div>
</div><br><br>
</div>
</div> </div>
<?php include('include/footer.php'); ?>
</div> </div>
<!-- End Page-content -->
<?php include('include/footer.php'); ?>
</div> </div>
<!-- end main content-->
</div> <script>
<!-- END layout-wrapper --> function toggleCard(card) {
card.classList.toggle("expanded");
}
function addToCalendar(button) {
const eventName = button.getAttribute('data-eventname');
const eventDate = button.getAttribute('data-eventdate');
const googleCalendarLink = `https://www.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(eventName)}&dates=${encodeURIComponent(eventDate)}`;
window.open(googleCalendarLink, '_blank');
const outlookCalendarLink = `webcal://outlook.live.com/calendar/0/deeplink/compose?path=/calendar/action/compose&subject=${encodeURIComponent(eventName)}&startdt=${encodeURIComponent(eventDate)}`;
window.open(outlookCalendarLink, '_blank');
}
</script>
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="assets/libs/metismenujs/metismenujs.min.js"></script>
<script src="assets/libs/simplebar/simplebar.min.js"></script>
<script src="assets/libs/eva-icons/eva.min.js"></script>
<script src="assets/js/app.js"></script>
<!-- JAVASCRIPT -->
<script>
function addToCalendar(button) {
const eventName = button.getAttribute('data-eventname');
const eventDate = button.getAttribute('data-eventdate');
// Qui dovresti implementare la logica per aggiungere l'evento al calendario.
// Puoi gestire l'aggiunta sia a Google Calendar che a Outlook.
// Esempio: Aggiunta a Google Calendar (il link potrebbe variare)
const googleCalendarLink = `https://www.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(eventName)}&dates=${encodeURIComponent(eventDate)}`;
window.open(googleCalendarLink, '_blank');
// Esempio: Aggiunta a Outlook (il link potrebbe variare)
const outlookCalendarLink = `webcal://outlook.live.com/calendar/0/deeplink/compose?path=/calendar/action/compose&subject=${encodeURIComponent(eventName)}&startdt=${encodeURIComponent(eventDate)}`;
window.open(outlookCalendarLink, '_blank');
}
</script>
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="assets/libs/metismenujs/metismenujs.min.js"></script>
<script src="assets/libs/simplebar/simplebar.min.js"></script>
<script src="assets/libs/eva-icons/eva.min.js"></script>
<script src="assets/js/app.js"></script>
</body> </body>
</html> </html>