This portal only for GCC Officers. Based on there roles and Group ID they can view there module`s Like PGR, QR Public Asset Feedback, Makkalai Thedi Mayor,etc...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

701 lines
29 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" dir="">
  3. <html xmlns:th="http://www.thymeleaf.org">
  4. <head th:replace="~{fragments/modules/base/head :: head}"></head>
  5. <style>
  6. .boxcard {
  7. height: 100px;
  8. border-radius: 20px;
  9. }
  10. .boxcard1 {
  11. height: 200px;
  12. border-radius: 20px;
  13. box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
  14. }
  15. .required{
  16. color: red;
  17. }
  18. /* Mobile screens - targeting devices with a max width of 767px */
  19. @media (max-width: 767px)
  20. {
  21. #qaqcRequestForm label{
  22. margin-top: 10px;
  23. }
  24. }
  25. .card-box {
  26. border-radius: 20px;
  27. box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
  28. }
  29. .bg-grey-inline-text {
  30. padding:2px 2px;
  31. background-color: #e6e6e6;
  32. border-radius: 4px;
  33. }
  34. #closedCard {
  35. transition: transform 0.2s ease; /* Smooth scaling transition */
  36. cursor: pointer; /* Default cursor change */
  37. }
  38. #closedCard:hover {
  39. transform: scale(1.05); /* Slightly scale up on hover */
  40. cursor: pointer; /* Change cursor to hand symbol */
  41. }
  42. #inProgressCard {
  43. transition: transform 0.2s ease; /* Smooth scaling transition */
  44. cursor: pointer; /* Default cursor change */
  45. }
  46. #inProgressCard:hover {
  47. transform: scale(1.05); /* Slightly scale up on hover */
  48. cursor: pointer; /* Change cursor to hand symbol */
  49. }
  50. #redressedCard {
  51. transition: transform 0.2s ease; /* Smooth scaling transition */
  52. cursor: pointer; /* Default cursor change */
  53. }
  54. #redressedCard:hover {
  55. transform: scale(1.05); /* Slightly scale up on hover */
  56. cursor: pointer; /* Change cursor to hand symbol */
  57. }
  58. #reopenedCard {
  59. transition: transform 0.2s ease; /* Smooth scaling transition */
  60. cursor: pointer; /* Default cursor change */
  61. }
  62. #reopenedCard:hover {
  63. transform: scale(1.05); /* Slightly scale up on hover */
  64. cursor: pointer; /* Change cursor to hand symbol */
  65. }
  66. #closedCard {
  67. transition: transform 0.2s ease; /* Smooth scaling transition */
  68. cursor: pointer; /* Default cursor change */
  69. }
  70. #closedCard:hover {
  71. transform: scale(1.05); /* Slightly scale up on hover */
  72. cursor: pointer; /* Change cursor to hand symbol */
  73. }
  74. </style>
  75. <body>
  76. <!--[if lt IE 8]>
  77. <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>
  78. <![endif]-->
  79. <div class="wrapper">
  80. <!-- header top menu Start -->
  81. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  82. <!-- header top menu end -->
  83. <div class="page-wrap">
  84. <!--=============== Left Menu side Start ================-->
  85. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  86. <!--=============== Left side End ================-->
  87. <div class="main-content">
  88. <div class="container-fluid">
  89. <div class="page-header mb-2">
  90. <div class="row align-items-end">
  91. <div class="col-lg-8">
  92. <div class="page-header-title">
  93. <i class="fas fa-tachometer-alt bg-blue"></i>
  94. <div class="d-inline">
  95. <h5>Dashboard QAQC</h5>
  96. <span>1913 QAQC Dashboard</span>
  97. </div>
  98. </div>
  99. </div>
  100. <div class="col-lg-4">
  101. <nav class="breadcrumb-container" aria-label="breadcrumb">
  102. <ol class="breadcrumb">
  103. <li class="breadcrumb-item"><a href="index"><i
  104. class="ik ik-home"></i></a></li>
  105. <li class="breadcrumb-item" aria-current="page">1913 QAQC</li>
  106. <li class="breadcrumb-item" aria-current="page">Admin QAQC</li>
  107. <li class="breadcrumb-item active" aria-current="page">Grievance Dashboard</li>
  108. </ol>
  109. </nav>
  110. </div>
  111. </div>
  112. </div>
  113. <!-- <h4 class="h4 text-right text-mute" style="font-size: 12px;">
  114. Auto refresh in <font id="refresh-countdown">00</font> seconds
  115. </h4> -->
  116. <div class="card mt-4">
  117. <div class="card-header">
  118. <h3>
  119. <img alt="No image" src="/gcc/assets/images/donut-chart.png"
  120. style="height: 23px; width: 23px;" class="mr-2"><b>Overall Grievance
  121. Dashboard</b>
  122. </h3>
  123. </div>
  124. <div class="card-body">
  125. <div class="row">
  126. <div class="col-sm-2 mb-2">
  127. <label for="startDate" style="font-size: medium; margin-bottom: 0px;">From Date:</label>
  128. <input type="date" id="startDate" class="form-control">
  129. </div>
  130. <div class="col-sm-2 mb-2">
  131. <label for="endDate" style="font-size: medium; margin-bottom: 0px;">To Date:</label>
  132. <input type="date" id="endDate" class="form-control">
  133. </div>
  134. <div class="col-sm-2 mb-2">
  135. <label for="dropdown4" style="font-size: medium; margin-bottom: 0px;">Group:</label>
  136. <select id="dropdown4" class="form-control">
  137. <option value="">Select</option>
  138. <!-- <option value="">general</option> -->
  139. <!-- Add options here -->
  140. </select>
  141. </div>
  142. <div class="col-sm-2 mb-2">
  143. <label for="dropdown1" style="font-size: medium; margin-bottom: 0px;">Type:</label>
  144. <select id="dropdown1" class="form-control">
  145. <option value="">Select</option>
  146. <!-- <option value="Cleanliness in Parks">Cleanliness in Parks</option> -->
  147. </select>
  148. </div>
  149. <div class="col-sm-2 mb-2">
  150. <label for="dropdown3" style="font-size: medium; margin-bottom: 0px;">Mode:</label>
  151. <select id="dropdown3" class="form-control">
  152. <option value="">Select</option>
  153. <!-- <option value="">INTERNET</option> -->
  154. </select>
  155. </div>
  156. <div class="col-sm-2 mb-2">
  157. <label for="dropdown2" style="font-size: medium; margin-bottom: 0px;">zone:</label>
  158. <select id="dropdown2" class="form-control">
  159. <option value="">Select</option>
  160. <!-- <option value="N01">N01</option> -->
  161. <!-- <option value="ALL">ALL</option> -->
  162. </select>
  163. </div>
  164. </div>
  165. <div class="row mt-4">
  166. <div class="col-12 d-flex justify-content-center">
  167. <button type="submit" id="searchButton"
  168. class="btn btn-primary mx-2">Filter</button>
  169. <button class="btn btn-danger mx-2" onclick="resetDate()"
  170. name="reset" type="reset">Reset</button>
  171. </div>
  172. </div>
  173. </div>
  174. <div class="col-12">
  175. <div class="row mt-3">
  176. <!-- First Part: 2 cards vertically -->
  177. <div class="col-lg-4 col-md-4 col-sm-12">
  178. <div class="card card-box" id="inProgressCard">
  179. <p class="text-facebook mb-20 text-center mt-4" id="inProgressname" style="font-size: medium;"><i class="fas fa-spinner text-center" ></i>&nbsp;<b>In-progress</b></p>
  180. <h3 class="text-twitter fw-700 ml-5 text-center" id="inProgressCount"></h3>
  181. </div>
  182. <div class="card card-box" id="redressedCard">
  183. <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>&nbsp;<b>Action Taken Level 1</b></p>
  184. <h3 class="text-twitter fw-700 ml-5 text-center" id="redressedCount"></h3>
  185. </div>
  186. </div>
  187. <!-- Second Part: 1 card, height equal to both cards in the first part -->
  188. <div class="col-lg-4 col-md-4 col-sm-12 mt-3">
  189. <div class="card boxcard1">
  190. <div class="card-body">
  191. <p class="text-facebook mb-20 text-center mt-4" style="font-size: medium;"><i class="fas fa-clipboard-list text-center"></i>&nbsp;<b>Total Complaints</b></p>
  192. <h3 class="text-twitter fw-700 ml-5 text-center" id="totalComplaints"></h3>
  193. </div>
  194. </div>
  195. </div>
  196. <!-- Third Part: 2 cards vertically -->
  197. <div class="col-lg-4 col-md-4 col-sm-12">
  198. <div class="card card-box" id="reopenedCard">
  199. <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>&nbsp;<b>Reopened</b></p>
  200. <h3 class="text-twitter fw-700 ml-5 text-center" id="reopenedCount"></h3>
  201. </div>
  202. <div class="card card-box" id="closedCard">
  203. <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>&nbsp;<b>Action Taken Level 2</b></p>
  204. <h3 class="text-twitter fw-700 ml-5 text-center" id="closedCount"></h3>
  205. </div>
  206. </div>
  207. </div>
  208. </div>
  209. <!-- agent wise yesterday performance counts card-->
  210. <div class="card-body">
  211. <div class="page-header-title" >
  212. <h5 style="margin: 0;font-weight: bold;">Yesterday Event - Agent Performance Dashboard</h5><hr>
  213. </div>
  214. <div class="row mt-2">
  215. <div class="col-xl-3 col-md-6 col-sm-12">
  216. <div class="card card-box">
  217. <p class="text-facebook mb-20 text-center mt-4"><b>Agent Assigned</b></p>
  218. <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalAgents}"></h3>
  219. </div>
  220. </div>
  221. <div class="col-xl-3 col-md-6 col-sm-12">
  222. <div class="card card-box">
  223. <p class="text-facebook mb-20 text-center mt-4"><b>Assigned Calls</b></p>
  224. <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalAssigned != null ? previousday[0].TotalAssigned : 0}"></h3>
  225. </div>
  226. </div>
  227. <div class="col-xl-3 col-md-6 col-sm-12">
  228. <div class="card card-box">
  229. <p class="text-facebook mb-20 text-center mt-4"><b>Finished</b></p>
  230. <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalCompleted != null ? previousday[0].TotalCompleted : 0}"></h3>
  231. </div>
  232. </div>
  233. <div class="col-xl-3 col-md-6 col-sm-12">
  234. <div class="card card-box">
  235. <p class="text-facebook mb-20 text-center mt-4"><b>Pending Calls</b></p>
  236. <h3 class="text-twitter fw-700 ml-5 text-center" th:text="${previousday[0].TotalPending != null ? previousday[0].TotalPending : 0}"></h3>
  237. </div>
  238. </div>
  239. </div>
  240. </div>
  241. <div class="col-md-16">
  242. <div class="card-body">
  243. <div class="page-header-title" >
  244. <h5 style="margin: 0;font-weight: bold;">Yesterday Event - Agents Wise Breakup</h5><hr>
  245. </div>
  246. <table id="YesterdayQaqctable" class="table table-striped table-bordered table-hover dataTable" role="grid">
  247. <thead class="thead-dark">
  248. <tr role="row">
  249. <th rowspan="2" class="text-center">S.No</th>
  250. <th rowspan="2" class="text-center">Agent</th>
  251. <th colspan="4" class="text-center">Performance</th>
  252. <th colspan="4" class="text-center">Call Results</th>
  253. </tr>
  254. <tr role="row">
  255. <th class="text-center">Assigned Calls</th>
  256. <th class="text-center">Finished</th>
  257. <th class="text-center">Pending Calls</th>
  258. <th class="text-center">Completion (%)</th>
  259. <th class="text-center">Completed</th>
  260. <th class="text-center">ReOpen</th>
  261. <th class="text-center">Followup</th>
  262. <th class="text-center">Others</th>
  263. </tr>
  264. </thead>
  265. <tbody>
  266. <!-- Loop through the agentcount data -->
  267. <tr th:each="row, iterStat : ${agentcount}">
  268. <td class="text-center" th:text="${iterStat.index + 1}"></td>
  269. <td class="text-center" th:text="${row.agent_name}"></td>
  270. <td class="text-center" th:text="${row.Assigned}"></td>
  271. <td class="text-center" th:text="${row.TotalCompleted}"></td>
  272. <td class="text-center" th:text="${row.Pending}"></td>
  273. <td class="text-center" th:text="${row.CompletionPercentage + '%'}"></td> <td class="text-center" th:text="${row.Completed_count}"></td>
  274. <td class="text-center" th:text="${row.Reopened_count}"></td>
  275. <td class="text-center" th:text="${row.Followup_count}"></td>
  276. <td class="text-center" th:text="${row.Other_count}"></td>
  277. </tr>
  278. </tbody>
  279. </table>
  280. </div>
  281. </div>
  282. </div>
  283. </div>
  284. </div>
  285. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  286. </div>
  287. </div>
  288. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  289. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  290. <script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
  291. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  292. <script type="text/javascript">
  293. $(document).ready(function() {
  294. var table = $('#YesterdayQaqctable').DataTable({
  295. dom: 'Bftip',
  296. columnDefs: [
  297. { targets: 'no-sort', orderable: false }
  298. ],
  299. lengthMenu: [
  300. [50, 100, 200, 500, -1],
  301. ['50 rows', '100 rows', '200 rows', 'Show all']
  302. ],
  303. scrollY: '50vh',
  304. fixedColumns: {
  305. left: 1,
  306. right: 1
  307. },
  308. buttons: [
  309. {
  310. extend: 'pageLength',
  311. className: 'btn btn-warning'
  312. },
  313. {
  314. title: 'Data export',
  315. extend: 'copyHtml5',
  316. text: 'Copy',
  317. className: 'btn btn-secondary',
  318. id: 'copyBtn'
  319. },
  320. {
  321. extend: 'excelHtml5',
  322. text: 'Excel',
  323. className: 'btn btn-secondary',
  324. id: 'excelBtn'
  325. },
  326. {
  327. extend: 'csvHtml5',
  328. text: 'CSV',
  329. className: 'btn btn-secondary',
  330. id: 'csvBtn'
  331. },
  332. {
  333. extend: 'pdfHtml5',
  334. text: 'PDF',
  335. className: 'btn btn-secondary',
  336. id: 'pdfBtn'
  337. }
  338. ],
  339. fixedHeader: true,
  340. autoWidth: true,
  341. responsive: true,
  342. searching: false,
  343. select: false,
  344. processing: false
  345. });
  346. });
  347. <!------------------ this is updated getting data function ---------------->
  348. document.addEventListener('DOMContentLoaded', function () {
  349. // Get today's date
  350. const today = new Date();
  351. const year = today.getFullYear();
  352. const month = String(today.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
  353. const day = String(today.getDate()).padStart(2, '0');
  354. // Calculate the first day of the current month
  355. const startOfMonth = `${year}-${month}-01`; // yyyy-MM-dd format
  356. const todayFormatted = `${year}-${month}-${day}`; // yyyy-MM-dd format
  357. const startDateField = document.getElementById('startDate');
  358. const endDateField = document.getElementById('endDate');
  359. // Event listener for To Date
  360. endDateField.addEventListener('change', function () {
  361. if (endDateField.value) {
  362. startDateField.max = endDateField.value; // Set max value for From Date
  363. } else {
  364. startDateField.removeAttribute('max'); // Remove max if To Date is cleared
  365. }
  366. // Validate From Date against updated To Date
  367. if (startDateField.value && new Date(startDateField.value) > new Date(endDateField.value)) {
  368. startDateField.value = ''; // Clear invalid From Date
  369. alert("From Date cannot be after To Date.");
  370. }
  371. });
  372. // Event listener for From Date
  373. startDateField.addEventListener('change', function () {
  374. if (startDateField.value) {
  375. endDateField.min = startDateField.value; // Set min value for To Date
  376. } else {
  377. endDateField.removeAttribute('min'); // Remove min if From Date is cleared
  378. }
  379. // Validate To Date against updated From Date
  380. if (endDateField.value && new Date(endDateField.value) < new Date(startDateField.value)) {
  381. endDateField.value = ''; // Clear invalid To Date
  382. alert("To Date cannot be before From Date.");
  383. }
  384. });
  385. // Set the default date values in the input fields
  386. if (startDateField && endDateField) {
  387. startDateField.value = startOfMonth; // yyyy-MM-dd format required for input[type="date"]
  388. endDateField.value = todayFormatted; // yyyy-MM-dd format required for input[type="date"]
  389. } else {
  390. console.error("Start date or end date input field not found!");
  391. }
  392. // Call the search logic directly to load default data on page load
  393. loadDashboardData(formatDateForAPI(startOfMonth), formatDateForAPI(todayFormatted));
  394. });
  395. // Helper function to convert yyyy-MM-dd to dd-MM-yyyy for API calls
  396. function formatDateForAPI(dateStr) {
  397. const [year, month, day] = dateStr.split('-');
  398. return `${day}-${month}-${year}`; // Convert to dd-MM-yyyy
  399. }
  400. function loadDashboardData(startDate, endDate) {
  401. // Show loading indicators
  402. call_loading('totalComplaints', 'start');
  403. call_loading('inProgressCount', 'start');
  404. call_loading('redressedCount', 'start');
  405. call_loading('reopenedCount', 'start');
  406. call_loading('closedCount', 'start');
  407. // Get dropdown values
  408. const startDateValue = document.getElementById('startDate').value;
  409. const endDateValue = document.getElementById('endDate').value;
  410. const dropdown1 = document.getElementById('dropdown1').value;
  411. const dropdown2 = document.getElementById('dropdown2').value;
  412. const dropdown3 = document.getElementById('dropdown3').value;
  413. const dropdown4 = document.getElementById('dropdown4').value;
  414. // Make API call to get dashboard data
  415. fetch(`/gcc/api/callcenterqaqc/dashboard?startDate=${startDate}&endDate=${endDate}&dropdown1=${dropdown1}&dropdown2=${dropdown2}&dropdown3=${dropdown3}&dropdown4=${dropdown4}`)
  416. .then(response => response.json())
  417. .then(data => {
  418. //console.log(data);
  419. // Store data in sessionStorage
  420. sessionStorage.setItem('closename', 'closed');
  421. sessionStorage.setItem('closedcount', data["Closed"] || "0");
  422. sessionStorage.setItem('reopenname', 'reopened');
  423. sessionStorage.setItem('reopenedcount', data["Reopened"] || "0");
  424. sessionStorage.setItem('inProgressName', 'processing');
  425. sessionStorage.setItem('inProgressCount', data["In Progress"] || "0");
  426. sessionStorage.setItem('redressedName', 'redressed');
  427. sessionStorage.setItem('redressedCount', data["Redressed"] || "0");
  428. sessionStorage.setItem('startDate', startDateValue);
  429. sessionStorage.setItem('endDate', endDateValue);
  430. sessionStorage.setItem('type', dropdown1);
  431. sessionStorage.setItem('zone', dropdown2);
  432. sessionStorage.setItem('mode', dropdown3);
  433. sessionStorage.setItem('group', dropdown4);
  434. sessionStorage.setItem('redirected', 'true'); // Set flag for redirection
  435. // Function to handle redirection based on count
  436. function handleCardClick(count, cardType, url) {
  437. if (parseInt(count) === 0) {
  438. Swal.fire({
  439. icon: 'info',
  440. title: 'No Data',
  441. text: `No ${cardType} records available.`,
  442. });
  443. } else {
  444. sessionStorage.setItem('cardType', cardType); // Set card type
  445. window.location.href = url;
  446. }
  447. }
  448. // Attach click events to each card
  449. document.getElementById('closedCard').addEventListener('click', function () {
  450. handleCardClick(sessionStorage.getItem('closedcount'), 'Closed', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents');
  451. });
  452. document.getElementById('reopenedCard').addEventListener('click', function () {
  453. handleCardClick(sessionStorage.getItem('reopenedcount'), 'Reopened', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents');
  454. });
  455. document.getElementById('inProgressCard').addEventListener('click', function () {
  456. handleCardClick(sessionStorage.getItem('inProgressCount'), 'In Progress', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents');
  457. });
  458. document.getElementById('redressedCard').addEventListener('click', function () {
  459. handleCardClick(sessionStorage.getItem('redressedCount'), 'Redressed', '/gcc/callcenterqaqc/admin/qaqcassigntaskagents');
  460. });
  461. // Update UI with fetched data
  462. document.getElementById('totalComplaints').textContent = data["Total Complaints"] || "0";
  463. document.getElementById('inProgressCount').textContent = data["In Progress"] || "0";
  464. document.getElementById('redressedCount').textContent = data["Redressed"] || "0";
  465. document.getElementById('reopenedCount').textContent = data["Reopened"] || "0";
  466. document.getElementById('closedCount').textContent = data["Closed"] || "0";
  467. // Stop loading indicators
  468. call_loading('totalComplaints', 'stop');
  469. call_loading('inProgressCount', 'stop');
  470. call_loading('redressedCount', 'stop');
  471. call_loading('reopenedCount', 'stop');
  472. call_loading('closedCount', 'stop');
  473. })
  474. .catch(error => {
  475. console.error('Error:', error);
  476. });
  477. }
  478. //Event listener for the search button to reload data based on selected filters
  479. document.getElementById('searchButton').addEventListener('click', function () {
  480. // Get values from input fields
  481. const startDateValue = document.getElementById('startDate').value; // yyyy-MM-dd format
  482. const endDateValue = document.getElementById('endDate').value; // yyyy-MM-dd format
  483. // Function to format date as dd-MM-yyyy
  484. const formatDate = (dateStr) => {
  485. const [year, month, day] = dateStr.split('-'); // Split yyyy-MM-dd
  486. return `${day}-${month}-${year}`; // Rearrange to dd-MM-yyyy
  487. };
  488. // Convert to dd-MM-yyyy format
  489. const formattedStartDate = formatDate(startDateValue);
  490. const formattedEndDate = formatDate(endDateValue);
  491. // Validate dates
  492. const startDate = new Date(startDateValue); // Use original yyyy-MM-dd for comparison
  493. const endDate = new Date(endDateValue);
  494. if (startDate && endDate && startDate > endDate) {
  495. alert("Start Date should be earlier than End Date.");
  496. return;
  497. }
  498. // Call dashboard data loading logic with formatted date values
  499. loadDashboardData(formattedStartDate, formattedEndDate);
  500. });
  501. //api for complainttypes,group,zone,ward
  502. document.addEventListener("DOMContentLoaded", function () {
  503. const complaintTypeDropdown = document.getElementById('dropdown1');
  504. const complaintGroupDropdown = document.getElementById('dropdown4');
  505. const complaintModeDropdown = document.getElementById('dropdown3');
  506. const complaintZoneDropdown = document.getElementById('dropdown2');
  507. // Load Complaint Groups
  508. fetch('/gcc/api/callcenterqaqc/getComplaintGroup')
  509. .then(response => response.json())
  510. .then(data => {
  511. // Clear existing options
  512. complaintGroupDropdown.innerHTML = `<option value="">Select</option>`;
  513. // Add options from the API response
  514. data.forEach(complaintGroupName => {
  515. complaintGroupDropdown.innerHTML += `<option value="${complaintGroupName}">${complaintGroupName}</option>`;
  516. });
  517. })
  518. .catch(error => {
  519. console.error('Error fetching complaint groups:', error);
  520. });
  521. // Event Listener for Complaint Group Change
  522. complaintGroupDropdown.addEventListener('change', function () {
  523. const selectedGroup = complaintGroupDropdown.value;
  524. if (selectedGroup) {
  525. // Fetch Complaint Types based on selected group
  526. fetch(`/gcc/api/callcenterqaqc/getComplaintTypesByGroup?group=${encodeURIComponent(selectedGroup)}`)
  527. .then(response => response.json())
  528. .then(data => {
  529. // Clear existing options
  530. complaintTypeDropdown.innerHTML = `<option value="">Select</option>`;
  531. // Add options from the API response
  532. data.forEach(complaintTypeName => {
  533. complaintTypeDropdown.innerHTML += `<option value="${complaintTypeName}">${complaintTypeName}</option>`;
  534. });
  535. })
  536. .catch(error => {
  537. console.error('Error fetching complaint types:', error);
  538. });
  539. } else {
  540. // Clear complaint type dropdown if no group is selected
  541. complaintTypeDropdown.innerHTML = `<option value="">Select</option>`;
  542. }
  543. });
  544. // Load all Modes
  545. fetch('/gcc/api/callcenterqaqc/getModes')
  546. .then(response => response.json())
  547. .then(data => {
  548. // Clear existing options
  549. complaintModeDropdown.innerHTML = `<option value="">Select</option>`;
  550. // Add options from the API response
  551. data.forEach(complaintMode => {
  552. complaintModeDropdown.innerHTML += `<option value="${complaintMode}">${complaintMode}</option>`;
  553. });
  554. })
  555. .catch(error => {
  556. console.error('Error fetching complaint groups:', error);
  557. });
  558. // Load all zones
  559. fetch('/gcc/api/callcenterqaqc/getZones')
  560. .then(response => response.json())
  561. .then(data => {
  562. // Clear existing options
  563. complaintZoneDropdown.innerHTML = `<option value="">Select</option>`;
  564. // Add options from the API response
  565. data.forEach(complaintZone => {
  566. complaintZoneDropdown.innerHTML += `<option value="${complaintZone}">${complaintZone}</option>`;
  567. });
  568. })
  569. .catch(error => {
  570. console.error('Error fetching complaint groups:', error);
  571. });
  572. });
  573. //Function to reset date fields
  574. function resetDate() {
  575. window.location.href = "/gcc/callcenterqaqc/admin/qaqcgrievancedashboard";
  576. }
  577. </script>
  578. <script type="text/javascript">
  579. </script>
  580. </body>
  581. </html>