| 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/portal.urbanpillar.in/public_html/ |
| Current File : /home/u901718425/domains/portal.urbanpillar.in/public_html/leave.js |
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 border-0 d-flex justify-content-center align-items-center" id="${containerId}-prev"><span class="material-symbols-outlined">
chevron_left
</span></button>
<strong class="fs-5 text-dark">${monthName} ${year}</strong>
<button class="btn btn-sm btn-outline-secondary border-0 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 gap-1';
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);
// }
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 today = new Date();
today.setHours(0, 0, 0, 0); // Normalize today to midnight
const dateStr = dateObj.getFullYear() + '-' +
String(dateObj.getMonth() + 1).padStart(2, '0') + '-' +
String(dateObj.getDate()).padStart(2, '0');
// if (dateObj < today) {
// btn.disabled = true;
// btn.classList.add('text-muted');
// } else {
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>
<option value="FHLeave">First Half <span class="fs-9">Leave</span></option>
<option value="SHLeave">First Half <span class="fs-9">Leave</span></option>
</select>
`;
document.getElementById('selectedDateOptions').appendChild(dropdown);
}
renderCalendar();
}
createCalendar('calender');
$('#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('/api/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('/api/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);