| Linux in-mum-web1499.main-hosting.eu 5.14.0-503.40.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Mon May 5 06:06:04 EDT 2025 x86_64 Path : /home/u901718425/domains/task.urbanpillar.in/public_html/ |
| Current File : /home/u901718425/domains/task.urbanpillar.in/public_html/leave.php |
<?php
require_once "db.php";
if (!isset($_SESSION['user_id'])) {
header('location: /');
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="/style.css" rel="stylesheet"/>
<style>
body {
font-family: Arial, sans-serif;
}
#calendar {
display: inline-block;
}
#month {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 50px);
gap: 5px;
justify-content: center;
}
.day-label,
.day {
width: 50px;
height: 50px;
line-height: 50px;
border-radius: 5px;
}
.day-label {
font-weight: bold;
background-color: transparent;
}
.day {
background-color: #f0f0f0;
cursor: pointer;
}
.past-day {
background-color: #e0e0e0;
color: #999;
}
.today {
background-color: #689820;
color: white;
cursor: pointer;
}
.today:hover {
background-color: #557c1c;
}
#startCalendar, #endCalendar {
border: 1px solid #ccc;
padding: 10px;
border-radius: 8px;
max-width: 300px;
margin: auto;
}
</style>
</head>
<body>
<div class="row m-0">
<div class="d-flex flex-column flex-shrink-0 p-3 bg-body-tertiary" style="width: 240px;">
<a href="/" class="d-flex align-items-center justify-content-center w-100 link-body-emphasis text-decoration-none">
<img src="https://cdn.urbanpillar.com/images/urban.png" height="40px">
</a>
<hr>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="/dashboard.php" class="nav-link link-body-emphasis" aria-current="page">
<!--<svg class="bi pe-none me-2" width="16" height="16" aria-hidden="true"><use xlink:href="#home"></use></svg>-->
<span class="bi me-2 fs-6 material-symbols-outlined">
add_task
</span>
Tasks
</a>
</li>
<li>
<a href="/leave.php" class="nav-link active">
<span class="bi me-2 fs-6 material-symbols-outlined">
calendar_month
</span>
Leave
</a>
</li>
</ul>
<hr>
<div class="dropdown">
<a href="#" class="d-flex align-items-center link-body-emphasis text-decoration-none dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<strong><?= isset($_SESSION['user_name']) && $_SESSION['user_name'] !== '' ? $_SESSION['user_name'] : $_SESSION['email'] ?></strong>
</a>
<ul class="dropdown-menu text-small shadow">
<li><a class="dropdown-item" href="#">New project...</a></li>
<li><a class="dropdown-item" href="#">Settings</a></li>
<li><a class="dropdown-item" href="#">Profile</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" id="logout">Logout</a></li>
</ul>
</div>
</div>
<div class="col vh-100 overflow-x-auto text-center p-4">
<div class="">
<div class="row m-0 justify-content-center justify-content-md-between mb-3">
<h4 class="col-auto ps-md-0 mb-0">Previously Applied Leaves</h4>
<div class="col-auto pe-md-0 leave-summary row m-0 g-3">
<div class="col-auto m-0"><strong>Leave Used:</strong> <span id="leaveUsed">0</span> / 10</div>
<div class="col-auto m-0"><strong>WFH Used:</strong> <span id="wfhUsed">0</span> / 10</div>
</div>
</div>
<table class="table table-bordered table-striped" id="leaveTable">
<thead class="table-dark">
<tr>
<th>#</th>
<th>Leave Summary</th>
<th>Reason</th>
<th>Status</th>
<th>Status Reason</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="row m-3 col-12 justify-content-between">
<h4 class="col-auto">Apply for Leave</h4>
<div class="col-auto">
<button class="btn btn-success d-flex justify-content-center align-items-center" id="applyLeaveBtn">Apply for Leave</button>
</div>
</div>
<div class="row justify-content-center">
<div class="col-12 col-md-4">
<div id="startCalendar"></div>
</div>
<div class="col">
<div id="selectedDateOptions" class="row m-0"></div>
</div>
</div>
<div class="row mt-3">
<div class="col-md-12">
<textarea class="form-control" id="leaveReason" rows="3" placeholder="Enter reason here..."></textarea>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
let selectedDates = {};
function createCalendar(containerId) {
const container = document.getElementById(containerId);
let current = new Date();
function renderCalendar() {
container.innerHTML = '';
const monthName = current.toLocaleString('default', { month: 'long' });
const year = current.getFullYear();
const firstDay = new Date(year, current.getMonth(), 1).getDay();
const daysInMonth = new Date(year, current.getMonth() + 1, 0).getDate();
const header = document.createElement('div');
header.className = 'd-flex justify-content-between align-items-center mb-2';
header.innerHTML = `
<button class="btn btn-sm btn-outline-secondary d-flex justify-content-center align-items-center" id="${containerId}-prev"><span class="material-symbols-outlined">
chevron_left
</span></button>
<strong>${monthName} ${year}</strong>
<button class="btn btn-sm btn-outline-secondary d-flex justify-content-center align-items-center" id="${containerId}-next"><span class="material-symbols-outlined">
chevron_right
</span></button>
`;
container.appendChild(header);
const grid = document.createElement('div');
grid.className = 'd-grid';
grid.style.gridTemplateColumns = 'repeat(7, 1fr)';
grid.classList.add('text-center', 'small');
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
days.forEach(day => {
const el = document.createElement('div');
el.className = 'fw-bold mb-1';
el.innerText = day;
grid.appendChild(el);
});
for (let i = 0; i < firstDay; i++) {
grid.appendChild(document.createElement('div'));
}
for (let d = 1; d <= daysInMonth; d++) {
const btn = document.createElement('button');
btn.className = 'btn btn-sm btn-light mb-1';
btn.textContent = d;
btn.style.width = '100%';
const dateObj = new Date(year, current.getMonth(), d);
const dateStr = dateObj.getFullYear() + '-' +
String(dateObj.getMonth() + 1).padStart(2, '0') + '-' +
String(dateObj.getDate()).padStart(2, '0');
if (selectedDates[dateStr]) {
btn.classList.replace('btn-light', 'btn-success');
btn.classList.add('text-white');
}
btn.onclick = () => {
if (selectedDates[dateStr]) {
delete selectedDates[dateStr];
document.getElementById(`dropdown-${dateStr}`)?.remove();
} else {
selectedDates[dateStr] = "WFH"; // default
addDropdown(dateStr);
}
renderCalendar();
};
grid.appendChild(btn);
}
container.appendChild(grid);
document.getElementById(`${containerId}-prev`).onclick = () => {
current.setMonth(current.getMonth() - 1);
renderCalendar();
};
document.getElementById(`${containerId}-next`).onclick = () => {
current.setMonth(current.getMonth() + 1);
renderCalendar();
};
}
function addDropdown(dateStr) {
const dropdown = document.createElement('div');
dropdown.id = `dropdown-${dateStr}`;
dropdown.className = 'col-6 col-md-4';
dropdown.innerHTML = `
<label><strong>${dateStr}</strong></label>
<select class="form-select mb-2" onchange="selectedDates['${dateStr}'] = this.value;">
<option value="WFH">WFH</option>
<option value="Leave">Leave</option>
</select>
`;
document.getElementById('selectedDateOptions').appendChild(dropdown);
}
renderCalendar();
}
createCalendar('startCalendar');
$('#applyLeaveBtn').click(function () {
const reason = $('#leaveReason').val().trim();
if (Object.keys(selectedDates).length === 0 || !reason) {
alert('Please select at least one date and enter a reason.');
return;
}
$(this).html(`<div class="spinner-border text-light" role="status">
<span class="visually-hidden">Loading...</span>
</div>`);
const leaveData = Object.entries(selectedDates).map(([date, type]) => ({ date, type }));
$.post('/apply_leave.php', {
data: JSON.stringify(leaveData),
reason: reason
}, function (res) {
$('#applyLeaveBtn').html('Send');
setTimeout(()=>{
$('#applyLeaveBtn').html('Apply for Leave');
},1000);
selectedDates = {};
$('#selectedDateOptions').empty();
createCalendar('startCalendar');
loadPreviousLeaves();
});
});
function formatLeaveSummary(leaveDataJson) {
let entries = [];
try {
entries = JSON.parse(leaveDataJson);
} catch (e) {
return 'Invalid data';
}
const grouped = {};
entries.forEach(entry => {
const { date, type } = entry;
if (!grouped[type]) grouped[type] = [];
grouped[type].push(date);
});
const summaryParts = [];
for (const type in grouped) {
const dates = grouped[type].sort();
const formattedDays = dates.map(d => new Date(d).getDate());
const monthYear = new Date(dates[0]).toLocaleDateString('en-US', {
month: 'long', year: 'numeric'
});
summaryParts.push(`${dates.length} ${type} on ${formattedDays.join(', ')} ${monthYear}`);
}
return summaryParts.join(', ');
}
function loadPreviousLeaves() {
$.get('/get_leaves.php', function(data) {
try {
if (typeof data === 'string') {
data = JSON.parse(data);
}
const tbody = $('#leaveTable tbody');
tbody.empty();
if (!Array.isArray(data) || data.length === 0) {
tbody.append('<tr><td colspan="5">No leaves found.</td></tr>');
$('#leaveUsed').text(0);
$('#wfhUsed').text(0);
return;
}
let leaveCount = 0;
let wfhCount = 0;
data.forEach((leave, index) => {
let entries = [];
try {
entries = JSON.parse(leave.leave_data_json);
} catch (e) {
entries = [];
}
// Count types
entries.forEach(entry => {
if (entry.type === 'Leave') leaveCount++;
else if (entry.type === 'WFH') wfhCount++;
});
const summary = formatLeaveSummary(leave.leave_data_json);
const row = `
<tr>
<td>${index + 1}</td>
<td>${summary}</td>
<td>${leave.reason}</td>
<td><span class="badge bg-${getStatusColor(leave.status)}">${leave.status}</span></td>
<td>${leave.status_reason ?? '-'}</td>
</tr>
`;
tbody.append(row);
});
// Update leave and WFH usage display
$('#leaveUsed').text(leaveCount);
$('#wfhUsed').text(wfhCount);
} catch (err) {
console.error('Failed to parse response or unexpected data:', err);
$('#leaveTable tbody').html('<tr><td colspan="5">Error loading leaves.</td></tr>');
$('#leaveUsed').text(0);
$('#wfhUsed').text(0);
}
});
}
function getStatusColor(status) {
switch (status.toLowerCase()) {
case 'approved': return 'success';
case 'pending': return 'warning';
case 'rejected': return 'danger';
default: return 'secondary';
}
}
$(document).ready(loadPreviousLeaves);
</script>
</body>
</html>