getConnection(); if (!isset($iduserlogin)) { header("Location: login.php"); exit; } function setFlash(string $type, string $text): void { $_SESSION['flash'] = ['type' => $type, 'text' => $text]; } function getFlash(): ?array { if (!isset($_SESSION['flash'])) return null; $f = $_SESSION['flash']; unset($_SESSION['flash']); return $f; } function e(?string $v): string { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); } function statusMeta(string $status): array { switch ($status) { case 'confirmed': return ['class' => 'status-confirmed', 'badge' => 'bg-success', 'label' => 'Confermato']; case 'pending': return ['class' => 'status-pending', 'badge' => 'bg-warning text-dark', 'label' => 'In attesa']; case 'cancelled': return ['class' => 'status-cancelled', 'badge' => 'bg-danger', 'label' => 'Annullato']; case 'no_show': return ['class' => 'status-no_show', 'badge' => 'bg-secondary', 'label' => 'No-show']; case 'completed': return ['class' => 'status-completed', 'badge' => 'bg-primary', 'label' => 'Completato']; default: return ['class' => 'status-generic', 'badge' => 'bg-dark', 'label' => ucfirst($status)]; } } $stmt = $pdo->prepare("SELECT COUNT(*) FROM shops WHERE owner_id = ?"); $stmt->execute([$iduserlogin]); if ((int)$stmt->fetchColumn() === 0) { header("Location: onboarding_salon.php"); exit; } $stmt = $pdo->prepare(" SELECT id, name FROM shops WHERE owner_id = ? ORDER BY created_at ASC LIMIT 1 "); $stmt->execute([$iduserlogin]); $shop = $stmt->fetch(PDO::FETCH_ASSOC); if (!$shop) die("Errore: salone non trovato."); $shop_id = (int)$shop['id']; $shop_name = $shop['name']; $selected_date = $_GET['date'] ?? date('Y-m-d'); $selected_staff = isset($_GET['staff_id']) ? (int)$_GET['staff_id'] : 0; $stmt = $pdo->prepare(" SELECT id, first_name, last_name, color_hex FROM staff WHERE shop_id = ? AND is_active = 1 AND can_book_online = 1 ORDER BY first_name, last_name "); $stmt->execute([$shop_id]); $staff_list = $stmt->fetchAll(PDO::FETCH_ASSOC); // RECUPERA I SERVIZI DEL SALONE $stmt = $pdo->prepare(" SELECT id, name, duration_minutes, price, category, color_hex FROM services WHERE shop_id = ? AND is_active = 1 ORDER BY category ASC, `order` ASC, name ASC "); $stmt->execute([$shop_id]); $services_list = $stmt->fetchAll(PDO::FETCH_ASSOC); $selected_staff_obj = null; if ($selected_staff > 0) { foreach ($staff_list as $st) { if ((int)$st['id'] === $selected_staff) { $selected_staff_obj = $st; break; } } } $where_staff = $selected_staff > 0 ? "AND a.staff_id = ?" : ""; $params = [$shop_id, $selected_date]; if ($selected_staff > 0) $params[] = $selected_staff; $stmt = $pdo->prepare(" SELECT a.id, a.start_at, a.end_at, a.status, a.notes, CONCAT(c.first_name, ' ', c.last_name) AS customer_name, c.phone AS customer_phone, s.name AS service_name, st.first_name AS staff_first, st.last_name AS staff_last, st.color_hex AS staff_color FROM appointments a LEFT JOIN customers c ON a.customer_id = c.id LEFT JOIN services s ON a.service_id = s.id LEFT JOIN staff st ON a.staff_id = st.id WHERE a.shop_id = ? AND DATE(a.start_at) = ? $where_staff ORDER BY a.start_at ASC "); $stmt->execute($params); $appointments = $stmt->fetchAll(PDO::FETCH_ASSOC); $flash = getFlash(); $start_hour = 8; $end_hour = 21; $interval = 30; function ts(string $dateYmd, string $timeHi): int { return strtotime($dateYmd . ' ' . $timeHi . ':00'); } $prev_date = date('Y-m-d', strtotime($selected_date . ' -1 day')); $next_date = date('Y-m-d', strtotime($selected_date . ' +1 day')); ?> Appuntamenti - <?= e($shop_name) ?>
Appuntamenti •
Tutti i parrucchieri
Oggi
Slot da min • :00–:00
Confermato In attesa Annullato No-show Completato
0) break; $time_str = sprintf("%02d:%02d", $h, $m); $slot_ts = ts($selected_date, $time_str); while ($idx < $count) { $a_end_ts = strtotime($appointments[$idx]['end_at']); if ($a_end_ts <= $slot_ts) $idx++; else break; } $appt = null; if ($idx < $count) { $a_start_ts = strtotime($appointments[$idx]['start_at']); $a_end_ts = strtotime($appointments[$idx]['end_at']); if ($a_start_ts <= $slot_ts && $a_end_ts > $slot_ts) $appt = $appointments[$idx]; } ?>
Slot libero
ID
120 ? mb_substr($notes, 0, 120) . '…' : $notes) ?>