|
|
<!DOCTYPE html><html lang="en" dir=""><html xmlns:th="http://www.thymeleaf.org"><head th:replace="~{fragments/modules/base/head :: head}"></head><style>.boxcard { height: 100px; border-radius: 20px;}.boxcard1 { height: 200px; border-radius: 20px; box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;}
.required{ color: red;}/* Mobile screens - targeting devices with a max width of 767px */@media (max-width: 767px) { #qaqcRequestForm label{ margin-top: 10px; } }
.card-box { border-radius: 20px; box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px; } .bg-grey-inline-text { padding:2px 2px; background-color: #e6e6e6; border-radius: 4px; } #closedCard { transition: transform 0.2s ease; /* Smooth scaling transition */ cursor: pointer; /* Default cursor change */}
#closedCard:hover { transform: scale(1.05); /* Slightly scale up on hover */ cursor: pointer; /* Change cursor to hand symbol */}
#inProgressCard { transition: transform 0.2s ease; /* Smooth scaling transition */ cursor: pointer; /* Default cursor change */}
#inProgressCard:hover { transform: scale(1.05); /* Slightly scale up on hover */ cursor: pointer; /* Change cursor to hand symbol */} #redressedCard { transition: transform 0.2s ease; /* Smooth scaling transition */ cursor: pointer; /* Default cursor change */}
#redressedCard:hover { transform: scale(1.05); /* Slightly scale up on hover */ cursor: pointer; /* Change cursor to hand symbol */} #reopenedCard { transition: transform 0.2s ease; /* Smooth scaling transition */ cursor: pointer; /* Default cursor change */}
#reopenedCard:hover { transform: scale(1.05); /* Slightly scale up on hover */ cursor: pointer; /* Change cursor to hand symbol */} #closedCard { transition: transform 0.2s ease; /* Smooth scaling transition */ cursor: pointer; /* Default cursor change */}
#closedCard:hover { transform: scale(1.05); /* Slightly scale up on hover */ cursor: pointer; /* Change cursor to hand symbol */}
</style> <body> <!--[if lt IE 8]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> <![endif]-->
<div class="wrapper"> <!-- header top menu Start --> <header th:replace="~{fragments/modules/base/header :: header}"></header> <!-- header top menu end -->
<div class="page-wrap"> <!--=============== Left Menu side Start ================--> <div th:replace="~{fragments/modules/base/menu :: menu}"></div> <!--=============== Left side End ================--> <div class="main-content"> <div class="container-fluid"> <div class="page-header mb-2"> <div class="row align-items-end"> <div class="col-lg-8"> <div class="page-header-title"> <i class="fas fa-tachometer-alt bg-blue"></i> <div class="d-inline"> <h5>Dashboard QAQC</h5> <span>1913 QAQC Dashboard</span> </div> </div> </div> <div class="col-lg-4"> <nav class="breadcrumb-container" aria-label="breadcrumb"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a href="index"><i class="ik ik-home"></i></a></li> <li class="breadcrumb-item" aria-current="page">1913 QAQC</li> <li class="breadcrumb-item" aria-current="page">Admin QAQC</li> <li class="breadcrumb-item active" aria-current="page">Grievance Dashboard</li> </ol> </nav> </div> </div> </div> <!-- <h4 class="h4 text-right text-mute" style="font-size: 12px;">
Auto refresh in <font id="refresh-countdown">00</font> seconds </h4> --> <div class="card mt-4"> <div class="card-header"> <h3> <img alt="No image" src="/gcc/assets/images/donut-chart.png" style="height: 23px; width: 23px;" class="mr-2"><b>Overall Grievance Dashboard</b> </h3> </div> <div class="card-body"> <div class="row"> <div class="col-sm-2 mb-2"> <label for="startDate" style="font-size: medium; margin-bottom: 0px;">From Date:</label> <input type="date" id="startDate" class="form-control"> </div> <div class="col-sm-2 mb-2"> <label for="endDate" style="font-size: medium; margin-bottom: 0px;">To Date:</label> <input type="date" id="endDate" class="form-control"> </div>
<div class="col-sm-2 mb-2"> <label for="dropdown4" style="font-size: medium; margin-bottom: 0px;">Group:</label> <select id="dropdown4" class="form-control"> <option value="">Select</option> <!-- <option value="">general</option> --> <!-- Add options here --> </select> </div> <div class="col-sm-2 mb-2"> <label for="dropdown1" style="font-size: medium; margin-bottom: 0px;">Type:</label> <select id="dropdown1" class="form-control"> <option value="">Select</option> <!-- <option value="Cleanliness in Parks">Cleanliness in Parks</option> -->
</select> </div>
<div class="col-sm-2 mb-2"> <label for="dropdown3" style="font-size: medium; margin-bottom: 0px;">Mode:</label> <select id="dropdown3" class="form-control"> <option value="">Select</option> <!-- <option value="">INTERNET</option> -->
</select> </div> <div class="col-sm-2 mb-2"> <label for="dropdown2" style="font-size: medium; margin-bottom: 0px;">zone:</label> <select id="dropdown2" class="form-control"> <option value="">Select</option> <!-- <option value="N01">N01</option> --> <!-- <option value="ALL">ALL</option> -->
</select> </div>
</div> <div class="row mt-4"> <div class="col-12 d-flex justify-content-center"> <button type="submit" id="searchButton" class="btn btn-primary mx-2">Filter</button>
<button class="btn btn-danger mx-2" onclick="resetDate()" name="reset" type="reset">Reset</button> </div> </div>
</div> <div class="col-12"> <div class="row mt-3"> <!-- First Part: 2 cards vertically --> <div class="col-lg-4 col-md-4 col-sm-12"> <div class="card card-box" id="inProgressCard"> <p class="text-facebook mb-20 text-center mt-4" id="inProgressname" style="font-size: medium;"><i class="fas fa-spinner text-center" ></i> <b>In-progress</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" id="inProgressCount"></h3> </div> <div class="card card-box" id="redressedCard"> <p class="text-facebook mb-20 text-center mt-4"id="redressedname" style="font-size: medium;"><i class="fas fa-check-circle text-center" style=" color: green;"></i> <b>Action Taken Level 1</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" id="redressedCount"></h3> </div> </div> <!-- Second Part: 1 card, height equal to both cards in the first part --> <div class="col-lg-4 col-md-4 col-sm-12 mt-3"> <div class="card boxcard1"> <div class="card-body"> <p class="text-facebook mb-20 text-center mt-4" style="font-size: medium;"><i class="fas fa-clipboard-list text-center"></i> <b>Total Complaints</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" id="totalComplaints"></h3> </div> </div> </div> <!-- Third Part: 2 cards vertically --> <div class="col-lg-4 col-md-4 col-sm-12"> <div class="card card-box" id="reopenedCard"> <p class="text-facebook mb-20 text-center mt-4" id="Reopenname" style="font-size: medium;"><i class="fas fa-exclamation-circle text-center" style=" color: orange;"></i> <b>Reopened</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" id="reopenedCount"></h3> </div> <div class="card card-box" id="closedCard"> <p class="text-facebook mb-20 text-center mt-4" id="Closename" style="font-size: medium;"><i class="fas fa-check-circle text-center" style=" color: green;"></i> <b>Action Taken Level 2</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" id="closedCount"></h3> </div> </div> </div> </div> <!-- agent wise yesterday performance counts card--> <div class="card-body"> <div class="page-header-title" > <h5 style="margin: 0;font-weight: bold;">Yesterday Event - Agent Performance Dashboard</h5><hr> </div> <div class="row mt-2"> <div class="col-xl-3 col-md-6 col-sm-12"> <div class="card card-box"> <p class="text-facebook mb-20 text-center mt-4"><b>Agent Assigned</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalAgents}"></h3> </div> </div> <div class="col-xl-3 col-md-6 col-sm-12"> <div class="card card-box"> <p class="text-facebook mb-20 text-center mt-4"><b>Assigned Calls</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalAssigned != null ? previousday[0].TotalAssigned : 0}"></h3> </div> </div> <div class="col-xl-3 col-md-6 col-sm-12"> <div class="card card-box"> <p class="text-facebook mb-20 text-center mt-4"><b>Finished</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalCompleted != null ? previousday[0].TotalCompleted : 0}"></h3> </div> </div> <div class="col-xl-3 col-md-6 col-sm-12"> <div class="card card-box"> <p class="text-facebook mb-20 text-center mt-4"><b>Pending Calls</b></p> <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalPending != null ? previousday[0].TotalPending : 0}"></h3> </div> </div> </div> </div> <div class="col-md-16"> <div class="card-body"> <div class="page-header-title" > <h5 style="margin: 0;font-weight: bold;">Yesterday Event - Agents Wise Breakup</h5><hr> </div> <table id="YesterdayQaqctable" class="table table-striped table-bordered table-hover dataTable" role="grid"> <thead class="thead-dark"> <tr role="row"> <th rowspan="2" class="text-center">S.No</th> <th rowspan="2" class="text-center">Agent</th> <th colspan="4" class="text-center">Performance</th> <th colspan="4" class="text-center">Call Results</th> </tr> <tr role="row"> <th class="text-center">Assigned Calls</th> <th class="text-center">Finished</th> <th class="text-center">Pending Calls</th> <th class="text-center">Completion (%)</th> <th class="text-center">Completed</th> <th class="text-center">ReOpen</th> <th class="text-center">Followup</th> <th class="text-center">Others</th> </tr> </thead> <tbody> <!-- Loop through the agentcount data --> <tr th:each="row, iterStat : ${agentcount}"> <td class="text-center" th:text="${iterStat.index + 1}"></td> <td class="text-center" th:text="${row.agent_name}"></td> <td class="text-center" th:text="${row.Assigned}"></td> <td class="text-center" th:text="${row.TotalCompleted}"></td> <td class="text-center" th:text="${row.Pending}"></td> <td class="text-center" th:text="${row.CompletionPercentage + '%'}"></td> <td class="text-center" th:text="${row.Completed_count}"></td> <td class="text-center" th:text="${row.Reopened_count}"></td> <td class="text-center" th:text="${row.Followup_count}"></td> <td class="text-center" th:text="${row.Other_count}"></td> </tr> </tbody> </table> </div> </div> </div> </div> </div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer> </div> </div> <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div> <script th:replace="~{fragments/modules/base/script :: script}"></script> <script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script type="text/javascript"> $(document).ready(function() {
var table = $('#YesterdayQaqctable').DataTable({ dom: 'Bftip', columnDefs: [ { targets: 'no-sort', orderable: false } ], lengthMenu: [ [50, 100, 200, 500, -1], ['50 rows', '100 rows', '200 rows', 'Show all'] ], scrollY: '50vh', fixedColumns: { left: 1, right: 1 }, buttons: [ { extend: 'pageLength', className: 'btn btn-warning' }, { title: 'Data export', extend: 'copyHtml5', text: 'Copy', className: 'btn btn-secondary', id: 'copyBtn' }, { extend: 'excelHtml5', text: 'Excel', className: 'btn btn-secondary', id: 'excelBtn' }, { extend: 'csvHtml5', text: 'CSV', className: 'btn btn-secondary', id: 'csvBtn' }, { extend: 'pdfHtml5', text: 'PDF', className: 'btn btn-secondary', id: 'pdfBtn' } ], fixedHeader: true, autoWidth: true, responsive: true, searching: false, select: false, processing: false }); });
<!------------------ this is updated getting data function ---------------->
document.addEventListener('DOMContentLoaded', function () { // Get today's date const today = new Date(); const year = today.getFullYear(); const month = String(today.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed const day = String(today.getDate()).padStart(2, '0');
// Calculate the first day of the current month const startOfMonth = `${year}-${month}-01`; // yyyy-MM-dd format const todayFormatted = `${year}-${month}-${day}`; // yyyy-MM-dd format
const startDateField = document.getElementById('startDate'); const endDateField = document.getElementById('endDate'); // Event listener for To Date endDateField.addEventListener('change', function () { if (endDateField.value) { startDateField.max = endDateField.value; // Set max value for From Date } else { startDateField.removeAttribute('max'); // Remove max if To Date is cleared }
// Validate From Date against updated To Date if (startDateField.value && new Date(startDateField.value) > new Date(endDateField.value)) { startDateField.value = ''; // Clear invalid From Date alert("From Date cannot be after To Date."); } });
// Event listener for From Date startDateField.addEventListener('change', function () { if (startDateField.value) { endDateField.min = startDateField.value; // Set min value for To Date } else { endDateField.removeAttribute('min'); // Remove min if From Date is cleared }
// Validate To Date against updated From Date if (endDateField.value && new Date(endDateField.value) < new Date(startDateField.value)) { endDateField.value = ''; // Clear invalid To Date alert("To Date cannot be before From Date."); } });
// Set the default date values in the input fields if (startDateField && endDateField) { startDateField.value = startOfMonth; // yyyy-MM-dd format required for input[type="date"] endDateField.value = todayFormatted; // yyyy-MM-dd format required for input[type="date"] } else { console.error("Start date or end date input field not found!"); }
// Call the search logic directly to load default data on page load loadDashboardData(formatDateForAPI(startOfMonth), formatDateForAPI(todayFormatted));});
// Helper function to convert yyyy-MM-dd to dd-MM-yyyy for API callsfunction formatDateForAPI(dateStr) { const [year, month, day] = dateStr.split('-'); return `${day}-${month}-${year}`; // Convert to dd-MM-yyyy}
function loadDashboardData(startDate, endDate) { // Show loading indicators call_loading('totalComplaints', 'start'); call_loading('inProgressCount', 'start'); call_loading('redressedCount', 'start'); call_loading('reopenedCount', 'start'); call_loading('closedCount', 'start');
// Get dropdown values const startDateValue = document.getElementById('startDate').value; const endDateValue = document.getElementById('endDate').value; const dropdown1 = document.getElementById('dropdown1').value; const dropdown2 = document.getElementById('dropdown2').value; const dropdown3 = document.getElementById('dropdown3').value; const dropdown4 = document.getElementById('dropdown4').value;
// Make API call to get dashboard data fetch(`/gcc/api/callcenterqaqc/dashboard?startDate=${startDate}&endDate=${endDate}&dropdown1=${dropdown1}&dropdown2=${dropdown2}&dropdown3=${dropdown3}&dropdown4=${dropdown4}`) .then(response => response.json()) .then(data => { //console.log(data);
// Store data in sessionStorage sessionStorage.setItem('closename', 'closed'); sessionStorage.setItem('closedcount', data["Closed"] || "0"); sessionStorage.setItem('reopenname', 'reopened'); sessionStorage.setItem('reopenedcount', data["Reopened"] || "0"); sessionStorage.setItem('inProgressName', 'processing'); sessionStorage.setItem('inProgressCount', data["In Progress"] || "0"); sessionStorage.setItem('redressedName', 'redressed'); sessionStorage.setItem('redressedCount', data["Redressed"] || "0"); sessionStorage.setItem('startDate', startDateValue); sessionStorage.setItem('endDate', endDateValue); sessionStorage.setItem('type', dropdown1); sessionStorage.setItem('zone', dropdown2); sessionStorage.setItem('mode', dropdown3); sessionStorage.setItem('group', dropdown4); sessionStorage.setItem('redirected', 'true'); // Set flag for redirection // Function to handle redirection based on count function handleCardClick(count, cardType, url) { if (parseInt(count) === 0) { Swal.fire({ icon: 'info', title: 'No Data', text: `No ${cardType} records available.`, }); } else { sessionStorage.setItem('cardType', cardType); // Set card type window.location.href = url; } }
// Attach click events to each card document.getElementById('closedCard').addEventListener('click', function () { handleCardClick(sessionStorage.getItem('closedcount'), 'Closed', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents'); });
document.getElementById('reopenedCard').addEventListener('click', function () { handleCardClick(sessionStorage.getItem('reopenedcount'), 'Reopened', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents'); });
document.getElementById('inProgressCard').addEventListener('click', function () { handleCardClick(sessionStorage.getItem('inProgressCount'), 'In Progress', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents'); });
document.getElementById('redressedCard').addEventListener('click', function () { handleCardClick(sessionStorage.getItem('redressedCount'), 'Redressed', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents'); });
// Update UI with fetched data document.getElementById('totalComplaints').textContent = data["Total Complaints"] || "0"; document.getElementById('inProgressCount').textContent = data["In Progress"] || "0"; document.getElementById('redressedCount').textContent = data["Redressed"] || "0"; document.getElementById('reopenedCount').textContent = data["Reopened"] || "0"; document.getElementById('closedCount').textContent = data["Closed"] || "0";
// Stop loading indicators call_loading('totalComplaints', 'stop'); call_loading('inProgressCount', 'stop'); call_loading('redressedCount', 'stop'); call_loading('reopenedCount', 'stop'); call_loading('closedCount', 'stop'); }) .catch(error => { console.error('Error:', error); });}
//Event listener for the search button to reload data based on selected filtersdocument.getElementById('searchButton').addEventListener('click', function () { // Get values from input fields const startDateValue = document.getElementById('startDate').value; // yyyy-MM-dd format const endDateValue = document.getElementById('endDate').value; // yyyy-MM-dd format
// Function to format date as dd-MM-yyyy const formatDate = (dateStr) => { const [year, month, day] = dateStr.split('-'); // Split yyyy-MM-dd return `${day}-${month}-${year}`; // Rearrange to dd-MM-yyyy };
// Convert to dd-MM-yyyy format const formattedStartDate = formatDate(startDateValue); const formattedEndDate = formatDate(endDateValue);
// Validate dates const startDate = new Date(startDateValue); // Use original yyyy-MM-dd for comparison const endDate = new Date(endDateValue);
if (startDate && endDate && startDate > endDate) { alert("Start Date should be earlier than End Date."); return; }
// Call dashboard data loading logic with formatted date values loadDashboardData(formattedStartDate, formattedEndDate);});
//api for complainttypes,group,zone,ward
document.addEventListener("DOMContentLoaded", function () { const complaintTypeDropdown = document.getElementById('dropdown1'); const complaintGroupDropdown = document.getElementById('dropdown4'); const complaintModeDropdown = document.getElementById('dropdown3'); const complaintZoneDropdown = document.getElementById('dropdown2');
// Load Complaint Groups fetch('/gcc/api/callcenterqaqc/getComplaintGroup') .then(response => response.json()) .then(data => { // Clear existing options complaintGroupDropdown.innerHTML = `<option value="">Select</option>`;
// Add options from the API response data.forEach(complaintGroupName => { complaintGroupDropdown.innerHTML += `<option value="${complaintGroupName}">${complaintGroupName}</option>`; }); }) .catch(error => { console.error('Error fetching complaint groups:', error); });
// Event Listener for Complaint Group Change complaintGroupDropdown.addEventListener('change', function () { const selectedGroup = complaintGroupDropdown.value;
if (selectedGroup) { // Fetch Complaint Types based on selected group fetch(`/gcc/api/callcenterqaqc/getComplaintTypesByGroup?group=${encodeURIComponent(selectedGroup)}`) .then(response => response.json()) .then(data => { // Clear existing options complaintTypeDropdown.innerHTML = `<option value="">Select</option>`;
// Add options from the API response data.forEach(complaintTypeName => { complaintTypeDropdown.innerHTML += `<option value="${complaintTypeName}">${complaintTypeName}</option>`; }); }) .catch(error => { console.error('Error fetching complaint types:', error); }); } else { // Clear complaint type dropdown if no group is selected complaintTypeDropdown.innerHTML = `<option value="">Select</option>`; } }); // Load all Modes fetch('/gcc/api/callcenterqaqc/getModes') .then(response => response.json()) .then(data => { // Clear existing options complaintModeDropdown.innerHTML = `<option value="">Select</option>`;
// Add options from the API response data.forEach(complaintMode => { complaintModeDropdown.innerHTML += `<option value="${complaintMode}">${complaintMode}</option>`; }); }) .catch(error => { console.error('Error fetching complaint groups:', error); }); // Load all zones fetch('/gcc/api/callcenterqaqc/getZones') .then(response => response.json()) .then(data => { // Clear existing options complaintZoneDropdown.innerHTML = `<option value="">Select</option>`;
// Add options from the API response data.forEach(complaintZone => { complaintZoneDropdown.innerHTML += `<option value="${complaintZone}">${complaintZone}</option>`; }); }) .catch(error => { console.error('Error fetching complaint groups:', error); }); });
//Function to reset date fields function resetDate() {
window.location.href = "/gcc/callcenterqaqc/admin/qaqcgrievancedashboard"; }
</script>
<script type="text/javascript">
</script>
</body></html>
|