holidays.php
6.29 KB
<?php
require_once __DIR__ . '/../bootstrap.php';
require_once __DIR__ . '/../lib/feature_modules.php';
requireAuth();
if (!(isAdminRole() || hasPermission('management.access') || hasPermission('holidays.manage'))) {
http_response_code(403);
die('Access denied.');
}
$pageTitle = 'Holiday Requests';
if (isset($_GET['export']) && $_GET['export'] === 'csv') {
$stmt = $pdo->query("SELECT request_code, username, role_name, start_date, end_date, total_days, priority, status, reviewed_by_name, submitted_at, reason, notes FROM holiday_requests ORDER BY submitted_at DESC");
$rows = [];
foreach ($stmt->fetchAll() as $r) {
$rows[] = [$r['request_code'], $r['username'], $r['role_name'], $r['start_date'], $r['end_date'], $r['total_days'], $r['priority'], $r['status'], $r['reviewed_by_name'], $r['submitted_at'], $r['reason'], $r['notes']];
}
wp_feature_csv_download('holiday_requests_' . date('Ymd_His') . '.csv', ['Request','User','Role','Start','End','Days','Priority','Status','Reviewed By','Submitted At','Reason','Notes'], $rows);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && (hasPermission('holidays.manage') || isAdminRole())) {
$id = (int)($_POST['id'] ?? 0);
$status = trim((string)($_POST['status'] ?? 'Pending'));
if ($id > 0 && in_array($status, ['Pending','Approved','Rejected'], true)) {
$stmt = $pdo->prepare("UPDATE holiday_requests SET status=?, reviewed_by=?, reviewed_by_name=?, reviewed_at=NOW() WHERE id=?");
$stmt->execute([$status, wp_feature_current_user_id(), wp_feature_current_user_name(), $id]);
logActivity('holiday_request_reviewed', 'holiday_request', $id, 'Holiday request set to ' . $status);
wp_feature_flash_set('success', 'Holiday request updated.');
app_redirect('management/holidays');
}
}
$status = trim((string)($_GET['status'] ?? ''));
$userFilter = trim((string)($_GET['user'] ?? ''));
$where = [];
$params = [];
if ($status !== '') { $where[] = 'status = ?'; $params[] = $status; }
if ($userFilter !== '') { $where[] = 'username LIKE ?'; $params[] = '%' . $userFilter . '%'; }
$sql = 'SELECT * FROM holiday_requests' . ($where ? ' WHERE ' . implode(' AND ', $where) : '') . ' ORDER BY submitted_at DESC LIMIT 250';
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$requests = $stmt->fetchAll() ?: [];
$flash = wp_feature_flash_get();
$stats = ['Pending' => 0, 'Approved' => 0, 'Rejected' => 0];
foreach ($requests as $row) { if (isset($stats[$row['status']])) $stats[$row['status']]++; }
include __DIR__ . '/../partials/header.php';
?>
<div class="content-header">
<div>
<h1 class="content-title">🏖️ Holiday Requests</h1>
<p class="content-subtitle">Requests are submitted from the main dashboard. This screen is the management queue for review, approval and export.</p>
</div>
<div class="d-flex gap-md" style="flex-wrap:wrap;">
<a class="btn btn-secondary" href="<?= e(app_url('management/holidays?export=csv')) ?>">⬇️ Export CSV</a>
</div>
</div>
<?php if ($flash): ?><div class="alert alert-<?= e($flash['type'] === 'error' ? 'error' : 'success') ?>" style="margin-bottom:16px;"><?= e($flash['message']) ?></div><?php endif; ?>
<div class="grid-3 mb-lg">
<div class="card"><p class="text-muted" style="margin:0;">Pending</p><h2 style="margin:8px 0 0 0;"><?= (int)$stats['Pending'] ?></h2></div>
<div class="card"><p class="text-muted" style="margin:0;">Approved</p><h2 style="margin:8px 0 0 0;"><?= (int)$stats['Approved'] ?></h2></div>
<div class="card"><p class="text-muted" style="margin:0;">Rejected</p><h2 style="margin:8px 0 0 0;"><?= (int)$stats['Rejected'] ?></h2></div>
</div>
<div class="card mb-lg">
<div class="card-header"><h3 class="card-title">Filters</h3></div>
<form method="get" class="d-flex gap-md" style="flex-wrap:wrap;align-items:end;">
<div><label class="field-label">Status</label><select class="input" name="status"><option value="">All</option><?php foreach (['Pending','Approved','Rejected'] as $opt): ?><option value="<?= e($opt) ?>" <?= $status === $opt ? 'selected' : '' ?>><?= e($opt) ?></option><?php endforeach; ?></select></div>
<div><label class="field-label">User</label><input class="input" type="text" name="user" value="<?= e($userFilter) ?>" placeholder="Search username / display name"></div>
<div><button class="btn btn-secondary" type="submit">Apply</button></div>
<div><a class="btn btn-secondary" href="<?= e(app_url('management/holidays')) ?>">Reset</a></div>
</form>
</div>
<div class="card">
<div class="card-header"><h3 class="card-title">Holiday Queue</h3></div>
<div class="table-wrap">
<table class="table" style="min-width:1100px;">
<thead><tr><th>Request</th><th>User</th><th>Dates</th><th>Days</th><th>Priority</th><th>Reason / Notes</th><th>Status</th><th>Actions</th></tr></thead>
<tbody>
<?php if (!$requests): ?><tr><td colspan="8" class="text-muted">No holiday requests found.</td></tr>
<?php else: foreach ($requests as $row): ?>
<tr>
<td><?= e($row['request_code']) ?><br><small class="text-muted"><?= e((string)$row['submitted_at']) ?></small></td>
<td><?= e($row['username']) ?><br><small class="text-muted"><?= e($row['role_name']) ?></small></td>
<td><?= e($row['start_date']) ?> → <?= e($row['end_date']) ?></td>
<td><?= (int)$row['total_days'] ?></td>
<td><?= e($row['priority']) ?></td>
<td><?= e((string)($row['reason'] ?: $row['notes'])) ?></td>
<td><span class="badge badge-muted"><?= e($row['status']) ?></span></td>
<td>
<?php if (hasPermission('holidays.manage') || isAdminRole()): ?>
<form method="post" class="d-flex gap-sm" style="flex-wrap:wrap;">
<input type="hidden" name="id" value="<?= (int)$row['id'] ?>">
<select class="input" name="status" style="min-width:130px;"><?php foreach (['Pending','Approved','Rejected'] as $opt): ?><option value="<?= e($opt) ?>" <?= $row['status'] === $opt ? 'selected' : '' ?>><?= e($opt) ?></option><?php endforeach; ?></select>
<button class="btn btn-secondary btn-xs" type="submit">Save</button>
</form>
<?php else: ?>—<?php endif; ?>
</td>
</tr>
<?php endforeach; endif; ?>
</tbody>
</table>
</div>
</div>
<?php include __DIR__ . '/../partials/footer.php'; ?>