2026-01-27 14:53:37 +01:00

408 lines
17 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// Forza la visualizzazione degli errori (solo dev)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
include('include/headscript.php');
// Connessione DB
$dbHandler = DBHandlerSelect::getInstance();
$pdo = $dbHandler->getConnection();
// Verifica utente loggato
if (!isset($iduserlogin)) {
header("Location: login.php");
exit;
}
// Controlla se esiste almeno un salone
$stmt = $pdo->prepare("SELECT COUNT(*) FROM shops WHERE owner_id = ?");
$stmt->execute([$iduserlogin]);
if ((int)$stmt->fetchColumn() === 0) {
header("Location: onboarding_salon.php");
exit;
}
// Prendi il primo salone (o quello attivo puoi aggiungere switcher dopo)
$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'];
// =========================================================================
// Helpers
// =========================================================================
function isValidDateYmd(string $date): bool {
$d = DateTime::createFromFormat('Y-m-d', $date);
return $d && $d->format('Y-m-d') === $date;
}
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;
}
// =========================================================================
// Gestione POST (add / edit / delete)
// =========================================================================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
try {
if ($action === 'add') {
$start_date = trim($_POST['start_date'] ?? '');
$end_date = trim($_POST['end_date'] ?? '');
$title = trim($_POST['title'] ?? '');
$description = trim($_POST['description'] ?? '');
if ($start_date === '' || $end_date === '') {
setFlash('danger', "Le date di inizio e fine sono obbligatorie.");
} elseif (!isValidDateYmd($start_date) || !isValidDateYmd($end_date)) {
setFlash('danger', "Formato data non valido.");
} elseif (strtotime($end_date) < strtotime($start_date)) {
setFlash('danger', "La data di fine non può essere precedente alla data di inizio.");
} else {
$pdo->beginTransaction();
// Inserisco una riga per ogni giorno del range (B2)
$stmt = $pdo->prepare("
INSERT INTO shop_day_off (shop_id, date, title, description, is_recurring)
VALUES (?, ?, ?, ?, 0)
ON DUPLICATE KEY UPDATE
title = VALUES(title),
description = VALUES(description),
updated_at = CURRENT_TIMESTAMP
");
$start = new DateTime($start_date);
$end = new DateTime($end_date);
$end->setTime(0,0,0);
// +1 giorno per includere la fine
$period = new DatePeriod($start, new DateInterval('P1D'), (clone $end)->modify('+1 day'));
$inserted = 0;
foreach ($period as $dt) {
$day = $dt->format('Y-m-d');
$ok = $stmt->execute([
$shop_id,
$day,
$title !== '' ? $title : 'Chiusura',
$description
]);
if ($ok) $inserted++;
}
$pdo->commit();
setFlash('success', "Chiusura aggiunta: salvati/aggiornati {$inserted} giorni.");
}
header("Location: day_off.php");
exit;
}
if ($action === 'edit') {
$id = (int)($_POST['id'] ?? 0);
$date = trim($_POST['start_date'] ?? ''); // nel form edit usiamo start_date come "data singola"
$title = trim($_POST['title'] ?? '');
$description = trim($_POST['description'] ?? '');
if ($id <= 0) {
setFlash('danger', "ID non valido.");
} elseif ($date === '' || !isValidDateYmd($date)) {
setFlash('danger', "La data è obbligatoria e deve essere valida.");
} else {
$stmt = $pdo->prepare("
UPDATE shop_day_off
SET date = ?, title = ?, description = ?, updated_at = NOW()
WHERE id = ? AND shop_id = ?
");
$ok = $stmt->execute([
$date,
$title !== '' ? $title : 'Chiusura',
$description,
$id,
$shop_id
]);
setFlash($ok ? 'success' : 'danger', $ok ? "Giorno di chiusura aggiornato!" : "Errore durante l'aggiornamento.");
}
header("Location: day_off.php");
exit;
}
if ($action === 'delete') {
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
setFlash('danger', "ID non valido.");
} else {
$stmt = $pdo->prepare("DELETE FROM shop_day_off WHERE id = ? AND shop_id = ?");
$ok = $stmt->execute([$id, $shop_id]);
setFlash($ok ? 'success' : 'danger', $ok ? "Giorno di chiusura eliminato!" : "Errore durante l'eliminazione.");
}
header("Location: day_off.php");
exit;
}
// action sconosciuta
setFlash('danger', "Azione non valida.");
header("Location: day_off.php");
exit;
} catch (Throwable $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
setFlash('danger', "Errore: " . $e->getMessage());
header("Location: day_off.php");
exit;
}
}
// =========================================================================
// Recupera tutti i giorni di chiusura
// =========================================================================
$stmt = $pdo->prepare("
SELECT id, date, title, description, is_recurring
FROM shop_day_off
WHERE shop_id = ?
ORDER BY date ASC
");
$stmt->execute([$shop_id]);
$days_off = $stmt->fetchAll(PDO::FETCH_ASSOC);
$flash = getFlash();
?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<?php include('siteinfo.php'); ?>
<title>Giorni di Chiusura - <?= htmlspecialchars($shop_name) ?></title>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card radius-10">
<div class="card-header bg-light d-flex align-items-center justify-content-between">
<h6 class="mb-0">Giorni di Chiusura - <?= htmlspecialchars($shop_name) ?></h6>
<div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addDayOffModal">
<i class="bx bx-plus me-1"></i> Aggiungi Chiusura
</button>
<a href="salon_dashboard.php" class="btn btn-outline-secondary ms-2">
<i class="bx bx-arrow-back me-1"></i> Dashboard
</a>
</div>
</div>
<div class="card-body">
<?php if ($flash): ?>
<div class="alert alert-<?= htmlspecialchars($flash['type']) ?> alert-dismissible fade show" role="alert">
<?= htmlspecialchars($flash['text']) ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if (empty($days_off)): ?>
<div class="alert alert-info text-center py-4">
Non hai ancora impostato giorni di chiusura.<br>
Aggiungine uno per bloccare le prenotazioni in quei giorni.
</div>
<?php else: ?>
<div class="table-responsive">
<table id="daysOffTable" class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>Data</th>
<th>Titolo / Descrizione</th>
<th>Ricorrente</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
<?php foreach ($days_off as $day): ?>
<tr>
<td><?= htmlspecialchars($day['date']) ?></td>
<td><?= htmlspecialchars(($day['title'] ?: '') . (($day['description'] ?? '') ? ' — ' . $day['description'] : '')) ?: 'Chiusura' ?></td>
<td>
<?php if (!empty($day['is_recurring'])): ?>
<span class="badge bg-success">Sì (ogni anno)</span>
<?php else: ?>
<span class="badge bg-secondary">No</span>
<?php endif; ?>
</td>
<td>
<button type="button" class="btn btn-sm btn-warning me-1"
data-bs-toggle="modal" data-bs-target="#editDayOffModal"
onclick='fillEditModal(<?= json_encode([
"id" => (int)$day["id"],
"date" => $day["date"],
"title" => $day["title"] ?? "",
"description" => $day["description"] ?? ""
], JSON_HEX_APOS | JSON_HEX_QUOT) ?>)'>
<i class="bx bx-edit"></i> Modifica
</button>
<form action="" method="POST" style="display:inline;"
onsubmit="return confirm('Confermi l\'eliminazione?');">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= (int)$day['id'] ?>">
<button type="submit" class="btn btn-sm btn-danger">
<i class="bx bx-trash"></i> Elimina
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
<!-- Modal Aggiungi -->
<div class="modal fade" id="addDayOffModal" tabindex="-1" aria-labelledby="addDayOffModalLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title" id="addDayOffModalLabel">Aggiungi Giorni di Chiusura</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<form action="" method="POST">
<div class="modal-body">
<input type="hidden" name="action" value="add">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label fw-bold">Dal <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="start_date" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label fw-bold">Al <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="end_date" required>
</div>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Titolo (es. Ferie estive)</label>
<input type="text" class="form-control" name="title" placeholder="Titolo breve">
</div>
<div class="mb-3">
<label class="form-label fw-bold">Descrizione / Note</label>
<textarea class="form-control" name="description" rows="3"
placeholder="Dettagli (es. chiuso tutto il giorno per ferie)"></textarea>
</div>
<div class="alert alert-secondary mb-0">
Verrà salvata una riga per ogni giorno del range (così blocchi facilmente le prenotazioni).
</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">Aggiungi</button>
</div>
</form>
</div>
</div>
</div>
<!-- Modal Modifica (singolo giorno) -->
<div class="modal fade" id="editDayOffModal" tabindex="-1" aria-labelledby="editDayOffModalLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-warning text-dark">
<h5 class="modal-title" id="editDayOffModalLabel">Modifica Giorno di Chiusura</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form action="" method="POST">
<div class="modal-body">
<input type="hidden" name="action" value="edit">
<input type="hidden" name="id" id="edit_id">
<div class="mb-3">
<label class="form-label fw-bold">Data <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="start_date" id="edit_date" required>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Titolo</label>
<input type="text" class="form-control" name="title" id="edit_title" placeholder="Es: Chiusura straordinaria">
</div>
<div class="mb-3">
<label class="form-label fw-bold">Descrizione / Motivo</label>
<input type="text" class="form-control" name="description" id="edit_description"
placeholder="Es: Ferie natalizie">
</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-warning">Salva Modifiche</button>
</div>
</form>
</div>
</div>
</div>
<?php include('jsinclude.php'); ?>
<script>
$(document).ready(function () {
$('#daysOffTable').DataTable({
language: { url: '//cdn.datatables.net/plug-ins/1.13.6/i18n/it-IT.json' },
order: [[0, 'asc']]
});
});
function fillEditModal(data) {
document.getElementById('edit_id').value = data.id;
document.getElementById('edit_date').value = data.date;
document.getElementById('edit_title').value = data.title || '';
document.getElementById('edit_description').value = data.description || '';
}
</script>
</body>
</html>