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.

1899 lines
74 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head th:replace="~{fragments/modules/base/head :: head}">
  4. <link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap" rel="stylesheet">
  5. <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css">
  6. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  7. <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
  8. </head>
  9. <style>
  10. .required {
  11. color: red;
  12. }
  13. /* Mobile screens - targeting devices with a max width of 767px */
  14. @media ( max-width : 767px) {
  15. #complaintform label {
  16. margin-top: 10px;
  17. }
  18. }
  19. .form-row {
  20. margin-bottom: 20px;
  21. }
  22. .form-step {
  23. display: none;
  24. }
  25. .form-step.active {
  26. display: block;
  27. }
  28. .container {
  29. max-width: 100%;
  30. }
  31. /*css for step 3*/
  32. .complaint-icons {
  33. display: flex;
  34. justify-content: space-around;
  35. margin-bottom: 20px;
  36. }
  37. .complaint-icon {
  38. text-align: center;
  39. cursor: pointer;
  40. }
  41. .complaint-icon img {
  42. width: 50px;
  43. height: 50px;
  44. }
  45. .complaint-fields {
  46. display: none;
  47. }
  48. .complaint-fields.active {
  49. display: block;
  50. }
  51. /*for radio button style*/
  52. .radio-group {
  53. display: flex;
  54. align-items: center;
  55. /* Ensures all items are aligned to the center */
  56. }
  57. .radio-item {
  58. display: flex;
  59. align-items: center;
  60. margin-right: 20px;
  61. /* Adds space between each radio item */
  62. }
  63. .radio-item input[type="radio"] {
  64. margin-right: 10px;
  65. /* Adds space between the radio button and its label */
  66. vertical-align: middle;
  67. /* Ensures vertical alignment */
  68. }
  69. .radio-item label {
  70. margin: 0;
  71. /* Removes any default margins that might affect alignment */
  72. }
  73. .back-button {
  74. background: none;
  75. border: none;
  76. color: #000;
  77. font-size: 16px;
  78. cursor: pointer;
  79. padding: 0;
  80. margin-right: auto;
  81. /* Align the button to the left */
  82. }
  83. .title {
  84. text-align: center;
  85. flex-grow: 1;
  86. font-size: 24px;
  87. font-weight: bold;
  88. margin: 0;
  89. }
  90. /*css for map in step2*/
  91. #googleMap {
  92. height: 300px;
  93. width: 100%;
  94. position: relative;
  95. overflow: hidden;
  96. max-width: 100%;
  97. }
  98. #pac-input {
  99. position: absolute;
  100. top: 10px;
  101. left: 50%;
  102. transform: translateX(-50%);
  103. width: 300px;
  104. z-index: 5;
  105. padding: 10px;
  106. border: 1px solid #ccc;
  107. background-color: white;
  108. border-radius: 4px;
  109. }
  110. #search-container {
  111. position: absolute;
  112. top: 10px;
  113. left: 50%;
  114. transform: translateX(-50%);
  115. z-index: 1000;
  116. width: 500px;
  117. box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
  118. background-color: white;
  119. border-radius: 4px;
  120. padding: 0;
  121. /* Removed extra padding to match the input width */
  122. }
  123. #search-box {
  124. width: 100%;
  125. /* Ensures the input takes up the entire width of the container */
  126. padding: 5px;
  127. font-size: 16px;
  128. border: 1px solid #ccc;
  129. border-radius: 4px;
  130. /* Rounded corners matching the container */
  131. box-sizing: border-box;
  132. /* Makes sure padding is considered in width */
  133. }
  134. #suggestions {
  135. border: 1px solid #ccc;
  136. border-radius: 4px;
  137. max-height: 200px;
  138. overflow-y: auto;
  139. margin-top: 5px;
  140. background-color: white;
  141. display: none;
  142. width: 100%;
  143. /* Matches the width of the container and input */
  144. box-sizing: border-box;
  145. /* Ensures the width includes borders and padding */
  146. }
  147. #suggestions ul {
  148. list-style: none;
  149. padding: 0;
  150. margin: 0;
  151. }
  152. #suggestions ul li {
  153. padding: 5px;
  154. cursor: pointer;
  155. }
  156. #suggestions ul li:hover {
  157. background-color: #f0f0f0;
  158. }
  159. #reader-btn, #invertColorBtn {
  160. padding: 5px 10px;
  161. font-size: 14px;
  162. cursor: pointer;
  163. }
  164. .loader {
  165. border: 16px solid #f3f3f3;
  166. /* Light grey */
  167. border-top: 16px solid #3498db;
  168. /* Blue */
  169. border-radius: 50%;
  170. width: 120px;
  171. height: 120px;
  172. animation: spin 2s linear infinite;
  173. position: absolute;
  174. top: 50%;
  175. left: 50%;
  176. margin: -60px 0 0 -100px;
  177. /* Center the loader */
  178. z-index: 9999;
  179. /* Ensure it's on top of everything */
  180. display: none;
  181. /* Initially hidden */
  182. }
  183. .row {
  184. display: flex;
  185. flex-wrap: wrap;
  186. margin-bottom: 15px;
  187. gap: 15px;
  188. }
  189. .col-md-6 {
  190. flex: 0 0 48%;
  191. max-width: 48%;
  192. display: flex;
  193. flex-direction: column;
  194. }
  195. .col-md-6 label {
  196. font-weight: 600;
  197. margin-bottom: 5px;
  198. }
  199. .col-md-6 select,
  200. .col-md-6 input {
  201. height: 38px;
  202. padding: 5px 10px;
  203. border-radius: 5px;
  204. border: 1px solid #ccc;
  205. }
  206. @keyframes spin { 0%
  207. {
  208. transform: rotate(0deg);
  209. }
  210. 100%
  211. {
  212. transform:rotate(360deg);
  213. }
  214. }
  215. #snackbar {
  216. visibility: hidden;
  217. min-width: 250px;
  218. background-color: #333;
  219. color: #fff;
  220. text-align: center;
  221. border-radius: 2px;
  222. padding: 16px;
  223. position: fixed;
  224. z-index: 1;
  225. left: 50%;
  226. bottom: 30px;
  227. font-size: 17px;
  228. transform: translateX(-50%);
  229. }
  230. #snackbar.show {
  231. visibility: visible;
  232. -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
  233. animation: fadein 0.5s, fadeout 0.5s 2.5s;
  234. }
  235. @-webkit-keyframes fadein {from { bottom:0;
  236. opacity: 0;
  237. }
  238. to {
  239. bottom: 30px;
  240. opacity: 1;
  241. }
  242. }
  243. @keyframes fadein {from { bottom:0;
  244. opacity: 0;
  245. }
  246. to {
  247. bottom: 30px;
  248. opacity: 1;
  249. }
  250. }
  251. @-webkit-keyframes fadeout {from { bottom:30px;
  252. opacity: 1;
  253. }
  254. to {
  255. bottom: 0;
  256. opacity: 0;
  257. }
  258. }
  259. @keyframes fadeout {from { bottom:30px;
  260. opacity: 1;
  261. }
  262. to {
  263. bottom: 0;
  264. opacity: 0;
  265. }
  266. }
  267. /*for snack bar*/
  268. </style>
  269. <body>
  270. <div id="snackbar"></div>
  271. <!--[if lt IE 8]>
  272. <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>
  273. <![endif]-->
  274. <div class="wrapper">
  275. <!-- header top menu Start -->
  276. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  277. <!-- header top menu end -->
  278. <div class="page-wrap">
  279. <!--=============== Left Menu side Start ================-->
  280. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  281. <!--=============== Left side End ================-->
  282. <div class="main-content">
  283. <div class="container-fluid">
  284. <div class="page-header mb-2">
  285. <div class="row align-items-end">
  286. <div class="col-lg-8">
  287. <div class="page-header-title">
  288. <i class="fas fa-ticket-alt bg-blue"></i>
  289. <div class="d-inline">
  290. <h5>PGR Complaint Registration</h5>
  291. <span>1913 PGR Complaint Registration</span>
  292. </div>
  293. </div>
  294. </div>
  295. <div class="col-lg-4">
  296. <nav class="breadcrumb-container" aria-label="breadcrumb">
  297. <ol class="breadcrumb">
  298. <li class="breadcrumb-item"><a href="/gcc/index"><i class="ik ik-home"></i></a></li>
  299. <li class="breadcrumb-item" aria-current="page">Register Complaint</li>
  300. <li class="breadcrumb-item active" aria-current="page">Complaint Registration</li>
  301. </ol>
  302. </nav>
  303. </div>
  304. </div>
  305. </div>
  306. <div class="row inside mt-4">
  307. <div class="col-md-12">
  308. <div class="card" style="margin-top: 0px;">
  309. <div class="card-body">
  310. <!-- Step 1 -->
  311. <!-- Step 1 -->
  312. <div class=" form-step active" id="step-1">
  313. <!-- <div class="card-body"> -->
  314. <h5 class="card-title">1. Complaining Person's Details:</h5>
  315. <div class="form-row">
  316. <div class="col-md-4">
  317. <label for="mobile">Mobile Number:<span class="required">*</span></label>
  318. <div class="input-group">
  319. <input type="text" id="mobileNo" name="mobileNo"
  320. class="form-control mb-1"
  321. placeholder="Enter Mobile Number" maxlength="10"
  322. minlength="10" required>
  323. </div>
  324. </div>
  325. </div>
  326. <div class="form-row">
  327. <div class="col-md-4">
  328. <label for="name">Name:<span class="required">*</span></label>
  329. <input type="text" class="form-control" id="name"
  330. placeholder="Enter your name" required>
  331. </div>
  332. <div class="col-md-4">
  333. <label for="gender" class="ml-4">Gender/பாலினம்:<span
  334. class="required">*</span></label>
  335. <div class="radio-group mt-2 ml-4">
  336. <div class="radio-item">
  337. <input type="radio" id="male" name="gender" value="male"
  338. > <label for="male">Male</label>
  339. </div>
  340. <div class="radio-item">
  341. <input type="radio" id="female" name="gender"
  342. value="female"> <label for="female">Female</label>
  343. </div>
  344. <div class="radio-item">
  345. <input type="radio" id="transgender" name="gender"
  346. value="transgender"> <label for="transgender">Transgender</label>
  347. </div>
  348. </div>
  349. </div>
  350. <div class="col-md-4">
  351. <label for="email">Email:</label> <input type="email"
  352. class="form-control" id="email"
  353. placeholder="Enter your email">
  354. </div>
  355. </div>
  356. <button id="nextStep1" class="btn btn-primary float-right"
  357. onclick="nextStep('nextStep1')"
  358. style="background-color: #414f69;">Next</button>
  359. <!-- </div> -->
  360. </div>
  361. <!--step-2-->
  362. <div class=" form-step readable" id="step-2">
  363. <!-- <div class="card-body"> -->
  364. <h5 class="card-title">2. Complaint Location Details:</h5>
  365. <div class="form-row">
  366. <!-- loader section -->
  367. <!-- <div id="loader" class="loader" style="display: none;"></div> -->
  368. <!--map fields-->
  369. <div class="col-md-12">
  370. <!-- <div id="map"></div> -->
  371. <div id="mapContainer" style="position: relative; height: 500px;">
  372. <input id="pac-input" class="controls" type="text" placeholder="Search location">
  373. <div id="googleMap" style="height: 100%; width: 100%;"></div>
  374. </div>
  375. <div id="search-container">
  376. <!-- <input type="text" id="search-box" placeholder="Search for a location..."> -->
  377. <div id="suggestions"></div>
  378. </div>
  379. <div class="row">
  380. <div class="col-md-6">
  381. <!-- <label for="street">Street:</label>
  382. <input type="text" class="form-control" id="street"> -->
  383. <label for="streetName">Street:</label>
  384. <select id="streetName" name="streetName"></select>
  385. <!-- <label for="streetName">Street:</label>
  386. <input type="text" class="form-control" id="streetName"> -->
  387. </div>
  388. <div class="col-md-6">
  389. <!-- <label for="longitude_field">Longtitude</label>
  390. <input type="text" class="form-control" id="longitude_field" name="longtitude"> -->
  391. <label for="longitude_field">Longtitude</label>
  392. <input type="text" class="form-control" id="longitude_field" readonly>
  393. </div>
  394. <div class="col-md-6">
  395. <!-- <label for="latitude_field">Latitide</label>
  396. <input type="text" class="form-control" id="latitude_field"> -->
  397. <label for="latitude_field">Latitude</label>
  398. <input type="text" class="form-control" id="latitude_field" readonly>
  399. </div>
  400. <div class="col-md-6">
  401. <!-- <label for="street_id">Street Id</label>
  402. <input type="text" class="form-control" id="street_id"> -->
  403. <label for="streetId">Street Id</label>
  404. <input type="text" class="form-control" id="streetId" readonly>
  405. </div>
  406. <div class="col-md-6">
  407. <!-- <label for="landmark">Landmark</label>
  408. <input type="text" class="form-control" id="landmark"> -->
  409. <label for="landmark">Landmark</label>
  410. <input type="text" class="form-control" id="landmark" readonly>
  411. </div>
  412. <!-- <div class="col-md-6">
  413. <label for="zone">Zone</label>
  414. <input type="text" class="form-control" id="zone" readonly>
  415. </div>
  416. <div class="col-md-6">
  417. <label for="ward">Ward</label>
  418. <input type="text" class="form-control" id="ward" readonly>
  419. </div> -->
  420. </div>
  421. </div>
  422. </div>
  423. <button id="prevStep2" class="btn btn-secondary"
  424. onclick="prevStep('prevStep2')">Previous</button>
  425. <button id="nextStep2" class="btn btn-primary float-right"
  426. onclick="nextStep('nextStep2')"
  427. style="background-color: #414f69;">Next</button>
  428. <!-- </div> -->
  429. </div>
  430. <!-- Step 3 -->
  431. <div class=" form-step active readable" id="step-3">
  432. <div class="card-body">
  433. <h5 class="card-title">3. Complaint Type:&nbsp;<span>(Please Select Complaint Type from Below...)</span></h5>
  434. <!-- Icons -->
  435. <div class="complaint-icons">
  436. <div class="complaint-icon" data-type="specific"
  437. data-id="112">
  438. <img src="/gcc/assets/images/road.png" alt="Pothole">
  439. <p>Pothole</p>
  440. </div>
  441. <div class="complaint-icon" data-type="specific"
  442. data-id="97">
  443. <img src="/gcc/assets/images/recycle.png" alt="garbage">
  444. <p>Garbage</p>
  445. </div>
  446. <div class="complaint-icon" data-type="specific"
  447. data-id="104">
  448. <img src="/gcc/assets/images/waste-bin.png" alt="broken-bin">
  449. <p>Broken-Bin</p>
  450. </div>
  451. <div class="complaint-icon" data-type="specific"
  452. data-id="146">
  453. <img src="/gcc/assets/images/street-lamp.png" alt="StreetLight">
  454. <p>StreetLight</p>
  455. </div>
  456. <div class="complaint-icon" data-type="specific"
  457. data-id="199">
  458. <img src="/gcc/assets/images/portable-bathroom.png"
  459. alt="public-toilet">
  460. <p>Public Toilet</p>
  461. </div>
  462. <div class="complaint-icon" data-type="specific"
  463. data-id="118">
  464. <img src="/gcc/assets/images/mosquito.png" alt="mosquito">
  465. <p>Mosquito Menace</p>
  466. </div>
  467. <div class="complaint-icon" data-type="specific"
  468. data-id="138">
  469. <img src="/gcc/assets/images/tsunami.png" alt="waterstag">
  470. <p>WaterStagnation</p>
  471. </div>
  472. <div class="complaint-icon" data-type="specific"
  473. data-id="142">
  474. <img src="/gcc/assets/images/sewage.png" alt="sewage">
  475. <p>Storm Water Drains</p>
  476. </div>
  477. <div class="complaint-icon" data-type="specific"
  478. data-id="119">
  479. <img src="/gcc/assets/images/dog.png" alt="dog">
  480. <p>Street Dog</p>
  481. </div>
  482. <!--<div class="complaint-icon" data-type="specific" data-id="">
  483. <img src="images/bad-weather.png" alt="weather">
  484. <p>Tree Fallen</p>
  485. </div>-->
  486. <!-- <div class="complaint-icon" data-type="others">
  487. <img src="/gcc/assets/images/menu.png" alt="Others">
  488. <p>Others</p>
  489. </div> -->
  490. </div>
  491. <!-- Specific Complaint Fields -->
  492. <div class="complaint-fields active" id="specific-fields">
  493. <div class="form-row">
  494. <div class="col-md-6">
  495. <label for="complaint-title">Complaint Title:</label> <input
  496. type="text" class="form-control" id="complaint-title"
  497. placeholder="Enter Complaint Type">
  498. </div>
  499. <div class="col-md-6">
  500. <label for="complaint-id">Complaint Type:</label> <input
  501. type="text" class="form-control" id="complaint-id"
  502. disabled>
  503. </div>
  504. </div>
  505. <div class="form-row">
  506. <div class="col-md-6">
  507. <label for="othercomplaint-details">Details of
  508. Complaint:</label>
  509. <textarea class="form-control" id="othercomplaint-details"
  510. rows="3" placeholder="Enter complaint details"
  511. maxlength="400"></textarea>
  512. </div>
  513. <div class="col-md-6">
  514. <label for="complaint-image">Upload Photo:&nbsp;<span style="color: orange;">
  515. Less than 1 MB.</span></label>
  516. <input type="file" class="form-control" id="complaint-image" name="Comp_Image">
  517. </div>
  518. </div>
  519. </div>
  520. <!-- Others Complaint Fields -->
  521. <div class="complaint-fields" id="others-fields">
  522. <div class="form-row">
  523. <div class="col-md-4">
  524. <label for="type">Type:</label> <select
  525. class="form-control" id="type">
  526. <option value="">Please Select</option>
  527. </select>
  528. </div>
  529. <div class="col-md-4">
  530. <label for="sub-type">Sub-Type:</label> <select
  531. class="form-control" id="sub-type">
  532. <option value="">Select complaint</option>
  533. </select>
  534. </div>
  535. <div class="col-md-4">
  536. <label for="uploadothers">Upload Photo:</label> <input
  537. type="file" class="form-control" id="uploadothers"
  538. accept="image/*"> <span style="color: red;">
  539. <p>Upload Photo Less Than 1mb*.</p>
  540. </span>
  541. </div>
  542. </div>
  543. <div class="form-row">
  544. <div class="col-md-6">
  545. <label for="othercomplaintdetailsss">Details of
  546. Complaint:</label>
  547. <textarea class="form-control"
  548. id="othercomplaintdetailsss" rows="3"
  549. placeholder="Enter complaint details" maxlength="400"></textarea>
  550. </div>
  551. </div>
  552. </div>
  553. <button id="prevStep3" class="btn btn-secondary"
  554. onclick="prevStep('prevStep3')">Previous</button>
  555. <button id="nextStep3" class="btn btn-primary float-right"
  556. style="background-color: #414f69;">Next</button>
  557. </div>
  558. </div>
  559. <!-- Step 4 -->
  560. <div class=" form-step readable" id="step-4">
  561. <div class="card-body">
  562. <h5 class="card-title">4. Complaint Details:</h5>
  563. <table class="table">
  564. <tbody>
  565. <tr>
  566. <td><strong>Name</strong></td>
  567. <td>: <span id="summaryName"></span></td>
  568. <td><strong>Complaint Location</strong></td>
  569. <td>: <span id="summaryStreet"></span></td>
  570. </tr>
  571. <tr>
  572. <td><strong>Mobile Number</strong></td>
  573. <td>: <span id="summaryMobile"></span></td>
  574. <td><strong>Email Address</strong></td>
  575. <td>: <span id="summaryEmail"></span></td>
  576. </tr>
  577. <tr>
  578. <td><strong>Complaint Type</strong></td>
  579. <td>: <span id="summaryComplaintType"></span></td>
  580. <td><strong>Complaint Title</strong></td>
  581. <td>: <span id="summaryComplaintTitle"></span></td>
  582. </tr>
  583. <tr>
  584. <td><strong>Description</strong></td>
  585. <td>: <span id="summaryDescription"></span></td>
  586. <td><strong>Street Id</strong></td>
  587. <td>: <span id="summaryStreetId"></span></td>
  588. </tr>
  589. <tr>
  590. <td><strong>Landmark</strong></td>
  591. <td>: <span id="summaryLandmark"></span></td>
  592. <td><strong>Latitude</strong></td>
  593. <td>: <span id="summaryLatitude"></span></td>
  594. </tr>
  595. <tr>
  596. <td><strong>Longitude</strong></td>
  597. <td>: <span id="summaryLongitude"></span></td>
  598. <td><strong>Gender</strong></td>
  599. <td>: <span id="summaryGender"></span></td>
  600. </tr>
  601. <tr>
  602. <td><strong>Image / Video</strong></td>
  603. <td>: <img id="summaryImage" src="#"
  604. alt="Uploaded Image/Video" width="100"
  605. style="display: none;">
  606. </td>
  607. </tr>
  608. </tbody>
  609. </table>
  610. <button id="prevStep4" class="btn btn-secondary"
  611. onclick="prevStep('prevStep4')">Previous</button>
  612. <button id="submitButton" class="btn btn-success float-right">Submit</button>
  613. </div>
  614. </div>
  615. </div>
  616. </div>
  617. </div>
  618. </div>
  619. </div>
  620. </div>
  621. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  622. </div>
  623. </div>
  624. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  625. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  626. <script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
  627. <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
  628. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  629. <script src="https://kit.fontawesome.com/a076d05399.js"></script>
  630. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  631. <script th:src="@{/js/screenreader.js}"></script>
  632. <script async defer
  633. src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCi7N6uW5MZaSkd50Kzw7ax2GkMN1vjE-E&callback=myMap&libraries=places">
  634. </script>
  635. <script type="text/javascript">
  636. //for snackbar script
  637. function showSnackbar(message) {
  638. var snackbar = document.getElementById("snackbar");
  639. snackbar.innerHTML = message;
  640. snackbar.className = "show";
  641. setTimeout(function () {snackbar.className = snackbar.className.replace("show", "");}, 3000);
  642. }
  643. //for snackbar script
  644. let currentStep = 1;
  645. let mapInitialized = false;
  646. function showStep(step) {
  647. $('.form-step').removeClass('active');
  648. $('#step-' + step).addClass('active');
  649. /* updateProgressBar(step); */
  650. if (step === 2 && !mapInitialized) {
  651. //document.getElementById('loader').style.display = 'block'; // Show loader before map initialization
  652. //setTimeout(initializeMap, 3000); // Load the map after 3 seconds
  653. mapInitialized = true; // Ensure the map is only initialized once
  654. }
  655. // If we're on step 4, populate the summary fields
  656. if (step === 4) {
  657. populateSummary();
  658. }
  659. }
  660. function nextStep() {
  661. if (currentStep < 4) {
  662. // Perform validation for the current step
  663. if (validateStep(currentStep)) {
  664. currentStep++;
  665. showStep(currentStep);
  666. }
  667. }
  668. }
  669. function prevStep() {
  670. if (currentStep > 1) {
  671. currentStep--;
  672. showStep(currentStep);
  673. }
  674. }
  675. /* function updateProgressBar(step) {
  676. const progress = (step / 4) * 100;
  677. $('.progress-bar').css('width', progress + '%').attr('aria-valuenow', progress);
  678. } */
  679. function validateStep(step) {
  680. let isValid = true;
  681. if (step === 1) {
  682. console.log("step 1");
  683. const mobileNo = $('#mobileNo').val().trim();
  684. const gender = $('input[name="gender"]:checked').val();
  685. const name = $('#name').val().trim();
  686. let email = $('#email').val().trim();
  687. console.log("mobileNo"+mobileNo);
  688. console.log("gender="+gender);
  689. console.log("name="+name);
  690. console.log("email="+email);
  691. // Validate mobile number
  692. if (mobileNo === '' || !/^\d{10}$/.test(mobileNo)) {
  693. isValid = false;
  694. showSnackbar("Please enter a valid 10-digit mobile number.");
  695. return false;
  696. }
  697. // Validate name
  698. if (!name) {
  699. isValid = false;
  700. showSnackbar("Please enter your name.");
  701. return false;
  702. }
  703. // Validate gender
  704. if (!gender) {
  705. showSnackbar("Please select your gender.");
  706. return false;
  707. }
  708. // Check email
  709. if (email === '') {
  710. email = 'N/A'; // Set N/A if empty
  711. $('#email').val(email); // Update the input field with N/A
  712. } else if (!/^\S+@\S+\.\S+$/.test(email)) {
  713. isValid = false;
  714. showSnackbar("Please enter a valid email address.");
  715. return false;
  716. }
  717. } else if (step === 2) {
  718. const streets = $('#streetName option:selected').val();
  719. console.log("streets="+streets);
  720. const longitude = $('#longitude_field').val();
  721. const latitude = $('#latitude_field').val();
  722. const streetId = $('#streetId').val();
  723. const landmark = $('#landmark').val();
  724. // Validate street
  725. if (!streets) {
  726. isValid = false;
  727. showSnackbar("Please enter the street.");
  728. return false;
  729. }
  730. // Validate longitude and latitude
  731. if (longitude === '' || isNaN(longitude)) {
  732. isValid = false;
  733. showSnackbar("Please enter a valid longitude.");
  734. return false;
  735. }
  736. if (latitude === '' || isNaN(latitude)) {
  737. isValid = false;
  738. showSnackbar("Please enter a valid latitude.");
  739. return false;
  740. }
  741. // Validate street ID
  742. if (streetId === '') {
  743. isValid = false;
  744. showSnackbar("Please enter the street ID.");
  745. return false;
  746. }
  747. // Validate landmark
  748. if (landmark === '') {
  749. isValid = false;
  750. showSnackbar("Please enter the landmark.");
  751. return false;
  752. }
  753. }
  754. return isValid;
  755. }
  756. function populateSummary() {
  757. const name = $('#name').val();
  758. const street = $('#streetName option:selected').text();
  759. const mobileNo = $('#mobileNo').val();
  760. const gender = $('input[name="gender"]:checked').val();
  761. const email = $('#email').val();
  762. // Check if 'specific-fields' is active and use its values
  763. if ($('#specific-fields').hasClass('active')) {
  764. const complaintTitle = $('#complaint-title').val();
  765. const complaintid = $('#complaint-id').val();
  766. const complaintDetails = $('#othercomplaint-details').val(); // Specific complaint details
  767. $('#summaryComplaintTitle').text(complaintTitle);
  768. $('#summaryComplaintType').text(complaintid);
  769. $('#summaryDescription').text(complaintDetails);
  770. } else if ($('#others-fields').hasClass('active')) {
  771. const complaintTitle = $('#type').find('option:selected').text();
  772. const complaintSubType = $('#sub-type').find('option:selected').text();
  773. const complaintDetails = $('#othercomplaintdetailsss').val(); // Others complaint details
  774. $('#summaryComplaintTitle').text(complaintTitle + ' - ' + complaintSubType);
  775. $('#summaryComplaintType').text('Other Complaint');
  776. $('#summaryDescription').text(complaintDetails);
  777. }
  778. //const streetid = $('#street_id').val();
  779. const streetid = $('#streetId').val();
  780. const landmark = $('#landmark').val();
  781. const latitude = $('#latitude_field').val();
  782. const longtitude = $('#longitude_field').val();
  783. $('#summaryName').text(name);
  784. $('#summaryStreet').text(street);
  785. $('#summaryMobile').text(mobileNo);
  786. $('#summaryGender').text(gender);
  787. $('#summaryEmail').text(email);
  788. $('#summaryStreetId').text(streetid);
  789. $('#summaryLandmark').text(landmark);
  790. $('#summaryLatitude').text(latitude);
  791. $('#summaryLongitude').text(longtitude);
  792. // Handle image preview
  793. /* const fileInput = $('#complaint-image')[0]; // Assuming this is for the "Others" section
  794. if (fileInput.files && fileInput.files[0]) {
  795. const reader = new FileReader();
  796. reader.onload = function (e) {
  797. $('#summaryImage').attr('src', e.target.result).show();
  798. }
  799. reader.readAsDataURL(fileInput.files[0]);
  800. } else {
  801. $('#summaryImage').hide();
  802. }*/
  803. // If there's a separate image input for the specific form, handle it similarly:
  804. // Check if specific fields section is active
  805. if ($('#specific-fields').hasClass('active')) {
  806. const specificFileInput = $('#complaint-image')[0]; // Example ID for specific form
  807. if (specificFileInput.files && specificFileInput.files[0]) {
  808. const reader = new FileReader();
  809. reader.onload = function (e) {
  810. $('#summaryImage').attr('src', e.target.result).show();
  811. };
  812. reader.readAsDataURL(specificFileInput.files[0]);
  813. } else {
  814. $('#summaryImage').hide(); // Hide the image if no file is selected
  815. }
  816. }
  817. // Check if "Others" section is active
  818. else if ($('#others-fields').hasClass('active')) {
  819. const fileInput = $('#uploadothers')[0]; // Assuming this is for the "Others" section
  820. if (fileInput.files && fileInput.files[0]) {
  821. const reader = new FileReader();
  822. reader.onload = function (e) {
  823. $('#summaryImage').attr('src', e.target.result).show();
  824. };
  825. reader.readAsDataURL(fileInput.files[0]);
  826. } else {
  827. $('#summaryImage').hide(); // Hide the image if no file is selected
  828. }
  829. } else {
  830. $('#summaryImage').hide(); // Default hide if no section is active
  831. }
  832. }
  833. $(document).ready(function () {
  834. showStep(currentStep);
  835. });
  836. $(document).ready(function () {
  837. showStep(currentStep);
  838. });
  839. //for step3 onclick function
  840. $(document).ready(function () {
  841. // On icon click
  842. $('.complaint-icon').click(function () {
  843. const type = $(this).data('type'); // Get the type (specific or others)
  844. const title = $(this).find('p').text().trim(); // Get the icon name (complaint title)
  845. const complaintId = $(this).data('id'); // Get the complaint ID
  846. // Toggle complaint fields based on type
  847. $('.complaint-fields').removeClass('active');
  848. if (type === 'specific') {
  849. $('#specific-fields').addClass('active'); // Show specific fields form
  850. $('#others-fields').removeClass('active'); // Hide others form
  851. $('#complaint-title').val(title); // Set the complaint title to the icon name
  852. $('#complaint-id').val(complaintId); // Set the complaint ID to the corresponding ID
  853. } else if (type === 'others') {
  854. $('#others-fields').addClass('active'); // Show others form
  855. $('#specific-fields').removeClass('active'); // Hide specific fields form
  856. $('#complaint-title').val(''); // Clear the complaint title for 'Others'
  857. $('#complaint-id').val(''); // Clear the complaint ID for 'Others'
  858. }
  859. });
  860. });
  861. //for complaint group and complainttype wise options dropdown api
  862. $(document).ready(function () {
  863. const $type = $('#type');
  864. const $subType = $('#sub-type');
  865. $subType.prop('disabled', true);
  866. // Fetch and populate the Type dropdown
  867. $.ajax({
  868. url: '/gcc/api/callcenterqaqc/pgrcomplaint/getComplaintCategories',
  869. method: 'GET',
  870. success: function (response) {
  871. const data = typeof response === 'string' ? JSON.parse(response) : response;
  872. //console.log('Response:', response); // Log the response to verify
  873. let optionsHtml = '<option value="">Please Select</option>';
  874. data.ComplaintCategoryListResult.forEach(function (group) {
  875. optionsHtml += `<option value="${group.groupid}">${group.groupname}</option>`;
  876. });
  877. $type.html(optionsHtml);
  878. },
  879. error: function (error) {
  880. console.error('Error fetching complaint categories:', error);
  881. }
  882. });
  883. // Handle Type dropdown change
  884. $type.change(function () {
  885. const selectedType = $(this).val();
  886. $subType.empty().append('<option value="">Select complaint</option>');
  887. if (selectedType) {
  888. $.ajax({
  889. url: `/gcc/api/callcenterqaqc/pgrcomplaint/getComplaintSubTypes?groupId=${selectedType}`,
  890. method: 'GET',
  891. success: function (response) {
  892. const data = typeof response === 'string' ? JSON.parse(response) : response;
  893. const selectedGroup = data.ComplaintCategoryListResult[0];
  894. //console.log(data);
  895. if (selectedGroup && selectedGroup.group) {
  896. $subType.prop('disabled', false);
  897. selectedGroup.group.forEach(function (complaint) {
  898. $subType.append(`<option value="${complaint.id}">${complaint.complaintname}</option>`);
  899. });
  900. } else {
  901. $subType.prop('disabled', true);
  902. }
  903. },
  904. error: function (error) {
  905. console.error('Error fetching sub-types:', error);
  906. $subType.prop('disabled', true);
  907. }
  908. });
  909. } else {
  910. $subType.prop('disabled', true);
  911. }
  912. });
  913. });
  914. //api for saving
  915. //for sweet alert
  916. /* function showSuccessAlert() {
  917. Swal.fire({
  918. icon: 'success',
  919. title: 'Complaint Registration Success',
  920. text: 'Complaint Number 123456. Use this Number for Complaint Status Check.',
  921. confirmButtonText: 'Back to Home',
  922. confirmButtonColor: '#3085d6',
  923. }).then((result) => {
  924. if (result.isConfirmed) {
  925. window.location.href = 'home';
  926. }
  927. });
  928. } */
  929. $('#complaint-image, #uploadothers').on('change', function () {
  930. const file = this.files[0];
  931. const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
  932. if (file) {
  933. // Check file type
  934. if (!allowedTypes.includes(file.type)) {
  935. Swal.fire({
  936. icon: 'error',
  937. title: 'Invalid File Format',
  938. text: 'Only JPG, JPEG, and PNG image formats are allowed.',
  939. confirmButtonText: 'OK'
  940. });
  941. $(this).val(''); // Clear the input
  942. return;
  943. }
  944. // Check file size
  945. if (file.size > 1024 * 1024) {
  946. Swal.fire({
  947. icon: 'error',
  948. title: 'File Too Large',
  949. text: 'File size exceeds 1MB. Please upload an image less than 1MB.',
  950. confirmButtonText: 'OK'
  951. });
  952. $(this).val(''); // Clear the input
  953. return;
  954. }
  955. }
  956. });
  957. //Script For Map
  958. function myMap() {
  959. const defaultCenter = { lat: 13.0827, lng: 80.2707 };
  960. const map = new google.maps.Map(document.getElementById("googleMap"), {
  961. center: defaultCenter,
  962. zoom: 14
  963. });
  964. let marker = null;
  965. let streetsList = []; // ✅ Define globally inside myMap
  966. const infowindow = new google.maps.InfoWindow();
  967. // 🔍 Initialize the SearchBox
  968. const input = document.getElementById('pac-input');
  969. const searchBox = new google.maps.places.SearchBox(input);
  970. //map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
  971. map.addListener('bounds_changed', function () {
  972. searchBox.setBounds(map.getBounds());
  973. });
  974. searchBox.addListener('places_changed', function () {
  975. const places = searchBox.getPlaces();
  976. if (places.length === 0) return;
  977. if (marker) marker.setMap(null);
  978. const place = places[0];
  979. if (!place.geometry) return;
  980. marker = new google.maps.Marker({
  981. map: map,
  982. position: place.geometry.location
  983. });
  984. const lat = place.geometry.location.lat().toFixed(6);
  985. const lng = place.geometry.location.lng().toFixed(6);
  986. document.getElementById("latitude_field").value = lat;
  987. document.getElementById("longitude_field").value = lng;
  988. map.setCenter(place.geometry.location);
  989. map.setZoom(15);
  990. infowindow.setContent(`Latitude: ${lat}<br>Longitude: ${lng}`);
  991. infowindow.open(map, marker);
  992. fetchStreets(lat, lng);
  993. });
  994. map.addListener("click", function (event) {
  995. const clickedLatLng = event.latLng;
  996. if (marker) marker.setMap(null);
  997. marker = new google.maps.Marker({
  998. position: clickedLatLng,
  999. map: map
  1000. });
  1001. const lat = clickedLatLng.lat().toFixed(6);
  1002. const lng = clickedLatLng.lng().toFixed(6);
  1003. document.getElementById("latitude_field").value = lat;
  1004. document.getElementById("longitude_field").value = lng;
  1005. infowindow.setContent(`Latitude: ${lat}<br>Longitude: ${lng}`);
  1006. infowindow.open(map, marker);
  1007. fetchStreets(lat, lng);
  1008. });
  1009. // ✅ Move fetchStreets here inside myMap, and use local streetsList
  1010. function fetchStreets(lat, lng) {
  1011. const encodedGeometry = encodeURIComponent(JSON.stringify({ y: lat, x: lng }));
  1012. const streetURL = `https://gisgcc.chennaicorporation.gov.in/server/rest/services/GCCDepts/EDPMobile2025/FeatureServer/0/query?` +
  1013. `where=&objectIds=&time=&geometry=${encodedGeometry}` +
  1014. `&geometryType=esriGeometryPoint&inSR=4326&defaultSR=4326&spatialRel=esriSpatialRelIntersects&distance=25` +
  1015. `&units=esriSRUnit_Meter&relationParam=&outFields=region%2Cnew_zone%2C+new_ward%2Croad_id%2C+road_name%2Cgis_id%2Ctype` +
  1016. `&returnGeometry=false&maxAllowableOffset=&geometryPrecision=&outSR=&havingClause=&gdbVersion=&historicMoment=` +
  1017. `&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&orderByFields=` +
  1018. `&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&multipatchOption=xyFootprint&resultOffset=` +
  1019. `&resultRecordCount=&returnTrueCurves=false&returnExceededLimitFeatures=false&quantizationParameters=&returnCentroid=false` +
  1020. `&timeReferenceUnknownClient=false&maxRecordCountFactor=&sqlFormat=none&resultType=&featureEncoding=esriDefault` +
  1021. `&datumTransformation=&f=geojson`;
  1022. const streetSelect = document.getElementById("streetName");
  1023. streetSelect.innerHTML = "";
  1024. const defaultOption = document.createElement("option");
  1025. defaultOption.value = "";
  1026. defaultOption.text = "-- Select Street --";
  1027. streetSelect.appendChild(defaultOption);
  1028. document.getElementById("streetId").value = "";
  1029. document.getElementById("landmark").value = "";
  1030. fetch(streetURL)
  1031. .then(res => res.json())
  1032. .then(data => {
  1033. const features = data.features;
  1034. if (!features || features.length === 0) {
  1035. Swal.fire({
  1036. icon: 'warning',
  1037. title: 'No Street Found',
  1038. text: 'Please select the nearby street.',
  1039. });
  1040. return;
  1041. }
  1042. streetsList = features.map(f => f.properties); // ✅ Save for use in dropdown
  1043. streetsList.forEach((props, index) => {
  1044. const option = document.createElement("option");
  1045. option.value = index;
  1046. option.text = props.road_name;
  1047. streetSelect.appendChild(option);
  1048. });
  1049. })
  1050. .catch(err => {
  1051. console.error("Error fetching street:", err);
  1052. Swal.fire("Failed to load street data", '', 'error');
  1053. });
  1054. }
  1055. document.getElementById("streetName").addEventListener("change", function () {
  1056. const selectedIndex = this.value;
  1057. if (selectedIndex !== "") {
  1058. const selectedStreet = streetsList[selectedIndex];
  1059. document.getElementById("streetId").value = selectedStreet.road_id;
  1060. document.getElementById("landmark").value = selectedStreet.type;
  1061. // document.getElementById("zone").value = selectedStreet.new_zone;
  1062. // document.getElementById("ward").value = selectedStreet.new_ward;
  1063. console.log("Selected street:", selectedStreet);
  1064. } else {
  1065. document.getElementById("streetId").value = "";
  1066. document.getElementById("landmark").value = "";
  1067. // document.getElementById("zone").value = "";
  1068. // document.getElementById("ward").value = "";
  1069. }
  1070. });
  1071. }
  1072. function fetchSuggestions(query) {
  1073. // ArcGIS API URL to fetch suggestions based on the input query
  1074. const arcgisSuggestionUrl = `https://gisgcc.chennaicorporation.gov.in/server/rest/services/Hosted/Road_API/FeatureServer/0/query?where=UPPER(road_name)%20LIKE%20'%25${query.toUpperCase()}%25'&outFields=road_name,zone,ward,road_id&returnGeometry=true&f=geojson`;
  1075. fetch(arcgisSuggestionUrl)
  1076. .then(response => response.json())
  1077. .then(data => {
  1078. var suggestions = document.getElementById('suggestions');
  1079. suggestions.innerHTML = '';
  1080. if (data.features && data.features.length > 0) {
  1081. suggestions.style.display = 'block';
  1082. var ul = document.createElement('ul');
  1083. data.features.forEach(function (result) {
  1084. var lat = result.geometry.coordinates[1];
  1085. var lng = result.geometry.coordinates[0];
  1086. var roadName = result.properties.road_name || 'Unknown Road';
  1087. /* var zone = result.properties.zone || 'Unknown Zone';
  1088. var ward = result.properties.ward || 'Unknown Ward'; */
  1089. var roadId = result.properties.road_id || 'Unknown Road ID'
  1090. // Creating the suggestion item with road name, zone, and ward
  1091. var li = document.createElement('li');
  1092. li.textContent = `${roadName} - Zone: ${zone}, Ward: ${ward}`;
  1093. li.dataset.latlng = JSON.stringify([lat, lng]);
  1094. li.dataset.roadName = roadName;
  1095. li.dataset.roadId = roadId;
  1096. /* li.dataset.zone = zone;
  1097. li.dataset.ward = ward; */
  1098. ul.appendChild(li);
  1099. });
  1100. suggestions.appendChild(ul);
  1101. } else {
  1102. suggestions.style.display = 'none';
  1103. }
  1104. })
  1105. .catch(error => console.error('Error fetching suggestions:', error));
  1106. }
  1107. function fetchLocationInfoByMap(lat, lng, marker) {
  1108. const arcgisUrl = `https://gisgcc.chennaicorporation.gov.in/server/rest/services/Hosted/Road_API/FeatureServer/0/query?where=&objectIds=&time=&geometry=%7B%22y%22%3A${lat}%2C%22x%22%3A${lng}%7D&geometryType=esriGeometryEnvelope&inSR=4326&defaultSR=4326&spatialRel=esriSpatialRelIntersects&distance=25&units=esriSRUnit_Meter&relationParam=&outFields=zone%2Cward%2Croad_id%2Croad_name&returnGeometry=false&maxAllowableOffset=&geometryPrecision=&outSR=&havingClause=&gdbVersion=&historicMoment=&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&multipatchOption=xyFootprint&resultOffset=&resultRecordCount=&returnTrueCurves=false&returnCentroid=false&timeReferenceUnknownClient=false&maxRecordCountFactor=&sqlFormat=none&resultType=&datumTransformation=&lodType=geohash&lod=&lodSR=&f=geojson`;
  1109. fetch(arcgisUrl)
  1110. .then(response => response.json())
  1111. .then(data => {
  1112. console.log(data);
  1113. let info;
  1114. if (data.features && data.features.length > 0) {
  1115. const properties = data.features[0].properties;
  1116. const roadName = properties.road_name || 'N/A';
  1117. /* const zone = properties.zone || 'N/A';
  1118. const ward = properties.ward || 'N/A'; */
  1119. const roadId = properties.road_id || 'N/A';
  1120. info = `Road Name: ${roadName}<br>Zone: ${zone}<br>Ward: ${ward}<br>Latitude: ${lat}<br>Longitude: ${lng}`;
  1121. document.getElementById("street").value = roadName;
  1122. document.getElementById("latitude_field").value = lat;
  1123. document.getElementById("longitude_field").value = lng;
  1124. //document.getElementById("street_id").value = roadId;
  1125. document.getElementById("streetId").value = roadId;
  1126. document.getElementById("landmark").value = roadName;
  1127. marker.bindTooltip(info, {permanent: false, direction: 'top'}).openTooltip();
  1128. } else {
  1129. document.getElementById("street").value = "No road data found for this location";
  1130. document.getElementById("latitude_field").value = "No latitude data found for this location";
  1131. document.getElementById("longitude_field").value = "No latitude data found for this location";
  1132. //document.getElementById("street_id").value = "No street id data found for this location";
  1133. document.getElementById("streetId").value = "No street id data found for this location";
  1134. document.getElementById("landmark").value = "No landmark data found for this location";
  1135. info = `No road data found for this location`
  1136. marker.bindTooltip(info, {permanent: false, direction: 'top'}).openTooltip();
  1137. }
  1138. })
  1139. .catch(error => {
  1140. console.error('Error fetching road data:', error);
  1141. marker.bindTooltip(`Error fetching road data.<br>Latitude: ${lat}<br>Longitude: ${lng}`, {permanent: false, direction: 'top'}).openTooltip();
  1142. });
  1143. }
  1144. function fetchLocationInfoBySuggestions(lat, lng, marker) {
  1145. const arcgisUrl = `https://gisgcc.chennaicorporation.gov.in/server/rest/services/Hosted/Road_API/FeatureServer/0/query?where=&objectIds=&time=&geometry=%7B%22y%22%3A${lat}%2C%22x%22%3A${lng}%7D&geometryType=esriGeometryEnvelope&inSR=4326&defaultSR=4326&spatialRel=esriSpatialRelIntersects&distance=25&units=esriSRUnit_Meter&relationParam=&outFields=zone%2Cward%2Croad_id%2Croad_name&returnGeometry=false&maxAllowableOffset=&geometryPrecision=&outSR=&havingClause=&gdbVersion=&historicMoment=&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&multipatchOption=xyFootprint&resultOffset=&resultRecordCount=&returnTrueCurves=false&returnCentroid=false&timeReferenceUnknownClient=false&maxRecordCountFactor=&sqlFormat=none&resultType=&datumTransformation=&lodType=geohash&lod=&lodSR=&f=geojson`;
  1146. fetch(arcgisUrl)
  1147. .then(response => response.json())
  1148. .then(data => {
  1149. console.log(data);
  1150. let info;
  1151. if (data.features && data.features.length > 0) {
  1152. const properties = data.features[0].properties;
  1153. const roadName = properties.road_name || 'N/A';
  1154. /* const zone = properties.zone || 'N/A';
  1155. const ward = properties.ward || 'N/A'; */
  1156. const roadId = properties.road_id || 'N/A';
  1157. info = `Road Name: ${roadName}<br>Zone: ${zone}<br>Ward: ${ward}<br>Latitude: ${lat}<br>Longitude: ${lng}`;
  1158. document.getElementById("street").value = roadName;
  1159. document.getElementById("latitude_field").value = lat;
  1160. document.getElementById("longitude_field").value = lng;
  1161. //document.getElementById("street_id").value = roadId;
  1162. document.getElementById("streetId").value = roadId;
  1163. document.getElementById("landmark").value = roadName;
  1164. marker.bindTooltip(info, {permanent: false, direction: 'top'}).openTooltip();
  1165. } else {
  1166. document.getElementById("street").value = suggestedRoadName;
  1167. document.getElementById("latitude_field").value = lat;
  1168. document.getElementById("longitude_field").value = lng;
  1169. //document.getElementById("street_id").value = suggestedRoadId;
  1170. document.getElementById("streetId").value = suggestedRoadId;
  1171. document.getElementById("landmark").value = suggestedRoadName;
  1172. info = `Road Name: ${suggestedRoadName}<br>Zone: ${suggestedZone}<br>Ward: ${suggestedWard}<br>Latitude: ${lat}<br>Longitude: ${lng}`
  1173. marker.bindTooltip(info, {permanent: false, direction: 'top'}).openTooltip();
  1174. }
  1175. })
  1176. .catch(error => {
  1177. console.error('Error fetching road data:', error);
  1178. marker.bindTooltip(`Error fetching road data.<br>Latitude: ${lat}<br>Longitude: ${lng}`, {permanent: false, direction: 'top'}).openTooltip();
  1179. });
  1180. }
  1181. $(document).ready(function () {
  1182. $('#submitButton').click(function (e) {
  1183. e.preventDefault(); // Prevent the default form submission
  1184. $('#submitButton').prop('disabled', true).text('Processing...');
  1185. // Collect data from the form fields
  1186. var complainantName = $('#summaryName').text().trim();
  1187. var complainantAddr = $('#summaryStreet').text().trim();
  1188. var mobileNo = $('#summaryMobile').text().trim();
  1189. var email = $('#summaryEmail').text().trim();
  1190. var complaintType = $('#summaryComplaintType').text().trim();
  1191. var complaintTitle = $('#summaryComplaintTitle').text().trim();
  1192. var complaintDetails = $('#summaryDescription').text().trim();
  1193. var streetId = $('#summaryStreetId').text().trim();
  1194. var landmark = $('#summaryLandmark').text().trim();
  1195. var latitude = $('#summaryLatitude').text().trim();
  1196. var longtitude = $('#summaryLongitude').text().trim(); // Note the misspelling
  1197. var gender = $('#summaryGender').text().trim();
  1198. var imageSrc = $('#summaryImage').attr('src');
  1199. /* console.log({
  1200. ComplainantName: complainantName,
  1201. ComplainantAddr: complainantAddr,
  1202. MobileNo: mobileNo,
  1203. Email: email,
  1204. ComplaintType: complaintType,
  1205. ComplaintTitle: complaintTitle,
  1206. ComplaintDetails: complaintDetails,
  1207. StreetId: streetId,
  1208. Comp_Image: imageSrc,
  1209. latitude: latitude,
  1210. longtitude: longtitude,
  1211. Landmark: landmark,
  1212. gender: gender
  1213. }); */
  1214. // AJAX call to your backend controller
  1215. $.ajax({
  1216. url: '/gcc/api/callcenterqaqc/pgrcomplaint/register', // Update to your Spring Boot endpoint
  1217. type: 'POST',
  1218. data: {
  1219. ComplainantName: complainantName,
  1220. ComplainantAddr: complainantAddr,
  1221. MobileNo: mobileNo,
  1222. Email: email,
  1223. ComplaintType: complaintType,
  1224. ComplaintTitle: complaintTitle,
  1225. ComplaintDetails: complaintDetails,
  1226. StreetId: streetId,
  1227. Comp_Image: imageSrc,
  1228. latitude: latitude,
  1229. longtitude: longtitude,
  1230. Landmark: landmark,
  1231. gender: gender
  1232. },
  1233. success: function (response) {
  1234. $('#submitButton').prop('disabled', false).text('Submit');
  1235. // SweetAlert upon success
  1236. console.log("API Response:", response);
  1237. // Ensure response is a JavaScript object
  1238. if (typeof response === "string") {
  1239. try {
  1240. response = JSON.parse(response);
  1241. } catch (error) {
  1242. console.error("Failed to parse response:", error);
  1243. }
  1244. }
  1245. let complaintNumber = response["complaintNumber"];
  1246. if (!complaintNumber || complaintNumber === "null" || complaintNumber === null) {
  1247. complaintNumber = "N/A";
  1248. }
  1249. Swal.fire({
  1250. title: 'Success!',
  1251. text: `Your complaint has been submitted successfully. Your Complaint Number is ${complaintNumber}. It will be sent to your mobile number.`,
  1252. icon: 'success',
  1253. allowOutsideClick: false, // Disable clicking outside the modal to close it
  1254. allowEscapeKey: false, // Disable escape key to close the modal
  1255. allowEnterKey: false, // Disable enter key to close the modal
  1256. showConfirmButton: true, // Ensure the confirm button is visible
  1257. confirmButtonText: 'OK'
  1258. }).then((result) => {
  1259. if (result.isConfirmed) {
  1260. location.reload();
  1261. }
  1262. });
  1263. },
  1264. error: function (xhr, status, error) {
  1265. // Improved error handling
  1266. $('#submitButton').prop('disabled', false).text('Submit');
  1267. console.log('Error:', xhr.responseText, status, error);
  1268. //alert('Error: ' + xhr.status + ' ' + xhr.statusText);
  1269. Swal.fire({
  1270. title: 'Error!',
  1271. text: 'Submission failed. Please try again.',
  1272. icon: 'error'
  1273. });
  1274. }
  1275. });
  1276. });
  1277. // ✅ Step 1: Map complaint ID to complaint title
  1278. const complaintTypeMap = {
  1279. "97": "Removal of Garbage",
  1280. "98": "Overflowing of Garbage Bin",
  1281. "99": "Removal of Debris",
  1282. "100": "Absenteeism of Sweepers",
  1283. "101": "Absenteeism of Door to door garbage Collector",
  1284. "102": "Improper Sweeping",
  1285. "103": "Provison of Garbage Bin",
  1286. "104": "Broken Bin",
  1287. "105": "Shifting of Garbage Bin",
  1288. "106": "Cleaning of Water Table",
  1289. "107": "Nuisance by Garbage Tractor/Truck",
  1290. "108": "Burning of Garbage",
  1291. "109": "Garbage Lorry without Net",
  1292. "110": "Spilling of Garbage from Lorry",
  1293. "111": "Burning of Garbage at Dumping Ground",
  1294. "112": "Pot hole fill up / Repairs to the damaged surface",
  1295. "113": "Relaying of Road",
  1296. "114": "Formation of New Road",
  1297. "115": "Repairs to existing Footpath",
  1298. "116": "Request to provide Footpath",
  1299. "117": "Removal of Shops in the Footpath",
  1300. "118": "Mosquito Menace",
  1301. "119": "Street Dogs",
  1302. "120": "Stray Cattle",
  1303. "121": "Stray Pigs",
  1304. "122": "Death of Stray Animals",
  1305. "123": "Public Health / Dengue / Malaria / Gastro Enteritis",
  1306. "124": "Transfer Station Smell",
  1307. "125": "Flies Menace from Dumping Ground",
  1308. "126": "Open Defecation",
  1309. "127": "Illegal Draining of Sewage to SWD / Open Site",
  1310. "128": "Complaints regarding unhygenic Restaurants",
  1311. "129": "Complaints regarding quality of food in hotels",
  1312. "130": "Road Side Eateries",
  1313. "131": "Slaughter House related complaints",
  1314. "132": "Unauthorized Sale of Meat and Meat products",
  1315. "133": "Illegal Slaughtering",
  1316. "134": "Unhygenic and Improper Transport of Meat and Livestock",
  1317. "135": "Biomedical waste / Health hazard waste removal",
  1318. "136": "Complaints regarding Corporation Hospitals",
  1319. "137": "Complaints regarding CDH",
  1320. "138": "Stagnation of Water",
  1321. "139": "Obstruction of Water Flow",
  1322. "140": "Desilting of Drain",
  1323. "141": "Desilting of Canal",
  1324. "142": "Repairs to Storm Water Drain",
  1325. "143": "Covering Manholes of Storm Water Drain",
  1326. "144": "New Drain Construction",
  1327. "145": "Disposal of Removed Silt on the Road",
  1328. "146": "Non burning of Street lights",
  1329. "147": "Electric shock due to street light",
  1330. "148": "Damage to the Electric pole",
  1331. "149": "New Street lights",
  1332. "150": "Shifting of Street light pole",
  1333. "151": "Overhead cable wires running in a haphazard manner",
  1334. "152": "Removal of Fallen Trees",
  1335. "153": "Complaints regarding Park",
  1336. "154": "Complaints regarding Playground",
  1337. "155": "Complaints regarding Centre Median",
  1338. "156": "Complaints regarding Traffic Island",
  1339. "157": "Unauthorized Tree Cutting",
  1340. "158": "Obstruction of Trees",
  1341. "159": "Complaints regarding Public Toilets",
  1342. "160": "Complaints regarding Free Usage of Public Toilets",
  1343. "161": "Complaints regarding Cleanliness of Toilets in Theatre",
  1344. "162": "Complaints regarding Cleanliness of Toilets in Shopping Complex",
  1345. "163": "Building Plan Sanction",
  1346. "164": "Violation of DCR/Building By laws",
  1347. "165": "Unauthorized / Illegal Construction",
  1348. "166": "Complaints related to Property Tax",
  1349. "167": "Complaints related to Professional Tax",
  1350. "168": "Complaints related to Trade Licence",
  1351. "174": "Name Error (Spelling Related)",
  1352. "175": "Change of Address in Electoral Roll",
  1353. "176": "Issue of Voter ID",
  1354. "177": "Inclusion, Deletion, Correction in Voter List",
  1355. "178": "Complaints regarding Voter List",
  1356. "179": "Name not found in the Electoral Roll",
  1357. "180": "Issue of Birth and Death Certificate",
  1358. "181": "Encroachment on the Public Property",
  1359. "182": " Complaints related to Schools",
  1360. "183": "Sanction of Financial Assistance under Moovalaur Thirumana Thittam",
  1361. "184": "Complaints related to issue of all types of Registration Certificate",
  1362. "185": "Slow Progress of Work",
  1363. "186": "Poor Quality of Work",
  1364. "187": "Unauthorized Advertisement Boards",
  1365. "188": "Complaints regarding Bridges / Flyovers / Subways",
  1366. "189": "Complaints related Shopping Complex",
  1367. "190": "Complaints regarding Community Hall",
  1368. "191": "Complaints regarding Burial Ground",
  1369. "192": "Complaints regarding any other CoC building",
  1370. "193": "Parking Issue",
  1371. "195": "Complaints Regarding Plastics",
  1372. "196": "No electricity in public toilet",
  1373. "197": "No water supply in public toilet",
  1374. "198": "Public toilet blockage",
  1375. "199": "Public toilet cleaning",
  1376. "200": "Burning of street light in daytime",
  1377. "201": "Illegal Parking on foot path",
  1378. "202": "Complaints regarding non availability of Doctors",
  1379. "203": "Complaints regarding non availability of medicines",
  1380. "204": "Complaints regarding laboratory issues",
  1381. "205": "Issues regarding amma baby care kits (After Delivery)",
  1382. "206": "Issues regarding Amma nutrition kit for pregnant woman",
  1383. "207": "Issues regarding Muthulakshmi Reddy Maternity Benefit Scheme (MRMBS)",
  1384. "208": "Issues regarding janani suraksha yojana scheme (JSY)",
  1385. "209": "Travel pass related complaints",
  1386. "210": "Food related complaints",
  1387. "212": "Covid Health Related Queries",
  1388. "213": "Hospital and Covid care centre(CCC) Related Queries",
  1389. "214": "Medical Emergencies",
  1390. "215": "Essentials and Medicines",
  1391. "216": "PSYCHO-SOCIO support",
  1392. "218": "Quarantine and isolation Related Queries",
  1393. "219": "General Health Queries",
  1394. "220": "Disinfection request",
  1395. "221": "Non Covid Health Related Queries",
  1396. "222": "Milling/Scraping of Road before Relaying of Road",
  1397. "226": "Food Requirement",
  1398. "227": "Relief Center Requirement",
  1399. "228": "Covid19 Ambulance Service",
  1400. "229": "Air Quality",
  1401. "230": "Online Payment Issue",
  1402. "231": "General Revision Objection",
  1403. "232": "Water Mixed with Sewarage",
  1404. "233": "Sewerage Overflow",
  1405. "234": "Drinking water supply",
  1406. "235": "Electricity Shock",
  1407. "236": "Electricity Unavailability",
  1408. "237": "Insufficient Barricading",
  1409. "238": "Fallen poles/towers/hoardings/other infra",
  1410. "239": "Fallen EB cables",
  1411. "240": "Project information not provided (Thiruvotriyur High Road)",
  1412. "241": "Project information not provided (Arunachaleshwar Road)",
  1413. "242": "Project information not provided (MC Road)",
  1414. "243": "Project information not provided (Washermenpet Metro)",
  1415. "244": "Project information not provided (Khadar Nawas Khan Road)",
  1416. "245": "Project information not provided (Race Course road + Guindy MMI)",
  1417. "246": "Advance information on consultation not provided (Thiruvotriyur High Road)",
  1418. "247": "Advance information on consultation not provided (Arunachaleshwar Road)",
  1419. "248": "Advance information on consultation not provided (MC Road)",
  1420. "249": "Advance information on consultation not provided (Washermenpet Metro)",
  1421. "250": "Advance information on consultation not provided (Khadar Nawas Khan Road)",
  1422. "251": "Advance information on consultation not provided (Race Course road + Guindy MMI)",
  1423. "252": "Location and area of consultation not provided (Thiruvotriyur High Road)",
  1424. "253": "Location and area of consultation not provided (Arunachaleshwar Road)",
  1425. "254": "Location and area of consultation not provided (MC Road)",
  1426. "255": "Location and area of consultation not provided (Washermenpet Metro)",
  1427. "256": "Location and area of consultation not provided (Khadar Nawas Khan Road)",
  1428. "257": "Location and area of consultation not provided (Race Course road + Guindy MMI)",
  1429. "258": "Information on detailed work plan not provided (Thiruvotriyur High Road)",
  1430. "259": "Information on detailed work plan not provided (Arunachaleshwar Road)",
  1431. "260": "Information on detailed work plan not provided (MC Road)",
  1432. "261": "Information on detailed work plan not provided (Washermenpet Metro)",
  1433. "262": "Information on detailed work plan not provided (Khadar Nawas Khan Road)",
  1434. "263": "Information on detailed work plan not provided (Race Course road + Guindy MMI)",
  1435. "264": "Others (Thiruvotriyur High Road)",
  1436. "265": "Others (Arunachaleshwar Road)",
  1437. "266": "Others (MC Road)",
  1438. "267": "Others (Washermenpet Metro)",
  1439. "268": "Others (Khadar Nawas Khan Road)",
  1440. "269": "Others (Race Course road + Guindy MMI)",
  1441. "270": "No information in advance provided on the date and time of civil works (Thiruvotriyur High Road)",
  1442. "271": "No information in advance provided on the date and time of civil works (Arunachaleshwar Road)",
  1443. "272": "No information in advance provided on the date and time of civil works (MC Road)",
  1444. "273": "No information in advance provided on the date and time of civil works (Washermenpet Metro)",
  1445. "274": "No information in advance provided on the date and time of civil works (Khadar Nawas Khan Road)",
  1446. "275": "No information in advance provided on the date and time of civil works (Race Course road + Guindy MMI)",
  1447. "276": "No information provided on the nature and schedule of civil work (Thiruvotriyur High Road)",
  1448. "277": "No information provided on the nature and schedule of civil work (Arunachaleshwar Road)",
  1449. "278": "No information provided on the nature and schedule of civil work (MC Road)",
  1450. "279": "No information provided on the nature and schedule of civil work (Washermenpet Metro)",
  1451. "280": "No information provided on the nature and schedule of civil work (Khadar Nawas Khan Road)",
  1452. "281": "No information provided on the nature and schedule of civil work (Race Course road + Guindy MMI)",
  1453. "282": "No consultation carried out with the people affected by the civil works (Thiruvotriyur High Road)",
  1454. "283": "No consultation carried out with the people affected by the civil works (Arunachaleshwar Road)",
  1455. "284": "No consultation carried out with the people affected by the civil works (MC Road)",
  1456. "285": "No consultation carried out with the people affected by the civil works (Washermenpet Metro)",
  1457. "286": "No consultation carried out with the people affected by the civil works (Khadar Nawas Khan Road)",
  1458. "287": "No consultation carried out with the people affected by the civil works (Race Course road + Guindy MMI)",
  1459. "288": "No arrangement made for temporary displacement (Thiruvotriyur High Road)",
  1460. "289": "No arrangement made for temporary displacement (Arunachaleshwar Road)",
  1461. "290": "No arrangement made for temporary displacement (MC Road)",
  1462. "291": "No arrangement made for temporary displacement (Washermenpet Metro)",
  1463. "292": "No arrangement made for temporary displacement (Khadar Nawas Khan Road)",
  1464. "293": "No arrangement made for temporary displacement (Race Course road + Guindy MMI)",
  1465. "294": "No display board on the project installed at work site (Thiruvotriyur High Road)",
  1466. "295": "No display board on the project installed at work site (Arunachaleshwar Road)",
  1467. "296": "No display board on the project installed at work site (MC Road)",
  1468. "297": "No display board on the project installed at work site (Washermenpet Metro)",
  1469. "298": "No display board on the project installed at work site (Khadar Nawas Khan Road)",
  1470. "299": "No display board on the project installed at work site (Race Course road + Guindy MMI)",
  1471. "300": "Temporary access to structures not provided and or not adequate (Thiruvotriyur High Road)",
  1472. "301": "Temporary access to structures not provided and or not adequate (Arunachaleshwar Road)",
  1473. "302": "Temporary access to structures not provided and or not adequate (MC Road)",
  1474. "303": "Temporary access to structures not provided and or not adequate (Washermenpet Metro)",
  1475. "304": "Temporary access to structures not provided and or not adequate (Khadar Nawas Khan Road)",
  1476. "305": "Temporary access to structures not provided and or not adequate (Race Course road + Guindy MMI)",
  1477. "306": "No safety measures taken at worksite (Thiruvotriyur High Road)",
  1478. "307": "No safety measures taken at worksite (Arunachaleshwar Road)",
  1479. "308": "No safety measures taken at worksite (MC Road)",
  1480. "309": "No safety measures taken at worksite (Washermenpet Metro)",
  1481. "310": "No safety measures taken at worksite (Khadar Nawas Khan Road)",
  1482. "311": "No safety measures taken at worksite (Race Course road + Guindy MMI)",
  1483. "312": "Water supply disrupted and alternate arrangement not provided (Thiruvotriyur High Road)",
  1484. "313": "Water supply disrupted and alternate arrangement not provided (Arunachaleshwar Road)",
  1485. "314": "Water supply disrupted and alternate arrangement not provided (MC Road)",
  1486. "315": "Water supply disrupted and alternate arrangement not provided (Washermenpet Metro)",
  1487. "316": "Water supply disrupted and alternate arrangement not provided (Khadar Nawas Khan Road)",
  1488. "317": "Water supply disrupted and alternate arrangement not provided (Race Course road + Guindy MMI)",
  1489. "318": "Electricity supply disrupted and alternate arrangement not provided (Thiruvotriyur High Road)",
  1490. "319": "Electricity supply disrupted and alternate arrangement not provided (Arunachaleshwar Road)",
  1491. "320": "Electricity supply disrupted and alternate arrangement not provided (MC Road)",
  1492. "321": "Electricity supply disrupted and alternate arrangement not provided (Washermenpet Metro)",
  1493. "322": "Electricity supply disrupted and alternate arrangement not provided (Khadar Nawas Khan Road)",
  1494. "323": "Electricity supply disrupted and alternate arrangement not provided (Race Course road + Guindy MMI)",
  1495. "324": "Disposal of debris not appropriately managed (Thiruvotriyur High Road)",
  1496. "325": "Disposal of debris not appropriately managed (Arunachaleshwar Road)",
  1497. "326": "Disposal of debris not appropriately managed (MC Road)",
  1498. "327": "Disposal of debris not appropriately managed (Washermenpet Metro)",
  1499. "328": "Disposal of debris not appropriately managed (Khadar Nawas Khan Road)",
  1500. "329": "Disposal of debris not appropriately managed (Race Course road + Guindy MMI)",
  1501. "330": " Temporary arrangement for parking not provided (Thiruvotriyur High Road)",
  1502. "331": " Temporary arrangement for parking not provided (Arunachaleshwar Road)",
  1503. "332": " Temporary arrangement for parking not provided (MC Road)",
  1504. "333": " Temporary arrangement for parking not provided (Washermenpet Metro)",
  1505. "334": " Temporary arrangement for parking not provided (Khadar Nawas Khan Road)",
  1506. "335": " Temporary arrangement for parking not provided (Race Course road + Guindy MMI)",
  1507. "336": "GRM and helpline numbers not displayed at worksite (Thiruvotriyur High Road)",
  1508. "337": "GRM and helpline numbers not displayed at worksite (Arunachaleshwar Road)",
  1509. "338": "GRM and helpline numbers not displayed at worksite (MC Road)",
  1510. "339": "GRM and helpline numbers not displayed at worksite (Washermenpet Metro)",
  1511. "340": "GRM and helpline numbers not displayed at worksite (Khadar Nawas Khan Road)",
  1512. "341": "GRM and helpline numbers not displayed at worksite (Race Course road + Guindy MMI)",
  1513. "342": "Drinking water/ other basic needs for Labour not available at worksite (Thiruvotriyur High Road)",
  1514. "343": "Drinking water/ other basic needs for Labour not available at worksite (Arunachaleshwar Road)",
  1515. "344": "Drinking water/ other basic needs for Labour not available at worksite (MC Road)",
  1516. "345": "Drinking water/ other basic needs for Labour not available at worksite (Washermenpet Metro)",
  1517. "346": "Drinking water/ other basic needs for Labour not available at worksite (Khadar Nawas Khan Road)",
  1518. "347": "Drinking water/ other basic needs for Labour not available at worksite (Race Course road + Guindy MMI)",
  1519. "348": "Noise levels are very high (Thiruvotriyur High Road)",
  1520. "349": "Noise levels are very high (Arunachaleshwar Road)",
  1521. "350": "Noise levels are very high (MC Road)",
  1522. "351": "Noise levels are very high (Washermenpet Metro)",
  1523. "352": "Noise levels are very high (Khadar Nawas Khan Road)",
  1524. "353": "Noise levels are very high (Race Course road + Guindy MMI)",
  1525. "354": " Sprinkling of water at worksite not carried out (Thiruvotriyur High Road)",
  1526. "355": " Sprinkling of water at worksite not carried out (Arunachaleshwar Road)",
  1527. "356": " Sprinkling of water at worksite not carried out (MC Road)",
  1528. "357": " Sprinkling of water at worksite not carried out (Washermenpet Metro)",
  1529. "358": " Sprinkling of water at worksite not carried out (Khadar Nawas Khan Road)",
  1530. "359": " Sprinkling of water at worksite not carried out (Race Course road + Guindy MMI)",
  1531. "360": "The worksite is not barricaded; (Thiruvotriyur High Road)",
  1532. "361": "The worksite is not barricaded; (Arunachaleshwar Road)",
  1533. "362": "The worksite is not barricaded; (MC Road)",
  1534. "363": "The worksite is not barricaded; (Washermenpet Metro)",
  1535. "364": "The worksite is not barricaded; (Khadar Nawas Khan Road)",
  1536. "365": "The worksite is not barricaded; (Race Course road + Guindy MMI)",
  1537. "366": " No information on number of labour working at the site (Thiruvotriyur High Road)",
  1538. "367": " No information on number of labour working at the site (Arunachaleshwar Road)",
  1539. "368": " No information on number of labour working at the site (MC Road)",
  1540. "369": " No information on number of labour working at the site (Washermenpet Metro)",
  1541. "370": " No information on number of labour working at the site (Khadar Nawas Khan Road)",
  1542. "371": " No information on number of labour working at the site (Race Course road + Guindy MMI)",
  1543. "372": "Labourer not using the safety equipment (Thiruvotriyur High Road)",
  1544. "373": "Labourer not using the safety equipment (Arunachaleshwar Road)",
  1545. "374": "Labourer not using the safety equipment (MC Road)",
  1546. "375": "Labourer not using the safety equipment (Washermenpet Metro)",
  1547. "376": "Labourer not using the safety equipment (Khadar Nawas Khan Road)",
  1548. "377": "Labourer not using the safety equipment (Race Course road + Guindy MMI)",
  1549. "378": "Sewerage pipe is damaged (Thiruvotriyur High Road)",
  1550. "379": "Sewerage pipe is damaged (Arunachaleshwar Road)",
  1551. "380": "Sewerage pipe is damaged (MC Road)",
  1552. "381": "Sewerage pipe is damaged (Washermenpet Metro)",
  1553. "382": "Sewerage pipe is damaged (Khadar Nawas Khan Road)",
  1554. "383": "Sewerage pipe is damaged (Race Course road + Guindy MMI)",
  1555. "384": "Others (Thiruvotriyur High Road)",
  1556. "385": "Others (Arunachaleshwar Road)",
  1557. "386": "Others (MC Road)",
  1558. "387": "Others (Washermenpet Metro)",
  1559. "388": "Others (Khadar Nawas Khan Road)",
  1560. "389": "Others (Race Course road + Guindy MMI)",
  1561. "390": "Insufficient Barricading (Thiruvotriyur High Road)",
  1562. "391": "Insufficient Barricading (Arunachaleshwar Road)",
  1563. "392": "Insufficient Barricading (MC Road)",
  1564. "393": "Insufficient Barricading (Washermenpet Metro)",
  1565. "394": "Insufficient Barricading (Khadar Nawas Khan Road)",
  1566. "395": "Insufficient Barricading (Race Course road + Guindy MMI)",
  1567. "396": "Non Removal of Debris (Thiruvotriyur High Road)",
  1568. "397": "Non Removal of Debris (Arunachaleshwar Road)",
  1569. "398": "Non Removal of Debris (MC Road)",
  1570. "399": "Non Removal of Debris (Washermenpet Metro)",
  1571. "400": "Non Removal of Debris (Khadar Nawas Khan Road)",
  1572. "401": "Non Removal of Debris (Race Course road + Guindy MMI)",
  1573. "402": "Potholes fill up (Thiruvotriyur High Road)",
  1574. "403": "Potholes fill up (Arunachaleshwar Road)",
  1575. "404": "Potholes fill up (MC Road)",
  1576. "405": "Potholes fill up (Washermenpet Metro)",
  1577. "406": "Potholes fill up (Khadar Nawas Khan Road)",
  1578. "407": "Potholes fill up (Race Course road + Guindy MMI)",
  1579. "408": "Damage to utilities (TNEB, CMWSSB, BSNL) (Thiruvotriyur High Road)",
  1580. "409": "Damage to utilities (TNEB, CMWSSB, BSNL) (Arunachaleshwar Road)",
  1581. "410": "Damage to utilities (TNEB, CMWSSB, BSNL) (MC Road)",
  1582. "411": "Damage to utilities (TNEB, CMWSSB, BSNL) (Washermenpet Metro)",
  1583. "412": "Damage to utilities (TNEB, CMWSSB, BSNL) (Khadar Nawas Khan Road)",
  1584. "413": "Damage to utilities (TNEB, CMWSSB, BSNL) (Race Course road + Guindy MMI)",
  1585. "414": "Encroaching Public Space (Thiruvotriyur High Road)",
  1586. "415": "Encroaching Public Space (Arunachaleshwar Road)",
  1587. "416": "Encroaching Public Space (MC Road)",
  1588. "417": "Encroaching Public Space (Washermenpet Metro)",
  1589. "418": "Encroaching Public Space (Khadar Nawas Khan Road)",
  1590. "419": "Encroaching Public Space (Race Course road + Guindy MMI)",
  1591. "420": "Need Pathway ramp (Thiruvotriyur High Road)",
  1592. "421": "Need Pathway ramp (Arunachaleshwar Road)",
  1593. "422": "Need Pathway ramp (MC Road)",
  1594. "423": "Need Pathway ramp (Washermenpet Metro)",
  1595. "424": "Need Pathway ramp (Khadar Nawas Khan Road)",
  1596. "425": "Need Pathway ramp (Race Course road + Guindy MMI)",
  1597. "426": "Cleanliness in Parks",
  1598. "427": "Greenary in Parks",
  1599. "428": "Play Equipment",
  1600. "429": "Opening and closing hours",
  1601. "430": "Toilets in parks",
  1602. "431": "Non functional lights/ no lights in parks",
  1603. "432": "Safety in parks/playgrounds",
  1604. "433": "Women related safety issues in parks",
  1605. "434": "Availability or cleanliness of dustbins in public toilets",
  1606. "435": "Cleanliness/ water supply in toilets",
  1607. "436": "Broken sinks, toilets or urinals and doors",
  1608. "437": "Request for new toilet",
  1609. "438": "Illegal activities in toilet",
  1610. "439": "Toilets not in use/ closed",
  1611. "440": "Inadequate lighting in and around the toilet",
  1612. "441": "Safety in public toilets",
  1613. "442": "Cleanliness in footpath",
  1614. "443": "Electrical wires/obstruction on footpath",
  1615. "444": "Unsafe dark spots/ corners",
  1616. "445": "Public defecation/urination",
  1617. "446": "Women related safety issues ",
  1618. "447": "Inadequate light in a particular location or spot/ dark spots",
  1619. };
  1620. $('#nextStep3').off('click').on('click', function (e) {
  1621. e.preventDefault();
  1622. //const complaint_Title = $('#complaint-title').val().trim();
  1623. const complaint_Type = $('#complaint-id').val();
  1624. if (!complaint_Type) {
  1625. Swal.fire({
  1626. icon: 'warning',
  1627. title: 'Missing Information',
  1628. text: 'Please Select Complaint Type.',
  1629. confirmButtonText: 'OK'
  1630. });
  1631. return; // Stop further execution
  1632. }
  1633. const shareMobile = $('input[name="shareMobile"]:checked').val();
  1634. const mobileNo = $('#mobileNo').val().trim();
  1635. const streetName = $('#streetName option:selected').text().trim().toLowerCase();
  1636. if (shareMobile === 'no' || mobileNo === '') {
  1637. nextStep(); // Skip duplicate check if mobile not shared
  1638. return;
  1639. }
  1640. let complaintId = '';
  1641. let complaintTitle = '';
  1642. if ($('#specific-fields').hasClass('active')) {
  1643. complaintId = $('#complaint-id').val().trim();
  1644. complaintTitle = complaintTypeMap[complaintId] || "Selected complaint";
  1645. } else if ($('#others-fields').hasClass('active')) {
  1646. console.log("other fields...");
  1647. complaintId = $('#sub-type option:selected').val().trim(); // ✅ send ID
  1648. console.log("complaintId... "+complaintId);
  1649. //complaintId = $('#sub-type').val().trim(); // ✅ send ID
  1650. complaintTitle = $('#sub-type option:selected').text().trim(); // readable for alert
  1651. }
  1652. console.log("Checking for duplicate:", { complaintId, complaintTitle, streetName });
  1653. const backendUrl = `/gcc/api/callcenterqaqc/pgrcomplaint/checktypeforduplicate?mobileNo=${mobileNo}&complaintId=${complaintId}&streetName=${encodeURIComponent(streetName)}`;
  1654. $.get(backendUrl, function (response) {
  1655. if (response.duplicate) {
  1656. Swal.fire({
  1657. icon: 'warning',
  1658. title: 'Duplicate Complaint Found',
  1659. text: `A similar complaint like "${complaintTitle}" already exists for this street within the last 7 days.`,
  1660. confirmButtonText: 'OK',
  1661. allowOutsideClick: false
  1662. }).then(() => {
  1663. location.reload();
  1664. });
  1665. } else {
  1666. nextStep();
  1667. }
  1668. }).fail(function () {
  1669. Swal.fire({
  1670. icon: 'error',
  1671. title: 'Error',
  1672. text: 'Could not verify for duplicate complaints. Please try again.'
  1673. });
  1674. });
  1675. });
  1676. });
  1677. /* html: `Your complaint has been submitted successfully. Your Complaint Number is <strong>${complaintNumber}</strong>. It will be sent to your mobile number.`, */
  1678. </script>
  1679. </body>
  1680. </html>