teacher
This commit is contained in:
parent
dda63d9711
commit
7f7dff32d9
10
.env
10
.env
@ -23,12 +23,12 @@ REDIS_PASSWORD=null
|
|||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
MAIL_MAILER=mail
|
MAIL_MAILER=mail
|
||||||
MAIL_FROM_NAME=YogaSoul
|
MAIL_FROM_NAME=YogiBoook
|
||||||
MAIL_FROM_ADDRESS=info@yogasoul.it
|
MAIL_FROM_ADDRESS=info@yogiboook.com
|
||||||
MAIL_HOST=mail.yogasoul.it
|
MAIL_HOST=mail.yogiboook.com
|
||||||
MAIL_PORT=465
|
MAIL_PORT=465
|
||||||
MAIL_USERNAME=info@yogasoul.it
|
MAIL_USERNAME=info@yogiboook.com
|
||||||
MAIL_PASSWORD=!Testolina88
|
MAIL_PASSWORD=!NuovaZelanda2020
|
||||||
MAIL_ENCRYPTION=ssl
|
MAIL_ENCRYPTION=ssl
|
||||||
|
|
||||||
PUSHER_APP_ID=
|
PUSHER_APP_ID=
|
||||||
|
|||||||
BIN
public/phototeachers/qrcodes/2-5d518ce9cdb43b39.png
Normal file
BIN
public/phototeachers/qrcodes/2-5d518ce9cdb43b39.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 430 B |
156
public/userarea/add_teacher.php
Normal file
156
public/userarea/add_teacher.php
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
// add_teacher.php
|
||||||
|
|
||||||
|
include('include/headscript.php');
|
||||||
|
require_once 'class/mailer.php';
|
||||||
|
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
if (!isset($iduserlogin)) die("Accesso negato.");
|
||||||
|
|
||||||
|
$school_id = (int)($_POST['school_id'] ?? 0);
|
||||||
|
|
||||||
|
// Recupera scuola per email mittente
|
||||||
|
$stmt = $pdo->prepare("SELECT name, email FROM schools WHERE id = ?");
|
||||||
|
$stmt->execute([$school_id]);
|
||||||
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if (!$school) die("Scuola non trovata.");
|
||||||
|
|
||||||
|
$first_name = trim($_POST['first_name'] ?? '');
|
||||||
|
$last_name = trim($_POST['last_name'] ?? '');
|
||||||
|
$email = trim($_POST['email'] ?? '');
|
||||||
|
$phone = trim($_POST['phone'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$specializations = trim($_POST['specializations'] ?? '');
|
||||||
|
|
||||||
|
// Validazione base
|
||||||
|
if (empty($first_name) || empty($last_name) || empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
header("Location: teacher_list.php?error=Campi obbligatori mancanti o email non valida");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controlla se email esiste già
|
||||||
|
$stmt = $pdo->prepare("SELECT id, first_name, last_name FROM auth_users WHERE email = ? LIMIT 1");
|
||||||
|
$stmt->execute([$email]);
|
||||||
|
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($existing) {
|
||||||
|
|
||||||
|
// 1) Trova (o crea) la riga in teachers per questo auth_user
|
||||||
|
$stmtT = $pdo->prepare("SELECT id FROM teachers WHERE user_id = ? LIMIT 1");
|
||||||
|
$stmtT->execute([(int)$existing['id']]);
|
||||||
|
$teacherRow = $stmtT->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$teacherRow) {
|
||||||
|
$unique_code = bin2hex(random_bytes(8));
|
||||||
|
$insT = $pdo->prepare("
|
||||||
|
INSERT INTO teachers (user_id, unique_code, status, created_by)
|
||||||
|
VALUES (?, ?, 'active', ?)
|
||||||
|
");
|
||||||
|
$insT->execute([(int)$existing['id'], $unique_code, (int)$iduserlogin]);
|
||||||
|
$teacher_id = (int)$pdo->lastInsertId();
|
||||||
|
} else {
|
||||||
|
$teacher_id = (int)$teacherRow['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Crea (o riusa) il link in teacher_schools come pending
|
||||||
|
$checkLink = $pdo->prepare("
|
||||||
|
SELECT id, status
|
||||||
|
FROM teacher_schools
|
||||||
|
WHERE teacher_id = ? AND school_id = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$checkLink->execute([$teacher_id, $school_id]);
|
||||||
|
$link = $checkLink->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($link && $link['status'] === 'active') {
|
||||||
|
header("Location: teacher_list.php?error=Insegnante già collegata alla scuola.");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($link && $link['status'] === 'pending') {
|
||||||
|
$link_id = (int)$link['id'];
|
||||||
|
} else {
|
||||||
|
$insLink = $pdo->prepare("
|
||||||
|
INSERT INTO teacher_schools (teacher_id, school_id, status, created_at, updated_at)
|
||||||
|
VALUES (?, ?, 'pending', NOW(), NOW())
|
||||||
|
");
|
||||||
|
$insLink->execute([$teacher_id, $school_id]);
|
||||||
|
$link_id = (int)$pdo->lastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Email richiesta collegamento
|
||||||
|
$subject = "Richiesta di collegamento alla scuola {$school['name']}";
|
||||||
|
|
||||||
|
// ✅ NON cambio percorso base, aggiungo solo link_id
|
||||||
|
$confirmUrl = "http://localhost/yogiboook/public/userarea/confirm_teacher_link.php"
|
||||||
|
. "?email=" . urlencode($email)
|
||||||
|
. "&school_id={$school_id}"
|
||||||
|
. "&link_id={$link_id}";
|
||||||
|
|
||||||
|
$body = "
|
||||||
|
<h2>Ciao {$existing['first_name']},</h2>
|
||||||
|
<p>Il proprietario della scuola <strong>{$school['name']}</strong> vorrebbe collegarti alla sua struttura su YogiBoook.</p>
|
||||||
|
<p>Se accetti, comparirai nelle lezioni a te associate nella scuola.</p>
|
||||||
|
<p style='margin:30px 0;'>
|
||||||
|
<a href='{$confirmUrl}'
|
||||||
|
style='background:#0d6efd; color:white; padding:12px 24px; text-decoration:none; border-radius:6px;'>
|
||||||
|
Accetta collegamento
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>Se non riconosci questa richiesta, ignora questa email.</p>
|
||||||
|
<p style='color:#666; font-size:0.9em;'>YogiBoook – piattaforma per scuole yoga</p>
|
||||||
|
";
|
||||||
|
|
||||||
|
$result = sendEmail($email, $subject, $body);
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
header("Location: teacher_list.php?success=Insegnante esistente trovato! Email di richiesta collegamento inviata.");
|
||||||
|
} else {
|
||||||
|
header("Location: teacher_list.php?error=Insegnante esistente trovato, ma errore invio email: " . urlencode($result['message']));
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Nuovo utente ===
|
||||||
|
$password = password_hash(bin2hex(random_bytes(12)), PASSWORD_DEFAULT);
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO auth_users (email, first_name, last_name, password, role_id, status, created_at)
|
||||||
|
VALUES (?, ?, ?, ?, 2, 'active', NOW())
|
||||||
|
");
|
||||||
|
$stmt->execute([$email, $first_name, $last_name, $password]);
|
||||||
|
$user_id = (int)$pdo->lastInsertId();
|
||||||
|
|
||||||
|
// Foto profilo (opzionale)
|
||||||
|
$profile_picture = null;
|
||||||
|
if (!empty($_FILES['profile_picture']['name']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
|
||||||
|
$ext = strtolower(pathinfo($_FILES['profile_picture']['name'], PATHINFO_EXTENSION));
|
||||||
|
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||||
|
$new_name = "phototeachers/{$user_id}-" . time() . "-profile.$ext";
|
||||||
|
if (move_uploaded_file($_FILES['profile_picture']['tmp_name'], $new_name)) {
|
||||||
|
$profile_picture = $new_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crea record teachers
|
||||||
|
$unique_code = bin2hex(random_bytes(8));
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO teachers
|
||||||
|
(user_id, unique_code, phone, description, specializations, profile_picture, status, created_by)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, 'active', ?)
|
||||||
|
");
|
||||||
|
$stmt->execute([$user_id, $unique_code, $phone ?: null, $description, $specializations, $profile_picture, (int)$iduserlogin]);
|
||||||
|
$teacher_id = (int)$pdo->lastInsertId();
|
||||||
|
|
||||||
|
// Collega alla scuola (nuovo -> active diretto)
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO teacher_schools
|
||||||
|
(teacher_id, school_id, status, created_at, updated_at)
|
||||||
|
VALUES (?, ?, 'active', NOW(), NOW())
|
||||||
|
");
|
||||||
|
$stmt->execute([$teacher_id, $school_id]);
|
||||||
|
|
||||||
|
header("Location: teacher_list.php?success=Insegnante aggiunta con successo!");
|
||||||
|
exit;
|
||||||
118
public/userarea/ajax_client_bookings.php
Normal file
118
public/userarea/ajax_client_bookings.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
// ajax_client_bookings.php
|
||||||
|
|
||||||
|
// Non serve require_once se usi la stessa connessione del template principale
|
||||||
|
// Ma per sicurezza includi headscript.php (che contiene già DBHandler)
|
||||||
|
require_once('include/headscript.php'); // adatta il percorso se necessario
|
||||||
|
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
// Poi il resto del codice...
|
||||||
|
$user_id = (int)($_POST['user_id'] ?? 0);
|
||||||
|
$school_id = (int)($_POST['school_id'] ?? 0);
|
||||||
|
|
||||||
|
if ($user_id <= 0 || $school_id <= 0) {
|
||||||
|
echo '<div class="alert alert-warning">Dati non validi.</div>';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
cs.id AS session_id,
|
||||||
|
cs.session_date,
|
||||||
|
cs.start_time,
|
||||||
|
cs.end_time,
|
||||||
|
c.name AS class_name,
|
||||||
|
ct.level,
|
||||||
|
sb.status,
|
||||||
|
sb.booked_at,
|
||||||
|
o.id AS order_id,
|
||||||
|
o.order_number,
|
||||||
|
o.total_entries,
|
||||||
|
o.available_entries
|
||||||
|
FROM session_bookings sb
|
||||||
|
INNER JOIN class_sessions cs
|
||||||
|
ON sb.session_id = cs.id
|
||||||
|
AND cs.school_id = ?
|
||||||
|
INNER JOIN classes c
|
||||||
|
ON cs.class_id = c.id
|
||||||
|
AND c.school_id = ?
|
||||||
|
INNER JOIN class_types ct
|
||||||
|
ON cs.class_type_id = ct.id
|
||||||
|
AND ct.school_id = ?
|
||||||
|
LEFT JOIN orders o
|
||||||
|
ON sb.order_id = o.id
|
||||||
|
AND o.school_id = ?
|
||||||
|
WHERE sb.user_id = ?
|
||||||
|
ORDER BY cs.session_date DESC, cs.start_time DESC
|
||||||
|
LIMIT 100
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$school_id,
|
||||||
|
$school_id,
|
||||||
|
$school_id,
|
||||||
|
$school_id,
|
||||||
|
$user_id
|
||||||
|
]);
|
||||||
|
$bookings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (empty($bookings)) {
|
||||||
|
echo '<div class="alert alert-info">Nessuna prenotazione registrata per questo utente.</div>';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-sm table-bordered">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th>Data</th>
|
||||||
|
<th>Orario</th>
|
||||||
|
<th>Classe</th>
|
||||||
|
<th>Livello</th>
|
||||||
|
<th>Stato</th>
|
||||||
|
<th>Ordine</th>
|
||||||
|
<th>Data prenotazione</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($bookings as $b):
|
||||||
|
$statoClass = match ($b['status']) {
|
||||||
|
'attended' => 'bg-success',
|
||||||
|
'missed' => 'bg-danger',
|
||||||
|
'booked' => (strtotime($b['session_date']) >= time()) ? 'bg-primary' : 'bg-secondary',
|
||||||
|
'cancelled' => 'bg-dark',
|
||||||
|
'rescheduled' => 'bg-info',
|
||||||
|
default => 'bg-secondary'
|
||||||
|
};
|
||||||
|
$statoText = match ($b['status']) {
|
||||||
|
'attended' => 'Frequentata',
|
||||||
|
'missed' => 'Persa',
|
||||||
|
'booked' => (strtotime($b['session_date']) >= time()) ? 'Prenotata' : 'Scaduta',
|
||||||
|
'cancelled' => 'Cancellata',
|
||||||
|
'rescheduled' => 'Riprog.',
|
||||||
|
default => $b['status']
|
||||||
|
};
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?= date('d/m/Y', strtotime($b['session_date'])) ?></td>
|
||||||
|
<td><?= substr($b['start_time'], 0, 5) ?> – <?= substr($b['end_time'], 0, 5) ?></td>
|
||||||
|
<td><?= htmlspecialchars($b['class_name']) ?></td>
|
||||||
|
<td><?= ucfirst($b['level'] ?? '—') ?></td>
|
||||||
|
<td><span class="badge <?= $statoClass ?>"><?= $statoText ?></span></td>
|
||||||
|
<td>
|
||||||
|
<?php if ($b['order_id']): ?>
|
||||||
|
#<?= $b['order_number'] ?><br>
|
||||||
|
<small><?= $b['available_entries'] ?>/<?= $b['total_entries'] ?></small>
|
||||||
|
<?php else: ?>
|
||||||
|
—
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td><small><?= date('d/m/Y H:i', strtotime($b['booked_at'])) ?></small></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@ -12,16 +12,24 @@ $dotenv->load();
|
|||||||
|
|
||||||
function sendEmail($to, $subject, $body, $attachments = [], $cc = [], $bcc = [])
|
function sendEmail($to, $subject, $body, $attachments = [], $cc = [], $bcc = [])
|
||||||
{
|
{
|
||||||
|
|
||||||
// Configurazione SMTP
|
// Configurazione SMTP
|
||||||
$mail = new PHPMailer(true);
|
$mail = new PHPMailer(true);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Configurazione server SMTP con dati da .env
|
// Configurazione server SMTP con dati da .env
|
||||||
$mail->isSMTP();
|
$mail->isSMTP();
|
||||||
$mail->Host = $_ENV['MAIL_HOST'] ?? 'smtp.example.com';
|
$mail->Host = $_ENV['MAIL_HOST'] ?? 'smtp.example.com';
|
||||||
$mail->SMTPAuth = true;
|
$mail->SMTPAuth = true;
|
||||||
$mail->Username = $_ENV['MAIL_USERNAME'] ?? 'email@example.com';
|
$mail->Username = $_ENV['MAIL_USERNAME'] ?? 'email@example.com';
|
||||||
$mail->Password = $_ENV['MAIL_PASSWORD'] ?? 'password';
|
$mail->Password = $_ENV['MAIL_PASSWORD'] ?? 'password';
|
||||||
$mail->SMTPSecure = $_ENV['MAIL_ENCRYPTION'] ?? PHPMailer::ENCRYPTION_STARTTLS;
|
$enc = strtolower(trim($_ENV['MAIL_ENCRYPTION'] ?? 'tls'));
|
||||||
|
if ($enc === 'ssl') {
|
||||||
|
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
||||||
|
} else {
|
||||||
|
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||||||
|
}
|
||||||
|
|
||||||
$mail->Port = $_ENV['MAIL_PORT'] ?? 587;
|
$mail->Port = $_ENV['MAIL_PORT'] ?? 587;
|
||||||
|
|
||||||
// Mittente
|
// Mittente
|
||||||
|
|||||||
361
public/userarea/clients_situation.php
Normal file
361
public/userarea/clients_situation.php
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
<?php
|
||||||
|
// clients_situation.php
|
||||||
|
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
include('include/headscript.php');
|
||||||
|
require_once 'class/mailer.php'; // assumo sia incluso qui o in headscript
|
||||||
|
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
if (!isset($iduserlogin)) {
|
||||||
|
die("Errore: ID utente non definito.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scuola corrente
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT id, name, email AS school_email
|
||||||
|
FROM schools
|
||||||
|
WHERE owner_id = ?
|
||||||
|
");
|
||||||
|
$stmt->execute([$iduserlogin]);
|
||||||
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$school) {
|
||||||
|
die("Nessuna scuola trovata per questo proprietario.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$school_id = $school['id'];
|
||||||
|
$school_name = $school['name'];
|
||||||
|
$school_email = $school['school_email'];
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// INVIO EMAIL da modale
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'send_email_to_user') {
|
||||||
|
|
||||||
|
$user_id = (int)($_POST['user_id'] ?? 0);
|
||||||
|
$subject = trim($_POST['subject'] ?? '');
|
||||||
|
$message = trim($_POST['message'] ?? '');
|
||||||
|
|
||||||
|
if ($user_id <= 0 || empty($subject) || empty($message)) {
|
||||||
|
$error = "Dati mancanti per l'invio email.";
|
||||||
|
} else {
|
||||||
|
// Recupera email utente
|
||||||
|
$stmt = $pdo->prepare("SELECT email, first_name, last_name FROM auth_users WHERE id = ?");
|
||||||
|
$stmt->execute([$user_id]);
|
||||||
|
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$error = "Utente non trovato.";
|
||||||
|
} else {
|
||||||
|
$to = $user['email'];
|
||||||
|
$body = "
|
||||||
|
<h2>Comunicazione da {$school_name}</h2>
|
||||||
|
<p>Gentile {$user['first_name']} {$user['last_name']},</p>
|
||||||
|
<div style='margin: 20px 0; padding: 15px; border-left: 4px solid #0d6efd; background: #f8f9fa;'>
|
||||||
|
" . nl2br(htmlspecialchars($message)) . "
|
||||||
|
</div>
|
||||||
|
<p style='color:#555; font-size:0.95em;'>
|
||||||
|
Questa è una comunicazione ufficiale da parte della scuola.<br>
|
||||||
|
Per qualsiasi dubbio rispondi direttamente a questa email o contatta: {$school_email}
|
||||||
|
</p>
|
||||||
|
<hr style='border-color:#eee;'>
|
||||||
|
<small style='color:#777;'>YogiBoook – piattaforma per scuole yoga</small>
|
||||||
|
";
|
||||||
|
|
||||||
|
$result = sendEmail($to, $subject, $body);
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
$success = "Email inviata con successo a {$user['first_name']} {$user['last_name']}";
|
||||||
|
} else {
|
||||||
|
$error = "Errore nell'invio: " . $result['message'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// Lista clienti + statistiche aggregate
|
||||||
|
$clients = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
au.id,
|
||||||
|
au.first_name,
|
||||||
|
au.last_name,
|
||||||
|
au.email,
|
||||||
|
COUNT(DISTINCT o.id) AS num_orders,
|
||||||
|
COALESCE(SUM(o.total_entries), 0) AS total_entries,
|
||||||
|
|
||||||
|
-- Praticate = prenotate nel passato (booked + data < oggi)
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.user_id = au.id
|
||||||
|
AND cs.school_id = ?
|
||||||
|
AND sb.status = 'booked'
|
||||||
|
AND cs.session_date < CURDATE()
|
||||||
|
) AS lezioni_praticate,
|
||||||
|
|
||||||
|
-- Perse (missed + data passata)
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.user_id = au.id
|
||||||
|
AND cs.school_id = ?
|
||||||
|
AND sb.status = 'missed'
|
||||||
|
AND cs.session_date < CURDATE()
|
||||||
|
) AS lezioni_perse,
|
||||||
|
|
||||||
|
-- Prenotate future (booked + data >= oggi)
|
||||||
|
(SELECT COUNT(*)
|
||||||
|
FROM session_bookings sb
|
||||||
|
JOIN class_sessions cs ON sb.session_id = cs.id
|
||||||
|
WHERE sb.user_id = au.id
|
||||||
|
AND cs.school_id = ?
|
||||||
|
AND sb.status = 'booked'
|
||||||
|
AND cs.session_date >= CURDATE()
|
||||||
|
) AS prenotazioni_future
|
||||||
|
|
||||||
|
FROM auth_users au
|
||||||
|
INNER JOIN user_schools us ON au.id = us.user_id
|
||||||
|
LEFT JOIN orders o ON au.id = o.user_id AND o.school_id = ?
|
||||||
|
WHERE us.school_id = ?
|
||||||
|
AND us.status = 'active'
|
||||||
|
GROUP BY au.id
|
||||||
|
ORDER BY au.last_name, au.first_name
|
||||||
|
");
|
||||||
|
$clients->execute([$school_id, $school_id, $school_id, $school_id, $school_id]);
|
||||||
|
$client_list = $clients->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="it">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Situazione Clienti - <?= htmlspecialchars($school_name) ?></title>
|
||||||
|
<?php include('cssinclude.php'); ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<?php include('include/navbar.php'); ?>
|
||||||
|
<?php include('include/topbar.php'); ?>
|
||||||
|
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<div class="page-content">
|
||||||
|
|
||||||
|
<div class="page-breadcrumb d-none d-sm-flex align-items-center mb-3">
|
||||||
|
<div class="breadcrumb-title pe-3">Clienti</div>
|
||||||
|
<div class="ps-3">
|
||||||
|
<nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb mb-0 p-0">
|
||||||
|
<li class="breadcrumb-item"><a href="school_dashboard.php"><i class="bx bx-home-alt"></i></a></li>
|
||||||
|
<li class="breadcrumb-item active" aria-current="page">Situazione Clienti</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mb-4">Situazione Clienti – <?= htmlspecialchars($school_name) ?></h4>
|
||||||
|
|
||||||
|
<?php if (isset($success)): ?>
|
||||||
|
<div class="alert alert-success alert-dismissible fade show">
|
||||||
|
<?= htmlspecialchars($success) ?>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (isset($error)): ?>
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show">
|
||||||
|
<?= htmlspecialchars($error) ?>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card radius-10">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover table-striped align-middle" id="clientsTable">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th>Cliente</th>
|
||||||
|
<th>Ordini</th>
|
||||||
|
<th>Entrate totali</th>
|
||||||
|
<th>Praticate</th>
|
||||||
|
<th>Perse</th>
|
||||||
|
<th>Prenotate (future)</th>
|
||||||
|
<th>Rimanenti</th>
|
||||||
|
<th>Azioni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($client_list as $c):
|
||||||
|
$rimanenti = $c['total_entries'] - $c['lezioni_praticate'] - $c['lezioni_perse'];
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>
|
||||||
|
<?= htmlspecialchars($c['first_name'] . ' ' . $c['last_name']) ?>
|
||||||
|
</strong>
|
||||||
|
<br>
|
||||||
|
<small class="text-muted"><?= htmlspecialchars($c['email']) ?></small>
|
||||||
|
</td>
|
||||||
|
<td class="text-center"><?= $c['num_orders'] ?></td>
|
||||||
|
<td class="text-center"><?= $c['total_entries'] ?: '—' ?></td>
|
||||||
|
<td class="text-center text-success"><?= $c['lezioni_praticate'] ?></td>
|
||||||
|
<td class="text-center text-danger"><?= $c['lezioni_perse'] ?></td>
|
||||||
|
<td class="text-center text-primary"><?= $c['prenotazioni_future'] ?></td>
|
||||||
|
<td class="text-center fw-bold <?= $rimanenti <= 0 ? 'text-danger' : '' ?>">
|
||||||
|
<?= $rimanenti > 0 ? $rimanenti : '0' ?>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-sm btn-outline-primary me-1"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#detailModal"
|
||||||
|
data-userid="<?= $c['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($c['first_name'] . ' ' . $c['last_name']) ?>">
|
||||||
|
<i class="bx bx-detail"></i> Dettaglio
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn-sm btn-outline-info"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#emailModal"
|
||||||
|
data-userid="<?= $c['id'] ?>"
|
||||||
|
data-name="<?= htmlspecialchars($c['first_name'] . ' ' . $c['last_name']) ?>"
|
||||||
|
data-email="<?= htmlspecialchars($c['email']) ?>">
|
||||||
|
<i class="bx bx-envelope"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
<?php if (empty($client_list)): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="8" class="text-center py-5 text-muted">
|
||||||
|
Nessun cliente associato trovato.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MODALE DETTAGLIO PRENOTAZIONI -->
|
||||||
|
<div class="modal fade" id="detailModal" tabindex="-1" aria-labelledby="detailModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="detailModalLabel">Storico prenotazioni di <span id="modalClientName"></span></h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" id="detailBody">
|
||||||
|
<div class="text-center py-4">
|
||||||
|
<div class="spinner-border text-primary" role="status"></div>
|
||||||
|
<p class="mt-2">Caricamento...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Chiudi</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MODALE INVIO EMAIL -->
|
||||||
|
<div class="modal fade" id="emailModal" tabindex="-1" aria-labelledby="emailModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="emailModalLabel">Invia comunicazione a <span id="emailClientName"></span></h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form method="post">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" name="action" value="send_email_to_user">
|
||||||
|
<input type="hidden" name="user_id" id="emailUserId">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Oggetto</label>
|
||||||
|
<input type="text" name="subject" class="form-control" value="Comunicazione da YogiBoook" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">Messaggio</label>
|
||||||
|
<textarea name="message" class="form-control" rows="8" required placeholder="Scrivi qui il messaggio per il cliente..."></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<small class="text-muted d-block">
|
||||||
|
Il messaggio verrà inviato da sistema e includerà automaticamente il nome della scuola e il tuo indirizzo email di contatto.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Invia Email</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('include/footer.php'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('jsinclude.php'); ?>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#clientsTable').DataTable({
|
||||||
|
language: {
|
||||||
|
url: '//cdn.datatables.net/plug-ins/1.13.7/i18n/it-IT.json'
|
||||||
|
},
|
||||||
|
pageLength: 15,
|
||||||
|
order: [
|
||||||
|
[0, 'asc']
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dettaglio cliente
|
||||||
|
$('[data-bs-target="#detailModal"]').on('click', function() {
|
||||||
|
const userid = $(this).data('userid');
|
||||||
|
const name = $(this).data('name');
|
||||||
|
|
||||||
|
$('#modalClientName').text(name);
|
||||||
|
$('#detailBody').html('<div class="text-center py-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Caricamento storico...</p></div>');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: 'ajax_client_bookings.php',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
user_id: userid,
|
||||||
|
school_id: <?= $school_id ?>
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
$('#detailBody').html(response);
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
$('#detailBody').html('<div class="alert alert-danger">Errore durante il caricamento dei dati.</div>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Precompila modale email
|
||||||
|
$('[data-bs-target="#emailModal"]').on('click', function() {
|
||||||
|
const userid = $(this).data('userid');
|
||||||
|
const name = $(this).data('name');
|
||||||
|
$('#emailUserId').val(userid);
|
||||||
|
$('#emailClientName').text(name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
200
public/userarea/confirm_teacher_link.php
Normal file
200
public/userarea/confirm_teacher_link.php
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
<?php
|
||||||
|
// public/userarea/confirm_teacher_link.php
|
||||||
|
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
require_once('class/db-functions.php');
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
$error = null;
|
||||||
|
$success = null;
|
||||||
|
$action_taken = false;
|
||||||
|
|
||||||
|
// Parametri dalla mail / form
|
||||||
|
$email = trim($_POST['email'] ?? $_GET['email'] ?? '');
|
||||||
|
$school_id = (int)($_POST['school_id'] ?? $_GET['school_id'] ?? 0);
|
||||||
|
$link_id = (int)($_POST['link_id'] ?? $_GET['link_id'] ?? 0);
|
||||||
|
|
||||||
|
// Validazione minima: o link_id valido, oppure email+school_id
|
||||||
|
if ($link_id <= 0) {
|
||||||
|
if (empty($email) || $school_id <= 0 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
die("Link non valido. Parametri mancanti o email errata.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recupera scuola (serve sempre per messaggi UI)
|
||||||
|
$school = null;
|
||||||
|
if ($school_id > 0) {
|
||||||
|
$stmt = $pdo->prepare("SELECT id, name FROM schools WHERE id = ?");
|
||||||
|
$stmt->execute([$school_id]);
|
||||||
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ Se link_id NON c'è (vecchie mail), ricavalo dal pending usando email+school_id
|
||||||
|
if ($link_id <= 0 && $school) {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT ts.id
|
||||||
|
FROM teacher_schools ts
|
||||||
|
JOIN teachers t ON ts.teacher_id = t.id
|
||||||
|
JOIN auth_users u ON t.user_id = u.id
|
||||||
|
WHERE u.email = ?
|
||||||
|
AND ts.school_id = ?
|
||||||
|
AND ts.status = 'pending'
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$email, $school_id]);
|
||||||
|
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if ($tmp) {
|
||||||
|
$link_id = (int)$tmp['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carica richiesta (solo pending) tramite link_id
|
||||||
|
$request = null;
|
||||||
|
if ($link_id > 0) {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
ts.id, ts.status,
|
||||||
|
u.first_name, u.last_name,
|
||||||
|
s.id AS school_id, s.name AS school_name
|
||||||
|
FROM teacher_schools ts
|
||||||
|
JOIN schools s ON ts.school_id = s.id
|
||||||
|
JOIN teachers t ON ts.teacher_id = t.id
|
||||||
|
JOIN auth_users u ON t.user_id = u.id
|
||||||
|
WHERE ts.id = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$link_id]);
|
||||||
|
$request = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$request || $request['status'] !== 'pending') {
|
||||||
|
$error = "Nessuna richiesta di collegamento in attesa (potrebbe essere già stata gestita).";
|
||||||
|
} else {
|
||||||
|
// Allinea school dalla request (così non dipendi da school_id passato)
|
||||||
|
$school = ['id' => (int)$request['school_id'], 'name' => $request['school_name']];
|
||||||
|
$teacher_name = trim(($request['first_name'] ?? '') . ' ' . ($request['last_name'] ?? ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: accetta/rifiuta usando SOLO link_id
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
||||||
|
$link_id = (int)($_POST['link_id'] ?? 0);
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT id
|
||||||
|
FROM teacher_schools
|
||||||
|
WHERE id = ? AND status = 'pending'
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$link_id]);
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$row) {
|
||||||
|
$error = "Questa richiesta non è più disponibile (potrebbe essere già stata gestita).";
|
||||||
|
} else {
|
||||||
|
if ($_POST['action'] === 'accept') {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE teacher_schools
|
||||||
|
SET status = 'active', updated_at = NOW()
|
||||||
|
WHERE id = ? AND status = 'pending'
|
||||||
|
");
|
||||||
|
$stmt->execute([$link_id]);
|
||||||
|
|
||||||
|
$success = "Collegamento accettato! Ora sei collegata alla scuola <strong>" . htmlspecialchars($school['name']) . "</strong>.";
|
||||||
|
$action_taken = true;
|
||||||
|
} elseif ($_POST['action'] === 'reject') {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM teacher_schools WHERE id = ? AND status = 'pending'");
|
||||||
|
$stmt->execute([$link_id]);
|
||||||
|
|
||||||
|
$success = "Hai rifiutato il collegamento con la scuola <strong>" . htmlspecialchars($school['name']) . "</strong>.";
|
||||||
|
$action_taken = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="it">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Conferma Collegamento Scuola - YogiBoook</title>
|
||||||
|
<?php include(__DIR__ . '/cssinclude.php'); ?>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f8f9fa;
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 80px auto;
|
||||||
|
padding: 40px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 10px 40px rgba(0, 0, 0, .1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
padding: 14px 40px;
|
||||||
|
font-size: 1.15rem;
|
||||||
|
min-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-big {
|
||||||
|
font-size: 4rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="confirm-container">
|
||||||
|
<?php if ($action_taken && $success): ?>
|
||||||
|
<i class="bx bx-check-circle text-success icon-big"></i>
|
||||||
|
<h3 class="mb-4">Operazione completata!</h3>
|
||||||
|
<p class="lead mb-5"><?= $success ?></p>
|
||||||
|
<p class="mb-4 text-muted">Per gestire le lezioni di questa scuola, accedi o registrati su YogiBoook.</p>
|
||||||
|
<div class="d-flex justify-content-center gap-3">
|
||||||
|
<a href="../login.php" class="btn btn-primary btn-lg">Accedi</a>
|
||||||
|
<a href="../register.php" class="btn btn-outline-primary btn-lg">Registrati</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php elseif (!empty($error)): ?>
|
||||||
|
<i class="bx bx-error-circle text-danger icon-big"></i>
|
||||||
|
<h3>Errore</h3>
|
||||||
|
<p class="lead"><?= htmlspecialchars($error) ?></p>
|
||||||
|
<a href="../login.php" class="btn btn-secondary mt-4">Torna al sito</a>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
<h3 class="mb-4">Richiesta di collegamento scuola</h3>
|
||||||
|
<p class="lead mb-4">Ciao <?= htmlspecialchars($teacher_name ?: 'insegnante') ?>,</p>
|
||||||
|
<p class="mb-5">
|
||||||
|
La scuola <strong><?= htmlspecialchars($school['name']) ?></strong> vorrebbe collegarti alla sua struttura su YogiBoook.
|
||||||
|
</p>
|
||||||
|
<p class="mb-4">Accettando, verrai visualizzata/o nelle lezioni della scuola.</p>
|
||||||
|
|
||||||
|
<form method="POST" class="d-flex justify-content-center gap-4">
|
||||||
|
<input type="hidden" name="email" value="<?= htmlspecialchars($email) ?>">
|
||||||
|
<input type="hidden" name="school_id" value="<?= (int)$school['id'] ?>">
|
||||||
|
<input type="hidden" name="link_id" value="<?= (int)$request['id'] ?>">
|
||||||
|
|
||||||
|
<button type="submit" name="action" value="accept" class="btn btn-success btn-lg">
|
||||||
|
<i class="bx bx-check me-2"></i> Accetta collegamento
|
||||||
|
</button>
|
||||||
|
<button type="submit" name="action" value="reject" class="btn btn-outline-danger btn-lg">
|
||||||
|
<i class="bx bx-x me-2"></i> Rifiuta
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include(__DIR__ . '/include/footer.php'); ?>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -126,6 +126,12 @@ if (!empty($_SESSION['school_id'])) {
|
|||||||
<div class="menu-title">Dashboard Scuola</div>
|
<div class="menu-title">Dashboard Scuola</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="future_sessions.php">
|
||||||
|
<div class="parent-icon"><i class="bx bx-chalkboard"></i></div>
|
||||||
|
<div class="menu-title">Calendario Lezioni</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="products.php">
|
<a href="products.php">
|
||||||
<div class="parent-icon"><i class="bx bx-package"></i></div>
|
<div class="parent-icon"><i class="bx bx-package"></i></div>
|
||||||
@ -140,6 +146,19 @@ if (!empty($_SESSION['school_id'])) {
|
|||||||
</li>
|
</li>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
//menù teacher
|
||||||
|
if ((Auth::user()->hasRole('school_owner')) || (Auth::user()->hasRole('Admin')) || (Auth::user()->hasRole('teacher'))) : ?>
|
||||||
|
<li class="menu-label">Insegnanti</li>
|
||||||
|
<li>
|
||||||
|
<a href="teacher_list.php">
|
||||||
|
<div class="parent-icon"><i class="bx bx-chalkboard"></i></div>
|
||||||
|
<div class="menu-title">Profilo insegnanti</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
//menù admin only
|
//menù admin only
|
||||||
if ((Auth::user()->hasRole('Admin'))) : ?>
|
if ((Auth::user()->hasRole('Admin'))) : ?>
|
||||||
|
|||||||
BIN
public/userarea/phototeachers/2-1768987465-profile.png
Normal file
BIN
public/userarea/phototeachers/2-1768987465-profile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
public/userarea/phototeachers/2-1768987486-profile.jpg
Normal file
BIN
public/userarea/phototeachers/2-1768987486-profile.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
BIN
public/userarea/phototeachers/2-1768987735-profile.jpg
Normal file
BIN
public/userarea/phototeachers/2-1768987735-profile.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
BIN
public/userarea/phototeachers/3-1768987715-profile.png
Normal file
BIN
public/userarea/phototeachers/3-1768987715-profile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@ -840,7 +840,7 @@ $daily_sessions = $stmt->fetchAll();
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="d-flex flex-wrap justify-content-center gap-3">
|
<div class="d-flex flex-wrap justify-content-center gap-3">
|
||||||
<!-- Pulsante Situazione Clienti -->
|
<!-- Pulsante Situazione Clienti -->
|
||||||
<a href="#" class="btn btn-primary d-flex align-items-center px-3 py-2 shadow-sm rounded" style="min-width: 150px;">
|
<a href="clients_situation.php" class="btn btn-primary d-flex align-items-center px-3 py-2 shadow-sm rounded" style="min-width: 150px;">
|
||||||
<i class="bx bx-user me-2" style="font-size: 20px;"></i>
|
<i class="bx bx-user me-2" style="font-size: 20px;"></i>
|
||||||
<span class="fs-6">Situazione Clienti</span>
|
<span class="fs-6">Situazione Clienti</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -1,41 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
// Forza la visualizzazione degli errori
|
// school_profile.php
|
||||||
|
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('display_startup_errors', 1);
|
ini_set('display_startup_errors', 1);
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
include('include/headscript.php');
|
include('include/headscript.php');
|
||||||
|
|
||||||
// Connessione al database
|
|
||||||
$dbHandler = DBHandlerSelect::getInstance();
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
$pdo = $dbHandler->getConnection();
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
// ID dell'utente loggato (assumiamo sia definito)
|
|
||||||
if (!isset($iduserlogin)) {
|
if (!isset($iduserlogin)) {
|
||||||
die("Errore: ID utente non definito.");
|
die("Errore: ID utente non definito.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recupera i dati della scuola associata all'utente
|
// Recupera scuola dell'utente loggato
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
SELECT s.*, u.first_name, u.last_name, u.email
|
SELECT s.*, u.first_name, u.last_name, u.email
|
||||||
FROM auth_users u
|
FROM schools s
|
||||||
LEFT JOIN schools s ON s.owner_id = u.id
|
RIGHT JOIN auth_users u ON s.owner_id = u.id
|
||||||
WHERE u.id = ?
|
WHERE u.id = ?
|
||||||
");
|
");
|
||||||
$stmt->execute([$iduserlogin]);
|
$stmt->execute([$iduserlogin]);
|
||||||
$school = $stmt->fetch();
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if (!$school) {
|
$is_new = empty($school['id']);
|
||||||
die("Errore: Utente non trovato.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determina se è una nuova scuola
|
|
||||||
$is_new = !isset($school['id']);
|
|
||||||
if ($is_new) {
|
if ($is_new) {
|
||||||
$school = [
|
$school = [
|
||||||
'id' => null,
|
'id' => null,
|
||||||
'owner_id' => $iduserlogin,
|
'owner_id' => $iduserlogin,
|
||||||
'name' => '',
|
'name' => '',
|
||||||
|
'slug' => '',
|
||||||
'website' => '',
|
'website' => '',
|
||||||
'email' => '',
|
'email' => '',
|
||||||
'phone' => '',
|
'phone' => '',
|
||||||
@ -44,176 +40,139 @@ if ($is_new) {
|
|||||||
'address_city' => '',
|
'address_city' => '',
|
||||||
'address_postal_code' => '',
|
'address_postal_code' => '',
|
||||||
'address_province' => '',
|
'address_province' => '',
|
||||||
'address_country' => '',
|
'address_country' => 'Italia',
|
||||||
'latitude' => '',
|
'latitude' => null,
|
||||||
'longitude' => '',
|
'longitude' => null,
|
||||||
'owner_name' => '',
|
'owner_name' => '',
|
||||||
'vat_number' => '',
|
'vat_number' => '',
|
||||||
'logo' => '',
|
'logo' => '',
|
||||||
'status' => 'active',
|
'status' => 'active',
|
||||||
'created_at' => '',
|
'first_name' => '',
|
||||||
'updated_at' => '',
|
'last_name' => '',
|
||||||
'slug' => '',
|
'email' => ''
|
||||||
'first_name' => $school['first_name'],
|
|
||||||
'last_name' => $school['last_name'],
|
|
||||||
'email' => $school['email']
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funzione per generare uno slug valido
|
// Generatore slug
|
||||||
function generateSlug($string)
|
function generateSlug($string)
|
||||||
{
|
{
|
||||||
$slug = strtolower($string); // Converti in minuscolo
|
$slug = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
|
||||||
$slug = preg_replace('/[^a-z0-9-]+/', '-', $slug); // Sostituisci caratteri non validi con trattini
|
$slug = preg_replace('/[^a-z0-9 -]/i', '', $slug);
|
||||||
$slug = preg_replace('/-+/', '-', $slug); // Rimuovi trattini multipli
|
$slug = trim($slug);
|
||||||
$slug = trim($slug, '-'); // Rimuovi trattini all'inizio e alla fine
|
$slug = preg_replace('/ +/', '-', $slug);
|
||||||
|
$slug = strtolower($slug);
|
||||||
return $slug;
|
return $slug;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione del form
|
// POST - Salvataggio
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
$success_message = $error = null;
|
||||||
$name = $_POST['name'] ?? '';
|
|
||||||
$website = $_POST['website'] ?? null;
|
|
||||||
$email = $_POST['email'] ?? '';
|
|
||||||
$phone = $_POST['phone'] ?? null;
|
|
||||||
$description = $_POST['description'] ?? null;
|
|
||||||
$address_street = $_POST['address_street'] ?? '';
|
|
||||||
$address_city = $_POST['address_city'] ?? '';
|
|
||||||
$address_postal_code = $_POST['address_postal_code'] ?? '';
|
|
||||||
$address_province = $_POST['address_province'] ?? null;
|
|
||||||
$address_country = $_POST['address_country'] ?? '';
|
|
||||||
$latitude = $_POST['latitude'] ? floatval($_POST['latitude']) : null;
|
|
||||||
$longitude = $_POST['longitude'] ? floatval($_POST['longitude']) : null;
|
|
||||||
$owner_name = $_POST['owner_name'] ?? '';
|
|
||||||
$vat_number = $_POST['vat_number'] ?? '';
|
|
||||||
$status = in_array($_POST['status'], ['active', 'inactive', 'suspended']) ? $_POST['status'] : 'active';
|
|
||||||
$slug = isset($_POST['slug']) ? generateSlug($_POST['slug']) : '';
|
|
||||||
|
|
||||||
// Validazione dello slug
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
if (empty($slug)) {
|
$name = trim($_POST['name'] ?? '');
|
||||||
$error = "Errore: Lo slug non può essere vuoto.";
|
$slug = generateSlug(trim($_POST['slug'] ?? $name));
|
||||||
} else {
|
$website = trim($_POST['website'] ?? '');
|
||||||
// Controlla se lo slug è univoco
|
$email = trim($_POST['email'] ?? '');
|
||||||
|
$phone = trim($_POST['phone'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$address_street = trim($_POST['address_street'] ?? '');
|
||||||
|
$address_city = trim($_POST['address_city'] ?? '');
|
||||||
|
$address_postal_code = trim($_POST['address_postal_code'] ?? '');
|
||||||
|
$address_province = trim($_POST['address_province'] ?? '');
|
||||||
|
$address_country = trim($_POST['address_country'] ?? 'Italia');
|
||||||
|
$latitude = !empty($_POST['latitude']) ? floatval($_POST['latitude']) : null;
|
||||||
|
$longitude = !empty($_POST['longitude']) ? floatval($_POST['longitude']) : null;
|
||||||
|
$owner_name = trim($_POST['owner_name'] ?? '');
|
||||||
|
$vat_number = trim($_POST['vat_number'] ?? '');
|
||||||
|
$status = in_array($_POST['status'] ?? 'active', ['active', 'inactive', 'suspended']) ? $_POST['status'] : 'active';
|
||||||
|
|
||||||
|
// Validazioni
|
||||||
|
if (empty($name)) $error = "Il nome della scuola è obbligatorio.";
|
||||||
|
elseif (empty($slug)) $error = "Lo slug non può essere vuoto.";
|
||||||
|
else {
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM schools WHERE slug = ? AND id != ?");
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM schools WHERE slug = ? AND id != ?");
|
||||||
$stmt->execute([$slug, $school['id'] ?? 0]);
|
$stmt->execute([$slug, $school['id'] ?? 0]);
|
||||||
$slug_exists = $stmt->fetchColumn();
|
if ($stmt->fetchColumn() > 0) {
|
||||||
|
$error = "Lo slug '$slug' è già in uso.";
|
||||||
if ($slug_exists) {
|
|
||||||
$error = "Errore: Lo slug '$slug' è già in uso. Scegli un altro slug.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione del caricamento del logo
|
// Logo
|
||||||
$logo = $school['logo'];
|
$logo = $school['logo'] ?? '';
|
||||||
if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) {
|
if (!empty($_FILES['logo']['name']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) {
|
||||||
$file = $_FILES['logo'];
|
$ext = strtolower(pathinfo($_FILES['logo']['name'], PATHINFO_EXTENSION));
|
||||||
$timestamp = time();
|
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||||
$original_name = basename($file['name']);
|
$new_name = "photoschool/{$iduserlogin}-" . time() . "-logo.$ext";
|
||||||
$extension = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));
|
if (move_uploaded_file($_FILES['logo']['tmp_name'], $new_name)) {
|
||||||
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
|
if ($logo && file_exists($logo) && !$is_new) @unlink($logo);
|
||||||
|
$logo = $new_name;
|
||||||
if (in_array($extension, $allowed_extensions)) {
|
|
||||||
$new_filename = "photoschool/{$iduserlogin}-{$timestamp}-{$original_name}";
|
|
||||||
if (move_uploaded_file($file['tmp_name'], $new_filename)) {
|
|
||||||
$logo = $new_filename;
|
|
||||||
if ($school['logo'] && file_exists($school['logo']) && !$is_new) {
|
|
||||||
unlink($school['logo']);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$error = "Errore durante il caricamento del logo.";
|
$error = "Errore caricamento logo.";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$error = "Estensione del file non consentita. Usa JPG, JPEG, PNG o GIF.";
|
$error = "Solo JPG, PNG, GIF ammessi.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se non ci sono errori, procedi con il salvataggio
|
|
||||||
if (!isset($error)) {
|
if (!isset($error)) {
|
||||||
// Aggiorna auth_users (opzionale, se vuoi aggiornare first_name e last_name)
|
$params = [
|
||||||
$stmt = $pdo->prepare("UPDATE auth_users SET first_name = ?, last_name = ? WHERE id = ?");
|
$name,
|
||||||
$stmt->execute([$school['first_name'], $school['last_name'], $iduserlogin]);
|
$slug,
|
||||||
|
$website ?: null,
|
||||||
|
$email,
|
||||||
|
$phone ?: null,
|
||||||
|
$description,
|
||||||
|
$address_street,
|
||||||
|
$address_city,
|
||||||
|
$address_postal_code,
|
||||||
|
$address_province,
|
||||||
|
$address_country,
|
||||||
|
$latitude,
|
||||||
|
$longitude,
|
||||||
|
$owner_name,
|
||||||
|
$vat_number,
|
||||||
|
$logo,
|
||||||
|
$status
|
||||||
|
];
|
||||||
|
|
||||||
if ($is_new) {
|
if ($is_new) {
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
INSERT INTO schools (owner_id, name, website, email, phone, description, address_street, address_city, address_postal_code, address_province, address_country, latitude, longitude, owner_name, vat_number, logo, status, slug)
|
INSERT INTO schools (
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
owner_id, name, slug, website, email, phone, description,
|
||||||
|
address_street, address_city, address_postal_code, address_province, address_country,
|
||||||
|
latitude, longitude, owner_name, vat_number, logo, status
|
||||||
|
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||||
");
|
");
|
||||||
$success = $stmt->execute([
|
array_unshift($params, $iduserlogin);
|
||||||
$iduserlogin,
|
$success = $stmt->execute($params);
|
||||||
$name,
|
|
||||||
$website,
|
|
||||||
$email,
|
|
||||||
$phone,
|
|
||||||
$description,
|
|
||||||
$address_street,
|
|
||||||
$address_city,
|
|
||||||
$address_postal_code,
|
|
||||||
$address_province,
|
|
||||||
$address_country,
|
|
||||||
$latitude,
|
|
||||||
$longitude,
|
|
||||||
$owner_name,
|
|
||||||
$vat_number,
|
|
||||||
$logo,
|
|
||||||
$status,
|
|
||||||
$slug
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
$success_message = "Scuola creata con successo!";
|
$success_message = "Scuola creata con successo!";
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("SELECT * FROM schools WHERE owner_id = ? ORDER BY id DESC LIMIT 1");
|
||||||
SELECT s.*, u.first_name, u.last_name, u.email
|
|
||||||
FROM auth_users u
|
|
||||||
LEFT JOIN schools s ON s.owner_id = u.id
|
|
||||||
WHERE u.id = ?
|
|
||||||
");
|
|
||||||
$stmt->execute([$iduserlogin]);
|
$stmt->execute([$iduserlogin]);
|
||||||
$school = $stmt->fetch();
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
$is_new = false;
|
$is_new = false;
|
||||||
} else {
|
} else {
|
||||||
$error = "Errore durante la creazione della scuola.";
|
$error = "Errore creazione scuola.";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
$params[] = $school['id'];
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
UPDATE schools
|
UPDATE schools SET
|
||||||
SET name = ?, website = ?, email = ?, phone = ?, description = ?, address_street = ?, address_city = ?,
|
name=?, slug=?, website=?, email=?, phone=?, description=?,
|
||||||
address_postal_code = ?, address_province = ?, address_country = ?, latitude = ?, longitude = ?,
|
address_street=?, address_city=?, address_postal_code=?, address_province=?,
|
||||||
owner_name = ?, vat_number = ?, logo = ?, status = ?, slug = ?
|
address_country=?, latitude=?, longitude=?, owner_name=?, vat_number=?,
|
||||||
WHERE owner_id = ?
|
logo=?, status=?
|
||||||
|
WHERE id=?
|
||||||
");
|
");
|
||||||
$success = $stmt->execute([
|
$success = $stmt->execute($params);
|
||||||
$name,
|
|
||||||
$website,
|
|
||||||
$email,
|
|
||||||
$phone,
|
|
||||||
$description,
|
|
||||||
$address_street,
|
|
||||||
$address_city,
|
|
||||||
$address_postal_code,
|
|
||||||
$address_province,
|
|
||||||
$address_country,
|
|
||||||
$latitude,
|
|
||||||
$longitude,
|
|
||||||
$owner_name,
|
|
||||||
$vat_number,
|
|
||||||
$logo,
|
|
||||||
$status,
|
|
||||||
$slug,
|
|
||||||
$iduserlogin
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
$success_message = "Dati aggiornati con successo!";
|
$success_message = "Profilo aggiornato con successo!";
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("SELECT * FROM schools WHERE id = ?");
|
||||||
SELECT s.*, u.first_name, u.last_name, u.email
|
$stmt->execute([$school['id']]);
|
||||||
FROM auth_users u
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
LEFT JOIN schools s ON s.owner_id = u.id
|
|
||||||
WHERE u.id = ?
|
|
||||||
");
|
|
||||||
$stmt->execute([$iduserlogin]);
|
|
||||||
$school = $stmt->fetch();
|
|
||||||
} else {
|
} else {
|
||||||
$error = "Errore durante l'aggiornamento dei dati.";
|
$error = "Errore aggiornamento.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,23 +185,54 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
<title><?php echo $is_new ? 'Crea' : 'Modifica'; ?> Profilo Scuola</title>
|
||||||
<?php include('cssinclude.php'); ?>
|
<?php include('cssinclude.php'); ?>
|
||||||
<?php include('siteinfo.php'); ?>
|
|
||||||
|
|
||||||
<!-- Leaflet CSS -->
|
<!-- Quill.js CDN -->
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.snow.css" rel="stylesheet" />
|
||||||
integrity="sha256-sA+Zcx6cNpCzIvJczQqny0Sg0r7GDL2wMpN4k1kJ0fPQ=" crossorigin="" />
|
|
||||||
<style>
|
<style>
|
||||||
#map {
|
#map {
|
||||||
height: 350px;
|
height: 380px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-top: 15px;
|
margin-top: 12px;
|
||||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.geocode-btn {
|
/* Editor Quill */
|
||||||
margin-top: 10px;
|
.ql-container {
|
||||||
|
min-height: 260px;
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-editor {
|
||||||
|
min-height: 260px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-toolbar {
|
||||||
|
border-radius: 0.375rem 0.375rem 0 0;
|
||||||
|
border-color: #ced4da;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logo rettangolare, non arrotondato */
|
||||||
|
.school-logo {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 220px;
|
||||||
|
object-fit: contain;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||||||
|
background: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto 1rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@ -255,169 +245,172 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="card radius-10">
|
<div class="card radius-10">
|
||||||
<div class="card-header">
|
<div class="card-header bg-gradient-primary text-white">
|
||||||
<h6 class="mb-0"><?php echo $is_new ? 'Crea Profilo Scuola' : 'Profilo Scuola'; ?></h6>
|
<h5 class="mb-0"><?php echo $is_new ? 'Crea il tuo profilo scuola' : 'Gestisci profilo scuola'; ?></h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<?php if ($success_message): ?>
|
||||||
<?php if (isset($success_message)): ?>
|
<div class="alert alert-success alert-dismissible fade show">
|
||||||
<div class="alert alert-success"><?php echo $success_message; ?></div>
|
<?php echo htmlspecialchars($success_message); ?>
|
||||||
<?php endif; ?>
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
<?php if (isset($error)): ?>
|
</div>
|
||||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<?php if ($error): ?>
|
||||||
<div class="row">
|
<div class="alert alert-danger alert-dismissible fade show">
|
||||||
<!-- Colonna sinistra: logo -->
|
<?php echo htmlspecialchars($error); ?>
|
||||||
<div class="col-md-4 text-center">
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<form method="POST" enctype="multipart/form-data" id="schoolForm">
|
||||||
|
<div class="row g-4">
|
||||||
|
<!-- Colonna sinistra: solo logo -->
|
||||||
|
<div class="col-lg-4 text-center">
|
||||||
|
<img src="<?php echo $school['logo'] ? htmlspecialchars($school['logo']) : 'photoschool/default-school.png'; ?>"
|
||||||
|
alt="Logo Scuola" class="school-logo mb-3">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<img src="<?php echo $school['logo'] ? htmlspecialchars($school['logo']) : 'photoschool/ndphoto.png'; ?>"
|
<label class="form-label">Cambia Logo (opzionale)</label>
|
||||||
alt="Logo" class="img-fluid rounded-circle"
|
<input type="file" class="form-control" name="logo" accept="image/jpeg,image/png,image/gif">
|
||||||
style="width:150px;height:150px;object-fit:cover;">
|
<small class="text-muted d-block mt-1">Max 2MB – JPG, PNG, GIF</small>
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="logo" class="form-label">Carica nuovo logo</label>
|
|
||||||
<input type="file" class="form-control" id="logo" name="logo" accept="image/*">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Colonna destra: tutti i campi -->
|
<!-- Colonna destra: tutti i campi inclusa descrizione con Quill -->
|
||||||
<div class="col-md-8">
|
<div class="col-lg-8">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Nome Scuola <span class="text-danger">*</span></label>
|
||||||
|
<input type="text" class="form-control" name="name" required
|
||||||
|
value="<?php echo htmlspecialchars($school['name'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Nome, slug, ecc... (tutto invariato fino all'indirizzo) -->
|
<div class="col-md-6">
|
||||||
<div class="mb-3">
|
<label class="form-label">Slug (URL personalizzato) <span class="text-danger">*</span></label>
|
||||||
<label for="name" class="form-label">Nome Scuola</label>
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" id="name" name="name"
|
<span class="input-group-text">yogiboook.com/</span>
|
||||||
value="<?php echo htmlspecialchars($school['name'] ?? ''); ?>" required>
|
<input type="text" class="form-control" name="slug" id="slug" required
|
||||||
</div>
|
value="<?php echo htmlspecialchars($school['slug'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="col-md-6">
|
||||||
<label for="slug" class="form-label">Slug (URL personalizzato)</label>
|
<label class="form-label">Sito web</label>
|
||||||
<input type="text" class="form-control" id="slug" name="slug"
|
<input type="url" class="form-control" name="website"
|
||||||
value="<?php echo htmlspecialchars($school['slug'] ?? ''); ?>" required>
|
value="<?php echo htmlspecialchars($school['website'] ?? ''); ?>">
|
||||||
<small class="text-muted">es. yoga-milano</small>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="col-md-6">
|
||||||
<label for="website" class="form-label">Sito Web</label>
|
<label class="form-label">Email scuola <span class="text-danger">*</span></label>
|
||||||
<input type="url" class="form-control" id="website" name="website"
|
<input type="email" class="form-control" name="email" required
|
||||||
value="<?php echo htmlspecialchars($school['website'] ?? ''); ?>">
|
value="<?php echo htmlspecialchars($school['email'] ?? ''); ?>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="col-md-6">
|
||||||
<label for="email" class="form-label">Email Scuola</label>
|
<label class="form-label">Telefono</label>
|
||||||
<input type="email" class="form-control" id="email" name="email"
|
<input type="tel" class="form-control" name="phone"
|
||||||
value="<?php echo htmlspecialchars($school['email'] ?? ''); ?>" required>
|
value="<?php echo htmlspecialchars($school['phone'] ?? ''); ?>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<!-- Editor Quill qui, nella colonna destra -->
|
||||||
<label for="phone" class="form-label">Telefono</label>
|
<div class="col-12">
|
||||||
<input type="text" class="form-control" id="phone" name="phone"
|
<label class="form-label">Descrizione scuola</label>
|
||||||
value="<?php echo htmlspecialchars($school['phone'] ?? ''); ?>">
|
<div id="quill-editor"></div>
|
||||||
</div>
|
<input type="hidden" name="description" id="description-hidden">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="col-12">
|
||||||
<label for="description" class="form-label">Descrizione</label>
|
<hr class="my-4">
|
||||||
<textarea class="form-control" id="description" name="description" rows="3"><?php echo htmlspecialchars($school['description'] ?? ''); ?></textarea>
|
<h6 class="mb-3">Indirizzo sede</h6>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ==================== INIZIO INDIRIZZO + MAPPA ==================== -->
|
<div class="col-12">
|
||||||
<div class="mb-3">
|
<label class="form-label">Via e numero civico</label>
|
||||||
<label for="address_street" class="form-label">Via / Numero civico</label>
|
<input type="text" class="form-control" name="address_street"
|
||||||
<input type="text" class="form-control" id="address_street" name="address_street"
|
value="<?php echo htmlspecialchars($school['address_street'] ?? ''); ?>">
|
||||||
value="<?php echo htmlspecialchars($school['address_street'] ?? ''); ?>">
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="col-md-4">
|
||||||
<div class="col-md-6 mb-3">
|
<label class="form-label">Città</label>
|
||||||
<label for="address_city" class="form-label">Città</label>
|
<input type="text" class="form-control" name="address_city"
|
||||||
<input type="text" class="form-control" id="address_city" name="address_city"
|
|
||||||
value="<?php echo htmlspecialchars($school['address_city'] ?? ''); ?>">
|
value="<?php echo htmlspecialchars($school['address_city'] ?? ''); ?>">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label for="address_postal_code" class="form-label">CAP</label>
|
<div class="col-md-4">
|
||||||
<input type="text" class="form-control" id="address_postal_code" name="address_postal_code"
|
<label class="form-label">CAP</label>
|
||||||
|
<input type="text" class="form-control" name="address_postal_code"
|
||||||
value="<?php echo htmlspecialchars($school['address_postal_code'] ?? ''); ?>">
|
value="<?php echo htmlspecialchars($school['address_postal_code'] ?? ''); ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="col-md-4">
|
||||||
<div class="col-md-6 mb-3">
|
<label class="form-label">Provincia</label>
|
||||||
<label for="address_province" class="form-label">Provincia</label>
|
<input type="text" class="form-control" name="address_province"
|
||||||
<input type="text" class="form-control" id="address_province" name="address_province"
|
|
||||||
value="<?php echo htmlspecialchars($school['address_province'] ?? ''); ?>">
|
value="<?php echo htmlspecialchars($school['address_province'] ?? ''); ?>">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
<label for="address_country" class="form-label">Nazione</label>
|
<div class="col-md-6">
|
||||||
<input type="text" class="form-control" id="address_country" name="address_country"
|
<label class="form-label">Nazione</label>
|
||||||
|
<input type="text" class="form-control" name="address_country"
|
||||||
value="<?php echo htmlspecialchars($school['address_country'] ?? 'Italia'); ?>">
|
value="<?php echo htmlspecialchars($school['address_country'] ?? 'Italia'); ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pulsante geocoding -->
|
<div class="col-md-6 mt-4 pt-2">
|
||||||
<div class="mb-3">
|
<button type="button" class="btn btn-outline-primary w-100" id="geocodeBtn">
|
||||||
<button type="button" class="btn btn-outline-primary geocode-btn" id="geocode-btn">
|
<i class="bx bx-map-pin me-1"></i> Trova coordinate sulla mappa
|
||||||
Cerca sulla mappa
|
</button>
|
||||||
</button>
|
</div>
|
||||||
<small class="text-muted d-block">Compila via + città + CAP → clicca qui</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Mappa -->
|
<div class="col-12">
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Latitudine e Longitudine (readonly ma modificabili manualmente se serve) -->
|
|
||||||
<div class="row mt-3">
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label for="latitude" class="form-label">Latitudine</label>
|
<label class="form-label">Latitudine</label>
|
||||||
<input type="text" class="form-control" id="latitude" name="latitude"
|
<input type="text" class="form-control" name="latitude" id="latitude"
|
||||||
value="<?php echo htmlspecialchars($school['latitude'] ?? ''); ?>" readonly>
|
value="<?php echo htmlspecialchars($school['latitude'] ?? ''); ?>" readonly>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label for="longitude" class="form-label">Longitudine</label>
|
<label class="form-label">Longitudine</label>
|
||||||
<input type="text" class="form-control" id="longitude" name="longitude"
|
<input type="text" class="form-control" name="longitude" id="longitude"
|
||||||
value="<?php echo htmlspecialchars($school['longitude'] ?? ''); ?>" readonly>
|
value="<?php echo htmlspecialchars($school['longitude'] ?? ''); ?>" readonly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<!-- ==================== FINE INDIRIZZO + MAPPA ==================== -->
|
|
||||||
|
|
||||||
<hr class="my-4">
|
<div class="col-12">
|
||||||
|
<hr class="my-4">
|
||||||
<div class="mb-3">
|
<h6 class="mb-3">Dati amministrativi</h6>
|
||||||
<label for="owner_name" class="form-label">Nome Proprietario</label>
|
|
||||||
<input type="text" class="form-control" id="owner_name" name="owner_name"
|
|
||||||
value="<?php echo htmlspecialchars($school['owner_name'] ?? ''); ?>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="vat_number" class="form-label">Partita IVA</label>
|
|
||||||
<input type="text" class="form-control" id="vat_number" name="vat_number"
|
|
||||||
value="<?php echo htmlspecialchars($school['vat_number'] ?? ''); ?>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="status" class="form-label">Stato</label>
|
|
||||||
<select class="form-control" id="status" name="status">
|
|
||||||
<option value="active" <?php echo ($school['status'] ?? '') === 'active' ? 'selected' : ''; ?>>Attivo</option>
|
|
||||||
<option value="inactive" <?php echo ($school['status'] ?? '') === 'inactive' ? 'selected' : ''; ?>>Inattivo</option>
|
|
||||||
<option value="suspended" <?php echo ($school['status'] ?? '') === 'suspended' ? 'selected' : ''; ?>>Sospeso</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (!$is_new): ?>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Creato il</label>
|
|
||||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($school['created_at'] ?? ''); ?>" readonly>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Ultimo aggiornamento</label>
|
|
||||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($school['updated_at'] ?? ''); ?>" readonly>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary btn-lg">
|
<div class="col-md-6">
|
||||||
<?php echo $is_new ? 'Crea Profilo' : 'Salva Modifiche'; ?>
|
<label class="form-label">Nome proprietario / legale</label>
|
||||||
</button>
|
<input type="text" class="form-control" name="owner_name"
|
||||||
|
value="<?php echo htmlspecialchars($school['owner_name'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Partita IVA</label>
|
||||||
|
<input type="text" class="form-control" name="vat_number"
|
||||||
|
value="<?php echo htmlspecialchars($school['vat_number'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Stato</label>
|
||||||
|
<select class="form-select" name="status">
|
||||||
|
<option value="active" <?php echo ($school['status'] ?? '') === 'active' ? 'selected' : ''; ?>>Attiva</option>
|
||||||
|
<option value="inactive" <?php echo ($school['status'] ?? '') === 'inactive' ? 'selected' : ''; ?>>Inattiva</option>
|
||||||
|
<option value="suspended" <?php echo ($school['status'] ?? '') === 'suspended' ? 'selected' : ''; ?>>Sospesa</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12 mt-5">
|
||||||
|
<button type="submit" class="btn btn-primary btn-lg px-5">
|
||||||
|
<i class="bx bx-save me-2"></i>
|
||||||
|
<?php echo $is_new ? 'Crea Scuola' : 'Salva Modifiche'; ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -426,54 +419,97 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overlay toggle-icon"></div>
|
|
||||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
|
||||||
<?php include('include/footer.php'); ?>
|
<?php include('include/footer.php'); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php include('jsinclude.php'); ?>
|
<?php include('jsinclude.php'); ?>
|
||||||
|
|
||||||
<!-- Leaflet JS -->
|
<!-- Quill.js -->
|
||||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"></script>
|
||||||
integrity="sha256-o9N1j3Z3B9n0nN2V3H7N7X8z0z1k6p3c1F0L5g0B6p8=" crossorigin=""></script>
|
|
||||||
|
<!-- Leaflet -->
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||||
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// ====================== QUILL EDITOR - colori testo e sfondo visibili ======================
|
||||||
|
const quill = new Quill('#quill-editor', {
|
||||||
|
theme: 'snow',
|
||||||
|
modules: {
|
||||||
|
toolbar: [
|
||||||
|
['bold', 'italic', 'underline', 'strike'],
|
||||||
|
['blockquote', 'code-block'],
|
||||||
|
[{
|
||||||
|
'header': [1, 2, 3, false]
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'color': [
|
||||||
|
'#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc', '#d9d9d9', '#ffffff',
|
||||||
|
'#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#0000ff', '#9900ff', '#ff00ff',
|
||||||
|
'#ffcccc', '#ffe6cc', '#ffffcc', '#ccffcc', '#ccffff', '#ccccff', '#e6ccff', '#ffccff'
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
'background': [
|
||||||
|
'#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc', '#d9d9d9', '#ffffff',
|
||||||
|
'#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#0000ff', '#9900ff', '#ff00ff',
|
||||||
|
'#ffcccc', '#ffe6cc', '#ffffcc', '#ccffcc', '#ccffff', '#ccccff', '#e6ccff', '#ffccff'
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'list': 'ordered'
|
||||||
|
}, {
|
||||||
|
'list': 'bullet'
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'align': []
|
||||||
|
}],
|
||||||
|
['link', 'clean']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Carica contenuto iniziale (HTML)
|
||||||
|
quill.root.innerHTML = `<?php echo addslashes($school['description'] ?? ''); ?>`;
|
||||||
|
|
||||||
|
// Salva HTML prima del submit
|
||||||
|
document.getElementById('schoolForm').addEventListener('submit', function(e) {
|
||||||
|
document.getElementById('description-hidden').value = quill.root.innerHTML;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ====================== MAPPA (invariata, funziona già) ======================
|
||||||
let map, marker;
|
let map, marker;
|
||||||
|
|
||||||
// Inizializza la mappa
|
function initMap(lat = 45.4642, lng = 9.1900, zoom = 12) {
|
||||||
function initMap(lat = 41.9028, lng = 12.4964, zoom = 5) {
|
|
||||||
if (map) map.remove();
|
if (map) map.remove();
|
||||||
|
|
||||||
map = L.map('map').setView([lat, lng], zoom);
|
map = L.map('map').setView([lat, lng], zoom);
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
attribution: '© OpenStreetMap contributors'
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
|
|
||||||
marker = L.marker([lat, lng], {
|
marker = L.marker([lat, lng], {
|
||||||
draggable: true
|
draggable: true
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
|
marker.on('dragend', function(e) {
|
||||||
marker.on('dragend', function() {
|
const pos = e.target.getLatLng();
|
||||||
const pos = marker.getLatLng();
|
|
||||||
document.getElementById('latitude').value = pos.lat.toFixed(8);
|
document.getElementById('latitude').value = pos.lat.toFixed(8);
|
||||||
document.getElementById('longitude').value = pos.lng.toFixed(8);
|
document.getElementById('longitude').value = pos.lng.toFixed(8);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aggiorna mappa e campi
|
|
||||||
function updateMap(lat, lng) {
|
function updateMap(lat, lng) {
|
||||||
|
if (!map) initMap(lat, lng, 16);
|
||||||
|
else {
|
||||||
|
map.setView([lat, lng], 16);
|
||||||
|
marker.setLatLng([lat, lng]);
|
||||||
|
}
|
||||||
document.getElementById('latitude').value = lat.toFixed(8);
|
document.getElementById('latitude').value = lat.toFixed(8);
|
||||||
document.getElementById('longitude').value = lng.toFixed(8);
|
document.getElementById('longitude').value = lng.toFixed(8);
|
||||||
map.setView([lat, lng], 16);
|
|
||||||
if (marker) marker.setLatLng([lat, lng]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Geocoding con Nominatim
|
document.getElementById('geocodeBtn')?.addEventListener('click', function() {
|
||||||
document.getElementById('geocode-btn').addEventListener('click', function() {
|
const street = document.querySelector('[name="address_street"]').value.trim();
|
||||||
const street = document.getElementById('address_street').value.trim();
|
const city = document.querySelector('[name="address_city"]').value.trim();
|
||||||
const city = document.getElementById('address_city').value.trim();
|
const cap = document.querySelector('[name="address_postal_code"]').value.trim();
|
||||||
const cap = document.getElementById('address_postal_code').value.trim();
|
const country = document.querySelector('[name="address_country"]').value.trim() || 'Italia';
|
||||||
const country = document.getElementById('address_country').value.trim() || 'Italia';
|
|
||||||
|
|
||||||
if (!street || !city) {
|
if (!street || !city) {
|
||||||
alert('Inserisci almeno Via e Città');
|
alert('Inserisci almeno Via e Città');
|
||||||
@ -486,52 +522,37 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
fetch(url)
|
fetch(url)
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data && data.length > 0) {
|
if (data?.length > 0) {
|
||||||
const r = data[0];
|
const loc = data[0];
|
||||||
updateMap(parseFloat(r.lat), parseFloat(r.lon));
|
updateMap(parseFloat(loc.lat), parseFloat(loc.lon));
|
||||||
} else {
|
} else {
|
||||||
alert('Indirizzo non trovato. Controlla i dati.');
|
alert('Indirizzo non trovato.');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => alert('Errore di rete. Riprova.'));
|
.catch(() => alert('Errore durante la ricerca.'));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Al caricamento della pagina
|
// Init mappa
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const lat = document.getElementById('latitude').value;
|
const lat = parseFloat(document.getElementById('latitude').value);
|
||||||
const lng = document.getElementById('longitude').value;
|
const lng = parseFloat(document.getElementById('longitude').value);
|
||||||
|
if (!isNaN(lat) && !isNaN(lng)) {
|
||||||
if (lat && lng) {
|
initMap(lat, lng, 16);
|
||||||
initMap(parseFloat(lat), parseFloat(lng), 16);
|
|
||||||
} else {
|
} else {
|
||||||
initMap(); // Italia centrata
|
initMap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Slug automatico (il tuo codice originale – invariato) */
|
// Slug automatico
|
||||||
const nameInput = document.getElementById('name');
|
const nameField = document.querySelector('[name="name"]');
|
||||||
const slugInput = document.getElementById('slug');
|
const slugField = document.querySelector('[name="slug"]');
|
||||||
let isUserTypingSlug = false;
|
let slugTouched = false;
|
||||||
|
|
||||||
function generateSlug(str) {
|
nameField?.addEventListener('input', function() {
|
||||||
return str.toLowerCase()
|
if (!slugTouched) slugField.value = generateSlug(this.value);
|
||||||
.replace(/[^a-z0-9-]+/g, '-')
|
|
||||||
.replace(/-+/g, '-')
|
|
||||||
.replace(/^-|-$/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
nameInput?.addEventListener('input', function() {
|
|
||||||
if (!isUserTypingSlug) {
|
|
||||||
slugInput.value = generateSlug(this.value);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
slugInput?.addEventListener('input', function(e) {
|
slugField?.addEventListener('input', () => slugTouched = true);
|
||||||
isUserTypingSlug = true;
|
|
||||||
this.value = generateSlug(this.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
slugInput?.addEventListener('blur', () => isUserTypingSlug = false);
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
317
public/userarea/teacher_list.php
Normal file
317
public/userarea/teacher_list.php
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<?php
|
||||||
|
// teacher_list.php
|
||||||
|
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('display_startup_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
include('include/headscript.php');
|
||||||
|
require_once 'class/mailer.php';
|
||||||
|
|
||||||
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
|
if (!isset($iduserlogin)) {
|
||||||
|
die("Errore: utente non loggato.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recupera scuola corrente
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT id, name, owner_id, email AS school_email
|
||||||
|
FROM schools
|
||||||
|
WHERE owner_id = ?
|
||||||
|
");
|
||||||
|
$stmt->execute([$iduserlogin]);
|
||||||
|
$school = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$school) {
|
||||||
|
die("Errore: nessuna scuola trovata per questo proprietario.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$school_id = $school['id'];
|
||||||
|
$school_name = $school['name'];
|
||||||
|
$school_email = $school['school_email'];
|
||||||
|
|
||||||
|
// Messaggi
|
||||||
|
$success = $_GET['success'] ?? null;
|
||||||
|
$error = $_GET['error'] ?? null;
|
||||||
|
|
||||||
|
// COLLEGAMENTO TRAMITE CODICE
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'link_by_code') {
|
||||||
|
$unique_code = trim($_POST['unique_code'] ?? '');
|
||||||
|
$link_id = (int)$pdo->lastInsertId();
|
||||||
|
|
||||||
|
|
||||||
|
if (empty($unique_code)) {
|
||||||
|
$error = "Inserisci un codice univoco valido.";
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT t.id AS teacher_id, u.first_name, u.last_name, u.email
|
||||||
|
FROM teachers t
|
||||||
|
JOIN auth_users u ON t.user_id = u.id
|
||||||
|
WHERE t.unique_code = ?
|
||||||
|
");
|
||||||
|
$stmt->execute([$unique_code]);
|
||||||
|
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$teacher) {
|
||||||
|
$error = "Nessun insegnante trovato con questo codice.";
|
||||||
|
} else {
|
||||||
|
$check = $pdo->prepare("SELECT id FROM teacher_schools WHERE teacher_id = ? AND school_id = ?");
|
||||||
|
$check->execute([$teacher['teacher_id'], $school_id]);
|
||||||
|
|
||||||
|
if ($check->fetch()) {
|
||||||
|
$error = "Insegnante già collegata.";
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO teacher_schools
|
||||||
|
(teacher_id, school_id, status, created_at, updated_at)
|
||||||
|
VALUES (?, ?, 'pending', NOW(), NOW())
|
||||||
|
");
|
||||||
|
$stmt->execute([$teacher['teacher_id'], $school_id]);
|
||||||
|
|
||||||
|
// Email richiesta
|
||||||
|
$subject = "Richiesta collegamento a {$school_name}";
|
||||||
|
$body = "
|
||||||
|
<h2>Ciao {$teacher['first_name']},</h2>
|
||||||
|
<p>{$school_name} vorrebbe collegarti alla sua scuola su YogiBoook.</p>
|
||||||
|
<p style='margin:30px 0;'>
|
||||||
|
<a href='http://localhost/yogiboook/public/userarea/confirm_link.php?code=" . urlencode($unique_code) . "&school={$school_id}'
|
||||||
|
style='background:#0d6efd;color:white;padding:12px 24px;text-decoration:none;border-radius:6px;'>
|
||||||
|
Accetta
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>Se non riconosci questa richiesta, ignora l'email.</p>
|
||||||
|
";
|
||||||
|
|
||||||
|
$result = sendEmail($teacher['email'], $subject, $body);
|
||||||
|
|
||||||
|
$success = $result['success']
|
||||||
|
? "Richiesta inviata!"
|
||||||
|
: "Collegamento creato, ma errore email: " . $result['message'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LISTA INSEGNANTI
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
t.id, t.user_id, t.phone, t.description, t.specializations, t.profile_picture,
|
||||||
|
u.first_name, u.last_name, u.email,
|
||||||
|
ts.status AS link_status, ts.created_at AS linked_at,
|
||||||
|
(t.created_by = ?) AS can_edit
|
||||||
|
FROM teacher_schools ts
|
||||||
|
JOIN teachers t ON ts.teacher_id = t.id
|
||||||
|
JOIN auth_users u ON t.user_id = u.id
|
||||||
|
WHERE ts.school_id = ? AND ts.status IN ('active','pending')
|
||||||
|
ORDER BY u.last_name, u.first_name
|
||||||
|
");
|
||||||
|
$stmt->execute([$iduserlogin, $school_id]);
|
||||||
|
$teachers = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="it">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Insegnanti - <?= htmlspecialchars($school_name) ?></title>
|
||||||
|
<?php include('cssinclude.php'); ?>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.snow.css" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
.quill-wrapper {
|
||||||
|
min-height: 260px;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-container {
|
||||||
|
min-height: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-editor {
|
||||||
|
min-height: 220px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<?php include('include/navbar.php'); ?>
|
||||||
|
<?php include('include/topbar.php'); ?>
|
||||||
|
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<div class="page-content">
|
||||||
|
<h4 class="mb-4">Insegnanti di <?= htmlspecialchars($school_name) ?></h4>
|
||||||
|
|
||||||
|
<?php if ($success): ?>
|
||||||
|
<div class="alert alert-success alert-dismissible fade show"><?= $success ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show"><?= htmlspecialchars($error) ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="card radius-10">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex justify-content-end mb-3">
|
||||||
|
<button class="btn btn-primary me-2" data-bs-toggle="modal" data-bs-target="#addTeacherModal">
|
||||||
|
<i class="bx bx-plus"></i> Nuova insegnante
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#linkTeacherModal">
|
||||||
|
<i class="bx bx-link"></i> Collega esistente
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (empty($teachers)): ?>
|
||||||
|
<div class="text-center py-5 text-muted">
|
||||||
|
<i class="bx bx-user-x fs-1 mb-3 opacity-50"></i>
|
||||||
|
<p>Nessuna insegnante collegata.</p>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Foto</th>
|
||||||
|
<th>Nome</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Telefono</th>
|
||||||
|
<th>Stato</th>
|
||||||
|
<th>Azioni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($teachers as $t): ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<?php if ($t['profile_picture']): ?>
|
||||||
|
<img src="<?= htmlspecialchars($t['profile_picture']) ?>" class="rounded" width="50" height="50" style="object-fit:cover;">
|
||||||
|
<?php else: ?>
|
||||||
|
<i class="bx bx-user-circle fs-3 text-muted"></i>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td><?= htmlspecialchars($t['first_name'] . ' ' . $t['last_name']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($t['email']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($t['phone'] ?: '—') ?></td>
|
||||||
|
<td>
|
||||||
|
<span class="badge bg-<?= $t['link_status'] === 'active' ? 'success' : 'warning' ?>">
|
||||||
|
<?= ucfirst($t['link_status']) ?>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<?php if ($t['can_edit']): ?>
|
||||||
|
<a href="teacher_profile.php?id=<?= $t['id'] ?>" class="btn btn-sm btn-warning"><i class="bx bx-edit"></i></a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MODALE AGGIUNGI -->
|
||||||
|
<div class="modal fade" id="addTeacherModal" tabindex="-1" aria-labelledby="addTeacherLabel">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="addTeacherLabel">Nuova insegnante</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<form action="add_teacher.php" method="POST" enctype="multipart/form-data" id="addTeacherForm">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" name="school_id" value="<?= $school_id ?>">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6"><label>Nome *</label><input type="text" name="first_name" class="form-control" required></div>
|
||||||
|
<div class="col-md-6"><label>Cognome *</label><input type="text" name="last_name" class="form-control" required></div>
|
||||||
|
<div class="col-md-6"><label>Email *</label><input type="email" name="email" class="form-control" required></div>
|
||||||
|
<div class="col-md-6"><label>Telefono</label><input type="tel" name="phone" class="form-control"></div>
|
||||||
|
<div class="col-12"><label>Specializzazioni</label><textarea name="specializations" class="form-control" rows="2"></textarea></div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<label>Descrizione</label>
|
||||||
|
<div id="quill-add-editor" style="min-height:260px;"></div>
|
||||||
|
<input type="hidden" name="description" id="add-desc-hidden">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6"><label>Foto</label><input type="file" name="profile_picture" class="form-control" accept="image/*"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Crea</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MODALE COLLEGAMENTO -->
|
||||||
|
<div class="modal fade" id="linkTeacherModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5>Collega insegnante esistente</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<form method="POST">
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" name="action" value="link_by_code">
|
||||||
|
<label>Codice univoco</label>
|
||||||
|
<input type="text" name="unique_code" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Collega</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('include/footer.php'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('jsinclude.php'); ?>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Quill per modale - inizializza DOPO apertura modale
|
||||||
|
const quillAdd = new Quill('#quill-add-editor', {
|
||||||
|
theme: 'snow',
|
||||||
|
modules: {
|
||||||
|
toolbar: [
|
||||||
|
['bold', 'italic', 'underline', 'strike'],
|
||||||
|
[{
|
||||||
|
'color': []
|
||||||
|
}, {
|
||||||
|
'background': []
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'list': 'ordered'
|
||||||
|
}, {
|
||||||
|
'list': 'bullet'
|
||||||
|
}],
|
||||||
|
['link', 'clean']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('addTeacherModal').addEventListener('shown.bs.modal', function() {
|
||||||
|
quillAdd.update(); // Forza refresh dopo apertura
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('addTeacherForm').addEventListener('submit', function(e) {
|
||||||
|
document.getElementById('add-desc-hidden').value = quillAdd.root.innerHTML;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@ -1,42 +1,72 @@
|
|||||||
<?php
|
<?php
|
||||||
// Forza la visualizzazione degli errori
|
// teacher_profile.php
|
||||||
|
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('display_startup_errors', 1);
|
ini_set('display_startup_errors', 1);
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
include('include/headscript.php');
|
include('include/headscript.php');
|
||||||
|
|
||||||
// Importa la libreria QR Code
|
// QR Code library
|
||||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||||
|
|
||||||
use Endroid\QrCode\Builder\Builder;
|
use Endroid\QrCode\QrCode;
|
||||||
use Endroid\QrCode\Writer\PngWriter;
|
use Endroid\QrCode\Writer\PngWriter;
|
||||||
|
|
||||||
// Connessione al database
|
|
||||||
$dbHandler = DBHandlerSelect::getInstance();
|
$dbHandler = DBHandlerSelect::getInstance();
|
||||||
$pdo = $dbHandler->getConnection();
|
$pdo = $dbHandler->getConnection();
|
||||||
|
|
||||||
// ID dell'utente loggato (assumiamo sia definito)
|
|
||||||
if (!isset($iduserlogin)) {
|
if (!isset($iduserlogin)) {
|
||||||
die("Errore: ID utente non definito.");
|
die("Errore: ID utente non definito.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recupera i dati dell'insegnante
|
$teacher_id = (int)($_GET['id'] ?? 0);
|
||||||
$stmt = $pdo->prepare("
|
$is_owner_view = ($teacher_id > 0); // se arrivi da teacher_list.php con ?id=...
|
||||||
SELECT t.*, u.first_name, u.last_name, u.email
|
|
||||||
FROM auth_users u
|
|
||||||
LEFT JOIN teachers t ON t.user_id = u.id
|
|
||||||
WHERE u.id = ?
|
|
||||||
");
|
|
||||||
$stmt->execute([$iduserlogin]);
|
|
||||||
$teacher = $stmt->fetch();
|
|
||||||
|
|
||||||
if (!$teacher) {
|
|
||||||
die("Errore: Utente non trovato.");
|
if ($teacher_id > 0) {
|
||||||
|
// === OWNER VIEW: carica teacher per teachers.id SOLO se l'owner ha diritto ===
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
t.*,
|
||||||
|
u.first_name, u.last_name, u.email
|
||||||
|
FROM teachers t
|
||||||
|
JOIN auth_users u ON t.user_id = u.id
|
||||||
|
JOIN teacher_schools ts ON ts.teacher_id = t.id
|
||||||
|
JOIN schools s ON s.id = ts.school_id
|
||||||
|
WHERE t.id = ?
|
||||||
|
AND s.owner_id = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$teacher_id, $iduserlogin]);
|
||||||
|
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$teacher) {
|
||||||
|
die("Errore: insegnante non trovata o non hai permessi.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// === TEACHER SELF VIEW: carica il profilo dell'utente loggato ===
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
t.*,
|
||||||
|
u.first_name, u.last_name, u.email
|
||||||
|
FROM auth_users u
|
||||||
|
LEFT JOIN teachers t ON t.user_id = u.id
|
||||||
|
WHERE u.id = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$iduserlogin]);
|
||||||
|
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determina se è un nuovo insegnante
|
|
||||||
$is_new = !isset($teacher['id']);
|
$is_new = empty($teacher['id']); // ok così
|
||||||
|
if ($teacher_id > 0) {
|
||||||
|
$is_new = false; // owner sta editando una teacher esistente
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($is_new) {
|
if ($is_new) {
|
||||||
$teacher = [
|
$teacher = [
|
||||||
'id' => null,
|
'id' => null,
|
||||||
@ -49,267 +79,351 @@ if ($is_new) {
|
|||||||
'status' => 'active',
|
'status' => 'active',
|
||||||
'created_at' => '',
|
'created_at' => '',
|
||||||
'updated_at' => '',
|
'updated_at' => '',
|
||||||
'first_name' => $teacher['first_name'],
|
'first_name' => '',
|
||||||
'last_name' => $teacher['last_name'],
|
'last_name' => '',
|
||||||
'email' => $teacher['email']
|
'email' => ''
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funzione per generare un codice univoco
|
|
||||||
function generateUniqueCode($pdo, $length = 16)
|
function generateUniqueCode($pdo, $length = 16)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
$code = bin2hex(random_bytes($length / 2));
|
$code = bin2hex(random_bytes($length / 2));
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM teachers WHERE unique_code = ?");
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM teachers WHERE unique_code = ?");
|
||||||
$stmt->execute([$code]);
|
$stmt->execute([$code]);
|
||||||
$count = $stmt->fetchColumn();
|
} while ($stmt->fetchColumn() > 0);
|
||||||
} while ($count > 0);
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generazione del QR Code
|
function writeQrPng($text, $filename, $size = 150, $margin = 10)
|
||||||
$qr_code_path = null;
|
{
|
||||||
if (!$is_new) {
|
// ✅ nella tua versione il costruttore vuole il testo
|
||||||
try {
|
$qrCode = new \Endroid\QrCode\QrCode($text);
|
||||||
$unique_code = $teacher['unique_code'];
|
|
||||||
if (empty($unique_code)) {
|
// size: alcune versioni hanno setSize(), altre setModuleSize()
|
||||||
throw new Exception("Errore: unique_code è vuoto.");
|
if (method_exists($qrCode, 'setSize')) {
|
||||||
|
$qrCode->setSize($size);
|
||||||
|
} elseif (method_exists($qrCode, 'setModuleSize')) {
|
||||||
|
$module = max(3, (int)round($size / 25)); // mapping semplice
|
||||||
|
$qrCode->setModuleSize($module);
|
||||||
|
}
|
||||||
|
|
||||||
|
// margin: alcune versioni setMargin(), altre setPadding()
|
||||||
|
if (method_exists($qrCode, 'setMargin')) {
|
||||||
|
$qrCode->setMargin($margin);
|
||||||
|
} elseif (method_exists($qrCode, 'setPadding')) {
|
||||||
|
$qrCode->setPadding($margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
$writer = new \Endroid\QrCode\Writer\PngWriter();
|
||||||
|
|
||||||
|
if (method_exists($writer, 'writeFile')) {
|
||||||
|
$writer->writeFile($qrCode, $filename);
|
||||||
|
} else {
|
||||||
|
$result = $writer->write($qrCode);
|
||||||
|
if (is_object($result) && method_exists($result, 'saveToFile')) {
|
||||||
|
$result->saveToFile($filename);
|
||||||
|
} else {
|
||||||
|
file_put_contents($filename, (string)$result);
|
||||||
}
|
}
|
||||||
|
|
||||||
$base_dir = __DIR__ . '/../../public/userarea/phototeachers/qrcodes/';
|
|
||||||
$qr_code_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
|
|
||||||
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
|
|
||||||
|
|
||||||
if (!file_exists($qr_code_filename)) {
|
|
||||||
if (!is_dir($base_dir)) {
|
|
||||||
mkdir($base_dir, 0755, true) or die("Errore: Impossibile creare la directory.");
|
|
||||||
}
|
|
||||||
if (!is_writable($base_dir)) {
|
|
||||||
die("Errore: La directory non è scrivibile.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$builder = new Builder();
|
|
||||||
$result = $builder->build(
|
|
||||||
writer: new PngWriter(),
|
|
||||||
data: $unique_code,
|
|
||||||
size: 150,
|
|
||||||
margin: 10
|
|
||||||
);
|
|
||||||
$result->saveToFile($qr_code_filename);
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$error = "Errore generazione QR Code: " . $e->getMessage();
|
|
||||||
error_log($error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestione del form
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
||||||
$first_name = $_POST['first_name'];
|
|
||||||
$last_name = $_POST['last_name'];
|
|
||||||
$phone = $_POST['phone'] ?? null;
|
|
||||||
$description = $_POST['description'] ?? null;
|
|
||||||
$specializations = $_POST['specializations'] ?? null;
|
|
||||||
$status = $_POST['status'] === 'active' ? 'active' : 'inactive';
|
|
||||||
|
|
||||||
// Gestione del caricamento della foto
|
|
||||||
$profile_picture = $teacher['profile_picture'];
|
|
||||||
if (isset($_FILES['profile_picture']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
|
|
||||||
$file = $_FILES['profile_picture'];
|
|
||||||
$timestamp = time();
|
|
||||||
$original_name = basename($file['name']);
|
|
||||||
$extension = strtolower(pathinfo($original_name, PATHINFO_EXTENSION));
|
|
||||||
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
|
|
||||||
|
|
||||||
if (in_array($extension, $allowed_extensions)) {
|
$qr_code_path = null;
|
||||||
$new_filename = "phototeachers/{$iduserlogin}-{$timestamp}-{$original_name}";
|
if (!$is_new && !empty($teacher['unique_code'])) {
|
||||||
if (move_uploaded_file($file['tmp_name'], $new_filename)) {
|
try {
|
||||||
$profile_picture = $new_filename;
|
$unique_code = $teacher['unique_code'];
|
||||||
if ($teacher['profile_picture'] && file_exists($teacher['profile_picture']) && !$is_new) {
|
$base_dir = __DIR__ . '/../../public/phototeachers/qrcodes/';
|
||||||
unlink($teacher['profile_picture']);
|
$qr_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
|
||||||
}
|
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
|
||||||
} else {
|
|
||||||
$error = "Errore durante il caricamento della foto.";
|
if (!file_exists($qr_filename)) {
|
||||||
}
|
if (!is_dir($base_dir)) mkdir($base_dir, 0755, true);
|
||||||
} else {
|
writeQrPng($unique_code, $qr_filename, 150, 10);
|
||||||
$error = "Estensione del file non consentita. Usa JPG, JPEG, PNG o GIF.";
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("Errore QR: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$success_message = $error = null;
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// ✅ target: se owner sta editando una teacher (?id=..), salva su QUELLA teacher
|
||||||
|
$target_user_id = ($teacher_id > 0) ? (int)$teacher['user_id'] : (int)$iduserlogin;
|
||||||
|
$target_teacher_id = ($teacher_id > 0) ? (int)$teacher['id'] : (int)($teacher['id'] ?? 0);
|
||||||
|
$first_name = trim($_POST['first_name'] ?? '');
|
||||||
|
$last_name = trim($_POST['last_name'] ?? '');
|
||||||
|
$phone = trim($_POST['phone'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$specializations = trim($_POST['specializations'] ?? '');
|
||||||
|
$status = ($_POST['status'] ?? 'active') === 'active' ? 'active' : 'inactive';
|
||||||
|
|
||||||
|
$target_user_id = ($teacher_id > 0) ? (int)$teacher['user_id'] : (int)$iduserlogin;
|
||||||
|
|
||||||
// Aggiorna auth_users
|
|
||||||
$stmt = $pdo->prepare("UPDATE auth_users SET first_name = ?, last_name = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE auth_users SET first_name = ?, last_name = ? WHERE id = ?");
|
||||||
$stmt->execute([$first_name, $last_name, $iduserlogin]);
|
$stmt->execute([$first_name, $last_name, $target_user_id]);
|
||||||
|
|
||||||
|
|
||||||
|
$profile_picture = $teacher['profile_picture'] ?? '';
|
||||||
|
if (!empty($_FILES['profile_picture']['name']) && $_FILES['profile_picture']['error'] === UPLOAD_ERR_OK) {
|
||||||
|
$ext = strtolower(pathinfo($_FILES['profile_picture']['name'], PATHINFO_EXTENSION));
|
||||||
|
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||||
|
$new_name = "phototeachers/{$target_user_id}-" . time() . "-profile.$ext";
|
||||||
|
|
||||||
|
if (move_uploaded_file($_FILES['profile_picture']['tmp_name'], $new_name)) {
|
||||||
|
if ($profile_picture && file_exists($profile_picture) && !$is_new) @unlink($profile_picture);
|
||||||
|
$profile_picture = $new_name;
|
||||||
|
} else $error = "Errore caricamento foto.";
|
||||||
|
} else $error = "Solo JPG, PNG, GIF ammessi.";
|
||||||
|
}
|
||||||
|
|
||||||
if ($is_new) {
|
if ($is_new) {
|
||||||
$unique_code = generateUniqueCode($pdo);
|
$unique_code = generateUniqueCode($pdo);
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
INSERT INTO teachers (user_id, unique_code, phone, description, specializations, profile_picture, status)
|
INSERT INTO teachers
|
||||||
|
(user_id, unique_code, phone, description, specializations, profile_picture, status)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
");
|
");
|
||||||
$success = $stmt->execute([$iduserlogin, $unique_code, $phone, $description, $specializations, $profile_picture, $status]);
|
$success = $stmt->execute([$target_user_id, $unique_code, $phone ?: null, $description, $specializations, $profile_picture, $status]);
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
$success_message = "Insegnante creato con successo!";
|
$success_message = "Profilo creato!";
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("SELECT t.*, u.first_name, u.last_name, u.email
|
||||||
SELECT t.*, u.first_name, u.last_name, u.email
|
FROM teachers t JOIN auth_users u ON t.user_id = u.id
|
||||||
FROM auth_users u
|
WHERE t.user_id = ?");
|
||||||
LEFT JOIN teachers t ON t.user_id = u.id
|
|
||||||
WHERE u.id = ?
|
|
||||||
");
|
|
||||||
$stmt->execute([$iduserlogin]);
|
$stmt->execute([$iduserlogin]);
|
||||||
$teacher = $stmt->fetch();
|
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
$is_new = false;
|
$is_new = false;
|
||||||
|
|
||||||
// Genera QR Code per il nuovo insegnante
|
|
||||||
try {
|
try {
|
||||||
$base_dir = __DIR__ . '/../../public/phototeachers/qrcodes/';
|
$base_dir = __DIR__ . '/../../public/phototeachers/qrcodes/';
|
||||||
$qr_code_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
|
$qr_filename = "{$base_dir}{$iduserlogin}-{$unique_code}.png";
|
||||||
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
|
$qr_code_path = "phototeachers/qrcodes/{$iduserlogin}-{$unique_code}.png";
|
||||||
|
if (!file_exists($qr_filename)) {
|
||||||
if (!file_exists($qr_code_filename)) {
|
if (!is_dir($base_dir)) mkdir($base_dir, 0755, true);
|
||||||
if (!is_dir($base_dir)) {
|
$writer = new PngWriter();
|
||||||
mkdir($base_dir, 0755, true) or die("Errore: Impossibile creare la directory.");
|
if (!file_exists($qr_filename)) {
|
||||||
|
if (!is_dir($base_dir)) mkdir($base_dir, 0755, true);
|
||||||
|
writeQrPng($unique_code, $qr_filename, 150, 10);
|
||||||
}
|
}
|
||||||
$builder = new Builder();
|
|
||||||
$result = $builder->build(
|
|
||||||
writer: new PngWriter(),
|
$result = $writer->write($qrCode);
|
||||||
data: $unique_code,
|
$result->saveToFile($qr_filename);
|
||||||
size: 150,
|
|
||||||
margin: 10
|
|
||||||
);
|
|
||||||
$result->saveToFile($qr_code_filename);
|
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$error = "Errore generazione QR Code: " . $e->getMessage();
|
error_log("Errore QR: " . $e->getMessage());
|
||||||
error_log($error);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else $error = "Errore creazione.";
|
||||||
$error = "Errore durante la creazione dell'insegnante.";
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
UPDATE teachers
|
UPDATE teachers
|
||||||
SET phone = ?, description = ?, specializations = ?, profile_picture = ?, status = ?
|
SET phone = ?, description = ?, specializations = ?, profile_picture = ?, status = ?
|
||||||
WHERE user_id = ?
|
WHERE user_id = ?
|
||||||
");
|
");
|
||||||
$success = $stmt->execute([$phone, $description, $specializations, $profile_picture, $status, $iduserlogin]);
|
$success = $stmt->execute([$phone ?: null, $description, $specializations, $profile_picture, $status, $target_user_id]);
|
||||||
|
|
||||||
if ($success) {
|
if ($success) {
|
||||||
$success_message = "Dati aggiornati con successo!";
|
$success_message = "Dati aggiornati!";
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("SELECT t.*, u.first_name, u.last_name, u.email
|
||||||
SELECT t.*, u.first_name, u.last_name, u.email
|
FROM teachers t JOIN auth_users u ON t.user_id = u.id
|
||||||
FROM auth_users u
|
WHERE t.user_id = ?");
|
||||||
LEFT JOIN teachers t ON t.user_id = u.id
|
|
||||||
WHERE u.id = ?
|
|
||||||
");
|
|
||||||
$stmt->execute([$iduserlogin]);
|
$stmt->execute([$iduserlogin]);
|
||||||
$teacher = $stmt->fetch();
|
$teacher = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
} else {
|
} else $error = "Errore aggiornamento.";
|
||||||
$error = "Errore durante l'aggiornamento dei dati.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="it">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
<title><?php echo $is_new ? 'Crea' : 'Modifica'; ?> Profilo Insegnante</title>
|
||||||
<?php include('cssinclude.php'); ?>
|
<?php include('cssinclude.php'); ?>
|
||||||
<?php include('siteinfo.php'); ?>
|
<?php include('siteinfo.php'); ?>
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.snow.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.teacher-photo {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 260px;
|
||||||
|
object-fit: contain;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
background: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quill-wrapper {
|
||||||
|
min-height: 300px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-container {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 0 0 0.375rem 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-editor {
|
||||||
|
min-height: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ql-toolbar {
|
||||||
|
border-radius: 0.375rem 0.375rem 0 0;
|
||||||
|
border-color: #ced4da;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<?php include('include/navbar.php'); ?>
|
<?php include('include/navbar.php'); ?>
|
||||||
<?php include('include/topbar.php'); ?>
|
<?php include('include/topbar.php'); ?>
|
||||||
|
|
||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
<div class="card radius-10">
|
<div class="card radius-10">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h6 class="mb-0"><?php echo $is_new ? 'Crea Profilo Insegnante' : 'Profilo Insegnante'; ?></h6>
|
<h6 class="mb-0"><?php echo $is_new ? 'Crea Profilo Insegnante' : 'Profilo Insegnante'; ?></h6>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php if (isset($success_message)): ?>
|
<?php if (isset($success_message)): ?>
|
||||||
<div class="alert alert-success" role="alert">
|
<div class="alert alert-success alert-dismissible fade show">
|
||||||
<?php echo $success_message; ?>
|
<?php echo htmlspecialchars($success_message); ?>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (isset($error)): ?>
|
<?php if (isset($error)): ?>
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger alert-dismissible fade show">
|
||||||
<?php echo $error; ?>
|
<?php echo htmlspecialchars($error); ?>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<form method="POST" enctype="multipart/form-data">
|
|
||||||
<div class="row">
|
<form method="POST" enctype="multipart/form-data" id="teacherForm">
|
||||||
<div class="col-md-4 text-center">
|
<div class="row g-4">
|
||||||
<div class="mb-3">
|
<!-- Colonna sinistra: foto + QR -->
|
||||||
<img src="<?php echo $teacher['profile_picture'] ? htmlspecialchars($teacher['profile_picture']) : 'phototeachers/ndphoto.png'; ?>"
|
<div class="col-lg-4 text-center">
|
||||||
alt="Foto Profilo" class="img-fluid rounded-circle" style="width: 150px; height: 150px; object-fit: cover;">
|
<img src="<?php echo $teacher['profile_picture'] ? htmlspecialchars($teacher['profile_picture']) : 'phototeachers/ndphoto.png'; ?>"
|
||||||
</div>
|
alt="Foto Profilo" class="teacher-photo">
|
||||||
<div class="mb-3">
|
|
||||||
|
<div class="mb-4">
|
||||||
<label for="profile_picture" class="form-label">Carica nuova foto</label>
|
<label for="profile_picture" class="form-label">Carica nuova foto</label>
|
||||||
<input type="file" class="form-control" id="profile_picture" name="profile_picture" accept="image/*">
|
<input type="file" class="form-control" id="profile_picture" name="profile_picture" accept="image/jpeg,image/png,image/gif">
|
||||||
|
<small class="text-muted d-block mt-1">Max 2MB – JPG, PNG, GIF</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (!$is_new && $qr_code_path): ?>
|
<?php if (!$is_new && $qr_code_path): ?>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Codice Univoco</label>
|
<label class="form-label">Codice Univoco</label>
|
||||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['unique_code']); ?>" readonly>
|
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['unique_code']); ?>" readonly>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">QR Code</label><br>
|
<label class="form-label">QR Code</label><br>
|
||||||
<img src="<?php echo htmlspecialchars($qr_code_path); ?>" alt="QR Code" class="img-fluid" style="width: 150px; height: 150px;">
|
<img src="<?php echo htmlspecialchars($qr_code_path); ?>" alt="QR Code" class="img-fluid shadow-sm" style="max-width: 180px;">
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="row">
|
<!-- Colonna destra: campi organizzati -->
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-lg-8">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6">
|
||||||
<label for="first_name" class="form-label">Nome</label>
|
<label for="first_name" class="form-label">Nome</label>
|
||||||
<input type="text" class="form-control" id="first_name" name="first_name" value="<?php echo htmlspecialchars($teacher['first_name']); ?>" required>
|
<input type="text" class="form-control" id="first_name" name="first_name"
|
||||||
|
value="<?php echo htmlspecialchars($teacher['first_name'] ?? ''); ?>" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 mb-3">
|
|
||||||
|
<div class="col-md-6">
|
||||||
<label for="last_name" class="form-label">Cognome</label>
|
<label for="last_name" class="form-label">Cognome</label>
|
||||||
<input type="text" class="form-control" id="last_name" name="last_name" value="<?php echo htmlspecialchars($teacher['last_name']); ?>" required>
|
<input type="text" class="form-control" id="last_name" name="last_name"
|
||||||
|
value="<?php echo htmlspecialchars($teacher['last_name'] ?? ''); ?>" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<label for="email" class="form-label">Email</label>
|
||||||
|
<input type="email" class="form-control" id="email" name="email"
|
||||||
|
value="<?php echo htmlspecialchars($teacher['email'] ?? ''); ?>" readonly>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="phone" class="form-label">Telefono</label>
|
||||||
|
<input type="tel" class="form-control" id="phone" name="phone"
|
||||||
|
value="<?php echo htmlspecialchars($teacher['phone'] ?? ''); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Editor descrizione -->
|
||||||
|
<div class="col-12 form-section">
|
||||||
|
<label class="form-label">Descrizione insegnante</label>
|
||||||
|
<div class="quill-wrapper">
|
||||||
|
<div id="quill-editor"></div>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="description" id="description-hidden">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Specializzazioni -->
|
||||||
|
<div class="col-12 form-section">
|
||||||
|
<label for="specializations" class="form-label">Specializzazioni</label>
|
||||||
|
<textarea class="form-control" id="specializations" name="specializations" rows="3"><?php echo htmlspecialchars($teacher['specializations'] ?? ''); ?></textarea>
|
||||||
|
<small class="text-muted">Es: Hatha Yoga, Vinyasa, Yin, Restorative...</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Stato</label>
|
||||||
|
<div class="form-check form-switch mt-2">
|
||||||
|
<input class="form-check-input" type="checkbox" id="status" name="status" value="active"
|
||||||
|
<?php echo ($teacher['status'] ?? 'active') === 'active' ? 'checked' : ''; ?>>
|
||||||
|
<label class="form-check-label" for="status">
|
||||||
|
<?php echo ($teacher['status'] ?? 'active') === 'active' ? 'Attivo' : 'Inattivo'; ?>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!$is_new): ?>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Data Creazione</label>
|
||||||
|
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['created_at'] ?? ''); ?>" readonly>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Ultimo Aggiornamento</label>
|
||||||
|
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['updated_at'] ?? ''); ?>" readonly>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="col-12 mt-5">
|
||||||
|
<button type="submit" class="btn btn-primary btn-lg px-5">
|
||||||
|
<?php echo $is_new ? 'Crea Profilo' : 'Salva Modifiche'; ?>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
|
||||||
<label for="email" class="form-label">Email</label>
|
|
||||||
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($teacher['email']); ?>" readonly>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="phone" class="form-label">Telefono</label>
|
|
||||||
<input type="text" class="form-control" id="phone" name="phone" value="<?php echo htmlspecialchars($teacher['phone'] ?? ''); ?>">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="description" class="form-label">Descrizione</label>
|
|
||||||
<textarea class="form-control" id="description" name="description" rows="3"><?php echo htmlspecialchars($teacher['description'] ?? ''); ?></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="specializations" class="form-label">Specializzazioni</label>
|
|
||||||
<textarea class="form-control" id="specializations" name="specializations" rows="2"><?php echo htmlspecialchars($teacher['specializations'] ?? ''); ?></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="status" class="form-label">Stato</label>
|
|
||||||
<div class="form-check form-switch">
|
|
||||||
<input class="form-check-input" type="checkbox" id="status" name="status" value="active" <?php echo $teacher['status'] === 'active' ? 'checked' : ''; ?>>
|
|
||||||
<label class="form-check-label" for="status"><?php echo $teacher['status'] === 'active' ? 'Attivo' : 'Inattivo'; ?></label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php if (!$is_new): ?>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Data Creazione</label>
|
|
||||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['created_at']); ?>" readonly>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Ultimo Aggiornamento</label>
|
|
||||||
<input type="text" class="form-control" value="<?php echo htmlspecialchars($teacher['updated_at']); ?>" readonly>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<button type="submit" class="btn btn-primary"><?php echo $is_new ? 'Crea Profilo' : 'Salva Modifiche'; ?></button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -317,11 +431,51 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overlay toggle-icon"></div>
|
<div class="overlay toggle-icon"></div>
|
||||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
||||||
<?php include('include/footer.php'); ?>
|
<?php include('include/footer.php'); ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php include('jsinclude.php'); ?>
|
<?php include('jsinclude.php'); ?>
|
||||||
|
|
||||||
|
<!-- Quill -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.2/dist/quill.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const quill = new Quill('#quill-editor', {
|
||||||
|
theme: 'snow',
|
||||||
|
modules: {
|
||||||
|
toolbar: [
|
||||||
|
['bold', 'italic', 'underline', 'strike'],
|
||||||
|
['blockquote', 'code-block'],
|
||||||
|
[{
|
||||||
|
'header': [1, 2, 3, false]
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'color': ['#000000', '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff', '#808080', '#c0c0c0']
|
||||||
|
}, {
|
||||||
|
'background': []
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'list': 'ordered'
|
||||||
|
}, {
|
||||||
|
'list': 'bullet'
|
||||||
|
}],
|
||||||
|
[{
|
||||||
|
'align': []
|
||||||
|
}],
|
||||||
|
['link', 'clean']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quill.root.innerHTML = `<?php echo addslashes($teacher['description'] ?? ''); ?>`;
|
||||||
|
|
||||||
|
document.getElementById('teacherForm').addEventListener('submit', function() {
|
||||||
|
document.getElementById('description-hidden').value = quill.root.innerHTML;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
10
public/userarea/testmail.php
Normal file
10
public/userarea/testmail.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'class/mailer.php';
|
||||||
|
|
||||||
|
$result = sendEmail(
|
||||||
|
'info@claudiosironi.com', // Cambia con un tuo indirizzo di test
|
||||||
|
'Test SMTP YogiBoook',
|
||||||
|
'<h1>Funziona!</h1><p>Se vedi questa mail, SMTP OK.</p>'
|
||||||
|
);
|
||||||
|
|
||||||
|
var_dump($result);
|
||||||
Loading…
x
Reference in New Issue
Block a user