|
Server : LiteSpeed System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64 User : outerorb ( 1091) PHP Version : 8.1.34 Disable Function : mail Directory : /home2/outerorb/emp.outerorbittech.in/admin/ | |
|
Path: /home2/outerorb/emp.outerorbittech.in/admin/leave_types.php
Size: 18.07 KB
Permissions: 0666
<?php
require __DIR__ . '/../includes/helpers.php';
require_admin();
ensure_leave_tables();
$roleLabel = 'Admin';
$pdo = db();
$flash = flash();
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!verify_csrf($_POST['csrf_token'] ?? '')) {
redirect_with_message('leave_types.php', 'Session expired.', 'error');
}
$action = $_POST['action'] ?? '';
$id = (int) ($_POST['id'] ?? 0);
if ($action === 'toggle' && $id) {
$pdo->prepare('UPDATE leave_types SET is_active = !is_active WHERE id = ?')->execute([$id]);
redirect_with_message('leave_types.php', 'Leave type updated.');
}
if ($action === 'delete' && $id) {
$used = $pdo->prepare('SELECT COUNT(*) FROM leave_applications WHERE leave_type_id = ?');
$used->execute([$id]);
if ($used->fetchColumn() > 0) {
redirect_with_message('leave_types.php', 'Cannot delete: this leave type has applications.', 'error');
}
$pdo->prepare('DELETE FROM leave_types WHERE id = ?')->execute([$id]);
redirect_with_message('leave_types.php', 'Leave type deleted.');
}
if (in_array($action, ['add', 'edit'], true)) {
$name = sanitize_text($_POST['name'] ?? '');
$code = strtoupper(sanitize_text($_POST['code'] ?? ''));
$annualDays = max(0, (int) ($_POST['annual_days'] ?? 0));
$isPaid = isset($_POST['is_paid']) ? 1 : 0;
$carryForward = isset($_POST['carry_forward']) ? 1 : 0;
$maxCarry = max(0, (int) ($_POST['max_carry_days'] ?? 0));
$encashable = isset($_POST['encashable']) ? 1 : 0;
if ($name === '') $errors['name'] = 'Name is required.';
if ($code === '') $errors['code'] = 'Code is required.';
if (empty($errors)) {
// unique checks
$dupName = $pdo->prepare('SELECT id FROM leave_types WHERE name = ?' . ($action === 'edit' ? ' AND id != ?' : ''));
$dupName->execute($action === 'edit' ? [$name, $id] : [$name]);
if ($dupName->fetch()) $errors['name'] = 'Name already exists.';
$dupCode = $pdo->prepare('SELECT id FROM leave_types WHERE code = ?' . ($action === 'edit' ? ' AND id != ?' : ''));
$dupCode->execute($action === 'edit' ? [$code, $id] : [$code]);
if ($dupCode->fetch()) $errors['code'] = 'Code already exists.';
}
if (empty($errors)) {
if ($action === 'add') {
$pdo->prepare('INSERT INTO leave_types (name, code, annual_days, is_paid, carry_forward, max_carry_days, encashable)
VALUES (?,?,?,?,?,?,?)')
->execute([$name, $code, $annualDays, $isPaid, $carryForward, $maxCarry, $encashable]);
redirect_with_message('leave_types.php', 'Leave type added.');
} else {
$pdo->prepare('UPDATE leave_types SET name=?, code=?, annual_days=?, is_paid=?, carry_forward=?, max_carry_days=?, encashable=? WHERE id=?')
->execute([$name, $code, $annualDays, $isPaid, $carryForward, $maxCarry, $encashable, $id]);
redirect_with_message('leave_types.php', 'Leave type updated.');
}
}
}
}
$editId = isset($_GET['edit']) ? (int) $_GET['edit'] : 0;
$editRow = null;
if ($editId) {
$s = $pdo->prepare('SELECT * FROM leave_types WHERE id = ? LIMIT 1');
$s->execute([$editId]);
$editRow = $s->fetch() ?: null;
}
$leaveTypes = $pdo->query('SELECT * FROM leave_types ORDER BY name ASC')->fetchAll();
function e(string $v): string { return htmlspecialchars($v, ENT_QUOTES, 'UTF-8'); }
$post = $editRow ?: [];
$admin = current_admin();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Leave Types — HRMS</title>
<link rel="stylesheet" href="../assets/css/style.css?v=<?php echo filemtime(__DIR__ . '/../assets/css/style.css'); ?>" />
<link rel="stylesheet" href="../assets/css/polish.css?v=<?php echo filemtime(__DIR__ . '/../assets/css/polish.css'); ?>" />
</head>
<body class="dashboard-layout">
<div class="app-wrapper">
<!-- ========== SIDEBAR ========== -->
<aside class="sidebar-wrapper" id="sidebar">
<div class="sidebar-header">
<div class="sidebar-logo">HR</div>
<div class="sidebar-company">
<div class="sidebar-company-name">Employee<br/>Records</div>
<div class="sidebar-company-role"><?php echo htmlspecialchars($roleLabel, ENT_QUOTES, 'UTF-8'); ?></div>
</div>
</div>
<nav class="sidebar-menu">
<!-- Employees Section -->
<div class="sidebar-section">
<div class="sidebar-section-title">[EMPLOYEES]</div>
<div class="sidebar-item">
<a href="dashboard.php" class="sidebar-link">Dashboard</a>
</div>
<div class="sidebar-item">
<a href="approvals.php" class="sidebar-link">Approvals</a>
</div>
<div class="sidebar-item">
<a href="departments.php" class="sidebar-link">Departments</a>
</div>
<div class="sidebar-item">
<a href="designations.php" class="sidebar-link">Designations</a>
</div>
<div class="sidebar-item">
<a href="trash.php" class="sidebar-link">Trash</a>
</div>
</div>
<!-- Attendance & Leave -->
<div class="sidebar-section">
<div class="sidebar-section-title">[ATTENDANCE & LEAVE]</div>
<div class="sidebar-item">
<a href="attendance.php" class="sidebar-link">Attendance</a>
</div>
<div class="sidebar-item">
<a href="leaves.php" class="sidebar-link">Leaves</a>
</div>
<div class="sidebar-item">
<a href="leave_types.php" class="sidebar-link active">Leave Types</a>
</div>
<div class="sidebar-item">
<a href="holidays.php?year=<?php echo date('Y'); ?>" class="sidebar-link">Holidays</a>
</div>
<div class="sidebar-item">
<a href="document_requests.php" class="sidebar-link">Requests</a>
</div>
</div>
<!-- Payroll -->
<div class="sidebar-section">
<div class="sidebar-section-title">[PAYROLL]</div>
<div class="sidebar-item">
<a href="salary.php" class="sidebar-link">Salary</a>
</div>
<div class="sidebar-item">
<a href="payroll.php" class="sidebar-link">Run Payroll</a>
</div>
</div>
<!-- HR Modules -->
<div class="sidebar-section">
<div class="sidebar-section-title">[HR MODULES]</div>
<div class="sidebar-item">
<a href="appraisals.php" class="sidebar-link">Appraisals</a>
</div>
<div class="sidebar-item">
<a href="assets.php" class="sidebar-link">Assets</a>
</div>
<div class="sidebar-item">
<a href="recruitment.php" class="sidebar-link">Recruitment</a>
</div>
<div class="sidebar-item">
<a href="announcements.php" class="sidebar-link">Notices</a>
</div>
</div>
<!-- Reports -->
<div class="sidebar-section">
<div class="sidebar-section-title">[REPORTS]</div>
<div class="sidebar-item">
<a href="reports.php" class="sidebar-link">Analytics</a>
</div>
</div>
<?php if (is_super_admin()): ?>
<!-- Admin Settings -->
<div class="sidebar-section">
<div class="sidebar-section-title">[SETTINGS]</div>
<div class="sidebar-item">
<a href="admins.php" class="sidebar-link">Manage Admins</a>
</div>
</div>
<?php endif; ?>
</nav>
</aside>
<!-- MAIN CONTENT -->
<div class="main-content">
<!-- Top Bar -->
<div class="top-bar">
<div class="top-bar-left">
<button class="sidebar-toggle" id="sidebarToggle" aria-label="Toggle sidebar">☰</button>
<div>
<h1 class="page-title">Leave Types</h1>
<div class="breadcrumb-nav">
<span>Configure leave categories and entitlements.</span>
</div>
</div>
</div>
<div class="top-bar-right">
<div class="user-menu">
<div class="user-avatar"><?php echo strtoupper(substr($admin['username'] ?? 'A', 0, 1)); ?></div>
<div class="user-name"><?php echo htmlspecialchars($admin['username'] ?? 'Admin', ENT_QUOTES, 'UTF-8'); ?></div>
</div>
<a href="logout.php" style="color: #cbd5e1; text-decoration: none; padding: 8px 12px; border-radius: 6px; transition: background 0.15s; font-size: 13px; font-weight: 600;" title="Logout">Logout</a>
</div>
</div>
<!-- Content Container -->
<div class="dashboard-container">
<?php if ($flash): ?>
<div class="alert <?php echo $flash['type'] === 'error' ? 'alert-error' : 'alert-success'; ?>">
<?php echo e($flash['message']); ?>
</div>
<?php endif; ?>
<div class="card" style="margin-bottom:20px;">
<h3 style="margin:0 0 16px;"><?php echo $editRow ? 'Edit Leave Type' : 'Add Leave Type'; ?></h3>
<form method="POST">
<input type="hidden" name="csrf_token" value="<?php echo e(csrf_token()); ?>" />
<input type="hidden" name="action" value="<?php echo $editRow ? 'edit' : 'add'; ?>" />
<?php if ($editRow): ?><input type="hidden" name="id" value="<?php echo (int)$editRow['id']; ?>" /><?php endif; ?>
<div style="display:grid; grid-template-columns:2fr 1fr 1fr; gap:14px;">
<div class="form-group" style="margin:0;">
<label>Name *</label>
<input type="text" name="name" class="form-control" value="<?php echo e($post['name'] ?? ''); ?>" required />
<?php if (!empty($errors['name'])): ?><span class="field-error"><?php echo e($errors['name']); ?></span><?php endif; ?>
</div>
<div class="form-group" style="margin:0;">
<label>Code * <small style="color:#9ca3af;">(e.g. CL)</small></label>
<input type="text" name="code" class="form-control" maxlength="10"
value="<?php echo e($post['code'] ?? ''); ?>" required style="text-transform:uppercase;" />
<?php if (!empty($errors['code'])): ?><span class="field-error"><?php echo e($errors['code']); ?></span><?php endif; ?>
</div>
<div class="form-group" style="margin:0;">
<label>Annual Days</label>
<input type="number" name="annual_days" class="form-control" min="0" max="365"
value="<?php echo (int)($post['annual_days'] ?? 0); ?>" />
</div>
</div>
<div style="display:flex; flex-wrap:wrap; gap:20px; margin-top:14px; align-items:center;">
<label style="display:flex; align-items:center; gap:6px; font-size:.875rem;">
<input type="checkbox" name="is_paid" <?php echo ($post['is_paid'] ?? 1) ? 'checked' : ''; ?> />
Paid Leave
</label>
<label style="display:flex; align-items:center; gap:6px; font-size:.875rem;">
<input type="checkbox" name="carry_forward" id="cf-chk"
<?php echo ($post['carry_forward'] ?? 0) ? 'checked' : ''; ?>
onchange="document.getElementById('cf-days').disabled=!this.checked" />
Carry Forward
</label>
<div style="display:flex; align-items:center; gap:6px; font-size:.875rem;">
<label for="cf-days" style="margin:0;">Max carry days:</label>
<input type="number" id="cf-days" name="max_carry_days" min="0" max="365"
value="<?php echo (int)($post['max_carry_days'] ?? 0); ?>"
<?php echo ($post['carry_forward'] ?? 0) ? '' : 'disabled'; ?>
style="width:70px;" class="form-control" />
</div>
<label style="display:flex; align-items:center; gap:6px; font-size:.875rem;">
<input type="checkbox" name="encashable" <?php echo ($post['encashable'] ?? 0) ? 'checked' : ''; ?> />
Encashable
</label>
<button type="submit" class="btn btn-primary">
<?php echo $editRow ? 'Update' : 'Add'; ?>
</button>
<?php if ($editRow): ?>
<a href="leave_types.php" style="font-size:.82rem;">Cancel</a>
<?php endif; ?>
</div>
</form>
</div>
<div class="card">
<table style="width:100%; border-collapse:collapse; font-size:.875rem;">
<thead>
<tr style="background:#f9fafb;">
<th style="padding:10px 12px; text-align:left; border-bottom:1px solid #e5e7eb;">Name</th>
<th style="padding:10px 12px; text-align:center; border-bottom:1px solid #e5e7eb;">Code</th>
<th style="padding:10px 12px; text-align:center; border-bottom:1px solid #e5e7eb;">Days/yr</th>
<th style="padding:10px 12px; text-align:center; border-bottom:1px solid #e5e7eb;">Paid</th>
<th style="padding:10px 12px; text-align:center; border-bottom:1px solid #e5e7eb;">Carry Fwd</th>
<th style="padding:10px 12px; text-align:center; border-bottom:1px solid #e5e7eb;">Encash</th>
<th style="padding:10px 12px; text-align:center; border-bottom:1px solid #e5e7eb;">Status</th>
<th style="padding:10px 12px; text-align:left; border-bottom:1px solid #e5e7eb;">Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($leaveTypes as $lt): ?>
<tr style="<?php echo $lt['is_active'] ? '' : 'opacity:.55;'; ?>">
<td style="padding:10px 12px; border-bottom:1px solid #f3f4f6;"><?php echo e($lt['name']); ?></td>
<td style="padding:10px 12px; text-align:center; border-bottom:1px solid #f3f4f6;"><code><?php echo e($lt['code']); ?></code></td>
<td style="padding:10px 12px; text-align:center; border-bottom:1px solid #f3f4f6;"><?php echo (int)$lt['annual_days']; ?></td>
<td style="padding:10px 12px; text-align:center; border-bottom:1px solid #f3f4f6;"><?php echo $lt['is_paid'] ? '✓' : '—'; ?></td>
<td style="padding:10px 12px; text-align:center; border-bottom:1px solid #f3f4f6;">
<?php echo $lt['carry_forward'] ? '✓ (max ' . (int)$lt['max_carry_days'] . 'd)' : '—'; ?>
</td>
<td style="padding:10px 12px; text-align:center; border-bottom:1px solid #f3f4f6;"><?php echo $lt['encashable'] ? '✓' : '—'; ?></td>
<td style="padding:10px 12px; text-align:center; border-bottom:1px solid #f3f4f6;">
<?php echo $lt['is_active'] ? '<span style="color:#16a34a;">Active</span>' : '<span style="color:#9ca3af;">Inactive</span>'; ?>
</td>
<td style="padding:10px 12px; border-bottom:1px solid #f3f4f6;">
<a href="leave_types.php?edit=<?php echo (int)$lt['id']; ?>">Edit</a>
<form method="POST" style="display:inline;">
<input type="hidden" name="csrf_token" value="<?php echo e(csrf_token()); ?>" />
<input type="hidden" name="action" value="toggle" />
<input type="hidden" name="id" value="<?php echo (int)$lt['id']; ?>" />
<button type="submit" style="background:none;border:none;color:#6b7280;cursor:pointer;padding:0;">
<?php echo $lt['is_active'] ? 'Disable' : 'Enable'; ?>
</button>
</form>
<form method="POST" style="display:inline;" onsubmit="return confirm('Delete this leave type?');">
<input type="hidden" name="csrf_token" value="<?php echo e(csrf_token()); ?>" />
<input type="hidden" name="action" value="delete" />
<input type="hidden" name="id" value="<?php echo (int)$lt['id']; ?>" />
<button type="submit" style="background:none;border:none;color:#ef4444;cursor:pointer;padding:0;">Delete</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
// Sidebar Toggle
const sidebar = document.getElementById('sidebar');
const sidebarToggle = document.getElementById('sidebarToggle');
sidebarToggle?.addEventListener('click', () => {
sidebar.classList.toggle('open');
});
</script>
</body>
</html>