LittleDemon WebShell


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/
File Upload :
Command :
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>

LittleDemon - FACEBOOK
[ KELUAR ]