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.
1845 lines
49 KiB
1845 lines
49 KiB
<!DOCTYPE html>
|
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
|
|
|
<head th:replace="~{fragments/modules/base/head :: head}"></head>
|
|
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css">
|
|
|
|
<style>
|
|
.mini-card {
|
|
box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
|
|
border-radius: 6px;
|
|
padding: 12px;
|
|
text-align: center;
|
|
background: #ffffff;
|
|
min-height: 90px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
}
|
|
|
|
.card-box {
|
|
box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
|
|
}
|
|
|
|
|
|
/* Header styling */
|
|
.govt-thead th {
|
|
background-color: #212529 !important;
|
|
color: #fff !important;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
/* 🔥 header single line */
|
|
}
|
|
|
|
/* Enable wrapping in body cells */
|
|
#GovtTypeDatatable th,
|
|
#GovtTypeDatatable td {
|
|
white-space: normal !important;
|
|
/* ALLOW WRAP */
|
|
word-break: break-word;
|
|
}
|
|
|
|
/* Table layout */
|
|
#GovtTypePersonDatatable {
|
|
width: 100% !important;
|
|
table-layout: fixed;
|
|
}
|
|
|
|
/* Modal body must not clip */
|
|
#govtTypePersonModal .modal-body {
|
|
max-height: 70vh;
|
|
/* controls height */
|
|
overflow-y: auto;
|
|
/* ✅ vertical scroll outside table */
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
|
|
/* Table base */
|
|
#GovtTypePersonDatatable {
|
|
width: 100% !important;
|
|
}
|
|
|
|
/* Header */
|
|
.govt-thead th {
|
|
background: #212529;
|
|
color: #fff;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Body cells */
|
|
#GovtTypePersonDatatable td {
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
vertical-align: top;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* FORCE SAME WIDTH FOR HEADER & BODY TABLE */
|
|
.dataTables_scrollHead table,
|
|
.dataTables_scrollBody table {
|
|
table-layout: fixed !important;
|
|
width: 100% !important;
|
|
}
|
|
|
|
/* Modal body scroll (OUTSIDE table) */
|
|
#govtTypeModal .modal-body {
|
|
max-height: 70vh;
|
|
/* adjust as needed */
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* Normal table behavior */
|
|
#GovtTypeDatatable {
|
|
width: 100% !important;
|
|
}
|
|
|
|
/* Header cells */
|
|
#GovtTypeDatatable thead th {
|
|
white-space: nowrap;
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* Body cells */
|
|
#GovtTypeDatatable tbody td {
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
vertical-align: top;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 🔥 Force horizontal scroll to full width */
|
|
.dataTables_wrapper {
|
|
width: 100%;
|
|
}
|
|
|
|
.dataTables_scroll {
|
|
overflow: auto !important;
|
|
}
|
|
|
|
.dataTables_scrollBody {
|
|
overflow-x: auto !important;
|
|
overflow-y: auto !important;
|
|
max-height: 50vh;
|
|
}
|
|
|
|
|
|
|
|
/* Fix header width sync */
|
|
.dataTables_scrollHeadInner,
|
|
.dataTables_scrollHeadInner table {
|
|
width: 100% !important;
|
|
}
|
|
|
|
/* Mobile fullscreen modal */
|
|
@media (max-width: 768px) {
|
|
#govtTypePersonModal .modal-dialog {
|
|
max-width: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
#govtTypePersonModal .modal-content {
|
|
height: 100vh;
|
|
border-radius: 0;
|
|
}
|
|
|
|
.dataTables_scrollBody {
|
|
max-height: 65vh;
|
|
}
|
|
}
|
|
|
|
|
|
/* Body cells wrap */
|
|
#GovtTypePersonDatatable td {
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
vertical-align: top;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Fix DataTable header/body width mismatch */
|
|
.dataTables_scrollHeadInner,
|
|
.dataTables_scrollHeadInner table {
|
|
width: 100% !important;
|
|
}
|
|
|
|
|
|
|
|
/* Fullscreen modal on mobile */
|
|
@media (max-width: 768px) {
|
|
#govtTypePersonModal .modal-dialog {
|
|
max-width: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
#govtTypePersonModal .modal-content {
|
|
height: 100vh;
|
|
border-radius: 0;
|
|
}
|
|
|
|
#govtTypePersonModal .modal-body {
|
|
overflow-y: auto;
|
|
}
|
|
}
|
|
|
|
/* MOBILE FIX */
|
|
@media (max-width: 768px) {
|
|
#GovtTypePersonDatatable {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.dataTables_wrapper {
|
|
overflow-x: auto;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
/* #GovtTypePersonDatatable td {
|
|
font-size: 13px;
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
} */
|
|
|
|
#GovtTypePersonDatatable th {
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* underline css*/
|
|
|
|
.underline-hover {
|
|
cursor: pointer;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.underline-hover:hover {
|
|
text-decoration: underline;
|
|
/* optional, keeps underline on hover */
|
|
}
|
|
|
|
|
|
#completedPivotTable {
|
|
table-layout: fixed;
|
|
width: 100% !important;
|
|
}
|
|
|
|
#completedPivotTable th,
|
|
#completedPivotTable td {
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
white-space: normal;
|
|
}
|
|
|
|
#completedPivotTable th {
|
|
word-wrap: break-word;
|
|
font-size: small;
|
|
}
|
|
|
|
/* 🔥 FIX HEADER ALIGNMENT */
|
|
table.dataTable thead th {
|
|
text-align: center;
|
|
vertical-align: middle;
|
|
white-space: normal;
|
|
}
|
|
|
|
/* Prevent header shifting */
|
|
.dataTables_scrollHeadInner,
|
|
.dataTables_scrollHeadInner table {
|
|
width: 100% !important;
|
|
}
|
|
|
|
/* Match body + header */
|
|
.dataTables_scrollBody table {
|
|
width: 100% !important;
|
|
}
|
|
|
|
/* Fix column spacing */
|
|
#completedPivotTable {
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
#personTable td:nth-child(4) {
|
|
max-width: 150px;
|
|
}
|
|
|
|
.text-wrap {
|
|
white-space: normal !important;
|
|
word-break: break-word;
|
|
}
|
|
</style>
|
|
|
|
<body>
|
|
|
|
<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="far fa-calendar-plus bg-blue"></i> -->
|
|
<div class="d-inline">
|
|
<h5>Dashboard</h5>
|
|
<!-- <span>Mark attendance for training sessions </span> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-4">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="row mt-2">
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2">
|
|
<b>Total Requirement</b>
|
|
</h6>
|
|
<!--<h4 class="text-twitter fw-700 mt-3"
|
|
th:text="${RequirementCount.final_value}"></h4>-->
|
|
<h4 class="text-twitter fw-700 mt-3">19594</h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2">
|
|
<b>Total Applications</b>
|
|
</h6>
|
|
<h4 class="text-twitter fw-700 mt-3"
|
|
th:text="${applicationsCount.total_applications}"></h4>
|
|
</div>
|
|
</div>
|
|
<!-- QA&QC Calls -->
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2">
|
|
<b>Completed</b>
|
|
</h6>
|
|
<h4 class="text-twitter fw-700 mt-3 underline-hover"
|
|
th:text="${applicationsCount.completed_applications}"
|
|
onclick="openCompletedPivotModal()">
|
|
</h4>
|
|
<!--<h4 class="text-twitter fw-700 mt-3"
|
|
th:text="${applicationsCount.completed_applications}"></h4>-->
|
|
</div>
|
|
</div>
|
|
<!-- In-progress Calls -->
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2">
|
|
<b>Pending</b>
|
|
</h6>
|
|
<h4 class="text-twitter fw-700 mt-3"
|
|
th:text="${applicationsCount.total_applications - applicationsCount.completed_applications}">
|
|
</h4>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="card-body mt-2">
|
|
<div class="row g-3 justify-content-center">
|
|
|
|
<div class="col-6 col-sm-4 col-md-2">
|
|
<div class="mini-card">
|
|
<h6 class="text-facebook mb-2"><b> PO </b></h6>
|
|
<h4 class="text-twitter fw-700 mt-3" th:text="${gradeCounts.PO}"></h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-6 col-sm-4 col-md-2">
|
|
<div class="mini-card">
|
|
<h6 class="text-facebook mb-2"><b> PO1 </b></h6>
|
|
<h4 class="text-twitter fw-700 mt-3" th:text="${gradeCounts.PO1}"></h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-6 col-sm-4 col-md-2">
|
|
<div class="mini-card">
|
|
<h6 class="text-facebook mb-2"><b> PO2 </b></h6>
|
|
<h4 class="text-twitter fw-700 mt-3" th:text="${gradeCounts.PO2}"></h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-6 col-sm-4 col-md-2">
|
|
<div class="mini-card">
|
|
<h6 class="text-facebook mb-2"><b> PO3 </b></h6>
|
|
<h4 class="text-twitter fw-700 mt-3" th:text="${gradeCounts.PO3}"></h4>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-6 col-sm-4 col-md-2">
|
|
<div class="mini-card">
|
|
<h6 class="text-facebook mb-2"><b> PO4 </b></h6>
|
|
<h4 class="text-twitter fw-700 mt-3" th:text="${gradeCounts.PO4}"></h4>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row mt-4">
|
|
|
|
<!-- Gender Card -->
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Gender</b></h6>
|
|
<p class="mb-1">Male :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.male}">0</b>
|
|
</p>
|
|
<p class="mb-0">Female :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.female}">0</b>
|
|
</p>
|
|
<p class="mb-0">Transgender :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.transgender}">0</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- voter -->
|
|
<!--<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Voter ID</b></h6>
|
|
|
|
<p class="mb-1">Available :
|
|
<b class="text-success fw-700 mt-3 underline-hover"
|
|
th:text="${validationCount.voter_filled}"
|
|
onclick="openCategorySummaryModal('VOTER_FILLED')">0</b>
|
|
</p>
|
|
|
|
<p class="mb-0">Not Available :
|
|
<b class="text-danger fw-700 mt-3 underline-hover"
|
|
th:text="${validationCount.voter_not_filled}"
|
|
onclick="openCategorySummaryModal('VOTER_NOT_FILLED')">0</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!– PHONE –>
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Phone</b></h6>
|
|
|
|
<p class="mb-1">Available :
|
|
<b class="text-success fw-700 mt-3 underline-hover"
|
|
th:text="${validationCount.phone_filled}"
|
|
onclick="openCategorySummaryModal('PHONE_FILLED')">0</b>
|
|
</p>
|
|
|
|
<p class="mb-0">Not Available :
|
|
<b class="text-danger fw-700 mt-3 underline-hover"
|
|
th:text="${validationCount.phone_not_filled}"
|
|
onclick="openCategorySummaryModal('PHONE_NOT_FILLED')">0</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!– IMAGE –>
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Image</b></h6>
|
|
|
|
<p class="mb-1">Available :
|
|
<b class="text-success fw-700 mt-3 underline-hover"
|
|
th:text="${validationCount.image_filled}"
|
|
onclick="openCategorySummaryModal('IMAGE_FILLED')">0</b>
|
|
</p>
|
|
|
|
<p class="mb-0">Not Available :
|
|
<b class="text-danger fw-700 mt-3 underline-hover"
|
|
th:text="${validationCount.image_not_filled}"
|
|
onclick="openCategorySummaryModal('IMAGE_NOT_FILLED')">0</b>
|
|
</p>
|
|
</div>
|
|
</div>-->
|
|
|
|
|
|
<!-- Voter ID Card -->
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Voter ID</b></h6>
|
|
<p class="mb-1">Available :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.voter_filled}">0</b>
|
|
</p>
|
|
<p class="mb-0">Not Available :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.voter_not_filled}">0</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Phone</b></h6>
|
|
<p class="mb-1">Available :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.phone_filled}">0</b>
|
|
</p>
|
|
<p class="mb-0">Not Available :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.phone_not_filled}">0</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="col-md-3">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2"><b>Image</b></h6>
|
|
<p class="mb-1">Available :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.image_filled}">0</b>
|
|
</p>
|
|
<p class="mb-0">Not Available :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${validationCount.image_not_filled}">0</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- ================= Central and State Report Count ================= -->
|
|
<div class="card-body">
|
|
<div class="row mt-2">
|
|
<div class="col-xl-6 col-sm-12">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2">
|
|
<b>Central Govt Offices</b>
|
|
</h6>
|
|
<h4 class="text-twitter fw-700 mt-3 cursor-pointer underline-hover"
|
|
th:text="${GovtTypeCount.central_count}"
|
|
onclick="openGovtTypeModal('C')"></h4>
|
|
<p class="mb-1">No of Applicant :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${GovtOfficeTypeCount.total_central}">0</b>
|
|
</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- In-progress Calls -->
|
|
<div class="col-xl-6 col-sm-12">
|
|
<div class="card card-box p-3 text-center h-100">
|
|
<h6 class="text-facebook mb-2">
|
|
<b>State Govt Offices </b>
|
|
</h6>
|
|
<h4 class="text-twitter fw-700 mt-3 cursor-pointer underline-hover"
|
|
th:text="${GovtTypeCount.state_count}"
|
|
onclick="openGovtTypeModal('S')"></h4>
|
|
|
|
<p class="mb-1">No of Applicant :
|
|
<b class="text-twitter fw-700 mt-3"
|
|
th:text="${GovtOfficeTypeCount.total_state}">0</b>
|
|
</p>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
<div id="pageLoader"
|
|
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;">
|
|
<div style="position: relative; top: 50%; transform: translateY(-50%);">
|
|
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
|
|
<span class="sr-only">Loading...</span>
|
|
</div>
|
|
<!-- Add the 'Please wait' text below the spinner -->
|
|
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="govtTypeModal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static"
|
|
data-keyboard="false">
|
|
|
|
<div class="modal-dialog modal-xl modal-dialog-centered" role="document">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title" id="govtTypeModalTitle"></h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<table id="GovtTypeDatatable" class="table table-bordered table-striped w-100">
|
|
<thead class="govt-thead">
|
|
<tr>
|
|
<th>S.No</th>
|
|
<th>Department</th>
|
|
<th>Office</th>
|
|
<th>Total Count</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="modal fade" id="govtTypePersonModal" tabindex="-1" role="dialog" aria-hidden="true"
|
|
data-backdrop="static" data-keyboard="false">
|
|
|
|
<div class="modal-dialog modal-xl modal-dialog-centered" role="document">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-dark text-white">
|
|
<h5 class="modal-title" id="govtTypePersonModalTitle"></h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<div class="table-responsive">
|
|
<table id="GovtTypePersonDatatable" class="table table-bordered table-striped nowrap">
|
|
|
|
|
|
|
|
<thead class="govt-thead">
|
|
<tr>
|
|
<th>S.No</th>
|
|
<th>Unique No</th>
|
|
<th>Name</th>
|
|
<th>Sex</th>
|
|
<th>Mobile</th>
|
|
<th>Designation</th>
|
|
<th>Department</th>
|
|
<th>Office</th>
|
|
<th>Govt Type</th>
|
|
<th>Office Address</th>
|
|
<th>Residential Address</th>
|
|
<th>Native AC</th>
|
|
<th>Residential AC</th>
|
|
<th>Elector AC</th>
|
|
<th>Working AC</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody></tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!--ak-->
|
|
<div class="modal fade" id="categorySummaryModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl modal-dialog-centered">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title" id="categorySummaryTitle"></h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<table id="categorySummaryTable" class="table table-bordered table-striped w-100">
|
|
<thead class="bg-dark text-white text-center">
|
|
<tr>
|
|
<th>S.No</th>
|
|
<th>Constiency</th>
|
|
|
|
<th>Department</th>
|
|
<th>Office</th>
|
|
<th>Total Count</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody id="categorySummaryBody"></tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="completedPivotModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title">Completed - Training Centre Summary</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<div class="table-responsive">
|
|
|
|
<table id="completedPivotTable" class="table table-bordered text-center">
|
|
<thead class="bg-dark text-white">
|
|
<tr>
|
|
<th rowspan="2">S.No</th>
|
|
<th rowspan="2" class="no-sort text-center">Training Centre</th>
|
|
<th colspan="4" class="text-center">PO</th>
|
|
<th colspan="4" class="text-center">PO1</th>
|
|
<th colspan="4" class="text-center">PO2</th>
|
|
<th colspan="4" class="text-center">PO3</th>
|
|
<th colspan="4" class="text-center">PO4</th>
|
|
|
|
</tr>
|
|
<tr>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">No Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter </th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter </th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter </th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter </th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone </th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter </th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="completedPivotBody"></tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="hallPivotModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title">Hall Wise Summary</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<div class="table-responsive">
|
|
|
|
<table id="hallPivotTable" class="table table-bordered text-center w-100">
|
|
<thead class="bg-dark text-white">
|
|
<tr>
|
|
<th rowspan="2">S.No</th>
|
|
<th rowspan="2" class="no-sort text-center">Hall No</th>
|
|
<th colspan="4" class="text-center">PO</th>
|
|
<th colspan="4" class="text-center">PO1</th>
|
|
<th colspan="4" class="text-center">PO2</th>
|
|
<th colspan="4" class="text-center">PO3</th>
|
|
<th colspan="4" class="text-center">PO4</th>
|
|
</tr>
|
|
<tr>
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">No Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter</th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter</th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter</th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter</th>
|
|
|
|
<th word-wrap="break-word" class="no-sort">Total</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Image</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Phone</th>
|
|
<th word-wrap="break-word" class="no-sort">NO Voter</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="hallPivotBody"></tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal fade" id="personModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title">Person Details</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal">
|
|
<span>×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<div class="table-responsive">
|
|
|
|
<table id="personTable" class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>S.No</th>
|
|
<th>Unique No</th>
|
|
<th>Hall NO</th>
|
|
<th>Name</th>
|
|
<th>Designation</th>
|
|
<th>Office Address</th>
|
|
<th>Mobile</th>
|
|
<th>Category</th>
|
|
<th>Photo</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="personTableBody"></tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- DataTables Buttons JS -->
|
|
<!-- <script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
|
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script>
|
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.print.min.js"></script> -->
|
|
|
|
<!-- Dependencies -->
|
|
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script> -->
|
|
|
|
|
|
|
|
|
|
<script th:replace="~{fragments/modules/base/script :: script}"></script>
|
|
<script type="text/javascript"></script>
|
|
|
|
|
|
<script>
|
|
let govtTypeTable = null;
|
|
|
|
function openGovtTypeModal(govtType) {
|
|
|
|
const title = govtType === 'C'
|
|
? 'Central Government Details'
|
|
: 'State Government Details';
|
|
|
|
$('#govtTypeModalTitle').text(title);
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/govt-type-details',
|
|
type: 'GET',
|
|
data: { govtType: govtType },
|
|
success: function (data) {
|
|
|
|
if ($.fn.DataTable.isDataTable('#GovtTypeDatatable')) {
|
|
govtTypeTable.destroy();
|
|
$('#GovtTypeDatatable tbody').empty();
|
|
}
|
|
|
|
let rows = '';
|
|
data.forEach((row, index) => {
|
|
rows += `
|
|
<tr>
|
|
<td class="text-center">${index + 1}</td>
|
|
<td>${row.dept_name ?? '-'}</td>
|
|
<td>${row.office_address ?? '-'}</td>
|
|
<td class="text-center">
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold"
|
|
onclick="openGovtTypePersonModal(
|
|
'${govtType}',
|
|
'${row.dept_name}',
|
|
'${row.office_name}'
|
|
)">
|
|
${row.total_count}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#GovtTypeDatatable tbody').html(rows);
|
|
|
|
// DataTable with Buttons
|
|
govtTypeTable = $('#GovtTypeDatatable').DataTable({
|
|
dom: 'Bftip',
|
|
autoWidth: false,
|
|
responsive: false,
|
|
ordering: true,
|
|
searching: true,
|
|
paging: true,
|
|
pageLength: 10,
|
|
|
|
buttons: [
|
|
{
|
|
extend: 'copy',
|
|
text: 'Copy',
|
|
title: title
|
|
},
|
|
{
|
|
extend: 'excelHtml5',
|
|
text: 'Excel',
|
|
title: title
|
|
},
|
|
{
|
|
extend: 'csvHtml5',
|
|
text: 'CSV',
|
|
title: title
|
|
},
|
|
/* {
|
|
extend: 'pdfHtml5',
|
|
text: 'PDF',
|
|
title: '',
|
|
orientation: 'landscape',
|
|
pageSize: 'A4',
|
|
customize: function (doc) {
|
|
|
|
// Page margins
|
|
doc.pageMargins = [20, 60, 20, 30];
|
|
|
|
// Add heading manually
|
|
doc.content.unshift({
|
|
text: title,
|
|
alignment: 'center',
|
|
fontSize: 14,
|
|
bold: true,
|
|
margin: [0, 0, 0, 12]
|
|
});
|
|
|
|
doc.defaultStyle.fontSize = 11;
|
|
doc.styles.tableHeader.alignment = 'center';
|
|
}
|
|
} */
|
|
],
|
|
|
|
columnDefs: [
|
|
{ targets: 0, width: "60px", className: "text-center" },
|
|
{ targets: 3, width: "120px", className: "text-center" }
|
|
]
|
|
});
|
|
|
|
govtTypeTable.columns.adjust().draw();
|
|
$('#govtTypeModal').modal('show');
|
|
},
|
|
error: function () {
|
|
alert('Error loading data');
|
|
}
|
|
});
|
|
}
|
|
|
|
$('#govtTypeModal').on('shown.bs.modal', function () {
|
|
if (govtTypeTable) {
|
|
govtTypeTable.columns.adjust();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<script>
|
|
let govtTypePersonTable = null;
|
|
|
|
function openGovtTypePersonModal(govtType, deptName, officeName) {
|
|
|
|
const govtLabel = govtType === 'C'
|
|
? 'Central Government'
|
|
: 'State Government';
|
|
const pdfHeading = govtLabel + ' - ' + deptName + ' - ' + officeName;
|
|
|
|
$('#govtTypePersonModalTitle').text(
|
|
govtLabel + ' - ' + deptName + ' - ' + officeName
|
|
);
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/govt-type-person-details',
|
|
type: 'GET',
|
|
data: {
|
|
govtType: govtType,
|
|
deptName: deptName,
|
|
officeName: officeName
|
|
},
|
|
success: function (data) {
|
|
|
|
if ($.fn.DataTable.isDataTable('#GovtTypePersonDatatable')) {
|
|
govtTypePersonTable.destroy();
|
|
$('#GovtTypePersonDatatable tbody').empty();
|
|
}
|
|
|
|
let rows = '';
|
|
data.forEach((row, index) => {
|
|
rows += `
|
|
<tr>
|
|
<td class="text-center">${index + 1}</td> <!-- ✅ S.No -->
|
|
<td class="text-center">${row.unique_no}</td>
|
|
<td>${row.name}</td>
|
|
<td class="text-center">${row.sex ?? ''}</td>
|
|
<td>${row.r_mobile_no ?? ''}</td>
|
|
<td>${row.new_designation ?? ''}</td>
|
|
<td>${row.dept_name ?? ''}</td>
|
|
<td>${row.office_name ?? ''}</td>
|
|
<td class="text-center">${row.govt_type}</td>
|
|
<td>${row.office_address ?? ''}</td>
|
|
<td>${row.residential_address ?? ''}</td>
|
|
<td>${row.native_constituency ?? ''}</td>
|
|
<td>${row.residential_constituency ?? ''}</td>
|
|
<td>${row.elector_constituency ?? ''}</td>
|
|
<td>${row.working_constituency ?? ''}</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#GovtTypePersonDatatable tbody').html(rows);
|
|
|
|
const isMobile = window.innerWidth <= 768;
|
|
|
|
govtTypePersonTable = $('#GovtTypePersonDatatable').DataTable({
|
|
dom: 'Bfrtip', // 🔥 Buttons + filter + table + pagination
|
|
autoWidth: false,
|
|
responsive: false,
|
|
ordering: true,
|
|
searching: true,
|
|
paging: true,
|
|
pageLength: 10,
|
|
fixedHeader: false,
|
|
|
|
buttons: [
|
|
{
|
|
extend: 'copy',
|
|
text: 'Copy'
|
|
},
|
|
{
|
|
extend: 'excelHtml5',
|
|
text: 'Excel',
|
|
title: pdfHeading
|
|
},
|
|
{
|
|
extend: 'csvHtml5',
|
|
text: 'CSV',
|
|
title: pdfHeading
|
|
},
|
|
/* {
|
|
extend: 'pdfHtml5',
|
|
text: 'PDF',
|
|
title: '',
|
|
orientation: 'landscape',
|
|
pageSize: 'A3',
|
|
exportOptions: { columns: ':visible' },
|
|
|
|
customize: function (doc) {
|
|
|
|
// Page setup
|
|
doc.pageMargins = [10, 50, 10, 20];
|
|
doc.defaultStyle.fontSize = 11;
|
|
|
|
// Title
|
|
doc.content.unshift({
|
|
text: pdfHeading,
|
|
alignment: 'center',
|
|
fontSize: 14,
|
|
bold: true,
|
|
margin: [0, 0, 0, 10]
|
|
});
|
|
|
|
// Header style
|
|
doc.styles.tableHeader.fontSize = 12;
|
|
doc.styles.tableHeader.alignment = 'center';
|
|
|
|
// 🔥 IMPORTANT: Adjust column widths
|
|
doc.content[1].table.widths = [
|
|
30, // S.No
|
|
50, // Unique No
|
|
85, // Name
|
|
30, // Sex
|
|
65, // Mobile
|
|
80, // Designation
|
|
85, // Department
|
|
90, // Office
|
|
40, // Govt Type
|
|
120, // Office Address
|
|
120, // Residential Address
|
|
60, // Native AC
|
|
60, // Residential AC
|
|
60, // Elector AC
|
|
70 // ✅ Working AC (FIXED WIDTH)
|
|
];
|
|
|
|
// Enable wrapping for all cells
|
|
doc.content[1].table.body.forEach(function (row, i) {
|
|
row.forEach(function (cell) {
|
|
if (typeof cell === 'object') {
|
|
cell.noWrap = false;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
} */
|
|
],
|
|
|
|
|
|
|
|
columnDefs: [
|
|
{ width: "60px", targets: 0 },
|
|
{ width: "90px", targets: 1 },
|
|
{ width: "180px", targets: 2 },
|
|
{ width: "60px", targets: 3 },
|
|
{ width: "120px", targets: 4 },
|
|
{ width: "200px", targets: 5 },
|
|
{ width: "220px", targets: 6 },
|
|
{ width: "250px", targets: 7 },
|
|
{ width: "80px", targets: 8 },
|
|
{ width: "260px", targets: 9 },
|
|
{ width: "260px", targets: 10 },
|
|
{ width: "140px", targets: 11 },
|
|
{ width: "140px", targets: 12 },
|
|
{ width: "140px", targets: 13 },
|
|
{ width: "140px", targets: 14 }
|
|
]
|
|
});
|
|
|
|
|
|
|
|
$('#govtTypePersonModal').modal('show');
|
|
},
|
|
error: function () {
|
|
alert('Error loading person details');
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
//ak
|
|
let categorySummaryTable = null;
|
|
function openCategorySummaryModal(category) {
|
|
|
|
$('#categorySummaryTitle').text(category.replaceAll('_', ' '));
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/category-summary',
|
|
type: 'GET',
|
|
data: { category: category },
|
|
|
|
success: function (data) {
|
|
// destroy old table
|
|
if ($.fn.DataTable.isDataTable('#categorySummaryTable')) {
|
|
categorySummaryTable.destroy();
|
|
$('#categorySummaryBody').empty();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td>${row.ac_display ?? ''}</td>
|
|
<td>${row.dept_name ?? ''}</td>
|
|
<td>${row.office_address ?? ''}</td>
|
|
<td class="text-center">
|
|
<a href="#" onclick="openCategoryPersonModal(
|
|
'${category}',
|
|
'${row.work_ac_no}',
|
|
'${row.dept_name}',
|
|
'${row.office_name}'
|
|
)">
|
|
${row.total_count}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#categorySummaryBody').html(rows);
|
|
categorySummaryTable = $('#categorySummaryTable').DataTable({
|
|
dom: 'Bfrtip',
|
|
pageLength: 10,
|
|
ordering: true,
|
|
searching: true,
|
|
|
|
buttons: [
|
|
|
|
{
|
|
extend: 'excelHtml5',
|
|
text: 'Excel',
|
|
title: category
|
|
},
|
|
|
|
{
|
|
extend: 'pdfHtml5',
|
|
text: 'PDF',
|
|
title: category,
|
|
orientation: 'landscape',
|
|
pageSize: 'A4'
|
|
}
|
|
]
|
|
});
|
|
$('#categorySummaryModal').modal('show');
|
|
}
|
|
});
|
|
}
|
|
/*function openCompletedPivotModal() {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.get('/election/api/dataentryadmin/dashboard/training-centre-category-pivot', function(data) {
|
|
if ($.fn.DataTable.isDataTable('#completedPivotTable')) {
|
|
$('#completedPivotTable').DataTable().destroy();
|
|
}
|
|
let rows = '';
|
|
|
|
function getCell(c) {
|
|
if (!c) return '-';
|
|
|
|
return `
|
|
<div style="text-align:left; font-size:13px; line-height:1.5">
|
|
|
|
<b>Total:</b> ${c.total}<br>
|
|
|
|
<b>Image Not Filled:</b> ${c.image_not_filled}<br>
|
|
|
|
<b>Phone Not Filled:</b> ${c.phone_not_filled}<br>
|
|
|
|
<b>Voter Not Filled:</b> ${c.voter_not_filled}
|
|
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
const cats = row.categories || {};
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openHallWiseModal('${row.training_centre_id}')">
|
|
${row.training_centre}
|
|
</a>
|
|
</td>
|
|
|
|
<td>${getCell(cats.PO)}</td>
|
|
<td>${getCell(cats.PO1)}</td>
|
|
<td>${getCell(cats.PO2)}</td>
|
|
<td>${getCell(cats.PO3)}</td>
|
|
<td>${getCell(cats.PO4)}</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#completedPivotBody').html(rows);
|
|
$('#completedPivotTable').DataTable({
|
|
dom: 'Bfrtip',
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Training Summary' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Training Summary', orientation: 'landscape' }
|
|
]
|
|
});
|
|
$('#pageLoader').hide();
|
|
$('#completedPivotModal').modal('show');
|
|
})
|
|
.fail(function() {
|
|
$('#pageLoader').hide();
|
|
alert("Error loading data");
|
|
});
|
|
}*/
|
|
function openCompletedPivotModal() {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.get('/election/api/dataentryadmin/dashboard/training-centre-category-pivot', function (data) {
|
|
|
|
if ($.fn.DataTable.isDataTable('#completedPivotTable')) {
|
|
$('#completedPivotTable').DataTable().destroy();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
// 🔥 return 4 columns
|
|
function getCells(c) {
|
|
if (!c) {
|
|
return `<td>0</td><td>0</td><td>0</td><td>0</td>`;
|
|
}
|
|
|
|
return `
|
|
<td>${c.total}</td>
|
|
<td>${c.image_not_filled}</td>
|
|
<td>${c.phone_not_filled}</td>
|
|
<td>${c.voter_not_filled}</td>
|
|
`;
|
|
}
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
const cats = row.categories || {};
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openHallWiseModal('${row.training_centre_id}')">
|
|
${row.training_centre}
|
|
</a>
|
|
</td>
|
|
|
|
${getCells(cats.PO)}
|
|
${getCells(cats.PO1)}
|
|
${getCells(cats.PO2)}
|
|
${getCells(cats.PO3)}
|
|
${getCells(cats.PO4)}
|
|
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#completedPivotBody').html(rows);
|
|
|
|
// 🔥 DATATABLE (IMPORTANT SETTINGS)
|
|
$('#completedPivotTable').DataTable({
|
|
destroy: true,
|
|
fixedHeader: false,
|
|
dom: 'Bfrtip',
|
|
scrollX: true,
|
|
info: true,
|
|
autoWidth: false,
|
|
ordering: false,
|
|
responsive: false,
|
|
lengthMenu: [
|
|
[100, 200, 500, -1],
|
|
['100 rows', '200 rows', 'Show all']
|
|
],
|
|
|
|
columnDefs: [
|
|
{ width: "150px", targets: 1 }
|
|
|
|
],
|
|
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Training Summary' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Training Summary', orientation: 'landscape', pageSize: 'A3' }
|
|
]
|
|
});
|
|
|
|
$('#pageLoader').hide();
|
|
$('#completedPivotModal').modal('show');
|
|
|
|
$('#completedPivotModal').on('shown.bs.modal', function () {
|
|
setTimeout(() => {
|
|
$('#completedPivotTable').DataTable().columns.adjust();
|
|
}, 200);
|
|
});
|
|
})
|
|
.fail(function () {
|
|
$('#pageLoader').hide();
|
|
alert("Error loading data");
|
|
});
|
|
}
|
|
/*function openHallWiseModal(centreId) {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/hall-wise-pivot',
|
|
type: 'GET',
|
|
data: { trainingCentreId: centreId },
|
|
|
|
success: function(data) {
|
|
if ($.fn.DataTable.isDataTable('#hallPivotTable')) {
|
|
$('#hallPivotTable').DataTable().destroy();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
const cats = row.categories || {};
|
|
|
|
function cell(c) {
|
|
if (!c) return '-';
|
|
|
|
return `
|
|
<b>Total:</b> ${c.total}<br>
|
|
<b>Image Not Filled:</b> ${c.image_not_filled}<br>
|
|
<b>Phone Not Filled:</b> ${c.phone_not_filled}<br>
|
|
<b>Voter Not Filled:</b> ${c.voter_not_filled}
|
|
`;
|
|
}
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}', '${row.hall_no}')">
|
|
${row.hall_no}
|
|
</a>
|
|
</td>
|
|
|
|
<td>${cell(cats.PO)}</td>
|
|
<td>${cell(cats.PO1)}</td>
|
|
<td>${cell(cats.PO2)}</td>
|
|
<td>${cell(cats.PO3)}</td>
|
|
<td>${cell(cats.PO4)}</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#hallPivotBody').html(rows);
|
|
$('#hallPivotTable').DataTable({
|
|
dom: 'Bfrtip',
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Hall Summary' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Hall Summary', orientation: 'landscape' }
|
|
]
|
|
});
|
|
$('#pageLoader').hide();
|
|
$('#hallPivotModal').modal('show');
|
|
},
|
|
|
|
error: function() {
|
|
$('#pageLoader').hide();
|
|
alert("Error loading hall data");
|
|
}
|
|
});
|
|
|
|
}*/
|
|
/*function openHallWiseModal(centreId) {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/hall-wise-pivot',
|
|
type: 'GET',
|
|
data: { trainingCentreId: centreId },
|
|
|
|
success: function(data) {
|
|
|
|
if ($.fn.DataTable.isDataTable('#hallPivotTable')) {
|
|
$('#hallPivotTable').DataTable().destroy();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
// 🔥 return 4 columns
|
|
function getCells(c) {
|
|
if (!c) {
|
|
return `<td>0</td><td>0</td><td>0</td><td>0</td>`;
|
|
}
|
|
|
|
return `
|
|
<td>${c.total}</td>
|
|
<td>${c.image_not_filled}</td>
|
|
<td>${c.phone_not_filled}</td>
|
|
<td>${c.voter_not_filled}</td>
|
|
`;
|
|
}
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
const cats = row.categories || {};
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}', '${row.hall_no}')">
|
|
${row.hall_no}
|
|
</a>
|
|
</td>
|
|
|
|
${getCells(cats.PO)}
|
|
${getCells(cats.PO1)}
|
|
${getCells(cats.PO2)}
|
|
${getCells(cats.PO3)}
|
|
${getCells(cats.PO4)}
|
|
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#hallPivotBody').html(rows);
|
|
|
|
// 🔥 SIMPLE DATATABLE (avoid misalignment)
|
|
$('#hallPivotTable').DataTable({
|
|
destroy: true,
|
|
dom: 'Bfrtip',
|
|
scrollX: true,
|
|
autoWidth: false,
|
|
ordering: false,
|
|
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Hall Summary' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Hall Summary', orientation: 'landscape', pageSize: 'A3' }
|
|
]
|
|
});
|
|
|
|
$('#pageLoader').hide();
|
|
$('#hallPivotModal').modal('show');
|
|
|
|
// 🔥 FIX ALIGNMENT AFTER MODAL OPEN
|
|
$('#hallPivotModal').on('shown.bs.modal', function () {
|
|
setTimeout(() => {
|
|
$('#hallPivotTable').DataTable().columns.adjust();
|
|
}, 200);
|
|
});
|
|
},
|
|
|
|
error: function() {
|
|
$('#pageLoader').hide();
|
|
alert("Error loading hall data");
|
|
}
|
|
});
|
|
}*/
|
|
function openHallWiseModal(centreId) {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/hall-wise-pivot',
|
|
type: 'GET',
|
|
data: { trainingCentreId: centreId },
|
|
|
|
success: function (data) {
|
|
|
|
if ($.fn.DataTable.isDataTable('#hallPivotTable')) {
|
|
$('#hallPivotTable').DataTable().destroy();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
// 🔥 clickable cells
|
|
/*function getCells(c, hallNo, category) {
|
|
|
|
if (!c) {
|
|
return `<td>0</td><td>0</td><td>0</td><td>0</td>`;
|
|
}
|
|
|
|
return `
|
|
<td>${c.total}</td>
|
|
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}','${hallNo}','${category}','IMAGE')">
|
|
${c.image_not_filled}
|
|
</a>
|
|
</td>
|
|
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}','${hallNo}','${category}','PHONE')">
|
|
${c.phone_not_filled}
|
|
</a>
|
|
</td>
|
|
|
|
<td>
|
|
<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}','${hallNo}','${category}','VOTER')">
|
|
${c.voter_not_filled}
|
|
</a>
|
|
</td>
|
|
`;
|
|
}*/
|
|
function getCells(c, hallNo, category) {
|
|
|
|
if (!c) {
|
|
return `<td>0</td><td>0</td><td>0</td><td>0</td>`;
|
|
}
|
|
|
|
return `
|
|
<td>${c.total}</td>
|
|
|
|
<td>
|
|
${c.image_not_filled > 0
|
|
? `<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}','${hallNo}','${category}','IMAGE')">
|
|
${c.image_not_filled}
|
|
</a>`
|
|
: `<span>${c.image_not_filled}</span>`
|
|
}
|
|
</td>
|
|
|
|
<td>
|
|
${c.phone_not_filled > 0
|
|
? `<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}','${hallNo}','${category}','PHONE')">
|
|
${c.phone_not_filled}
|
|
</a>`
|
|
: `<span>${c.phone_not_filled}</span>`
|
|
}
|
|
</td>
|
|
|
|
<td>
|
|
${c.voter_not_filled > 0
|
|
? `<a href="javascript:void(0)"
|
|
class="text-primary fw-bold text-decoration-underline"
|
|
onclick="openPersonList('${centreId}','${hallNo}','${category}','VOTER')">
|
|
${c.voter_not_filled}
|
|
</a>`
|
|
: `<span>${c.voter_not_filled}</span>`
|
|
}
|
|
</td>
|
|
`;
|
|
}
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
const cats = row.categories || {};
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td>${row.hall_no}</td>
|
|
|
|
${getCells(cats.PO, row.hall_no, 'PO')}
|
|
${getCells(cats.PO1, row.hall_no, 'PO1')}
|
|
${getCells(cats.PO2, row.hall_no, 'PO2')}
|
|
${getCells(cats.PO3, row.hall_no, 'PO3')}
|
|
${getCells(cats.PO4, row.hall_no, 'PO4')}
|
|
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#hallPivotBody').html(rows);
|
|
|
|
$('#hallPivotTable').DataTable({
|
|
destroy: true,
|
|
dom: 'Bfrtip',
|
|
scrollX: true,
|
|
autoWidth: false,
|
|
ordering: false,
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Hall Summary' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Hall Summary', orientation: 'landscape', pageSize: 'A3' }
|
|
]
|
|
});
|
|
|
|
$('#pageLoader').hide();
|
|
$('#hallPivotModal').modal('show');
|
|
|
|
setTimeout(() => {
|
|
$('#hallPivotTable').DataTable().columns.adjust();
|
|
}, 200);
|
|
}
|
|
});
|
|
}
|
|
/*function openPersonList(centreId, hallNo) {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/hall-persons',
|
|
type: 'GET',
|
|
data: {
|
|
trainingCentreId: centreId,
|
|
hallNo: hallNo
|
|
},
|
|
success: function(data) {
|
|
if ($.fn.DataTable.isDataTable('#personTable')) {
|
|
$('#personTable').DataTable().destroy();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td>${row.name}</td>
|
|
<td>${row.designation}</td>
|
|
<td>${row.office}</td>
|
|
<td>${row.mobile}</td>
|
|
<td>${row.category}</td>
|
|
<td>
|
|
${row.img_full_path ?
|
|
`<img src="${row.img_full_path}" width="60" height="60"/>`
|
|
: ''
|
|
}
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#personTableBody').html(rows);
|
|
|
|
$('#personTable').DataTable({
|
|
dom: 'Bfrtip',
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Person Details' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Person Details', orientation: 'landscape' }
|
|
]
|
|
});
|
|
|
|
$('#pageLoader').hide();
|
|
$('#personModal').modal('show');
|
|
}
|
|
});
|
|
}*/
|
|
|
|
function openPersonList(centreId, hallNo, category, type) {
|
|
|
|
$('#pageLoader').show();
|
|
|
|
$.ajax({
|
|
url: '/election/api/dataentryadmin/dashboard/hall-persons',
|
|
type: 'GET',
|
|
data: {
|
|
trainingCentreId: centreId,
|
|
hallNo: hallNo,
|
|
category: category,
|
|
type: type
|
|
},
|
|
|
|
success: function (data) {
|
|
console.log(data);
|
|
|
|
if ($.fn.DataTable.isDataTable('#personTable')) {
|
|
$('#personTable').DataTable().destroy();
|
|
}
|
|
|
|
let rows = '';
|
|
|
|
data.forEach((row, index) => {
|
|
|
|
rows += `
|
|
<tr>
|
|
<td>${index + 1}</td>
|
|
<td class="text-center">${row.unique_no}</td>
|
|
<td class="text-center">${row.hall_no}</td>
|
|
<td class="text-wrap">${row.name}</td>
|
|
<td>${row.designation}</td>
|
|
<td>${row.office}</td>
|
|
<td>${row.mobile || '-'}</td>
|
|
<td>${row.category}</td>
|
|
|
|
<td>
|
|
${row.img_full_path
|
|
? `<img src="${row.img_full_path}" width="60" height="60"/>`
|
|
: '-'
|
|
}
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
$('#personTableBody').html(rows);
|
|
|
|
$('#personTable').DataTable({
|
|
destroy: true,
|
|
dom: 'Bfrtip',
|
|
|
|
scrollX: true,
|
|
autoWidth: false,
|
|
lengthMenu: [
|
|
[25, 100, 200, 500, -1],
|
|
['25 rows', '100 rows', '200 rows', 'Show all']
|
|
],
|
|
buttons: [
|
|
{ extend: 'excelHtml5', text: 'Excel', title: 'Person Details' },
|
|
{ extend: 'pdfHtml5', text: 'PDF', title: 'Person Details', orientation: 'landscape' }
|
|
]
|
|
});
|
|
|
|
$('#pageLoader').hide();
|
|
$('#personModal').modal('show');
|
|
}
|
|
});
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|