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.

339 lines
13 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/modules/base/head :: head}">
  4. <style>
  5. </style>
  6. </head>
  7. <body>
  8. <div class="wrapper">
  9. <!-- header top menu Start -->
  10. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  11. <!-- header top menu end -->
  12. <div class="page-wrap">
  13. <!--=============== Left Menu side Start ================-->
  14. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  15. <!--=============== Left side End ================-->
  16. <div class="main-content">
  17. <div class="container-fluid">
  18. <div class="page-header mb-2">
  19. <div class="row align-items-end">
  20. <div class="col-lg-8">
  21. <div class="page-header-title">
  22. <!-- <i class="far fa-calendar-plus bg-blue"></i> -->
  23. <div class="d-inline">
  24. <h5>Check Availability</h5>
  25. <span>Check Availability for Hall Allocation</span>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. <div class="row">
  32. <div class="col-md-12">
  33. <div class="card" style="margin-top: 15px;">
  34. <div class="card-body">
  35. <input type="hidden" id="loginUserId" th:value="${loginUserId}">
  36. <div class="form-group">
  37. <div class="row">
  38. <!-- Department -->
  39. <div class="col-sm-12 col-md-6">
  40. <label class="form-label" for="traininglist">Select traininglist
  41. <span class="text-danger">*</span>
  42. </label>
  43. <select class="form-control" id="traininglist" required>
  44. <option value=""> Select traininglist </option>
  45. </select>
  46. </div>
  47. <!-- Office Name -->
  48. </div>
  49. </div>
  50. <div class="form-group text-center">
  51. <button type="submit" class="btn btn-primary " id="createdBtn">Submit</button>
  52. <button type="reset" class="btn btn-secondary ml-2" id="resetBtn">Reset</button>
  53. </div>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. <!-- Batch List Table -->
  59. <div class="row">
  60. <div class="col-12">
  61. <div class="card">
  62. <div class="card-header">
  63. <h3><b>All Centres</b></h3>
  64. </div>
  65. <div class="card-body">
  66. <table id="batchDatatable"
  67. class="table table-striped table-bordered table-hover dataTable" role="grid">
  68. <thead class="thead-dark">
  69. <tr role="row">
  70. <th class="text-center no-sort">S.No</th>
  71. <th class="text-center no-sort">AC Name</th>
  72. <th class="text-center no-sort">Center Name</th>
  73. <th class="text-center no-sort">Constituency Code</th>
  74. <th class="text-center no-sort">Allocated Count</th>
  75. <th class="text-center no-sort">Unallocated Count</th>
  76. <th class="text-center no-sort">Status</th>
  77. <th class="text-center no-sort">Action</th>
  78. </tr>
  79. </thead>
  80. <tbody style="text-align:center;">
  81. </tbody>
  82. </table>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. </div>
  88. </div>
  89. <div id="pageLoader"
  90. style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
  91. <div style="position: relative; top: 50%; transform: translateY(-50%);">
  92. <div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
  93. <span class="sr-only">Loading...</span>
  94. </div>
  95. <!-- Add the 'Please wait' text below the spinner -->
  96. <p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
  97. </div>
  98. </div>
  99. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  100. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  101. </div>
  102. </div>
  103. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  104. <script type="text/javascript">
  105. // ✅ Reset Button
  106. document.getElementById('resetBtn').addEventListener('click', function (e) {
  107. e.preventDefault();
  108. location.reload();
  109. });
  110. var batchTable; // ✅ GLOBAL
  111. $(document).ready(function () {
  112. // ✅✅✅ SINGLE & CORRECT DataTable Initialization
  113. batchTable = $('#batchDatatable').DataTable({
  114. dom: 'Bftip',
  115. autoWidth: false,
  116. responsive: false,
  117. scrollX: true,
  118. scrollY: '80vh',
  119. scrollCollapse: true,
  120. fixedHeader: false,
  121. ordering: true, // keep ordering enabled, but disable per column
  122. lengthMenu: [
  123. [50, 100, 200, -1],
  124. ['50 rows', '100 rows', '200 rows', 'Show all']
  125. ],
  126. buttons: [
  127. { extend: 'pageLength', className: 'btn btn-warning' },
  128. { extend: 'copyHtml5', className: 'btn btn-secondary' },
  129. { extend: 'excelHtml5', className: 'btn btn-secondary' },
  130. { extend: 'csvHtml5', className: 'btn btn-secondary' },
  131. { extend: 'pdfHtml5', className: 'btn btn-secondary' }
  132. ],
  133. columns: [
  134. {
  135. data: null,
  136. render: (d, t, r, m) => m.row + 1
  137. },
  138. { data: "ac_name" },
  139. { data: "center_name" },
  140. { data: "constcode" },
  141. { data: "allocated_count" },
  142. { data: "unallocated_count" },
  143. {
  144. data: "message",
  145. render: function (data) {
  146. if (!data) return "";
  147. const msg = data.toLowerCase();
  148. // 🟢 GREEN — halls assigned
  149. if (msg.includes("assigned") && !msg.includes("not") && !msg.includes("partially")) {
  150. return `<span class="badge bg-success text-white px-3 py-2">${data}</span>`;
  151. }
  152. // 🟡 YELLOW — halls partially assigned
  153. if (msg.includes("partially")) {
  154. return `<span style="
  155. background:#ffc107;
  156. color:#fff;
  157. padding:6px 12px;
  158. border-radius:4px;
  159. font-weight:600;">
  160. ${data}
  161. </span>`;
  162. }
  163. // 🔴 RED — halls not assigned
  164. if (msg.includes("not")) {
  165. return `<span class="badge bg-danger text-white px-3 py-2">${data}</span>`;
  166. }
  167. return data;
  168. }
  169. },
  170. /* ---------- ACTION COLUMN ---------- */
  171. {
  172. data: null,
  173. orderable: false,
  174. render: function (data, type, row) {
  175. const msg = (row.message || "").toLowerCase();
  176. // ✅ Show Proceed button ONLY for "halls assigned"
  177. if (
  178. msg.includes("assigned") &&
  179. !msg.includes("not") &&
  180. !msg.includes("partially")
  181. ) {
  182. return `
  183. <button class="btn btn-success btn-sm"
  184. onclick="proceedHallAllocation(${row.constcode})">
  185. Proceed
  186. </button>`;
  187. }
  188. return "-";
  189. }
  190. }
  191. ],
  192. columnDefs: [
  193. { orderable: false, targets: "_all" } // 🔥 disables sorting
  194. ]
  195. });
  196. // load training list
  197. $.ajax({
  198. url: "/election/api/checkAvailability",
  199. method: "GET",
  200. success: function (response) {
  201. let traininglist = $("#traininglist");
  202. traininglist.empty().append('<option value="">-- Select Training --</option>');
  203. if (response.status !== "success" || !response.data || response.data.length === 0) {
  204. return;
  205. }
  206. response.data.forEach(training => {
  207. traininglist.append(`
  208. <option
  209. value="${training.id}"
  210. data-availability-url="${training.availability_url || ''}">
  211. ${training.training_name}
  212. </option>
  213. `);
  214. });
  215. },
  216. error: function () {
  217. Swal.fire("Error", "Failed to load training list", "error");
  218. }
  219. });
  220. });
  221. // ✅ Create Batch
  222. $("#createdBtn").click(function (e) {
  223. e.preventDefault();
  224. const selectedOption = $("#traininglist option:selected");
  225. const availabilityUrl = selectedOption.data("availability-url");
  226. if (!availabilityUrl) {
  227. Swal.fire(
  228. "Validation Error",
  229. "Selected training does not have availability URL",
  230. "warning"
  231. );
  232. batchTable.clear().draw();
  233. batchTable.columns.adjust().draw(false);
  234. return;
  235. }
  236. // ✅ Call selected availability URL
  237. $.ajax({
  238. url: availabilityUrl,
  239. type: "GET",
  240. success: function (response) {
  241. batchTable.clear();
  242. if (response.data && response.data.length > 0) {
  243. batchTable.rows.add(response.data);
  244. } else {
  245. Swal.fire("No data found");
  246. }
  247. batchTable.draw();
  248. batchTable.columns.adjust().draw(false);
  249. },
  250. error: function () {
  251. Swal.fire("Error", "Failed to fetch availability data", "error");
  252. batchTable.clear().draw();
  253. batchTable.columns.adjust().draw(false);
  254. }
  255. });
  256. });
  257. </script>
  258. </body>
  259. </html>