regenrates pages
This commit is contained in:
+700
-788
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,34 @@
|
|||||||
<?php
|
<?php
|
||||||
|
// Buffer per scartare eventuale HTML degli include: risposta JSON pulita
|
||||||
|
ob_start();
|
||||||
|
require_once('include/headscript.php');
|
||||||
|
|
||||||
// Connessione al database. Assumiamo che tu abbia un file chiamato 'config.php' che gestisce la connessione.
|
/**
|
||||||
include('Connections/bkngstm.php');
|
* Segna una prenotazione come "persa" (lostlesson = 'Y').
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
*/
|
||||||
// Controllo se la variabile idbookingclass è stata inviata tramite POST
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
if(isset($_POST['idbookingclass'])) {
|
|
||||||
$idbookingclass = $_POST['idbookingclass'];
|
|
||||||
|
|
||||||
// Query per aggiornare il campo 'lostlesson' nella tabella 'bookingclass'
|
function jsonOut(array $payload): void
|
||||||
$query = "UPDATE bookingclass SET lostlesson = 'Y' WHERE idbookingclass = ?";
|
{
|
||||||
|
if (ob_get_length() !== false) {
|
||||||
// Preparazione ed esecuzione della query
|
ob_end_clean();
|
||||||
if($stmt = $conn->prepare($query)) {
|
|
||||||
$stmt->bind_param('i', $idbookingclass);
|
|
||||||
|
|
||||||
if($stmt->execute()) {
|
|
||||||
echo "success";
|
|
||||||
} else {
|
|
||||||
echo "error";
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmt->close();
|
|
||||||
} else {
|
|
||||||
echo "error";
|
|
||||||
}
|
}
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
} else {
|
echo json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||||||
echo "error";
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
$idbookingclass = isset($_POST['idbookingclass']) ? (int) $_POST['idbookingclass'] : 0;
|
||||||
|
|
||||||
|
if ($idbookingclass <= 0) {
|
||||||
|
jsonOut(['success' => false, 'error' => 'ID prenotazione non valido.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("UPDATE bookingclass SET lostlesson = 'Y' WHERE idbookingclass = :id");
|
||||||
|
$stmt->execute([':id' => $idbookingclass]);
|
||||||
|
jsonOut(['success' => true]);
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
error_log('aggiorna_campo_lost error: ' . $ex->getMessage());
|
||||||
|
jsonOut(['success' => false, 'error' => 'Errore durante l\'aggiornamento.']);
|
||||||
|
}
|
||||||
|
|||||||
+196
-230
@@ -1,96 +1,68 @@
|
|||||||
<?php require_once('include/headscript.php'); ?>
|
|
||||||
<?php
|
<?php
|
||||||
// Creazione della connessione
|
require_once('include/headscript.php');
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
|
||||||
|
|
||||||
// Verifica della connessione
|
/**
|
||||||
if ($conn->connect_error) {
|
* Vista admin di tutti i certificati caricati dagli utenti,
|
||||||
die("Connessione fallita: " . $conn->connect_error);
|
* con DataTables per ricerca e ordinamento.
|
||||||
}
|
*/
|
||||||
if (isset($_GET['message'])) {
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
$message = $_GET['message'];
|
|
||||||
} else {
|
|
||||||
$message = 'n';
|
|
||||||
}
|
|
||||||
// ID dell'insegnante
|
|
||||||
$idTeacher = 1;
|
|
||||||
|
|
||||||
// Controlla se il form è stato inviato
|
function e($value): string
|
||||||
if (isset($_POST['submit'])) {
|
{
|
||||||
// Recupera la data dal form
|
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
|
||||||
$dayoffdate = $_POST['dayoff'];
|
|
||||||
|
|
||||||
// Query SQL per l'inserimento del day off
|
|
||||||
$insertQuery = "INSERT INTO dayoff (idteacher, dayoffdate) VALUES ($idTeacher, '$dayoffdate')";
|
|
||||||
|
|
||||||
// Esegui la query di inserimento
|
|
||||||
if ($conn->query($insertQuery) === TRUE) {
|
|
||||||
echo "Inserimento riuscito!";
|
|
||||||
} else {
|
|
||||||
echo "Errore nell'inserimento: " . $conn->error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query SQL
|
function initials(string $first, string $last): string
|
||||||
$query = "SELECT * FROM certificateuserprofile LEFT JOIN auth_users ON certificateuserprofile.iduser=auth_users.id ORDER BY auth_users.last_name";
|
{
|
||||||
|
$ini = strtoupper(mb_substr(trim($first), 0, 1) . mb_substr(trim($last), 0, 1));
|
||||||
// Esecuzione della query
|
return $ini !== '' ? $ini : '?';
|
||||||
$result = $conn->query($query);
|
|
||||||
|
|
||||||
// Recupero delle date di permesso
|
|
||||||
$documents = [];
|
|
||||||
if ($result->num_rows > 0) {
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
$documents[] = $row;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function avatarColor(string $seed): string
|
||||||
|
{
|
||||||
|
$palette = ['#1ebf73', '#2980b9', '#8e44ad', '#e67e22', '#16a085', '#c0392b', '#2c3e50', '#d35400'];
|
||||||
|
return $palette[abs(crc32($seed)) % count($palette)];
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = $_GET['message'] ?? 'n';
|
||||||
|
|
||||||
|
// Elenco certificati con dati utente
|
||||||
|
$sql = "SELECT certificateuserprofile.*, auth_users.first_name, auth_users.last_name
|
||||||
|
FROM certificateuserprofile
|
||||||
|
LEFT JOIN auth_users ON certificateuserprofile.iduser = auth_users.id
|
||||||
|
ORDER BY auth_users.last_name, auth_users.first_name";
|
||||||
|
$documents = $pdo->query($sql)->fetchAll();
|
||||||
|
|
||||||
|
// Determina se un certificato è scaduto (per evidenziarlo)
|
||||||
|
$today = date('Y-m-d');
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="it">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>YogiBook - Prenotazioni YogaSoul</title>
|
<title>YogiBook - Certificati (admin)</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta content="YogiBook - Prenotazione facile YogaSOul" name="description" />
|
<meta content="YogiBook - Prenotazione facile YogaSoul" name="description" />
|
||||||
<meta content="Advanced Creative Solutions" name="author" />
|
<meta content="Advanced Creative Solutions" name="author" />
|
||||||
<!-- App favicon -->
|
|
||||||
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
||||||
|
|
||||||
<!-- Bootstrap Css -->
|
|
||||||
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
||||||
<!-- Icons Css -->
|
|
||||||
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
||||||
<!-- App Css-->
|
|
||||||
<link href="assets/css/app.min.css" id="app-style" rel="stylesheet" type="text/css" />
|
<link href="assets/css/app.min.css" id="app-style" 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">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||||
|
|
||||||
<!-- DataTables CSS -->
|
|
||||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/dataTables.bootstrap5.min.css">
|
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/dataTables.bootstrap5.min.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
|
||||||
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
|
||||||
<!-- DataTables JS -->
|
|
||||||
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
|
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="https://cdn.datatables.net/1.11.5/js/dataTables.bootstrap5.min.js"></script>
|
<script src="https://cdn.datatables.net/1.11.5/js/dataTables.bootstrap5.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
$("#expiryDate").datepicker({
|
|
||||||
dateFormat: "yy-mm-dd",
|
|
||||||
minDate: 0,
|
|
||||||
});
|
|
||||||
$("#dayoff").datepicker({
|
|
||||||
dateFormat: "yy-mm-dd"
|
|
||||||
});
|
|
||||||
// Initialize DataTables
|
|
||||||
$('#certificateTable').DataTable({
|
$('#certificateTable').DataTable({
|
||||||
"language": {
|
"language": {
|
||||||
"url": "//cdn.datatables.net/plug-ins/1.11.5/i18n/it-IT.json"
|
"url": "//cdn.datatables.net/plug-ins/1.11.5/i18n/it-IT.json"
|
||||||
},
|
},
|
||||||
"pageLength": 100,
|
"pageLength": 50,
|
||||||
"order": [
|
"order": [
|
||||||
[0, "asc"]
|
[0, "asc"]
|
||||||
]
|
]
|
||||||
@@ -100,12 +72,12 @@ if ($result->num_rows > 0) {
|
|||||||
function confirmDelete(id) {
|
function confirmDelete(id) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: "Sei sicuro?",
|
title: "Sei sicuro?",
|
||||||
text: "Questo certificato verrà cancellato definitivamente!",
|
text: "Questo certificato verrà cancellato definitivamente.",
|
||||||
icon: "warning",
|
icon: "warning",
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: "#d33",
|
confirmButtonColor: "#d33",
|
||||||
cancelButtonColor: "#3085d6",
|
cancelButtonColor: "#3085d6",
|
||||||
confirmButtonText: "Sì, cancella!",
|
confirmButtonText: "Sì, cancella",
|
||||||
cancelButtonText: "Annulla"
|
cancelButtonText: "Annulla"
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
@@ -114,212 +86,206 @@ if ($result->num_rows > 0) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.custom-card {
|
.admin-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;
|
border: none;
|
||||||
padding: 8px 12px;
|
border-radius: 14px;
|
||||||
border-radius: 4px;
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-action-button:hover {
|
.admin-card .card-body {
|
||||||
background-color: #e0e0e0;
|
padding: 26px 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
.section-title {
|
||||||
.custom-card {
|
font-size: 15px;
|
||||||
flex-direction: column;
|
font-weight: 700;
|
||||||
}
|
letter-spacing: 0.04em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.custom-date-box,
|
.section-lead {
|
||||||
.custom-event-details {
|
color: #9ca3af;
|
||||||
width: 100%;
|
font-size: 14px;
|
||||||
border-radius: 0;
|
margin-bottom: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-event-time {
|
#certificateTable thead th {
|
||||||
font-size: 24px;
|
font-size: 12px;
|
||||||
}
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
#certificateTable td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-chip {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-ok {
|
||||||
|
background: #e3f2ec;
|
||||||
|
color: #1a7f52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-expired {
|
||||||
|
background: #fdecec;
|
||||||
|
color: #c0392b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
color: #1ebf73;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- 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">Certificati</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'); ?>
|
||||||
<div class="dropdown d-inline-block">
|
<?php include('include/profiletopbar.php'); ?>
|
||||||
<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>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<?php include('include/profiletopbar.php'); ?>
|
|
||||||
</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>
|
||||||
<div class="d-flex"></div>
|
</div>
|
||||||
<div class="topnav">
|
<div class="topnav">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<nav class="navbar navbar-light navbar-expand-lg topnav-menu"></nav>
|
<nav class="navbar navbar-light navbar-expand-lg topnav-menu"></nav>
|
||||||
</div>
|
</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">
|
<?php if ($message === 'success') : ?>
|
||||||
<div class="row">
|
<div class="alert alert-success" role="alert">Certificato rimosso con successo.</div>
|
||||||
<div class="col-xl-12">
|
<?php endif; ?>
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
<div class="row">
|
||||||
<?php if ($message == 'success') { ?>
|
<div class="col-12">
|
||||||
<div class="alert alert-success" role="alert">
|
<div class="card admin-card">
|
||||||
Certificato rimosso con successo
|
<div class="card-body">
|
||||||
</div>
|
<div class="section-title">Certificati caricati</div>
|
||||||
<?php } ?>
|
<p class="section-lead">Ciao <?php echo e($firstname); ?>, qui trovi tutti i certificati medici caricati dagli utenti.</p>
|
||||||
<h5>Benvenuta/o <?php echo $firstname; ?> </h5>
|
|
||||||
<p>Certificati</p>
|
<div class="table-responsive">
|
||||||
<div class="table-responsive">
|
<table id="certificateTable" class="table table-striped">
|
||||||
<table id="certificateTable" class="table table-striped mb-0">
|
<thead>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Nome</th>
|
|
||||||
<th>Scadenza</th>
|
|
||||||
<th>Data Caricamento</th>
|
|
||||||
<th>Documento</th>
|
|
||||||
<th>Azione</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($documents as $document) { ?>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo $document["first_name"]; ?> <?php echo $document["last_name"]; ?></td>
|
<th>Utente</th>
|
||||||
<td><?php echo $document["expirydatedocument"]; ?></td>
|
<th>Descrizione</th>
|
||||||
<td><?php echo $document["uploaded_at"] ?? 'N/D'; ?></td>
|
<th>Scadenza</th>
|
||||||
<td><a href="user/document/<?php echo $document["filenamedocument"]; ?>" target="_blank">DOC</a></td>
|
<th>Caricato il</th>
|
||||||
<td>
|
<th>Documento</th>
|
||||||
<button class="btn btn-danger btn-sm" onclick="confirmDelete(<?php echo $document['idcertificateuserprofile']; ?>)">
|
<th>Azione</th>
|
||||||
<i class="fas fa-trash"></i> Cancella
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<?php } ?>
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
<?php foreach ($documents as $d) :
|
||||||
|
$fullName = trim($d['first_name'] . ' ' . $d['last_name']);
|
||||||
|
$idc = (int) $d['idcertificateuserprofile'];
|
||||||
|
$expTs = strtotime($d['expirydatedocument']);
|
||||||
|
$isExpired = $expTs && date('Y-m-d', $expTs) < $today;
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="user-cell">
|
||||||
|
<div class="avatar" style="background: <?php echo avatarColor($fullName); ?>;">
|
||||||
|
<?php echo e(initials($d['first_name'] ?? '', $d['last_name'] ?? '')); ?>
|
||||||
|
</div>
|
||||||
|
<span class="user-name"><?php echo e($fullName); ?></span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td><?php echo e($d['documentdescription']); ?></td>
|
||||||
|
<td>
|
||||||
|
<span class="exp-chip <?php echo $isExpired ? 'exp-expired' : 'exp-ok'; ?>">
|
||||||
|
<?php echo e($d['expirydatedocument']); ?>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td><?php echo e($d['uploaded_at'] ?? 'N/D'); ?></td>
|
||||||
|
<td>
|
||||||
|
<a class="doc-link" href="user/document/<?php echo e(rawurlencode($d['filenamedocument'])); ?>" target="_blank" rel="noopener">
|
||||||
|
<i class="fas fa-file-arrow-down"></i> Apri
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger btn-sm" onclick="confirmDelete(<?php echo $idc; ?>)">
|
||||||
|
<i class="fas fa-trash"></i> Cancella
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- container-fluid -->
|
<?php include('include/footer.php'); ?>
|
||||||
</div>
|
</div>
|
||||||
<!-- End Page-content -->
|
|
||||||
<?php include('include/footer.php'); ?>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- end main content-->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- END layout-wrapper -->
|
|
||||||
<!-- JAVASCRIPT -->
|
|
||||||
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></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/metismenujs/metismenujs.min.js"></script>
|
||||||
<script src="assets/libs/simplebar/simplebar.min.js"></script>
|
<script src="assets/libs/simplebar/simplebar.min.js"></script>
|
||||||
|
|||||||
+713
-351
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
// Buffer per scartare eventuale HTML degli include: risposta JSON pulita
|
||||||
ob_start();
|
ob_start();
|
||||||
require_once('include/headscript.php');
|
require_once('include/headscript.php');
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
|
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
/**
|
||||||
if ($conn->connect_error) {
|
* Restituisce l'elenco delle classi schedulate con posti occupati,
|
||||||
ob_end_clean();
|
* per la tendina di riprogrammazione. Risposta JSON.
|
||||||
echo json_encode(['error' => 'Connessione al database fallita: ' . $conn->connect_error]);
|
*/
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
|
function jsonOut(array $payload): void
|
||||||
|
{
|
||||||
|
if (ob_get_length() !== false) {
|
||||||
|
ob_end_clean();
|
||||||
|
}
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
echo json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = "SELECT
|
try {
|
||||||
ss.idserviceschedule,
|
$sql = "SELECT
|
||||||
s.servicename,
|
ss.idserviceschedule,
|
||||||
COALESCE(s.maxcapacity, 0) AS maxcapacity,
|
s.servicename,
|
||||||
DATE_FORMAT(ss.dateschedule, '%d %M %Y %H:%i') AS display_dateschedule,
|
COALESCE(s.maxcapacity, 0) AS maxcapacity,
|
||||||
DATE_FORMAT(ss.dateschedule, '%Y-%m-%d %H:%i') AS iso_dateschedule,
|
DATE_FORMAT(ss.dateschedule, '%d %M %Y %H:%i') AS display_dateschedule,
|
||||||
(SELECT COUNT(*)
|
DATE_FORMAT(ss.dateschedule, '%Y-%m-%d %H:%i') AS iso_dateschedule,
|
||||||
FROM bookingclass bc
|
(SELECT COUNT(*)
|
||||||
WHERE bc.idserviceschedule = ss.idserviceschedule
|
FROM bookingclass bc
|
||||||
AND bc.status != 'cancelled') AS occupied_seats
|
WHERE bc.idserviceschedule = ss.idserviceschedule
|
||||||
FROM serviceschedule ss
|
AND bc.status != 'cancelled') AS occupied_seats
|
||||||
LEFT JOIN service s ON ss.idservice = s.idservice
|
FROM serviceschedule ss
|
||||||
ORDER BY ss.dateschedule ASC";
|
LEFT JOIN service s ON ss.idservice = s.idservice
|
||||||
|
ORDER BY ss.dateschedule ASC";
|
||||||
|
|
||||||
$result = $conn->query($query);
|
$rows = $pdo->query($sql)->fetchAll();
|
||||||
|
|
||||||
$classes = [];
|
|
||||||
if ($result) {
|
|
||||||
$italianMonths = [
|
$italianMonths = [
|
||||||
'January' => 'Gennaio',
|
'January' => 'Gennaio',
|
||||||
'February' => 'Febbraio',
|
'February' => 'Febbraio',
|
||||||
@@ -40,27 +48,24 @@ if ($result) {
|
|||||||
'September' => 'Settembre',
|
'September' => 'Settembre',
|
||||||
'October' => 'Ottobre',
|
'October' => 'Ottobre',
|
||||||
'November' => 'Novembre',
|
'November' => 'Novembre',
|
||||||
'December' => 'Dicembre'
|
'December' => 'Dicembre',
|
||||||
];
|
];
|
||||||
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
$classes = [];
|
||||||
// Traduci il mese in italiano
|
foreach ($rows as $row) {
|
||||||
foreach ($italianMonths as $en => $it) {
|
// Traduci il mese in italiano nella data leggibile
|
||||||
$row['display_dateschedule'] = str_replace($en, $it, $row['display_dateschedule']);
|
$row['display_dateschedule'] = strtr($row['display_dateschedule'], $italianMonths);
|
||||||
}
|
|
||||||
|
|
||||||
// Assicura che maxcapacity sia positivo
|
// Assicura maxcapacity positivo (fallback)
|
||||||
if ($row['maxcapacity'] <= 0) {
|
if ((int) $row['maxcapacity'] <= 0) {
|
||||||
$row['maxcapacity'] = 1; // Valore positivo di fallback, cambialo se necessario
|
$row['maxcapacity'] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$classes[] = $row;
|
$classes[] = $row;
|
||||||
}
|
}
|
||||||
ob_end_clean();
|
|
||||||
echo json_encode(['classes' => $classes]);
|
|
||||||
} else {
|
|
||||||
ob_end_clean();
|
|
||||||
echo json_encode(['error' => 'Errore nella query: ' . $conn->error]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$conn->close();
|
jsonOut(['classes' => $classes]);
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
error_log('get_available_classes error: ' . $ex->getMessage());
|
||||||
|
jsonOut(['error' => 'Errore durante il recupero delle lezioni.']);
|
||||||
|
}
|
||||||
|
|||||||
+129
-171
@@ -1,185 +1,143 @@
|
|||||||
<!-- ========== Left Sidebar Start ========== -->
|
<!-- ========== Left Sidebar Start ========== -->
|
||||||
<div class="vertical-menu">
|
<div class="vertical-menu">
|
||||||
|
|
||||||
<!-- LOGO -->
|
<!-- LOGO -->
|
||||||
<div class="navbar-brand-box">
|
<div class="navbar-brand-box">
|
||||||
<a href="index.html" class="logo logo-dark">
|
<a href="index.html" class="logo logo-dark">
|
||||||
<span class="logo-sm">
|
<span class="logo-sm">
|
||||||
<img src="assets/images/logo-dark-sm.png" alt="" height="30">
|
<img src="assets/images/logo-dark-sm.png" alt="" height="30">
|
||||||
</span>
|
</span>
|
||||||
<span class="logo-lg">
|
<span class="logo-lg">
|
||||||
<img src="assets/images/logo-dark.png" alt="" height="32">
|
<img src="assets/images/logo-dark.png" alt="" height="32">
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="index.html" class="logo logo-light">
|
<a href="index.html" class="logo logo-light">
|
||||||
<span class="logo-lg">
|
<span class="logo-lg">
|
||||||
<img src="assets/images/logo-light.png" alt="" height="30">
|
<img src="assets/images/logo-light.png" alt="" height="30">
|
||||||
</span>
|
</span>
|
||||||
<span class="logo-sm">
|
<span class="logo-sm">
|
||||||
<img src="assets/images/logo-light-sm.png" alt="" height="26">
|
<img src="assets/images/logo-light-sm.png" alt="" height="26">
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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>
|
||||||
|
|
||||||
<div data-simplebar class="sidebar-menu-scroll">
|
<div data-simplebar class="sidebar-menu-scroll">
|
||||||
|
|
||||||
<!--- Sidemenu -->
|
<!--- Sidemenu -->
|
||||||
<div id="sidebar-menu">
|
<div id="sidebar-menu">
|
||||||
<!-- Left Menu Start -->
|
<!-- Left Menu Start -->
|
||||||
<ul class="metismenu list-unstyled" id="side-menu">
|
<ul class="metismenu list-unstyled" id="side-menu">
|
||||||
<li class="menu-title" data-key="t-menu">Dashboard</li>
|
|
||||||
|
|
||||||
|
<li class="menu-title" data-key="t-menu">Dashboard</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="userpanel.php" class="">
|
||||||
|
<i class="bx bx-calendar-event icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Prenotazioni</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="orders.php" class="">
|
||||||
|
<i class="bx bx-detail icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Ordini</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="menu-title" data-key="t-applications">Profilo Utente</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="userprofile.php" class="">
|
||||||
|
<i class="bx bx-user-circle icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Profilo utente</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="options.php" class="">
|
||||||
|
<i class="bx bx-cog icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Opzioni</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="userprofiledoc.php" class="">
|
||||||
|
<i class="bx bxs-file-doc icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Certificati</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<?php if (Auth::user()->hasRole('Admin')): ?>
|
||||||
|
<li class="menu-title" data-key="t-applications">Amministrazione</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a href="userpanel.php" class="">
|
<a href="admin-services.php" class="">
|
||||||
<i class="bx bx-calendar-event icon nav-icon"></i>
|
<i class="bx bx-edit-alt icon nav-icon"></i>
|
||||||
<span class="menu-item" data-key="t-email">Prenotazioni</span>
|
<span class="menu-item" data-key="t-email">Servizi</span>
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="adminpanel.php" class="">
|
||||||
|
<i class="bx bxs-school icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Classi</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="pendingbookedclass.php" class="">
|
||||||
|
<i class="bx bx-time-five icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Pending/Waiting</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="dayoff.php" class="">
|
||||||
|
<i class="bx bx-power-off icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Day Off</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="orderbooklist.php" class="">
|
||||||
|
<i class="bx bx-list-check icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Order Pending</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="certificati.php" class="">
|
||||||
|
<i class="bx bx-certification icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Certificati</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="situationusers.php" class="">
|
||||||
|
<i class="bx bx-bar-chart-alt-2 icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Situazione</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="ordersummary.php" class="">
|
||||||
|
<i class="bx bx-receipt icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-email">Sommario Ordini</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
</li>
|
<li class="menu-title" data-key="t-applications">Template</li>
|
||||||
<li>
|
|
||||||
<a href="orders.php" class="">
|
|
||||||
<i class="bx bx-detail icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Ordini</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
<li>
|
||||||
|
<a href="javascript: void(0);" class="has-arrow">
|
||||||
|
<i class="bx bx-table icon nav-icon"></i>
|
||||||
|
<span class="menu-item" data-key="t-tables">Tables</span>
|
||||||
|
</a>
|
||||||
|
<ul class="sub-menu" aria-expanded="false">
|
||||||
|
<li><a href="copiaintegra/dist/tables-basic.html" data-key="t-basic-tables">Basic Tables</a></li>
|
||||||
|
<li><a href="copiaintegra/dist/tables-advanced.html" data-key="t-advanced-tables">Advance Tables</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<li class="menu-title" data-key="t-applications">Profilo Utente</li>
|
</ul>
|
||||||
|
</div>
|
||||||
<li>
|
<!-- Sidebar -->
|
||||||
<a href="userprofile.php" class="">
|
</div>
|
||||||
<i class="bx bx-user-circle icon nav-icon"></i>
|
</div>
|
||||||
<span class="menu-item" data-key="t-email">Profilo utente</span>
|
<!-- Left Sidebar End -->
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="options.php" class="">
|
|
||||||
<i class="bx bx-user-circle icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Opzioni</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="userprofiledoc.php" class="">
|
|
||||||
<i class="bx bxs-file-doc icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Certificati</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<?php if (Auth::user()->hasRole('Admin')): ?>
|
|
||||||
<li class="menu-title" data-key="t-applications">Amministrazione</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="admin-services.php" class="">
|
|
||||||
<i class="bx bx-edit-alt icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Servizi</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="adminpanel.php" class="">
|
|
||||||
<i class="bx bxs-school icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Classi</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="pendingbookedclass.php" class="">
|
|
||||||
<i class="bx bx-skip-next icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Pending/Waiting</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="dayoff.php" class="">
|
|
||||||
<i class="bx bx-power-off icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Day Off</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="orderbooklist.php" class="">
|
|
||||||
<i class="bx bx-power-off icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Order Pending</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="certificati.php" class="">
|
|
||||||
<i class="bx bx-power-off icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Certificati</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="situationusers.php" class="">
|
|
||||||
<i class="bx bx-power-off icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Situazione</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="ordersummary.php" class="">
|
|
||||||
<i class="bx bx-power-off icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-email">Sommario Ordini</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li class="menu-title" data-key="t-applications">Template</li>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="javascript: void(0);" class="has-arrow">
|
|
||||||
<i class="bx bx-table icon nav-icon"></i>
|
|
||||||
<span class="menu-item" data-key="t-tables">Tables</span>
|
|
||||||
</a>
|
|
||||||
<ul class="sub-menu" aria-expanded="false">
|
|
||||||
<li><a href="copiaintegra/dist/tables-basic.html" data-key="t-basic-tables">Basic Tables</a></li>
|
|
||||||
<li><a href="copiaintegra/dist/tables-advanced.html" data-key="t-advanced-tables">Advance Tables</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<!-- Sidebar -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Left Sidebar End -->
|
|
||||||
+90
-56
@@ -1,63 +1,97 @@
|
|||||||
<?php
|
<?php
|
||||||
// Connessione al database (assicurati di avere le tue credenziali)
|
require_once('include/headscript.php');
|
||||||
include('Connections/bkngstm.php');
|
|
||||||
|
|
||||||
ini_set('display_errors', '1');
|
/**
|
||||||
ini_set('display_startup_errors', '1');
|
* Inserisce un partecipante in una classe (bookingclass).
|
||||||
error_reporting(E_ALL);
|
* Se l'utente non esiste ancora (userid mancante), lo crea in auth_users
|
||||||
// Crea una connessione al database
|
* riusando un eventuale account con la stessa email. Tutto in transazione.
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
*/
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
// Verifica la connessione al database
|
// --- Input ---
|
||||||
if ($conn->connect_error) {
|
$name = trim($_POST['name'] ?? '');
|
||||||
die("Connessione al database fallita: " . $conn->connect_error);
|
$surname = trim($_POST['surname'] ?? '');
|
||||||
}
|
$email = trim($_POST['email'] ?? '');
|
||||||
|
$userid = isset($_POST['userid']) ? (int) $_POST['userid'] : 0;
|
||||||
|
$idserviceschedule = isset($_POST['idserviceschedule']) ? (int) $_POST['idserviceschedule'] : 0;
|
||||||
|
$status = trim($_POST['status'] ?? 'booked');
|
||||||
|
$idorder = isset($_POST['idorder']) ? (int) $_POST['idorder'] : 0;
|
||||||
|
$idservice = isset($_POST['idservice']) ? (int) $_POST['idservice'] : 0;
|
||||||
|
$bookingstart = trim($_POST['bookingstart'] ?? '');
|
||||||
|
|
||||||
// Ottieni i dati dal form
|
// --- Validazione minima ---
|
||||||
$name = $_POST["name"];
|
if ($idserviceschedule <= 0 || $idservice <= 0) {
|
||||||
$surname = $_POST["surname"];
|
header('Location: adminpanel.php?error=missingdata');
|
||||||
$email = $_POST["email"];
|
|
||||||
$userid = $_POST["userid"];
|
|
||||||
$idserviceschedule = $_POST["idserviceschedule"];
|
|
||||||
$status = $_POST["status"];
|
|
||||||
$idorder = $_POST["idorder"];
|
|
||||||
$idservice = $_POST["idservice"];
|
|
||||||
$bookingstart = $_POST["bookingstart"];
|
|
||||||
|
|
||||||
// Se $userid non esiste o è 0, inserisci prima nella tabella auth_users
|
|
||||||
if (!$userid || $userid == 0) {
|
|
||||||
$password = "YogiBook159";
|
|
||||||
$role_id = 2;
|
|
||||||
$user_status = "Active";
|
|
||||||
$created_at = date('Y-m-d H:i:s'); // Data e ora attuali
|
|
||||||
$avatar = "mediationb.png";
|
|
||||||
|
|
||||||
$sql_user = "INSERT INTO auth_users (first_name, last_name, email, password, role_id, status, created_at, avatar)
|
|
||||||
VALUES ('$name', '$surname', '$email', '$password', '$role_id', '$user_status', '$created_at', '$avatar')";
|
|
||||||
|
|
||||||
|
|
||||||
if ($conn->query($sql_user) === TRUE) {
|
|
||||||
$userid = $conn->insert_id; // Ottieni l'ID dell'ultimo record inserito
|
|
||||||
} else {
|
|
||||||
// In caso di errore, gestiscilo appropriatamente
|
|
||||||
echo "Errore durante l'inserimento dell'utente: " . $conn->error;
|
|
||||||
$conn->close();
|
|
||||||
exit; // Termina lo script se c'è stato un errore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Esegui la query per inserire il record nella tabella "bookingclass"
|
|
||||||
$sql = "INSERT INTO bookingclass (iduser, idserviceschedule, status, idorder, idservice, bookingstart)
|
|
||||||
VALUES ('$userid', '$idserviceschedule', '$status', '$idorder', '$idservice', '$bookingstart')";
|
|
||||||
|
|
||||||
if ($conn->query($sql) === TRUE) {
|
|
||||||
// Inserimento riuscito, reindirizza l'utente a "adminpanel.php"
|
|
||||||
header("Location: adminpanel.php");
|
|
||||||
exit;
|
exit;
|
||||||
} else {
|
|
||||||
// In caso di errore, gestiscilo appropriatamente
|
|
||||||
echo "Errore durante l'inserimento del record: " . $conn->error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chiudi la connessione al database
|
try {
|
||||||
$conn->close();
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
// Se non abbiamo un userid valido, dobbiamo risolvere/creare l'utente
|
||||||
|
if ($userid <= 0) {
|
||||||
|
|
||||||
|
// 1) Se è stata fornita un'email, controlliamo se l'utente esiste già
|
||||||
|
if ($email !== '') {
|
||||||
|
$check = $pdo->prepare("SELECT id FROM auth_users WHERE email = :email LIMIT 1");
|
||||||
|
$check->execute([':email' => $email]);
|
||||||
|
$existing = $check->fetchColumn();
|
||||||
|
if ($existing) {
|
||||||
|
$userid = (int) $existing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Se ancora non c'è, creiamo un nuovo utente
|
||||||
|
if ($userid <= 0) {
|
||||||
|
// Password casuale hashata (questi account non usano una password condivisa)
|
||||||
|
$randomPassword = bin2hex(random_bytes(8));
|
||||||
|
$hashed = password_hash($randomPassword, PASSWORD_BCRYPT);
|
||||||
|
|
||||||
|
$insUser = $pdo->prepare(
|
||||||
|
"INSERT INTO auth_users
|
||||||
|
(first_name, last_name, email, password, role_id, status, created_at, avatar)
|
||||||
|
VALUES
|
||||||
|
(:first, :last, :email, :password, :role, :status, :created, :avatar)"
|
||||||
|
);
|
||||||
|
$insUser->execute([
|
||||||
|
':first' => $name,
|
||||||
|
':last' => $surname,
|
||||||
|
':email' => $email !== '' ? $email : null,
|
||||||
|
':password' => $hashed,
|
||||||
|
':role' => 2,
|
||||||
|
':status' => 'Active',
|
||||||
|
':created' => date('Y-m-d H:i:s'),
|
||||||
|
':avatar' => 'mediationb.png',
|
||||||
|
]);
|
||||||
|
$userid = (int) $pdo->lastInsertId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Inserimento della prenotazione
|
||||||
|
$insBooking = $pdo->prepare(
|
||||||
|
"INSERT INTO bookingclass
|
||||||
|
(iduser, idserviceschedule, status, idorder, idservice, bookingstart)
|
||||||
|
VALUES
|
||||||
|
(:iduser, :idschedule, :status, :idorder, :idservice, :bookingstart)"
|
||||||
|
);
|
||||||
|
$insBooking->execute([
|
||||||
|
':iduser' => $userid,
|
||||||
|
':idschedule' => $idserviceschedule,
|
||||||
|
':status' => $status,
|
||||||
|
':idorder' => $idorder,
|
||||||
|
':idservice' => $idservice,
|
||||||
|
':bookingstart' => $bookingstart !== '' ? $bookingstart : null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
header('Location: adminpanel.php?success=added');
|
||||||
|
exit;
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
if ($pdo->inTransaction()) {
|
||||||
|
$pdo->rollBack();
|
||||||
|
}
|
||||||
|
error_log('inserisci_record error: ' . $ex->getMessage());
|
||||||
|
header('Location: adminpanel.php?error=insert');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|||||||
+383
-311
@@ -1,195 +1,222 @@
|
|||||||
<?php require_once('include/headscript.php'); ?>
|
|
||||||
<?php
|
<?php
|
||||||
$conn = mysqli_connect($servername, $username, $password, $dbname);
|
require_once('include/headscript.php');
|
||||||
// Verifica la connessione
|
|
||||||
if (!$conn) {
|
/**
|
||||||
die("Connessione al database fallita: " . mysqli_connect_error());
|
* Gestione ordini in stato "pending": elenco, propagazione (con calcolo
|
||||||
|
* scadenza), cancellazione e inserimento manuale di un nuovo ordine.
|
||||||
|
* orderbook contiene già first_name, last_name, cod, ecc.
|
||||||
|
*/
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
|
function e($value): string
|
||||||
|
{
|
||||||
|
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
|
||||||
}
|
}
|
||||||
// Query SQL per ottenere le informazioni desiderate
|
|
||||||
$sql = "SELECT * from orderbook WHERE orderbook.status ='pending'";
|
function initials(string $first, string $last): string
|
||||||
$result = mysqli_query($conn, $sql);
|
{
|
||||||
// Verifica se la query ha restituito risultati
|
$ini = strtoupper(mb_substr(trim($first), 0, 1) . mb_substr(trim($last), 0, 1));
|
||||||
if (!$result) {
|
return $ini !== '' ? $ini : '?';
|
||||||
die("Errore nella query: " . mysqli_error($conn));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function avatarColor(string $seed): string
|
||||||
|
{
|
||||||
|
$palette = ['#1ebf73', '#2980b9', '#8e44ad', '#e67e22', '#16a085', '#c0392b', '#2c3e50', '#d35400'];
|
||||||
|
return $palette[abs(crc32($seed)) % count($palette)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ordini pending
|
||||||
|
$orders = $pdo->query("SELECT * FROM orderbook WHERE status = 'pending' ORDER BY order_date_created DESC")->fetchAll();
|
||||||
|
|
||||||
|
// Servizi per il dropdown del nuovo ordine
|
||||||
|
$services = $pdo->query("SELECT idservice, servicename, day, time FROM service ORDER BY servicename")->fetchAll();
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="it">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>YogiBook - Prenotazioni YogaSoul</title>
|
<title>YogiBook - Ordini in attesa</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta content="YogiBook - Prenotazione facile YogaSOul" name="description" />
|
<meta content="YogiBook - Prenotazione facile YogaSoul" name="description" />
|
||||||
<meta content="Advanced Creative Solutions" name="author" />
|
<meta content="Advanced Creative Solutions" name="author" />
|
||||||
<!-- App favicon -->
|
|
||||||
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
||||||
<!-- Bootstrap Css -->
|
|
||||||
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
||||||
<!-- Icons Css -->
|
|
||||||
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
||||||
<!-- App Css-->
|
|
||||||
<link href="assets/css/app.min.css" id="app-style" rel="stylesheet" type="text/css" />
|
<link href="assets/css/app.min.css" id="app-style" 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">
|
<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 rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$("#example-date-input, #first-lesson-date").datepicker({
|
|
||||||
dateFormat: "yy-mm-dd",
|
|
||||||
minDate: 0
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
console.log("Script loaded and running!");
|
|
||||||
$(".surname").on("input", function() {
|
|
||||||
var searchTerm = $(this).val();
|
|
||||||
var currentForm = $(this).closest('form');
|
|
||||||
if (searchTerm.length >= 2) {
|
|
||||||
$.ajax({
|
|
||||||
url: "search_users.php",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
searchTerm: searchTerm
|
|
||||||
},
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data) {
|
|
||||||
var results = data.results;
|
|
||||||
currentForm.next('.search-results').empty();
|
|
||||||
if (results.length > 0) {
|
|
||||||
currentForm.next('.search-results').append("<p>Seleziona un utente:</p>");
|
|
||||||
for (var i = 0; i < results.length; i++) {
|
|
||||||
var user = results[i];
|
|
||||||
currentForm.next('.search-results').append(
|
|
||||||
'<div class="user-result" data-email="' + user.email + '" data-userid="' + user.userid + '" data-firstname="' + user.first_name + '" data-lastname="' + user.last_name + '">' +
|
|
||||||
'Email: ' + user.email + ' | Nome: ' + user.first_name + ' | Cognome: ' + user.last_name +
|
|
||||||
'</div>'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
currentForm.next('.search-results').on('click', '.user-result', function() {
|
|
||||||
var selectedEmail = $(this).data("email");
|
|
||||||
var selectedUserId = $(this).data("userid");
|
|
||||||
var selectedFirstName = $(this).data("firstname");
|
|
||||||
var selectedLastName = $(this).data("lastname");
|
|
||||||
console.log("Email:", selectedEmail);
|
|
||||||
console.log("User ID:", selectedUserId);
|
|
||||||
console.log("First Name:", selectedFirstName);
|
|
||||||
console.log("Last Name:", selectedLastName);
|
|
||||||
currentForm.find(".email").val(selectedEmail);
|
|
||||||
currentForm.find(".userid").val(selectedUserId);
|
|
||||||
currentForm.find(".name").val(selectedFirstName);
|
|
||||||
currentForm.find(".surname").val(selectedLastName);
|
|
||||||
$("#userid").val(selectedUserId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
currentForm.next('.search-results').empty();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style>
|
<style>
|
||||||
.custom-card {
|
.admin-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;
|
border: none;
|
||||||
padding: 8px 12px;
|
border-radius: 14px;
|
||||||
border-radius: 4px;
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-card .card-body {
|
||||||
|
padding: 26px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-lead {
|
||||||
|
color: #9ca3af;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-table thead th {
|
||||||
|
font-size: 12px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
color: #6b7280;
|
||||||
|
border-bottom: 2px solid #eef0f3;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-table td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qty-pill {
|
||||||
|
display: inline-block;
|
||||||
|
background: #eef6f1;
|
||||||
|
color: #1a7f52;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 2px 10px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-propagate,
|
||||||
|
.btn-cancel {
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 7px 14px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.2s;
|
transition: filter 0.15s;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-action-button:hover {
|
.btn-propagate {
|
||||||
background-color: #e0e0e0;
|
background: #27ae60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
.btn-cancel {
|
||||||
.custom-card {
|
background: #e74c3c;
|
||||||
flex-direction: column;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.custom-date-box,
|
.btn-propagate:hover,
|
||||||
.custom-event-details {
|
.btn-cancel:hover {
|
||||||
width: 100%;
|
filter: brightness(0.93);
|
||||||
border-radius: 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.custom-event-time {
|
.form-label {
|
||||||
font-size: 24px;
|
font-weight: 600;
|
||||||
}
|
font-size: 14px;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control,
|
||||||
|
.form-select {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e2e4e9;
|
||||||
|
padding: 10px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus,
|
||||||
|
.form-select:focus {
|
||||||
|
border-color: #1ebf73;
|
||||||
|
box-shadow: 0 0 0 3px rgba(30, 191, 115, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-save {
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px 26px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-results {
|
||||||
|
border: 1px solid #e2e4e9;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 6px;
|
||||||
|
max-height: 220px;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: none;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-results.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-result {
|
||||||
|
padding: 10px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
border-bottom: 1px solid #f0f2f5;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-result:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-result:hover {
|
||||||
|
background: #eef6f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 10px;
|
||||||
|
color: #9ca3af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state i {
|
||||||
|
font-size: 34px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: block;
|
||||||
|
color: #d5d9e0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -204,26 +231,11 @@ if (!$result) {
|
|||||||
<i class="bx bx-menu align-middle"></i>
|
<i class="bx bx-menu align-middle"></i>
|
||||||
</button>
|
</button>
|
||||||
<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">Ordini in attesa</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<?php include('include/languageselection.php'); ?>
|
<?php include('include/languageselection.php'); ?>
|
||||||
<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>
|
||||||
@@ -239,44 +251,70 @@ if (!$result) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Elenco ordini pending -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xl-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card admin-card mb-4">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5>Benvenuta/o <?php echo $firstname; ?> </h5>
|
<div class="section-title">Ordini in attesa</div>
|
||||||
<p>Ordini Pending</p>
|
<p class="section-lead">Ciao <?php echo e($firstname); ?>, questi ordini sono in stato pending: propagali o cancellali.</p>
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped mb-0">
|
<table class="table order-table align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID Ordine</th>
|
<th>ID Ordine</th>
|
||||||
<th>Data</th>
|
<th>Data</th>
|
||||||
<th>Utente</th>
|
<th>Utente</th>
|
||||||
<th>Iduser</th>
|
<th>Classe</th>
|
||||||
<th>Class</th>
|
|
||||||
<th>Quantità</th>
|
<th>Quantità</th>
|
||||||
<th>Propaga</th>
|
<th class="text-end">Azioni</th>
|
||||||
<th>Cancella</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php if (empty($orders)) : ?>
|
||||||
while ($row = mysqli_fetch_assoc($result)) {
|
<tr>
|
||||||
echo "<tr>";
|
<td colspan="6">
|
||||||
echo "<td>" . $row['order_id'] . "</td>";
|
<div class="empty-state">
|
||||||
echo "<td>" . $row['order_date_created'] . "</td>";
|
<i class="fas fa-receipt"></i>
|
||||||
echo "<td>" . $row['first_name'] . " " . $row['last_name'] . "</td>";
|
Nessun ordine in attesa al momento.
|
||||||
echo "<td>" . $row['iduser'] . "</td>";
|
</div>
|
||||||
echo "<td>" . $row['cod'] . "</td>";
|
</td>
|
||||||
echo "<td>" . $row['quantityclass'] . "</td>";
|
</tr>
|
||||||
echo "<td><button type='button' class='btn btn-success waves-effect btn-label waves-light propagate-btn' data-idorder='" . $row['idorderbook'] . "'><i class='bx bx-check-double label-icon'></i> Propaga</button></td>";
|
<?php else : ?>
|
||||||
echo "<td>" . "<a href='cancelsingleorder.php?idorder=" . $row['idorderbook'] . "'><button type='button' class='btn btn-danger waves-effect waves-light'><i class='bx bx-block font-size-16 align-middle me-2'></i> Cancella</button></a>" . "</td>";
|
<?php foreach ($orders as $o) :
|
||||||
echo "</tr>";
|
$fullName = trim($o['first_name'] . ' ' . $o['last_name']);
|
||||||
}
|
$idorder = (int) $o['idorderbook'];
|
||||||
?>
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><strong><?php echo e($o['order_id']); ?></strong></td>
|
||||||
|
<td><?php echo e($o['order_date_created'] ? date('d-m-Y', strtotime($o['order_date_created'])) : '-'); ?></td>
|
||||||
|
<td>
|
||||||
|
<div class="user-cell">
|
||||||
|
<div class="avatar" style="background: <?php echo avatarColor($fullName); ?>;">
|
||||||
|
<?php echo e(initials($o['first_name'] ?? '', $o['last_name'] ?? '')); ?>
|
||||||
|
</div>
|
||||||
|
<span class="user-name"><?php echo e($fullName); ?></span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td><?php echo e($o['cod']); ?></td>
|
||||||
|
<td><span class="qty-pill"><?php echo e($o['quantityclass']); ?></span></td>
|
||||||
|
<td class="text-end">
|
||||||
|
<button type="button" class="btn-propagate propagate-btn" data-idorder="<?php echo $idorder; ?>">
|
||||||
|
<i class="bx bx-check-double"></i> Propaga
|
||||||
|
</button>
|
||||||
|
<a href="cancelsingleorder.php?idorder=<?php echo $idorder; ?>">
|
||||||
|
<button type="button" class="btn-cancel"><i class="bx bx-block"></i> Cancella</button>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -284,152 +322,186 @@ if (!$result) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Nuovo ordine -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xl-12">
|
<div class="col-12">
|
||||||
<div class="card">
|
<div class="card admin-card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5>Inserisci nuovo Ordine</h5>
|
<div class="section-title">Inserisci nuovo ordine</div>
|
||||||
<form action="inserisci_ordine.php" method="post">
|
<p class="section-lead">Cerca un utente esistente digitando il cognome, oppure inserisci i dati manualmente.</p>
|
||||||
|
|
||||||
|
<form action="inserisci_ordine.php" method="post" id="new-order-form">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label for="formrow-firstname-input" class="form-label">Enter First Name</label>
|
<label class="form-label">Nome</label>
|
||||||
<input type="text" class="form-control name" placeholder="First Name" id="formrow-firstname-input" name="formrow-firstname-input">
|
<input type="text" class="form-control name" placeholder="Nome" name="formrow-firstname-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label for="surname-input" class="form-label">Cognome</label>
|
<label class="form-label">Cognome</label>
|
||||||
<input list="users-suggestions" type="text" class="form-control surname" placeholder="Last Name" id="surname-input" name="surname-input">
|
<input type="text" class="form-control surname" placeholder="Cognome" name="surname-input" autocomplete="off">
|
||||||
|
<div class="search-results"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6 mb-3">
|
||||||
<div class="mb-3">
|
<label class="form-label">Email</label>
|
||||||
<label for="formrow-email-input" class="form-label">Enter Email</label>
|
<input type="email" class="form-control email" placeholder="Email" name="formrow-email-input">
|
||||||
<input type="email" class="form-control email" placeholder="Email" id="formrow-email-input" name="formrow-email-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6 mb-3">
|
||||||
<div class="mb-3">
|
<label class="form-label">Data ordine</label>
|
||||||
<label for="example-date-input" class="form-label">Data Ordine</label>
|
<input class="form-control" type="date" name="example-date-input">
|
||||||
<input class="form-control" type="date" value="" id="example-date-input" name="example-date-input">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-4 mb-3">
|
||||||
<div class="mb-3">
|
<label class="form-label">Data prima lezione</label>
|
||||||
<label for="first-lesson-date" class="form-label">Data Prima Lezione</label>
|
<input class="form-control" type="date" name="first-lesson-date">
|
||||||
<input class="form-control" type="date" value="" id="first-lesson-date" name="first-lesson-date">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-md-4 mb-3">
|
||||||
<div class="mb-3">
|
<label class="form-label">N. Ticket</label>
|
||||||
<label for="ticket" class="form-label">N. Ticket</label>
|
<input type="text" class="form-control" placeholder="Ticket" name="ticket">
|
||||||
<input type="text" class="form-control" placeholder="Ticket" id="ticket" name="ticket">
|
|
||||||
<input type="text" name="userid" id="userid" value="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-md-4 mb-3">
|
||||||
<div class="mb-3">
|
<label class="form-label">Classe</label>
|
||||||
<label for="formrow-inputState" class="form-label">Classe</label>
|
<select id="service-select" name="formrow-inputState" class="form-select">
|
||||||
<select id="formrow-inputState" name="formrow-inputState" class="form-select">
|
<option value="">Scegli...</option>
|
||||||
<?php
|
<?php foreach ($services as $svc) :
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
$label = trim($svc['servicename'] . ' - ' . $svc['day'] . ' - ' . $svc['time'], ' -');
|
||||||
if ($conn->connect_error) {
|
?>
|
||||||
die("Connection failed: " . $conn->connect_error);
|
<option value="<?php echo (int) $svc['idservice']; ?>"><?php echo e($label); ?></option>
|
||||||
}
|
<?php endforeach; ?>
|
||||||
$sql = "SELECT idservice, servicename, day, time FROM service ORDER BY servicename";
|
</select>
|
||||||
$result = $conn->query($sql);
|
<input type="hidden" name="cod" id="hiddenCod">
|
||||||
echo '<option selected="">Choose...</option>';
|
|
||||||
if ($result->num_rows > 0) {
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
$label = $row['servicename'] . ' - ' . $row['day'] . ' - ' . $row['time'];
|
|
||||||
$value = $row['idservice'];
|
|
||||||
echo "<option value='$value'>$label</option>";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo '<option>No services available</option>';
|
|
||||||
}
|
|
||||||
$conn->close();
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
<input type="hidden" name="cod" id="hiddenCod">
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
const selectElem = document.getElementById('formrow-inputState');
|
|
||||||
const hiddenElem = document.getElementById('hiddenCod');
|
|
||||||
selectElem.addEventListener('change', function() {
|
|
||||||
hiddenElem.value = selectElem.options[selectElem.selectedIndex].text;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<button type="submit" class="btn btn-primary w-md">Submit</button>
|
<input type="hidden" class="userid" name="userid" id="userid">
|
||||||
</div>
|
<button type="submit" class="btn btn-primary btn-save">Inserisci ordine</button>
|
||||||
</form>
|
</form>
|
||||||
<div class="search-results"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<?php include('include/footer.php'); ?>
|
<?php include('include/footer.php'); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
|
</div>
|
||||||
<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>
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('.propagate-btn').on('click', function() {
|
|
||||||
var idorder = $(this).data('idorder');
|
|
||||||
|
|
||||||
// Chiama AJAX per calcolare la scadenza
|
<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>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Salva il testo della classe scelta nel campo hidden 'cod'
|
||||||
|
const selectElem = document.getElementById('service-select');
|
||||||
|
const hiddenElem = document.getElementById('hiddenCod');
|
||||||
|
selectElem.addEventListener('change', function() {
|
||||||
|
hiddenElem.value = selectElem.options[selectElem.selectedIndex].text;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
// Ricerca utenti per cognome (e nome)
|
||||||
|
let searchTimeout;
|
||||||
|
$('.surname, .name').on('input', function() {
|
||||||
|
clearTimeout(searchTimeout);
|
||||||
|
var form = $(this).closest('form');
|
||||||
|
var results = form.find('.search-results');
|
||||||
|
var firstName = form.find('.name').val().trim();
|
||||||
|
var lastName = form.find('.surname').val().trim();
|
||||||
|
|
||||||
|
if (firstName.length < 2 && lastName.length < 2) {
|
||||||
|
results.removeClass('show').empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
searchTimeout = setTimeout(function() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'calculate_expiry.php',
|
url: 'search_users.php',
|
||||||
method: 'GET',
|
method: 'POST',
|
||||||
data: {
|
data: {
|
||||||
idorder: idorder
|
firstName: firstName,
|
||||||
|
lastName: lastName,
|
||||||
|
searchTerm: lastName
|
||||||
},
|
},
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
cache: false,
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
if (data.error) {
|
results.empty();
|
||||||
Swal.fire('Errore', data.error, 'error');
|
if (data.results && data.results.length > 0) {
|
||||||
return;
|
data.results.forEach(function(u) {
|
||||||
|
var uid = u.userid || u.id;
|
||||||
|
var ini = ((u.first_name || '').charAt(0) + (u.last_name || '').charAt(0)).toUpperCase();
|
||||||
|
results.append(
|
||||||
|
'<div class="user-result" data-email="' + u.email + '" data-userid="' + uid +
|
||||||
|
'" data-firstname="' + u.first_name + '" data-lastname="' + u.last_name + '">' +
|
||||||
|
'<span class="avatar" style="width:32px;height:32px;font-size:12px;background:#2980b9;">' + ini + '</span>' +
|
||||||
|
'<span><strong>' + u.first_name + ' ' + u.last_name + '</strong><br>' +
|
||||||
|
'<small style="color:#6b7280;">' + u.email + '</small></span></div>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
results.addClass('show');
|
||||||
|
results.find('.user-result').on('click', function() {
|
||||||
|
form.find('.email').val($(this).data('email'));
|
||||||
|
form.find('.userid').val($(this).data('userid'));
|
||||||
|
form.find('.name').val($(this).data('firstname'));
|
||||||
|
form.find('.surname').val($(this).data('lastname'));
|
||||||
|
results.removeClass('show').empty();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
results.append('<div class="user-result" style="color:#9ca3af;">Nessun utente trovato.</div>').addClass('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
var calculatedExpiry = data.expiry_date;
|
|
||||||
|
|
||||||
// Mostra modal di conferma
|
|
||||||
Swal.fire({
|
|
||||||
title: 'Conferma Scadenza',
|
|
||||||
html: `
|
|
||||||
<p>Data di scadenza calcolata: <strong>${calculatedExpiry}</strong></p>
|
|
||||||
<label for="expiry-date">Modifica scadenza (se necessario):</label>
|
|
||||||
<input type="date" id="expiry-date" class="swal2-input" value="${calculatedExpiry}">
|
|
||||||
`,
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonText: 'Conferma e Propaga',
|
|
||||||
cancelButtonText: 'Annulla',
|
|
||||||
preConfirm: () => {
|
|
||||||
return document.getElementById('expiry-date').value;
|
|
||||||
}
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
var expiryDate = result.value || calculatedExpiry; // Usa modificata o originale
|
|
||||||
window.location.href = `propagatesingleorder.php?idorder=${idorder}&expiry_date=${expiryDate}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
error: function() {
|
error: function() {
|
||||||
Swal.fire('Errore', 'Impossibile calcolare la scadenza', 'error');
|
results.html('<div class="user-result" style="color:#c0392b;">Errore durante la ricerca.</div>').addClass('show');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Propagazione ordine con calcolo scadenza
|
||||||
|
$('.propagate-btn').on('click', function() {
|
||||||
|
var idorder = $(this).data('idorder');
|
||||||
|
$.ajax({
|
||||||
|
url: 'calculate_expiry.php',
|
||||||
|
method: 'GET',
|
||||||
|
data: {
|
||||||
|
idorder: idorder
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
if (data.error) {
|
||||||
|
Swal.fire('Errore', data.error, 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var calculatedExpiry = data.expiry_date;
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Conferma Scadenza',
|
||||||
|
html: '<p>Data di scadenza calcolata: <strong>' + calculatedExpiry + '</strong></p>' +
|
||||||
|
'<label for="expiry-date">Modifica scadenza (se necessario):</label>' +
|
||||||
|
'<input type="date" id="expiry-date" class="swal2-input" value="' + calculatedExpiry + '">',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Conferma e Propaga',
|
||||||
|
cancelButtonText: 'Annulla',
|
||||||
|
preConfirm: () => document.getElementById('expiry-date').value
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
var expiryDate = result.value || calculatedExpiry;
|
||||||
|
window.location.href = 'propagatesingleorder.php?idorder=' + idorder + '&expiry_date=' + expiryDate;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
Swal.fire('Errore', 'Impossibile calcolare la scadenza', 'error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
+271
-292
@@ -1,330 +1,309 @@
|
|||||||
<?php require_once('include/headscript.php'); ?>
|
|
||||||
<?php // optionquery
|
|
||||||
$optionquery = new WA_MySQLi_RS("optionquery",$bkngstm,0);
|
|
||||||
$optionquery->setQuery("SELECT * FROM option");
|
|
||||||
$optionquery->execute();
|
|
||||||
?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// Crea la connessione al database
|
require_once('include/headscript.php');
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
|
||||||
|
|
||||||
// Verifica la connessione
|
/**
|
||||||
if ($conn->connect_error) {
|
* Pannello admin: prenotazioni in stato "pending" (richieste di
|
||||||
die("Connessione al database fallita: " . $conn->connect_error);
|
* riprogrammazione) da accettare o rifiutare.
|
||||||
|
*/
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
|
function e($value): string
|
||||||
|
{
|
||||||
|
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initials(string $first, string $last): string
|
||||||
|
{
|
||||||
// Query per selezionare i dati filtrati per iduser
|
$ini = strtoupper(mb_substr(trim($first), 0, 1) . mb_substr(trim($last), 0, 1));
|
||||||
$query = "SELECT bookingclass.status AS bookingclass_status, bookingclass.*, auth_users.*, service.*
|
return $ini !== '' ? $ini : '?';
|
||||||
FROM bookingclass
|
|
||||||
LEFT JOIN auth_users ON bookingclass.iduser = auth_users.id
|
|
||||||
LEFT JOIN service ON bookingclass.idservice = service.idservice
|
|
||||||
WHERE bookingclass.status = 'pending'";
|
|
||||||
$result = $conn->query($query);
|
|
||||||
|
|
||||||
// Array per memorizzare i risultati
|
|
||||||
$documents = array();
|
|
||||||
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
$documents[] = $row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function avatarColor(string $seed): string
|
||||||
|
{
|
||||||
|
$palette = ['#1ebf73', '#2980b9', '#8e44ad', '#e67e22', '#16a085', '#c0392b', '#2c3e50', '#d35400'];
|
||||||
|
return $palette[abs(crc32($seed)) % count($palette)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solo i campi che servono davvero (evita conflitti da SELECT *)
|
||||||
|
$sql = "SELECT bookingclass.idbookingclass, bookingclass.status AS booking_status,
|
||||||
|
bookingclass.prevbookingstart, bookingclass.bookingstart,
|
||||||
|
auth_users.first_name, auth_users.last_name,
|
||||||
|
service.servicename, service.day, service.time
|
||||||
|
FROM bookingclass
|
||||||
|
LEFT JOIN auth_users ON bookingclass.iduser = auth_users.id
|
||||||
|
LEFT JOIN service ON bookingclass.idservice = service.idservice
|
||||||
|
WHERE bookingclass.status = 'pending'
|
||||||
|
ORDER BY bookingclass.bookingstart";
|
||||||
|
$documents = $pdo->query($sql)->fetchAll();
|
||||||
|
|
||||||
|
$fmt = function ($dt) {
|
||||||
|
if (empty($dt)) return '-';
|
||||||
|
$ts = strtotime($dt);
|
||||||
|
return $ts ? date('d-m-Y H:i', $ts) : '-';
|
||||||
|
};
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="it">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>YogiBook - Prenotazioni in attesa</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" name="author" />
|
||||||
|
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
||||||
|
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="assets/css/app.min.css" id="app-style" 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@11"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
|
||||||
<meta charset="utf-8" />
|
<style>
|
||||||
<title>YogiBook - Prenotazioni YogaSoul</title>
|
.admin-card {
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
border: none;
|
||||||
<meta content="YogiBook - Prenotazione facile YogaSOul" name="description" />
|
border-radius: 14px;
|
||||||
<meta content="Advanced Creative Solutions" name="author" />
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
|
||||||
<!-- App favicon -->
|
|
||||||
<link rel="shortcut icon" href="assets/images/favicon.ico">
|
|
||||||
|
|
||||||
<!-- Bootstrap Css -->
|
|
||||||
<link href="assets/css/bootstrap.min.css" id="bootstrap-style" rel="stylesheet" type="text/css" />
|
|
||||||
<!-- Icons Css -->
|
|
||||||
<link href="assets/css/icons.min.css" rel="stylesheet" type="text/css" />
|
|
||||||
<!-- App Css-->
|
|
||||||
<link href="assets/css/app.min.css" id="app-style" 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>
|
|
||||||
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
||||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$("#expiryDate").datepicker({ dateFormat: "yy-mm-dd" });
|
|
||||||
});
|
|
||||||
</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 {
|
.admin-card .card-body {
|
||||||
width: 100%;
|
padding: 26px 30px;
|
||||||
border-radius: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-event-time {
|
.section-title {
|
||||||
font-size: 24px;
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
.section-lead {
|
||||||
<script>
|
color: #9ca3af;
|
||||||
function confirmDelete(id, deletePageUrl) {
|
font-size: 14px;
|
||||||
Swal.fire({
|
margin-bottom: 22px;
|
||||||
title: "Sei sicuro?",
|
|
||||||
text: "Questa prenotazione verrà cancellata definitivamente! Ricordati poi di riprogrammare la tua lezione!",
|
|
||||||
icon: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: "#d33",
|
|
||||||
cancelButtonColor: "#3085d6",
|
|
||||||
confirmButtonText: "Sì, cancella!",
|
|
||||||
cancelButtonText: "Annulla"
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
// Reindirizza direttamente alla pagina di cancellazione con l'ID come parametro.
|
|
||||||
window.location.href = `deleteclass.php?id=${id}`;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<body>
|
.pending-table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
<!-- <body data-layout="horizontal"> -->
|
.pending-table thead th {
|
||||||
|
font-size: 12px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
color: #6b7280;
|
||||||
|
border-bottom: 2px solid #eef0f3;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Begin page -->
|
.pending-table td {
|
||||||
<div id="layout-wrapper">
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Top Bar -->
|
.user-cell {
|
||||||
<header id="page-topbar" class="isvertical-topbar">
|
display: flex;
|
||||||
<div class="navbar-header">
|
align-items: center;
|
||||||
<div class="d-flex">
|
gap: 10px;
|
||||||
<!-- LOGO -->
|
}
|
||||||
<?php include('include/logoarea.php'); ?>
|
|
||||||
|
|
||||||
<button type="button" class="btn btn-sm px-3 font-size-24 header-item waves-effect vertical-menu-btn">
|
.avatar {
|
||||||
<i class="bx bx-menu align-middle"></i>
|
width: 38px;
|
||||||
</button>
|
height: 38px;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
<!-- start page title -->
|
.user-name {
|
||||||
<div class="page-title-box align-self-center d-none d-md-block">
|
font-weight: 600;
|
||||||
<h4 class="page-title mb-0">Prenotazione Classi</h4>
|
color: #1f2937;
|
||||||
</div>
|
}
|
||||||
<!-- end page title -->
|
|
||||||
|
|
||||||
</div>
|
.status-chip {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: #fff3cd;
|
||||||
|
color: #856404;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
<div class="d-flex">
|
.date-old {
|
||||||
|
color: #c0392b;
|
||||||
|
}
|
||||||
|
|
||||||
<?php include('include/languageselection.php'); ?>
|
.date-new {
|
||||||
|
color: #1a7f52;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-accept,
|
||||||
|
.btn-reject {
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 7px 14px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: filter 0.15s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-accept {
|
||||||
|
background: #27ae60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-reject {
|
||||||
|
background: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-accept:hover,
|
||||||
|
.btn-reject:hover {
|
||||||
|
filter: brightness(0.93);
|
||||||
|
}
|
||||||
|
|
||||||
<?php include('include/profiletopbar.php'); ?>
|
.empty-state {
|
||||||
</div>
|
text-align: center;
|
||||||
</div>
|
padding: 40px 10px;
|
||||||
</header>
|
color: #9ca3af;
|
||||||
<?php include('include/sidebar.php'); ?>
|
}
|
||||||
|
|
||||||
<header class="ishorizontal-topbar">
|
.empty-state i {
|
||||||
<div class="navbar-header">
|
font-size: 34px;
|
||||||
<div class="d-flex">
|
margin-bottom: 10px;
|
||||||
|
display: block;
|
||||||
|
color: #d5d9e0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</div>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="topnav">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<nav class="navbar navbar-light navbar-expand-lg topnav-menu">
|
|
||||||
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<!-- ============================================================== -->
|
|
||||||
<!-- Start right Content here -->
|
|
||||||
<!-- ============================================================== -->
|
|
||||||
<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">
|
|
||||||
<h5>Benvenuta/o <?php echo $firstname; ?> </h5>
|
|
||||||
<p>Di seguito puoi visualizzare le prenotazioni pending o waiting</p>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-striped mb-0">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Nome</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>Classe</th>
|
|
||||||
<th>Data Cancellata</th>
|
|
||||||
<th>Data Proposta</th>
|
|
||||||
<th>Accetta</th>
|
|
||||||
<th>Rifiuta</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($documents as $document) { ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo $document['first_name']; ?> <?php echo $document['last_name']; ?></td>
|
|
||||||
<td><?php echo $document['bookingclass_status']; ?></td>
|
|
||||||
<td><?php echo $document['servicename']; ?>-<?php echo $document['day']; ?>-<?php echo $document['time']; ?></td>
|
|
||||||
<td><?php echo date('d-m-Y H:i', strtotime($document['prevbookingstart'])); ?></td>
|
|
||||||
<td><?php echo date('d-m-Y H:i', strtotime($document['bookingstart'])); ?></td>
|
|
||||||
<td><a href="acceptbookingclass.php?idbookingclass=<?php echo $document['idbookingclass']; ?>"><button type="button" class="btn btn-success waves-effect btn-label waves-light"><i class="bx bx-check-double label-icon"></i> Accetta</button></a></td>
|
|
||||||
<td><a href="rejectbookingclass.php?idbookingclass=<?php echo $document['idbookingclass']; ?>"><button type="button" class="btn btn-danger waves-effect waves-light"><i class="bx bx-block font-size-16 align-middle me-2"></i> Rifiuta</button></a></td>
|
|
||||||
</tr>
|
|
||||||
<?php } ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<!-- container-fluid -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<?php include('include/footer.php'); ?>
|
|
||||||
</div>
|
|
||||||
<!-- end main content-->
|
|
||||||
|
|
||||||
|
<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">Prenotazioni in attesa</h4>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- END layout-wrapper -->
|
<div class="d-flex">
|
||||||
|
<?php include('include/languageselection.php'); ?>
|
||||||
|
<?php include('include/profiletopbar.php'); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<?php include('include/sidebar.php'); ?>
|
||||||
|
<header class="ishorizontal-topbar">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<div class="d-flex"></div>
|
||||||
|
</div>
|
||||||
|
<div class="topnav">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<nav class="navbar navbar-light navbar-expand-lg topnav-menu"></nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="main-content">
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card admin-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="section-title">Richieste in attesa</div>
|
||||||
|
<p class="section-lead">
|
||||||
|
Ciao <?php echo e($firstname); ?>, qui trovi le richieste di riprogrammazione da accettare o rifiutare.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table pending-table align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Utente</th>
|
||||||
|
<th>Stato</th>
|
||||||
|
<th>Classe</th>
|
||||||
|
<th>Data cancellata</th>
|
||||||
|
<th>Data proposta</th>
|
||||||
|
<th class="text-end">Azioni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($documents)) : ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6">
|
||||||
|
<div class="empty-state">
|
||||||
|
<i class="fas fa-inbox"></i>
|
||||||
|
Nessuna prenotazione in attesa al momento.
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php else : ?>
|
||||||
|
<?php foreach ($documents as $d) :
|
||||||
|
$fullName = trim($d['first_name'] . ' ' . $d['last_name']);
|
||||||
|
$idbc = (int) $d['idbookingclass'];
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="user-cell">
|
||||||
|
<div class="avatar" style="background: <?php echo avatarColor($fullName); ?>;">
|
||||||
|
<?php echo e(initials($d['first_name'] ?? '', $d['last_name'] ?? '')); ?>
|
||||||
|
</div>
|
||||||
|
<span class="user-name"><?php echo e($fullName); ?></span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td><span class="status-chip"><?php echo e($d['booking_status']); ?></span></td>
|
||||||
|
<td>
|
||||||
|
<?php echo e($d['servicename']); ?>
|
||||||
|
<small class="text-muted d-block">
|
||||||
|
<?php echo e(trim($d['day'] . ' ' . $d['time'], ' -')); ?>
|
||||||
|
</small>
|
||||||
|
</td>
|
||||||
|
<td class="date-old"><?php echo e($fmt($d['prevbookingstart'])); ?></td>
|
||||||
|
<td class="date-new"><?php echo e($fmt($d['bookingstart'])); ?></td>
|
||||||
|
<td class="text-end">
|
||||||
|
<a href="acceptbookingclass.php?idbookingclass=<?php echo $idbc; ?>">
|
||||||
|
<button type="button" class="btn-accept"><i class="bx bx-check-double"></i> Accetta</button>
|
||||||
|
</a>
|
||||||
|
<a href="rejectbookingclass.php?idbookingclass=<?php echo $idbc; ?>">
|
||||||
|
<button type="button" class="btn-reject"><i class="bx bx-block"></i> Rifiuta</button>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php include('include/footer.php'); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>
|
||||||
<!-- JAVASCRIPT -->
|
<script src="assets/js/app.js"></script>
|
||||||
<script src="assets/libs/bootstrap/js/bootstrap.bundle.min.js"></script>
|
</body>
|
||||||
<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>
|
</html>
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
require_once('include/headscript.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elimina completamente una classe schedulata (serviceschedule) insieme
|
||||||
|
* a tutte le sue prenotazioni (bookingclass), in un'unica transazione.
|
||||||
|
*
|
||||||
|
* Script di sola logica: nessun output, redirect finale.
|
||||||
|
*/
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
|
$idserviceschedule = isset($_GET['idserviceschedule']) ? (int) $_GET['idserviceschedule'] : 0;
|
||||||
|
|
||||||
|
if ($idserviceschedule <= 0) {
|
||||||
|
header('Location: adminpanel.php?error=invalid');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
// 1) Rimuove le prenotazioni collegate a questa schedulazione
|
||||||
|
$delBookings = $pdo->prepare(
|
||||||
|
"DELETE FROM bookingclass WHERE idserviceschedule = :id"
|
||||||
|
);
|
||||||
|
$delBookings->execute([':id' => $idserviceschedule]);
|
||||||
|
|
||||||
|
// 2) Rimuove la schedulazione stessa
|
||||||
|
$delSchedule = $pdo->prepare(
|
||||||
|
"DELETE FROM serviceschedule WHERE idserviceschedule = :id"
|
||||||
|
);
|
||||||
|
$delSchedule->execute([':id' => $idserviceschedule]);
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
header('Location: adminpanel.php?success=4');
|
||||||
|
exit;
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
if ($pdo->inTransaction()) {
|
||||||
|
$pdo->rollBack();
|
||||||
|
}
|
||||||
|
// Log server-side, messaggio generico all'utente
|
||||||
|
error_log('removeschedule error: ' . $ex->getMessage());
|
||||||
|
header('Location: adminpanel.php?error=delete');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
@@ -1,26 +1,35 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once('Connections/bkngstm.php');
|
// Buffer per scartare eventuale HTML degli include: risposta JSON pulita
|
||||||
|
ob_start();
|
||||||
|
require_once('include/headscript.php');
|
||||||
|
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
/**
|
||||||
|
* Ripristina una prenotazione precedentemente segnata come persa
|
||||||
|
* (lostlesson = 'N').
|
||||||
|
*/
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
if ($conn->connect_error) {
|
function jsonOut(array $payload): void
|
||||||
die("Connessione fallita: " . $conn->connect_error);
|
{
|
||||||
}
|
if (ob_get_length() !== false) {
|
||||||
|
ob_end_clean();
|
||||||
if (isset($_POST['idbookingclass'])) {
|
|
||||||
$idbookingclass = $_POST['idbookingclass'];
|
|
||||||
|
|
||||||
$query = "UPDATE bookingclass SET lostlesson = 'N' WHERE idbookingclass = ?";
|
|
||||||
$stmt = $conn->prepare($query);
|
|
||||||
$stmt->bind_param("i", $idbookingclass);
|
|
||||||
|
|
||||||
if ($stmt->execute()) {
|
|
||||||
echo json_encode(['success' => true]);
|
|
||||||
} else {
|
|
||||||
echo json_encode(['success' => false, 'error' => $conn->error]);
|
|
||||||
}
|
}
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
$stmt->close();
|
echo json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$conn->close();
|
$idbookingclass = isset($_POST['idbookingclass']) ? (int) $_POST['idbookingclass'] : 0;
|
||||||
|
|
||||||
|
if ($idbookingclass <= 0) {
|
||||||
|
jsonOut(['success' => false, 'error' => 'ID prenotazione non valido.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("UPDATE bookingclass SET lostlesson = 'N' WHERE idbookingclass = :id");
|
||||||
|
$stmt->execute([':id' => $idbookingclass]);
|
||||||
|
jsonOut(['success' => true]);
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
error_log('ripristina_campo_lost error: ' . $ex->getMessage());
|
||||||
|
jsonOut(['success' => false, 'error' => 'Errore durante il ripristino.']);
|
||||||
|
}
|
||||||
|
|||||||
+68
-29
@@ -1,36 +1,75 @@
|
|||||||
<?php
|
<?php
|
||||||
// Connessione al database
|
// Bufferizziamo da subito: qualsiasi output emesso dagli include
|
||||||
include('Connections/bkngstm.php');
|
// (headscript.php stampa dell'HTML, es. "<!-- query languages -->")
|
||||||
$conn = new mysqli($servername, $username, $password, $dbname);
|
// verrà scartato, così la risposta resta JSON puro.
|
||||||
|
ob_start();
|
||||||
|
|
||||||
if ($conn->connect_error) {
|
require_once('include/headscript.php');
|
||||||
die("Connessione al database fallita: " . $conn->connect_error);
|
|
||||||
|
/**
|
||||||
|
* Ricerca utenti per nome e/o cognome.
|
||||||
|
* Riceve firstName e lastName (POST) come campi separati e cerca in OR:
|
||||||
|
* trova risultati anche digitando solo uno dei due. Risponde in JSON.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$pdo = DBHandlerSelect::getInstance()->getConnection();
|
||||||
|
|
||||||
|
$firstName = trim($_POST['firstName'] ?? '');
|
||||||
|
$lastName = trim($_POST['lastName'] ?? '');
|
||||||
|
|
||||||
|
// Compatibilità col vecchio parametro unico "searchTerm"
|
||||||
|
if ($firstName === '' && $lastName === '' && isset($_POST['searchTerm'])) {
|
||||||
|
$parts = preg_split('/\s+/', trim($_POST['searchTerm']));
|
||||||
|
$firstName = $parts[0] ?? '';
|
||||||
|
$lastName = $parts[1] ?? $firstName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Estrai il termine di ricerca dall'input dell'utente
|
/**
|
||||||
$searchTerm = $_POST['searchTerm'];
|
* Emette JSON pulito: scarta tutto l'output bufferizzato prima,
|
||||||
|
* imposta l'header e termina.
|
||||||
// Esegui la query per cercare nella tabella auth_users
|
*/
|
||||||
$sql = "SELECT id, email, first_name, last_name FROM auth_users WHERE last_name LIKE '%$searchTerm%'";
|
function jsonOut(array $payload): void
|
||||||
$result = $conn->query($sql);
|
{
|
||||||
if ($result->num_rows > 0) {
|
if (ob_get_length() !== false) {
|
||||||
$resultsArray = array();
|
ob_end_clean();
|
||||||
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
$resultsArray[] = array(
|
|
||||||
'id' => $row['id'],
|
|
||||||
'email' => $row['email'],
|
|
||||||
'first_name' => $row['first_name'],
|
|
||||||
'last_name' => $row['last_name']
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// Imposta l'header "Content-Type" su "application/json"
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
header('Content-Type: application/json');
|
echo json_encode($payload, JSON_UNESCAPED_UNICODE);
|
||||||
// Restituisci i risultati in formato JSON
|
exit;
|
||||||
echo json_encode(array('results' => $resultsArray));
|
|
||||||
} else {
|
|
||||||
// Nessun risultato trovato
|
|
||||||
echo json_encode(array('results' => array()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$conn->close();
|
// Serve almeno 2 caratteri in uno dei due campi
|
||||||
|
if (mb_strlen($firstName) < 2 && mb_strlen($lastName) < 2) {
|
||||||
|
jsonOut(['results' => []]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$conditions = [];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
if (mb_strlen($firstName) >= 2) {
|
||||||
|
$conditions[] = "first_name LIKE :fn";
|
||||||
|
$params[':fn'] = '%' . $firstName . '%';
|
||||||
|
}
|
||||||
|
if (mb_strlen($lastName) >= 2) {
|
||||||
|
$conditions[] = "last_name LIKE :ln";
|
||||||
|
$params[':ln'] = '%' . $lastName . '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
$where = implode(' OR ', $conditions);
|
||||||
|
|
||||||
|
$sql = "SELECT id, first_name, last_name, email
|
||||||
|
FROM auth_users
|
||||||
|
WHERE $where
|
||||||
|
ORDER BY last_name, first_name
|
||||||
|
LIMIT 15";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute($params);
|
||||||
|
$rows = $stmt->fetchAll();
|
||||||
|
|
||||||
|
jsonOut(['results' => $rows]);
|
||||||
|
} catch (Throwable $ex) {
|
||||||
|
error_log('searchemail error: ' . $ex->getMessage());
|
||||||
|
jsonOut(['error' => 'Errore durante la ricerca.']);
|
||||||
|
}
|
||||||
|
|||||||
+483
-741
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user