7 changed files with 3013 additions and 4 deletions
-
89gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/childrensurvey/Controller/ChildrenSurveyController.java
-
26gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/childrensurvey/Controller/MainController.java
-
853gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/childrensurvey/Service/ChildrenSurveyService.java
-
10gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java
-
527gcc_officer_portal/src/main/resources/templates/modules/childrensurvey/childlist.html
-
836gcc_officer_portal/src/main/resources/templates/modules/childrensurvey/surveylist.html
-
668gcc_officer_portal/src/main/resources/templates/modules/childrensurvey/surveyorsreports.html
@ -0,0 +1,89 @@ |
|||
package in.gov.chennaicorporation.gccoffice.childrensurvey.Controller; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RequestParam; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import in.gov.chennaicorporation.gccoffice.childrensurvey.Service.ChildrenSurveyService; |
|||
|
|||
@RestController |
|||
@RequestMapping("/gcc/api/children-survey") |
|||
public class ChildrenSurveyController { |
|||
|
|||
@Autowired |
|||
private ChildrenSurveyService service; |
|||
|
|||
@GetMapping("/gender") |
|||
public List<Map<String, Object>> getGender() { |
|||
return service.getGender(); |
|||
} |
|||
|
|||
@GetMapping("/location") |
|||
public List<Map<String, Object>> getLocation() { |
|||
return service.getLocation(); |
|||
} |
|||
|
|||
@GetMapping("/education") |
|||
public List<Map<String, Object>> getEducation() { |
|||
return service.getEducation(); |
|||
} |
|||
|
|||
@GetMapping("/list") |
|||
public List<Map<String, Object>> getSurveyList( |
|||
@RequestParam(required = false) String name, |
|||
@RequestParam(required = false) String gender, |
|||
@RequestParam(required = false) String age, |
|||
@RequestParam(required = false) String area, |
|||
@RequestParam(required = false) String education, |
|||
@RequestParam(required = false) String fromDate, |
|||
@RequestParam(required = false) String toDate) { |
|||
return service.getSurveyList(name, gender, age, area, education, fromDate, toDate); |
|||
} |
|||
|
|||
@GetMapping("/details") |
|||
public Map<String, Object> getSurveyDetails( |
|||
@RequestParam String surveyId) { |
|||
return service.getSurveyDetails(surveyId); |
|||
} |
|||
|
|||
@GetMapping("/getSurveyorsList") |
|||
@ResponseBody |
|||
public List<Map<String, Object>> getSurveyorsList( |
|||
|
|||
@RequestParam(required = false) String name, |
|||
@RequestParam(required = false) String area, |
|||
@RequestParam(required = false) String fromDate, |
|||
@RequestParam(required = false) String toDate) { |
|||
|
|||
return service.getSurveyorsList( |
|||
name, |
|||
area, |
|||
fromDate, |
|||
toDate); |
|||
} |
|||
|
|||
@GetMapping("/survey-breakup") |
|||
@ResponseBody |
|||
public List<Map<String, Object>> getSurveyBreakup( |
|||
|
|||
@RequestParam(required = false) String loginId, |
|||
@RequestParam(required = false) String locationId, |
|||
@RequestParam(required = false) String surveyDate) { |
|||
|
|||
return service.getSurveyBreakup(loginId, locationId, surveyDate); |
|||
} |
|||
|
|||
@GetMapping("/dashboard") |
|||
public Map<String, Object> dashboard() { |
|||
|
|||
return service.getDashboardData(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
package in.gov.chennaicorporation.gccoffice.childrensurvey.Controller; |
|||
|
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
|
|||
@Controller("ChildrenSurveyController") |
|||
@RequestMapping("/gcc/childrensurvey") |
|||
public class MainController { |
|||
|
|||
@GetMapping("/surveylist") |
|||
public String surveylist() { |
|||
return "modules/childrensurvey/surveylist"; |
|||
} |
|||
|
|||
@GetMapping("/childlist") |
|||
public String childlist() { |
|||
return "modules/childrensurvey/childlist"; |
|||
} |
|||
|
|||
@GetMapping("/surveyorsreports") |
|||
public String surveyorsreports() { |
|||
return "modules/childrensurvey/surveyorsreports"; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,853 @@ |
|||
package in.gov.chennaicorporation.gccoffice.childrensurvey.Service; |
|||
|
|||
import java.nio.file.Path; |
|||
import java.sql.PreparedStatement; |
|||
import java.sql.Timestamp; |
|||
import java.time.LocalDate; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.Date; |
|||
import java.util.HashMap; |
|||
import java.util.LinkedHashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Objects; |
|||
import java.util.stream.Collectors; |
|||
import java.nio.file.Files; |
|||
import javax.sql.DataSource; |
|||
import java.nio.file.Paths; |
|||
import java.awt.image.BufferedImage; |
|||
import javax.imageio.ImageIO; |
|||
import java.io.ByteArrayInputStream; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Qualifier; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.core.env.Environment; |
|||
import org.springframework.dao.DataAccessException; |
|||
import org.springframework.dao.EmptyResultDataAccessException; |
|||
import org.springframework.jdbc.core.JdbcTemplate; |
|||
import org.springframework.jdbc.support.GeneratedKeyHolder; |
|||
import org.springframework.jdbc.support.KeyHolder; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
import java.io.ByteArrayOutputStream; |
|||
import java.io.IOException; |
|||
import javax.imageio.ImageWriteParam; |
|||
import javax.imageio.ImageWriter; |
|||
import javax.imageio.stream.ImageOutputStream; |
|||
import java.sql.Statement; |
|||
import in.gov.chennaicorporation.gccoffice.controller.DateTimeUtil; |
|||
import in.gov.chennaicorporation.gccoffice.nulm.repository.NulmRepository; |
|||
|
|||
@Service |
|||
public class ChildrenSurveyService { |
|||
|
|||
@Autowired |
|||
private JdbcTemplate jdbcTemplate; |
|||
|
|||
@Autowired |
|||
public void setDataSource(@Qualifier("mysqlChildrenSurveyDataSource") DataSource dataSource) { |
|||
this.jdbcTemplate = new JdbcTemplate(dataSource); |
|||
} |
|||
|
|||
public List<Map<String, Object>> getGender() { |
|||
|
|||
String sql = "SELECT id, english_name FROM gender_master"; |
|||
|
|||
return jdbcTemplate.queryForList(sql); |
|||
} |
|||
|
|||
public List<Map<String, Object>> getLocation() { |
|||
return jdbcTemplate.queryForList( |
|||
"SELECT id, english_name FROM location_master"); |
|||
} |
|||
|
|||
public List<Map<String, Object>> getEducation() { |
|||
return jdbcTemplate.queryForList( |
|||
"SELECT id, english_name FROM education_master"); |
|||
} |
|||
|
|||
public List<Map<String, Object>> getSurveyList( |
|||
String name, |
|||
String gender, |
|||
String age, |
|||
String area, |
|||
String education, |
|||
String fromDate, |
|||
String toDate) { |
|||
System.out.println("name: " + name); |
|||
System.out.println("gender: " + gender); |
|||
System.out.println("age: " + age); |
|||
System.out.println("area: " + area); |
|||
System.out.println("education: " + education); |
|||
System.out.println("fromDate: " + fromDate); |
|||
System.out.println("toDate: " + toDate); |
|||
|
|||
StringBuilder sql = new StringBuilder(""" |
|||
SELECT |
|||
csr.survey_id, |
|||
|
|||
MAX(CASE WHEN cqm.field_name = 'q6' THEN csr.answer END) AS child_name, |
|||
MAX(CASE WHEN cqm.field_name = 'q7' THEN gm.english_name END) AS gender, |
|||
MAX(CASE WHEN cqm.field_name = 'q10' THEN csr.answer END) AS age, |
|||
MAX(CASE WHEN cqm.field_name = 'q24' THEN csr.answer END) AS mobile_number, |
|||
MAX(CASE WHEN cqm.field_name = 'q1' THEN lm.english_name END) AS area, |
|||
MAX(CASE WHEN cqm.field_name = 'q25' THEN em.english_name END) AS education, |
|||
MAX(csr.cby) AS cby, |
|||
DATE(MAX(csr.cdate)) AS survey_date |
|||
|
|||
FROM child_survey_response csr |
|||
|
|||
INNER JOIN child_survey_questions_master cqm |
|||
ON csr.qid = cqm.qid |
|||
|
|||
LEFT JOIN gender_master gm |
|||
ON gm.id = csr.answer AND cqm.field_name = 'q7' |
|||
|
|||
LEFT JOIN location_master lm |
|||
ON lm.id = csr.answer AND cqm.field_name = 'q1' |
|||
|
|||
LEFT JOIN education_master em |
|||
ON em.id = csr.answer AND cqm.field_name = 'q25' |
|||
|
|||
WHERE csr.isactive = 1 |
|||
AND csr.isdelete = 0 |
|||
"""); |
|||
|
|||
List<Object> params = new ArrayList<>(); |
|||
|
|||
// 🔍 NAME |
|||
if (name != null && !name.isEmpty()) { |
|||
sql.append( |
|||
" AND csr.survey_id IN (SELECT survey_id FROM child_survey_response WHERE answer LIKE ?)"); |
|||
params.add("%" + name + "%"); |
|||
} |
|||
|
|||
// 🔍 GENDER |
|||
if (gender != null && !gender.isEmpty()) { |
|||
sql.append( |
|||
" AND csr.survey_id IN (SELECT survey_id FROM child_survey_response WHERE qid = 7 AND answer = ?)"); |
|||
params.add(gender); |
|||
} |
|||
|
|||
// 🔍 AREA |
|||
if (area != null && !area.isEmpty()) { |
|||
sql.append( |
|||
" AND csr.survey_id IN (SELECT survey_id FROM child_survey_response WHERE qid = 1 AND answer = ?)"); |
|||
params.add(area); |
|||
} |
|||
|
|||
// 🔍 EDUCATION |
|||
if (education != null && !education.isEmpty()) { |
|||
sql.append( |
|||
" AND csr.survey_id IN (SELECT survey_id FROM child_survey_response WHERE qid = 25 AND answer = ?)"); |
|||
params.add(education); |
|||
} |
|||
|
|||
// 🔍 AGE RANGE |
|||
if (age != null && !age.isEmpty()) { |
|||
|
|||
String[] range = age.split("-"); |
|||
|
|||
sql.append(""" |
|||
AND csr.survey_id IN ( |
|||
SELECT survey_id |
|||
FROM child_survey_response |
|||
WHERE qid = 10 |
|||
AND CAST(answer AS UNSIGNED) BETWEEN ? AND ? |
|||
) |
|||
"""); |
|||
|
|||
params.add(Integer.parseInt(range[0])); |
|||
params.add(Integer.parseInt(range[1])); |
|||
} |
|||
|
|||
// 🔍 DATE FILTER |
|||
if (fromDate != null && toDate != null && !fromDate.isEmpty() && !toDate.isEmpty()) { |
|||
sql.append(" AND DATE(csr.cdate) BETWEEN ? AND ?"); |
|||
params.add(fromDate); |
|||
params.add(toDate); |
|||
} |
|||
|
|||
sql.append(" GROUP BY csr.survey_id ORDER BY MAX(csr.cdate) DESC"); |
|||
|
|||
return jdbcTemplate.queryForList(sql.toString(), params.toArray()); |
|||
} |
|||
|
|||
public Map<String, Object> getSurveyDetails(String surveyId) { |
|||
|
|||
String sql = """ |
|||
SELECT |
|||
csr.qid, |
|||
csr.answer, |
|||
csr.others_answer, |
|||
csr.cby, |
|||
csr.survey_id, |
|||
|
|||
cqm.q_english, |
|||
cqm.question_type, |
|||
cqm.master_table_name, |
|||
cqm.field_name |
|||
|
|||
FROM child_survey_response csr |
|||
|
|||
INNER JOIN child_survey_questions_master cqm |
|||
ON csr.qid = cqm.qid |
|||
|
|||
WHERE csr.isactive = 1 |
|||
AND csr.isdelete = 0 |
|||
AND csr.survey_id = ? |
|||
|
|||
ORDER BY cqm.orderby |
|||
"""; |
|||
|
|||
List<Map<String, Object>> responseList = jdbcTemplate.queryForList(sql, surveyId); |
|||
|
|||
Map<String, Object> finalResponse = new LinkedHashMap<>(); |
|||
|
|||
for (Map<String, Object> row : responseList) { |
|||
|
|||
String question = row.get("q_english") != null |
|||
? row.get("q_english").toString() |
|||
: ""; |
|||
|
|||
String questionType = row.get("question_type") != null |
|||
? row.get("question_type").toString() |
|||
: ""; |
|||
|
|||
String masterTable = row.get("master_table_name") != null |
|||
? row.get("master_table_name").toString() |
|||
: ""; |
|||
|
|||
String rawAnswer = row.get("answer") != null |
|||
? row.get("answer").toString() |
|||
: ""; |
|||
|
|||
String finalAnswer = resolveAnswer( |
|||
questionType, |
|||
masterTable, |
|||
rawAnswer); |
|||
|
|||
finalResponse.put(question, finalAnswer); |
|||
} |
|||
|
|||
return finalResponse; |
|||
} |
|||
|
|||
// ========================================= |
|||
// ANSWER RESOLVER |
|||
// ========================================= |
|||
|
|||
private String resolveAnswer( |
|||
String questionType, |
|||
String masterTable, |
|||
String rawAnswer) { |
|||
|
|||
try { |
|||
|
|||
if (rawAnswer == null || rawAnswer.isEmpty()) { |
|||
return ""; |
|||
} |
|||
|
|||
// TEXT |
|||
if ("text".equalsIgnoreCase(questionType) |
|||
|| "textarea".equalsIgnoreCase(questionType) |
|||
|| "number".equalsIgnoreCase(questionType)) { |
|||
|
|||
return rawAnswer; |
|||
} |
|||
|
|||
// RADIO |
|||
if ("radio".equalsIgnoreCase(questionType)) { |
|||
|
|||
String sql = """ |
|||
SELECT english_name |
|||
FROM child_survey_answer_master |
|||
WHERE aid = ? |
|||
"""; |
|||
|
|||
return jdbcTemplate.queryForObject( |
|||
sql, |
|||
String.class, |
|||
Integer.parseInt(rawAnswer)); |
|||
} |
|||
|
|||
// MULTICHECK |
|||
if ("multicheck".equalsIgnoreCase(questionType)) { |
|||
|
|||
String[] ids = rawAnswer.split(","); |
|||
|
|||
List<String> values = new ArrayList<>(); |
|||
|
|||
String sql = """ |
|||
SELECT english_name |
|||
FROM child_survey_answer_master |
|||
WHERE aid = ? |
|||
"""; |
|||
|
|||
for (String id : ids) { |
|||
|
|||
String value = jdbcTemplate.queryForObject( |
|||
sql, |
|||
String.class, |
|||
Integer.parseInt(id.trim())); |
|||
|
|||
values.add(value); |
|||
} |
|||
|
|||
return String.join(", ", values); |
|||
} |
|||
|
|||
// DROPDOWN |
|||
if (masterTable != null |
|||
&& !masterTable.isEmpty()) { |
|||
|
|||
String dynamicSql = "SELECT english_name FROM " |
|||
+ masterTable |
|||
+ " WHERE id = ?"; |
|||
|
|||
return jdbcTemplate.queryForObject( |
|||
dynamicSql, |
|||
String.class, |
|||
Integer.parseInt(rawAnswer)); |
|||
} |
|||
|
|||
} catch (Exception e) { |
|||
|
|||
e.printStackTrace(); |
|||
} |
|||
|
|||
return rawAnswer; |
|||
} |
|||
|
|||
public List<Map<String, Object>> getSurveyorsList( |
|||
String name, |
|||
String area, |
|||
String fromDate, |
|||
String toDate) { |
|||
// ld.survey_id AS surveyor_id, |
|||
StringBuilder sql = new StringBuilder(""" |
|||
|
|||
SELECT |
|||
|
|||
|
|||
d.user_name, |
|||
d.mobile_no, |
|||
ld.loginId, |
|||
lm.id as location_id, |
|||
|
|||
|
|||
MAX(lm.english_name) AS area, |
|||
|
|||
COUNT(DISTINCT ld.survey_id) AS total_survey_done, |
|||
|
|||
DATE(MAX(sr.cdate)) AS survey_date |
|||
|
|||
FROM login_details d |
|||
|
|||
INNER JOIN surveyor_location_details ld |
|||
ON d.uid = ld.loginId |
|||
|
|||
INNER JOIN child_survey_response sr |
|||
ON sr.survey_id = ld.survey_id |
|||
|
|||
LEFT JOIN child_survey_response csr |
|||
ON csr.survey_id = ld.survey_id |
|||
AND csr.qid = 1 |
|||
|
|||
LEFT JOIN location_master lm |
|||
ON lm.id = csr.answer |
|||
|
|||
WHERE sr.isactive = 1 |
|||
AND sr.isdelete = 0 |
|||
|
|||
"""); |
|||
|
|||
List<Object> params = new ArrayList<>(); |
|||
|
|||
// NAME FILTER |
|||
if (name != null && !name.isEmpty()) { |
|||
|
|||
sql.append(""" |
|||
AND d.user_name LIKE ? |
|||
"""); |
|||
|
|||
params.add("%" + name + "%"); |
|||
} |
|||
|
|||
// AREA FILTER |
|||
if (area != null && !area.isEmpty()) { |
|||
|
|||
sql.append(""" |
|||
AND csr.answer = ? |
|||
"""); |
|||
|
|||
params.add(area); |
|||
} |
|||
|
|||
// DATE FILTER |
|||
if (fromDate != null |
|||
&& toDate != null |
|||
&& !fromDate.isEmpty() |
|||
&& !toDate.isEmpty()) { |
|||
|
|||
sql.append(""" |
|||
AND DATE(sr.cdate) BETWEEN ? AND ? |
|||
"""); |
|||
|
|||
params.add(fromDate); |
|||
params.add(toDate); |
|||
} |
|||
// ld.survey_id, |
|||
sql.append(""" |
|||
|
|||
GROUP BY |
|||
|
|||
d.user_name, |
|||
d.mobile_no, |
|||
ld.loginId, |
|||
lm.id |
|||
|
|||
ORDER BY |
|||
MAX(sr.cdate) DESC |
|||
|
|||
"""); |
|||
|
|||
return jdbcTemplate.queryForList( |
|||
sql.toString(), |
|||
params.toArray()); |
|||
} |
|||
|
|||
public List<Map<String, Object>> getSurveyBreakup(String loginId, String locationId, String surveyDate) { |
|||
System.out.println("......................................................."); |
|||
System.out.println(loginId + " " + locationId + " " + surveyDate); |
|||
System.out.println("......................................................."); |
|||
System.out.println("surveyDate=" + surveyDate); |
|||
System.out.println("locationId=" + locationId); |
|||
System.out.println("loginId=" + loginId); |
|||
String sql = """ |
|||
|
|||
SELECT |
|||
|
|||
sr.survey_id, |
|||
|
|||
MAX(CASE |
|||
WHEN cqm.field_name = 'q6' |
|||
THEN csr.answer |
|||
END) AS child_name, |
|||
|
|||
MAX(CASE |
|||
WHEN cqm.field_name = 'q7' |
|||
THEN gm.english_name |
|||
END) AS gender, |
|||
|
|||
MAX(CASE |
|||
WHEN cqm.field_name = 'q10' |
|||
THEN csr.answer |
|||
END) AS age, |
|||
|
|||
MAX(CASE |
|||
WHEN cqm.field_name = 'q24' |
|||
THEN csr.answer |
|||
END) AS mobile_number, |
|||
|
|||
MAX(CASE |
|||
WHEN cqm.field_name = 'q1' |
|||
THEN lm.english_name |
|||
END) AS area, |
|||
|
|||
MAX(CASE |
|||
WHEN cqm.field_name = 'q25' |
|||
THEN em.english_name |
|||
END) AS education, |
|||
|
|||
DATE(MAX(sr.cdate)) AS survey_date |
|||
|
|||
FROM surveyor_location_details sld |
|||
|
|||
INNER JOIN child_survey_response sr |
|||
ON sr.survey_id = sld.survey_id |
|||
|
|||
INNER JOIN child_survey_response csr |
|||
ON csr.survey_id = sr.survey_id |
|||
|
|||
INNER JOIN child_survey_questions_master cqm |
|||
ON cqm.qid = csr.qid |
|||
|
|||
LEFT JOIN gender_master gm |
|||
ON gm.id = csr.answer |
|||
AND cqm.field_name = 'q7' |
|||
|
|||
LEFT JOIN location_master lm |
|||
ON lm.id = csr.answer |
|||
AND cqm.field_name = 'q1' |
|||
|
|||
LEFT JOIN education_master em |
|||
ON em.id = csr.answer |
|||
AND cqm.field_name = 'q25' |
|||
|
|||
where sld.loginId = ? |
|||
AND sr.survey_id IN ( |
|||
|
|||
SELECT survey_id |
|||
FROM child_survey_response |
|||
WHERE qid = 1 |
|||
AND answer = ? |
|||
|
|||
|
|||
|
|||
) |
|||
and DATE(sr.cdate) = ? |
|||
|
|||
|
|||
AND sr.isactive = 1 |
|||
AND sr.isdelete = 0 |
|||
|
|||
GROUP BY sr.survey_id |
|||
|
|||
ORDER BY MAX(sr.cdate) DESC |
|||
|
|||
"""; |
|||
|
|||
return jdbcTemplate.queryForList(sql, loginId, locationId, surveyDate); |
|||
} |
|||
|
|||
// dashboard |
|||
|
|||
public Map<String, Object> getDashboardData() { |
|||
|
|||
Map<String, Object> response = new LinkedHashMap<>(); |
|||
|
|||
// TOTAL CHILDREN |
|||
|
|||
String totalSql = """ |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE isactive = 1 |
|||
AND isdelete = 0 |
|||
"""; |
|||
|
|||
Integer totalChildren = jdbcTemplate.queryForObject(totalSql, Integer.class); |
|||
|
|||
response.put("totalChildren", totalChildren); |
|||
|
|||
// AREAS COVERED |
|||
|
|||
String areaCountSql = """ |
|||
SELECT COUNT(*) |
|||
FROM location_master |
|||
"""; |
|||
|
|||
Integer areasCovered = jdbcTemplate.queryForObject(areaCountSql, Integer.class); |
|||
|
|||
response.put("areasCovered", areasCovered); |
|||
|
|||
// MALE |
|||
|
|||
String maleSql = """ |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 7 |
|||
AND answer = 1 |
|||
"""; |
|||
|
|||
response.put( |
|||
"maleCount", |
|||
jdbcTemplate.queryForObject(maleSql, Integer.class)); |
|||
|
|||
// FEMALE |
|||
|
|||
String femaleSql = """ |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 7 |
|||
AND answer = 2 |
|||
"""; |
|||
|
|||
response.put( |
|||
"femaleCount", |
|||
jdbcTemplate.queryForObject(femaleSql, Integer.class)); |
|||
|
|||
// CURRENTLY STUDYING |
|||
|
|||
/* |
|||
* String studyingSql = """ |
|||
* SELECT COUNT(DISTINCT survey_id) |
|||
* FROM child_survey_response |
|||
* WHERE qid = 25 |
|||
* AND answer = 1 |
|||
* """; |
|||
* |
|||
* response.put( |
|||
* "currentlyStudying", |
|||
* jdbcTemplate.queryForObject(studyingSql, Integer.class)); |
|||
*/ |
|||
String studyingSql = """ |
|||
|
|||
SELECT |
|||
|
|||
ROUND( |
|||
( |
|||
COUNT(DISTINCT CASE |
|||
WHEN qid = 25 |
|||
AND answer = 1 |
|||
THEN survey_id |
|||
END) |
|||
* 100.0 |
|||
) |
|||
/ |
|||
COUNT(DISTINCT survey_id), |
|||
0) AS studying_percentage |
|||
|
|||
FROM child_survey_response |
|||
|
|||
WHERE isactive = 1 |
|||
AND isdelete = 0 |
|||
|
|||
"""; |
|||
|
|||
response.put( |
|||
"currentlyStudying", |
|||
jdbcTemplate.queryForObject( |
|||
studyingSql, |
|||
Integer.class)); |
|||
|
|||
// AGE 4-8 |
|||
|
|||
String age4to8Sql = """ |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 10 |
|||
AND CAST(answer AS UNSIGNED) BETWEEN 4 AND 8 |
|||
"""; |
|||
|
|||
response.put( |
|||
"age4to8", |
|||
jdbcTemplate.queryForObject(age4to8Sql, Integer.class)); |
|||
|
|||
// AGE 9-13 |
|||
|
|||
String age9to13Sql = """ |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 10 |
|||
AND CAST(answer AS UNSIGNED) BETWEEN 9 AND 13 |
|||
"""; |
|||
|
|||
response.put( |
|||
"age9to13", |
|||
jdbcTemplate.queryForObject(age9to13Sql, Integer.class)); |
|||
|
|||
// AGE 14-18 |
|||
|
|||
String age14to18Sql = """ |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 10 |
|||
AND CAST(answer AS UNSIGNED) BETWEEN 14 AND 18 |
|||
"""; |
|||
|
|||
response.put( |
|||
"age14to18", |
|||
jdbcTemplate.queryForObject(age14to18Sql, Integer.class)); |
|||
|
|||
// AREA WISE |
|||
|
|||
String areaWiseSql = """ |
|||
SELECT |
|||
|
|||
lm.english_name AS area, |
|||
|
|||
COUNT(DISTINCT csr.survey_id) AS total_children |
|||
|
|||
FROM location_master lm |
|||
|
|||
LEFT JOIN child_survey_response csr |
|||
ON lm.id = csr.answer |
|||
AND csr.qid = 1 |
|||
AND csr.isactive = 1 |
|||
AND csr.isdelete = 0 |
|||
|
|||
GROUP BY lm.id, lm.english_name |
|||
|
|||
ORDER BY lm.orderby |
|||
"""; |
|||
|
|||
response.put( |
|||
"areaWise", |
|||
jdbcTemplate.queryForList(areaWiseSql)); |
|||
|
|||
// VULNERABILITY |
|||
|
|||
String vulnerabilitySql = """ |
|||
SELECT |
|||
|
|||
vm.english_name AS vulnerability, |
|||
|
|||
COUNT(DISTINCT csr.survey_id) AS total |
|||
|
|||
FROM vulnerability_master vm |
|||
|
|||
LEFT JOIN child_survey_response csr |
|||
ON FIND_IN_SET(vm.id, csr.answer) |
|||
AND csr.qid = 48 |
|||
AND csr.isactive = 1 |
|||
AND csr.isdelete = 0 |
|||
|
|||
GROUP BY vm.id, vm.english_name |
|||
|
|||
ORDER BY vm.orderby |
|||
"""; |
|||
|
|||
response.put( |
|||
"vulnerability", |
|||
jdbcTemplate.queryForList(vulnerabilitySql)); |
|||
|
|||
// EDUCATION STATUS |
|||
|
|||
// EDUCATION STATUS |
|||
|
|||
String educationSql = """ |
|||
SELECT |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 25 |
|||
AND answer = 1 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS currently_studying, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 25 |
|||
AND answer = 2 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS not_studying, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 34 |
|||
AND answer = 1 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS continue_education_intent |
|||
"""; |
|||
|
|||
response.put( |
|||
"educationStatus", |
|||
jdbcTemplate.queryForMap(educationSql)); |
|||
// HEALTH OVERVIEW |
|||
|
|||
String healthSql = """ |
|||
|
|||
SELECT |
|||
|
|||
CASE |
|||
|
|||
WHEN LOWER(cam.english_name) = 'yes' |
|||
THEN 'Health Issue' |
|||
|
|||
WHEN LOWER(cam.english_name) = 'no' |
|||
THEN 'No Health Issue' |
|||
|
|||
ELSE cam.english_name |
|||
|
|||
END AS status, |
|||
|
|||
COUNT(DISTINCT csr.survey_id) AS total |
|||
|
|||
FROM child_survey_response csr |
|||
|
|||
INNER JOIN child_survey_answer_master cam |
|||
ON cam.aid = csr.answer |
|||
AND csr.qid = 39 |
|||
|
|||
WHERE csr.qid = 39 |
|||
AND csr.isactive = 1 |
|||
AND csr.isdelete = 0 |
|||
|
|||
GROUP BY status |
|||
|
|||
"""; |
|||
|
|||
response.put( |
|||
"healthOverview", |
|||
jdbcTemplate.queryForList(healthSql)); |
|||
|
|||
// CERTIFICATE DETAILS |
|||
|
|||
String certificateSql = """ |
|||
|
|||
SELECT |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 42 |
|||
AND answer = 1 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS aadhar_yes, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 42 |
|||
AND answer = 2 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS aadhar_no, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 44 |
|||
AND answer = 1 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS community_yes, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 44 |
|||
AND answer = 2 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS community_no, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 45 |
|||
AND answer = 1 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS birth_yes, |
|||
|
|||
( |
|||
SELECT COUNT(DISTINCT survey_id) |
|||
FROM child_survey_response |
|||
WHERE qid = 45 |
|||
AND answer = 2 |
|||
AND isactive = 1 |
|||
AND isdelete = 0 |
|||
) AS birth_no |
|||
|
|||
"""; |
|||
|
|||
response.put( |
|||
"certificateDetails", |
|||
jdbcTemplate.queryForMap(certificateSql)); |
|||
|
|||
return response; |
|||
} |
|||
} |
|||
@ -0,0 +1,527 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en" dir=""> |
|||
<html xmlns:th="http://www.thymeleaf.org"> |
|||
|
|||
<head th:replace="~{fragments/modules/base/head :: head}"> |
|||
<style> |
|||
#surveyModal .modal-dialog { |
|||
max-width: 70%; |
|||
width: 70%; |
|||
} |
|||
|
|||
#surveyModal .modal-content { |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
#surveyModal .modal-header { |
|||
background-color: #f8f9fa; |
|||
border-bottom: 2px solid #007bff; |
|||
} |
|||
|
|||
#surveyModal .modal-title { |
|||
font-weight: 600; |
|||
color: #2c3e50; |
|||
} |
|||
|
|||
#surveyModal .modal-body { |
|||
padding: 30px 40px; |
|||
} |
|||
|
|||
#surveyDetails .row { |
|||
margin-bottom: 15px; |
|||
padding-bottom: 10px; |
|||
border-bottom: 1px solid #e9ecef; |
|||
} |
|||
|
|||
#surveyDetails .col-md-5 { |
|||
font-weight: 600; |
|||
color: #34495e; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
#surveyDetails .col-md-7 { |
|||
font-weight: 500; |
|||
color: #555; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
/* Modal scrollbar styling */ |
|||
#surveyModal .modal-body::-webkit-scrollbar { |
|||
width: 6px; |
|||
} |
|||
|
|||
#surveyModal .modal-body::-webkit-scrollbar-track { |
|||
background: #f1f1f1; |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
#surveyModal .modal-body::-webkit-scrollbar-thumb { |
|||
background: #007bff; |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
#surveyModal .modal-body::-webkit-scrollbar-thumb:hover { |
|||
background: #0056b3; |
|||
} |
|||
|
|||
@media (max-width: 768px) { |
|||
#surveyModal .modal-dialog { |
|||
max-width: 96%; |
|||
width: 96%; |
|||
} |
|||
|
|||
#surveyModal .modal-body { |
|||
padding: 20px; |
|||
} |
|||
} |
|||
</style> |
|||
</head> |
|||
|
|||
<body> |
|||
<div class="wrapper"> |
|||
<header th:replace="~{fragments/modules/base/header :: header}"></header> |
|||
|
|||
<div class="page-wrap"> |
|||
<div th:replace="~{fragments/modules/base/menu :: menu}"></div> |
|||
<div class="main-content"> |
|||
<div class="container-fluid"> |
|||
<!--<div class="page-header"> |
|||
<div class="row align-items-end"> |
|||
<div class="col-lg-6"> |
|||
<div class="page-header-title"> |
|||
<i class="ik ik-thumbs-up bg-blue"></i> |
|||
<div class="d-inline"> |
|||
<h5>Children Survey Dashboard</h5> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-lg-6 text-end"> |
|||
<input type="date" id="fromDate" class="form-control d-inline-block" |
|||
style="width:150px;"> |
|||
<span class="mx-1">to</span> |
|||
<input type="date" id="toDate" class="form-control d-inline-block" |
|||
style="width:150px;"> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-6"> |
|||
<nav class="breadcrumb-container" aria-label="breadcrumb"> |
|||
<ol class="breadcrumb"> |
|||
<li class="breadcrumb-item"> |
|||
<a href="/index"><i class="ik ik-home"></i></a> |
|||
</li> |
|||
<li class="breadcrumb-item active" aria-current="page">Update Staff</li> |
|||
</ol> |
|||
</nav> |
|||
</div> |
|||
</div> |
|||
</div>--> |
|||
<div class="page-header"> |
|||
<div class="row align-items-center"> |
|||
|
|||
<!-- LEFT SIDE --> |
|||
<div class="col-lg-6"> |
|||
<div class="page-header-title d-flex align-items-center"> |
|||
<i class="ik ik-thumbs-up bg-blue me-2"></i> |
|||
<h5 class="mb-0">Children Survey Dashboard</h5> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- RIGHT SIDE (DATE FILTER) --> |
|||
<div class="col-lg-6 text-end"> |
|||
<label class="form-label fw-semibold me-2">From Date:</label> |
|||
<input type="date" id="fromDate" class="form-control d-inline-block" |
|||
style="width:150px;"> |
|||
<label class="form-label fw-semibold me-2">To Date:</label> |
|||
<input type="date" id="toDate" class="form-control d-inline-block" style="width:150px;"> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<!-- BREADCRUMB (SEPARATE ROW) --> |
|||
<div class="row mt-2"> |
|||
<div class="col-lg-12"> |
|||
<nav class="breadcrumb-container"> |
|||
<ol class="breadcrumb"> |
|||
<li class="breadcrumb-item"> |
|||
<a href="/index"><i class="ik ik-home"></i></a> |
|||
</li> |
|||
<li class="breadcrumb-item active">Child List</li> |
|||
</ol> |
|||
</nav> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<hr> |
|||
|
|||
<!-- Filters Section --> |
|||
<div class="row mb-3"> |
|||
|
|||
|
|||
|
|||
<div class="col-md-2"> |
|||
<select id="gender" class="form-control"> |
|||
<option value="">Gender</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<div class="col-md-2"> |
|||
<select id="age" class="form-control"> |
|||
<option value="">Age</option> |
|||
<option value="4-8">4-8</option> |
|||
<option value="9-13">9-13</option> |
|||
<option value="14-18">14-18</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<div class="col-md-2"> |
|||
<select id="area" class="form-control"> |
|||
<option value="">Area Wise</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<div class="col-md-2"> |
|||
<select id="education" class="form-control"> |
|||
<option value="">Education</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<div class="col-md-2"> |
|||
<button class="btn btn-primary w-100" onclick="fetchSurveyData()">Search</button> |
|||
</div> |
|||
|
|||
</div> |
|||
<!-- Salary Report Table --> |
|||
<div class="card-block mt-3"> |
|||
<table id="surveyTable" class="table table-striped table-bordered"> |
|||
<thead class="thead-dark"> |
|||
<tr> |
|||
<th>Date</th> |
|||
<th>Survey ID</th> |
|||
<th>Name</th> |
|||
<th>Gender</th> |
|||
<th>Age</th> |
|||
<th>Mobile</th> |
|||
<th>Area</th> |
|||
<th>Education</th> |
|||
<th>Action</th> |
|||
|
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
|
|||
</tbody> |
|||
<tfoot class="thead-dark"> |
|||
|
|||
</tfoot> |
|||
</table> |
|||
</div> |
|||
|
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<div class="modal fade" id="surveyModal" tabindex="-1"> |
|||
<div class="modal-dialog modal-lg modal-dialog-scrollable" style="max-width:70%; width:70%;"> |
|||
<div class="modal-content"> |
|||
|
|||
<div class="modal-header"> |
|||
<h5 class="modal-title">Child Survey Details</h5> |
|||
<button type="button" class="close" data-bs-dismiss="modal"> |
|||
× |
|||
</button> |
|||
</div> |
|||
|
|||
<div class="modal-body"> |
|||
<div id="surveyDetails"></div> |
|||
</div> |
|||
|
|||
<div class="modal-footer"> |
|||
<button class="btn btn-secondary" data-bs-dismiss="modal">Close</button> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer> |
|||
</div> |
|||
</div> |
|||
|
|||
<div th:replace="~{fragments/modules/base/script :: script}"></div> |
|||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> |
|||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> |
|||
<!-- DataTables --> |
|||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css"> |
|||
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.bootstrap5.min.css"> |
|||
|
|||
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script> |
|||
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script> |
|||
<script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script> |
|||
|
|||
<!-- DataTable Buttons --> |
|||
<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.bootstrap5.min.js"></script> |
|||
<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 src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script> |
|||
|
|||
|
|||
<script th:inline="javascript"> |
|||
//var createdBy = /*[[${LoginUserId}]]*/''; |
|||
|
|||
|
|||
|
|||
/*$(document).ready(function () { |
|||
|
|||
function clearUrlParams() { |
|||
const currentUrl = window.location.href; |
|||
const urlWithoutParams = currentUrl.split('?')[0]; // Remove the query parameters |
|||
window.history.replaceState({}, document.title, urlWithoutParams); // Replace the current URL without params |
|||
} |
|||
|
|||
// Call this on page load to reset the URL |
|||
clearUrlParams(); |
|||
|
|||
// Initialize DataTable |
|||
var table = $('#salaryreporttable').DataTable({ |
|||
dom: 'Bftip', |
|||
columnDefs: [ |
|||
{ targets: 'no-sort', orderable: false } |
|||
], |
|||
lengthMenu: [ |
|||
[50, 100, 200, 500, -1], |
|||
['50 rows', '100 rows', '200 rows', 'Show all'] |
|||
], |
|||
scrollY: '50vh', |
|||
fixedColumns: { |
|||
left: 1, |
|||
right: 1 |
|||
}, |
|||
buttons: [ |
|||
{ |
|||
extend: 'pageLength', |
|||
className: 'btn btn-warning' |
|||
}, |
|||
{ |
|||
extend: 'pdfHtml5', |
|||
text: 'PDF', |
|||
className: 'btn btn-secondary', |
|||
id: 'pdfBtn', |
|||
exportOptions: { |
|||
columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] |
|||
}, |
|||
orientation: 'landscape', // Change to landscape for more horizontal space |
|||
pageSize: 'A3', // You can change to A4 or A3 depending on your needs |
|||
customize: function (doc) { |
|||
// Custom column widths for better fit |
|||
//doc.content[1].table.widths = ['2%', '6%', '6%', '6%', '6%', '6%', '6%', '3%', '3%', '3%', '3%', '3%', '3%', '6%', '6%', '6%']; |
|||
|
|||
// Optional: Adjust font size if needed |
|||
doc.styles.tableBodyEven.alignment = 'center'; |
|||
doc.styles.tableBodyOdd.alignment = 'center'; |
|||
} |
|||
} |
|||
], |
|||
fixedHeader: true, |
|||
autoWidth: true, |
|||
responsive: true, |
|||
searching: true, |
|||
select: false, |
|||
processing: false |
|||
}); |
|||
|
|||
|
|||
});*/ |
|||
$(document).ready(function () { |
|||
|
|||
// 🔹 Load dropdowns when page loads |
|||
loadDropdowns(); |
|||
fetchSurveyData(); |
|||
|
|||
// 🔹 (Optional) Load table initially |
|||
// fetchSurveyData(); |
|||
|
|||
}); |
|||
function viewSurvey(surveyId) { |
|||
|
|||
|
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/details", |
|||
type: "GET", |
|||
data: { surveyId: surveyId }, |
|||
|
|||
success: function (data) { |
|||
|
|||
let html = ""; |
|||
|
|||
Object.keys(data).forEach(function (key) { |
|||
|
|||
html += ` |
|||
<div class="row mb-2"> |
|||
<div class="col-md-5"> |
|||
<strong>${key}</strong> |
|||
</div> |
|||
<div class="col-md-7"> |
|||
: ${data[key]} |
|||
</div> |
|||
</div> |
|||
`; |
|||
}); |
|||
|
|||
$("#surveyDetails").html(html); |
|||
|
|||
// Show modal |
|||
let modal = new bootstrap.Modal(document.getElementById('surveyModal')); |
|||
modal.show(); |
|||
} |
|||
}); |
|||
} |
|||
function fetchSurveyData() { |
|||
|
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/list", |
|||
type: "GET", |
|||
data: { |
|||
name: $("#searchName").val(), |
|||
gender: $("#gender").val(), |
|||
age: $("#age").val(), |
|||
area: $("#area").val(), |
|||
education: $("#education").val(), |
|||
fromDate: $("#fromDate").val(), |
|||
toDate: $("#toDate").val() |
|||
}, |
|||
success: function (data) { |
|||
|
|||
let tbody = ""; |
|||
|
|||
data.forEach(function (row) { |
|||
//<td>${row.survey_date || ''}</td> |
|||
|
|||
tbody += ` |
|||
<tr> |
|||
<td>${formatDate(row.survey_date)}</td> |
|||
|
|||
<td>${row.survey_id || ''}</td> |
|||
<td>${row.child_name || ''}</td> |
|||
<td>${row.gender || ''}</td> |
|||
<td>${row.age || ''}</td> |
|||
<td>${row.mobile_number || ''}</td> |
|||
<td>${row.area || ''}</td> |
|||
<td>${row.education || ''}</td> |
|||
<td> |
|||
<button class="btn btn-sm btn-info" onclick="viewSurvey('${row.survey_id}')"> |
|||
<i class="fa fa-eye"></i> |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
`; |
|||
}); |
|||
|
|||
// 🔥 Destroy old DataTable if exists |
|||
if ($.fn.DataTable.isDataTable('#surveyTable')) { |
|||
$('#surveyTable').DataTable().clear().destroy(); |
|||
} |
|||
|
|||
// Set new data |
|||
$("#surveyTable tbody").html(tbody); |
|||
|
|||
// 🔥 Reinitialize DataTable WITH BUTTONS |
|||
$('#surveyTable').DataTable({ |
|||
dom: 'Bfrtip', |
|||
buttons: [ |
|||
{ |
|||
extend: 'pageLength', |
|||
className: 'btn btn-warning' |
|||
}, |
|||
{ |
|||
extend: 'excelHtml5', |
|||
text: 'Excel', |
|||
className: 'btn btn-success' |
|||
}, |
|||
{ |
|||
extend: 'pdfHtml5', |
|||
text: 'PDF', |
|||
className: 'btn btn-secondary', |
|||
orientation: 'landscape', |
|||
pageSize: 'A4' |
|||
} |
|||
], |
|||
responsive: true, |
|||
destroy: true |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
function formatDate(dateString) { |
|||
|
|||
if (!dateString) return ''; |
|||
|
|||
const date = new Date(dateString); |
|||
|
|||
const day = String(date.getDate()).padStart(2, '0'); |
|||
|
|||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|||
|
|||
const year = date.getFullYear(); |
|||
|
|||
return `${day}-${month}-${year}`; |
|||
} |
|||
function loadDropdowns() { |
|||
|
|||
// Gender |
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/gender", |
|||
type: "GET", |
|||
success: function (data) { |
|||
|
|||
let options = '<option value="">Gender</option>'; |
|||
|
|||
data.forEach(function (g) { |
|||
options += `<option value="${g.id}">${g.english_name}</option>`; |
|||
}); |
|||
|
|||
$("#gender").html(options); |
|||
} |
|||
}); |
|||
|
|||
// Area |
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/location", |
|||
type: "GET", |
|||
success: function (data) { |
|||
|
|||
let options = '<option value="">Area</option>'; |
|||
|
|||
data.forEach(function (a) { |
|||
options += `<option value="${a.id}">${a.english_name}</option>`; |
|||
}); |
|||
|
|||
$("#area").html(options); |
|||
} |
|||
}); |
|||
|
|||
// Education |
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/education", |
|||
type: "GET", |
|||
success: function (data) { |
|||
|
|||
let options = '<option value="">Education</option>'; |
|||
|
|||
data.forEach(function (e) { |
|||
options += `<option value="${e.id}">${e.english_name}</option>`; |
|||
}); |
|||
|
|||
$("#education").html(options); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
|
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
|||
@ -0,0 +1,836 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en" dir=""> |
|||
<html xmlns:th="http://www.thymeleaf.org"> |
|||
|
|||
<head th:replace="~{fragments/modules/base/head :: head}"></head> |
|||
<style> |
|||
#surveyorModal .modal-dialog { |
|||
max-width: 96%; |
|||
width: 96%; |
|||
} |
|||
|
|||
#surveyorModal .modal-content { |
|||
width: 100%; |
|||
} |
|||
|
|||
#surveyTable { |
|||
width: 100% !important; |
|||
} |
|||
|
|||
#surveyTable_wrapper { |
|||
width: 100%; |
|||
} |
|||
|
|||
#surveyTable_wrapper .row { |
|||
width: 100%; |
|||
margin: 0; |
|||
} |
|||
|
|||
#surveyTable_wrapper .col-sm-12 { |
|||
padding-left: 0; |
|||
padding-right: 0; |
|||
} |
|||
|
|||
#surveyModal .modal-body { |
|||
max-height: 75vh; |
|||
overflow-y: auto; |
|||
padding: 20px 30px; |
|||
} |
|||
|
|||
#surveyDetails .row { |
|||
border-bottom: 1px solid #f1f1f1; |
|||
padding: 8px 0; |
|||
margin: 0; |
|||
} |
|||
|
|||
#surveyDetails .col-md-5 { |
|||
font-weight: 600; |
|||
color: #222; |
|||
} |
|||
|
|||
#surveyDetails .col-md-7 { |
|||
color: #555; |
|||
} |
|||
|
|||
#surveyModal .modal-content { |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
.table-responsive { |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
|
|||
<body> |
|||
<div class="wrapper"> |
|||
<header th:replace="~{fragments/modules/base/header :: header}"></header> |
|||
|
|||
<div class="page-wrap"> |
|||
<div th:replace="~{fragments/modules/base/menu :: menu}"></div> |
|||
<div class="main-content"> |
|||
<div class="container-fluid"> |
|||
<!--<div class="page-header"> |
|||
<div class="row align-items-end"> |
|||
<div class="col-lg-6"> |
|||
<div class="page-header-title"> |
|||
<i class="ik ik-thumbs-up bg-blue"></i> |
|||
<div class="d-inline"> |
|||
<h5>Children Survey Dashboard</h5> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-lg-6 text-end"> |
|||
<input type="date" id="fromDate" class="form-control d-inline-block" |
|||
style="width:150px;"> |
|||
<span class="mx-1">to</span> |
|||
<input type="date" id="toDate" class="form-control d-inline-block" |
|||
style="width:150px;"> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-6"> |
|||
<nav class="breadcrumb-container" aria-label="breadcrumb"> |
|||
<ol class="breadcrumb"> |
|||
<li class="breadcrumb-item"> |
|||
<a href="/index"><i class="ik ik-home"></i></a> |
|||
</li> |
|||
<li class="breadcrumb-item active" aria-current="page">Update Staff</li> |
|||
</ol> |
|||
</nav> |
|||
</div> |
|||
</div> |
|||
</div>--> |
|||
<div class="page-header"> |
|||
<div class="row align-items-center"> |
|||
|
|||
<!-- LEFT SIDE --> |
|||
<div class="col-lg-6"> |
|||
<div class="page-header-title d-flex align-items-center"> |
|||
<i class="ik ik-thumbs-up bg-blue me-2"></i> |
|||
<h5 class="mb-0">Children Survey Dashboard</h5> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- RIGHT SIDE (DATE FILTER) --> |
|||
<div class="col-lg-6 text-end"> |
|||
<label class="form-label fw-semibold me-2">From Date:</label> |
|||
<input type="date" id="fromDate" class="form-control d-inline-block" |
|||
style="width:150px;"> |
|||
|
|||
<label class="form-label fw-semibold me-2">To Date:</label> |
|||
<input type="date" id="toDate" class="form-control d-inline-block" style="width:150px;"> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<!-- BREADCRUMB (SEPARATE ROW) --> |
|||
<div class="row mt-2"> |
|||
<div class="col-lg-12"> |
|||
<nav class="breadcrumb-container"> |
|||
<ol class="breadcrumb"> |
|||
<li class="breadcrumb-item"> |
|||
<a href="/index"><i class="ik ik-home"></i></a> |
|||
</li> |
|||
<li class="breadcrumb-item active"> Surveyors List</li> |
|||
</ol> |
|||
</nav> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<hr> |
|||
|
|||
<!-- Filters Section --> |
|||
<div class="row mb-3"> |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
<div class="col-md-2"> |
|||
<select id="area" class="form-control"> |
|||
<option value="">Area Wise</option> |
|||
</select> |
|||
</div> |
|||
|
|||
|
|||
|
|||
<div class="col-md-2"> |
|||
<button class="btn btn-primary w-100" onclick="loadSurveyors()">Search</button> |
|||
</div> |
|||
|
|||
</div> |
|||
<!-- Salary Report Table --> |
|||
<!--<div class="card-block mt-3"> |
|||
<table id="surveyTable" class="table table-striped table-bordered"> |
|||
<thead class="thead-dark"> |
|||
<tr> |
|||
<th>Date</th> |
|||
<th>Survey ID</th> |
|||
<th>Name</th> |
|||
<th>Gender</th> |
|||
<th>Age</th> |
|||
<th>Mobile</th> |
|||
<th>Area</th> |
|||
<th>Education</th> |
|||
<th>Action</th> |
|||
|
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
|
|||
</tbody> |
|||
<tfoot class="thead-dark"> |
|||
|
|||
</tfoot> |
|||
</table> |
|||
</div>--> |
|||
<div class="table-responsive"> |
|||
|
|||
<table id="surveyorTable" class="table table-bordered table-striped dt-responsive nowrap w-100"> |
|||
|
|||
<thead class="thead-dark"> |
|||
<tr> |
|||
<th>Date</th> |
|||
<!--<th>Surveyor ID</th>--> |
|||
<th>Surveyor Name</th> |
|||
<th>Mobile Number</th> |
|||
<th>Area</th> |
|||
<th>Total Survey Done</th> |
|||
<th>Action</th> |
|||
</tr> |
|||
</thead> |
|||
|
|||
<tbody></tbody> |
|||
|
|||
</table> |
|||
|
|||
</div> |
|||
|
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<div class="modal fade" id="surveyorModal" tabindex="-1"> |
|||
|
|||
<div class="modal-dialog modal-fullscreen-xl-down"> |
|||
|
|||
<div class="modal-content"> |
|||
|
|||
<div class="modal-header"> |
|||
|
|||
<h5 class="modal-title"> |
|||
Child Survey Details |
|||
</h5> |
|||
|
|||
<button type="button" class="close" data-bs-dismiss="modal"> |
|||
|
|||
× |
|||
|
|||
</button> |
|||
|
|||
</div> |
|||
|
|||
<div class="modal-body"> |
|||
|
|||
<div class="table-responsive"> |
|||
|
|||
<table id="surveyTable" class="table table-bordered table-striped"> |
|||
|
|||
<thead class="thead-dark"> |
|||
|
|||
<tr> |
|||
|
|||
<th>Date</th> |
|||
<th>Survey ID</th> |
|||
<th>Name</th> |
|||
<th>Gender</th> |
|||
<th>Age</th> |
|||
<th>Mobile</th> |
|||
<th>Area</th> |
|||
<th>Education</th> |
|||
<th>Action</th> |
|||
|
|||
</tr> |
|||
|
|||
</thead> |
|||
|
|||
<tbody></tbody> |
|||
|
|||
</table> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="modal-footer"> |
|||
|
|||
<button class="btn btn-secondary" data-bs-dismiss="modal"> |
|||
|
|||
Close |
|||
|
|||
</button> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
<div class="modal fade" id="surveyModal" tabindex="-1"> |
|||
|
|||
<div class="modal-dialog modal-dialog-scrollable" style="max-width:70%; width:70%;"> |
|||
|
|||
<div class="modal-content"> |
|||
|
|||
<div class="modal-header"> |
|||
|
|||
<h5 class="modal-title"> |
|||
Child Survey Details |
|||
</h5> |
|||
|
|||
<button type="button" class="close" data-bs-dismiss="modal"> |
|||
|
|||
× |
|||
|
|||
</button> |
|||
|
|||
</div> |
|||
|
|||
<div class="modal-body"> |
|||
|
|||
<div id="surveyDetails"></div> |
|||
|
|||
</div> |
|||
|
|||
<div class="modal-footer"> |
|||
|
|||
<button class="btn btn-secondary" data-bs-dismiss="modal"> |
|||
|
|||
Close |
|||
|
|||
</button> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer> |
|||
</div> |
|||
</div> |
|||
|
|||
<div th:replace="~{fragments/modules/base/script :: script}"></div> |
|||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> |
|||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> |
|||
<!-- DataTables --> |
|||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css"> |
|||
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.bootstrap5.min.css"> |
|||
|
|||
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script> |
|||
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script> |
|||
<script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script> |
|||
|
|||
<!-- DataTable Buttons --> |
|||
<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.bootstrap5.min.js"></script> |
|||
<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 src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script> |
|||
|
|||
|
|||
<script th:inline="javascript"> |
|||
//var createdBy = /*[[${LoginUserId}]]*/''; |
|||
|
|||
|
|||
|
|||
/*$(document).ready(function () { |
|||
|
|||
function clearUrlParams() { |
|||
const currentUrl = window.location.href; |
|||
const urlWithoutParams = currentUrl.split('?')[0]; // Remove the query parameters |
|||
window.history.replaceState({}, document.title, urlWithoutParams); // Replace the current URL without params |
|||
} |
|||
|
|||
// Call this on page load to reset the URL |
|||
clearUrlParams(); |
|||
|
|||
// Initialize DataTable |
|||
var table = $('#salaryreporttable').DataTable({ |
|||
dom: 'Bftip', |
|||
columnDefs: [ |
|||
{ targets: 'no-sort', orderable: false } |
|||
], |
|||
lengthMenu: [ |
|||
[50, 100, 200, 500, -1], |
|||
['50 rows', '100 rows', '200 rows', 'Show all'] |
|||
], |
|||
scrollY: '50vh', |
|||
fixedColumns: { |
|||
left: 1, |
|||
right: 1 |
|||
}, |
|||
buttons: [ |
|||
{ |
|||
extend: 'pageLength', |
|||
className: 'btn btn-warning' |
|||
}, |
|||
{ |
|||
extend: 'pdfHtml5', |
|||
text: 'PDF', |
|||
className: 'btn btn-secondary', |
|||
id: 'pdfBtn', |
|||
exportOptions: { |
|||
columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] |
|||
}, |
|||
orientation: 'landscape', // Change to landscape for more horizontal space |
|||
pageSize: 'A3', // You can change to A4 or A3 depending on your needs |
|||
customize: function (doc) { |
|||
// Custom column widths for better fit |
|||
//doc.content[1].table.widths = ['2%', '6%', '6%', '6%', '6%', '6%', '6%', '3%', '3%', '3%', '3%', '3%', '3%', '6%', '6%', '6%']; |
|||
|
|||
// Optional: Adjust font size if needed |
|||
doc.styles.tableBodyEven.alignment = 'center'; |
|||
doc.styles.tableBodyOdd.alignment = 'center'; |
|||
} |
|||
} |
|||
], |
|||
fixedHeader: true, |
|||
autoWidth: true, |
|||
responsive: true, |
|||
searching: true, |
|||
select: false, |
|||
processing: false |
|||
}); |
|||
|
|||
|
|||
});*/ |
|||
$(document).ready(function () { |
|||
|
|||
// 🔹 Load dropdowns when page loads |
|||
loadDropdowns(); |
|||
//fetchSurveyData(); |
|||
loadSurveyors(); |
|||
|
|||
// 🔹 (Optional) Load table initially |
|||
// fetchSurveyData(); |
|||
|
|||
}); |
|||
function viewSurvey1(loginId, locationId, surveyDate) { |
|||
|
|||
if ($.fn.DataTable.isDataTable('#surveyTable')) { |
|||
|
|||
$('#surveyTable').DataTable().destroy(); |
|||
} |
|||
|
|||
$("#surveyTable tbody").empty(); |
|||
|
|||
$.ajax({ |
|||
|
|||
url: "/gcc/api/children-survey/survey-breakup", |
|||
|
|||
type: "GET", |
|||
data: { |
|||
loginId: loginId, |
|||
locationId: locationId, |
|||
surveyDate: surveyDate |
|||
}, |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
success: function (data) { |
|||
|
|||
let tbody = ""; |
|||
|
|||
$.each(data, function (i, row) { |
|||
|
|||
tbody += ` |
|||
<tr> |
|||
<td>${formatDate(row.survey_date)}</td> |
|||
<td>${row.survey_id || ''}</td> |
|||
|
|||
<td>${row.child_name || ''}</td> |
|||
|
|||
<td>${row.gender || ''}</td> |
|||
|
|||
<td>${row.age || ''}</td> |
|||
|
|||
<td>${row.mobile_number || ''}</td> |
|||
|
|||
<td>${row.area || ''}</td> |
|||
|
|||
<td>${row.education || ''}</td> |
|||
|
|||
<td> |
|||
|
|||
<button class="btn btn-info btn-sm" |
|||
onclick="viewChildSurvey('${row.survey_id}')"> |
|||
|
|||
<i class="fa fa-eye"></i> |
|||
|
|||
</button> |
|||
|
|||
</td> |
|||
|
|||
</tr> |
|||
`; |
|||
}); |
|||
|
|||
$("#surveyTable tbody").html(tbody); |
|||
|
|||
$('#surveyTable').DataTable({ |
|||
|
|||
dom: 'Bfrtip', |
|||
|
|||
buttons: [ |
|||
{ |
|||
extend: 'pageLength', |
|||
className: 'btn btn-warning' |
|||
}, |
|||
{ |
|||
extend: 'excelHtml5', |
|||
text: 'Excel', |
|||
className: 'btn btn-success' |
|||
}, |
|||
{ |
|||
extend: 'pdfHtml5', |
|||
text: 'PDF', |
|||
className: 'btn btn-secondary', |
|||
orientation: 'landscape', |
|||
pageSize: 'A4' |
|||
} |
|||
], |
|||
|
|||
responsive: true, |
|||
pageLength: 10 |
|||
}); |
|||
|
|||
$("#surveyorModal").modal("show"); |
|||
} |
|||
}); |
|||
} |
|||
function viewChildSurvey(surveyId) { |
|||
|
|||
$.ajax({ |
|||
|
|||
url: "/gcc/api/children-survey/details", |
|||
|
|||
type: "GET", |
|||
|
|||
data: { |
|||
surveyId: surveyId |
|||
}, |
|||
|
|||
success: function (data) { |
|||
|
|||
let html = ""; |
|||
|
|||
Object.keys(data).forEach(function (key) { |
|||
|
|||
html += ` |
|||
<div class="row mb-2"> |
|||
|
|||
<div class="col-md-5"> |
|||
<strong>${key}</strong> |
|||
</div> |
|||
|
|||
<div class="col-md-7"> |
|||
: ${data[key] || ''} |
|||
</div> |
|||
|
|||
</div> |
|||
`; |
|||
}); |
|||
|
|||
$("#surveyDetails").html(html); |
|||
|
|||
// 🔥 OPEN MODAL |
|||
let modal = new bootstrap.Modal( |
|||
document.getElementById('surveyModal') |
|||
); |
|||
|
|||
modal.show(); |
|||
}, |
|||
|
|||
error: function (xhr) { |
|||
|
|||
console.log(xhr); |
|||
|
|||
alert("Unable to fetch survey details"); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
|
|||
function loadSurveyors() { |
|||
|
|||
if ($.fn.DataTable.isDataTable('#surveyorTable')) { |
|||
$('#surveyorTable').DataTable().destroy(); |
|||
} |
|||
|
|||
$("#surveyorTable tbody").empty(); |
|||
|
|||
$.ajax({ |
|||
|
|||
url: "/gcc/api/children-survey/getSurveyorsList", |
|||
|
|||
type: "GET", |
|||
|
|||
data: { |
|||
|
|||
area: $("#area").val(), |
|||
|
|||
fromDate: $("#fromDate").val(), |
|||
|
|||
toDate: $("#toDate").val() |
|||
|
|||
}, |
|||
|
|||
|
|||
success: function (response) { |
|||
|
|||
let rows = ""; |
|||
|
|||
$.each(response, function (i, item) { |
|||
// <td>${item.surveyor_id || ''}</td> |
|||
// <td>${item.survey_date || ''}</td> |
|||
rows += ` |
|||
<tr> |
|||
<td>${formatDate(item.survey_date)}</td> |
|||
|
|||
<td>${item.user_name || ''}</td> |
|||
<td>${item.mobile_no || ''}</td> |
|||
<td>${item.area || ''}</td> |
|||
<td>${item.total_survey_done || 0}</td> |
|||
<td> |
|||
|
|||
<button class="btn btn-info btn-sm" |
|||
onclick="viewSurvey1('${item.loginId}', '${item.location_id}', '${item.survey_date}')"> |
|||
|
|||
<i class="fa fa-eye"></i> |
|||
|
|||
</button> |
|||
|
|||
</td> |
|||
|
|||
</tr> |
|||
`; |
|||
}); |
|||
|
|||
$("#surveyorTable tbody").html(rows); |
|||
|
|||
$('#surveyorTable').DataTable({ |
|||
|
|||
dom: 'Bfrtip', |
|||
|
|||
buttons: [ |
|||
{ |
|||
extend: 'pageLength', |
|||
className: 'btn btn-warning' |
|||
}, |
|||
{ |
|||
extend: 'excelHtml5', |
|||
text: 'Excel', |
|||
className: 'btn btn-success' |
|||
}, |
|||
{ |
|||
extend: 'pdfHtml5', |
|||
text: 'PDF', |
|||
className: 'btn btn-secondary', |
|||
orientation: 'landscape', |
|||
pageSize: 'A4' |
|||
} |
|||
], |
|||
|
|||
responsive: true, |
|||
pageLength: 10 |
|||
|
|||
}); |
|||
|
|||
} |
|||
}); |
|||
} |
|||
function formatDate(dateString) { |
|||
|
|||
if (!dateString) return ''; |
|||
|
|||
const date = new Date(dateString); |
|||
|
|||
const day = String(date.getDate()).padStart(2, '0'); |
|||
|
|||
const month = String(date.getMonth() + 1).padStart(2, '0'); |
|||
|
|||
const year = date.getFullYear(); |
|||
|
|||
return `${day}-${month}-${year}`; |
|||
} |
|||
function viewSurvey(surveyId) { |
|||
|
|||
|
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/details", |
|||
type: "GET", |
|||
data: { surveyId: surveyId }, |
|||
|
|||
success: function (data) { |
|||
|
|||
let html = ""; |
|||
|
|||
Object.keys(data).forEach(function (key) { |
|||
|
|||
html += ` |
|||
<div class="row mb-2"> |
|||
<div class="col-md-5"> |
|||
<strong>${key}</strong> |
|||
</div> |
|||
<div class="col-md-7"> |
|||
: ${data[key]} |
|||
</div> |
|||
</div> |
|||
`; |
|||
}); |
|||
|
|||
$("#surveyDetails").html(html); |
|||
|
|||
// Show modal |
|||
let modal = new bootstrap.Modal(document.getElementById('surveyModal')); |
|||
modal.show(); |
|||
} |
|||
}); |
|||
} |
|||
function fetchSurveyData() { |
|||
|
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/list", |
|||
type: "GET", |
|||
data: { |
|||
name: $("#searchName").val(), |
|||
gender: $("#gender").val(), |
|||
age: $("#age").val(), |
|||
area: $("#area").val(), |
|||
education: $("#education").val(), |
|||
fromDate: $("#fromDate").val(), |
|||
toDate: $("#toDate").val() |
|||
}, |
|||
success: function (data) { |
|||
|
|||
let tbody = ""; |
|||
|
|||
data.forEach(function (row) { |
|||
|
|||
tbody += ` |
|||
<tr> |
|||
<td>${row.survey_date || ''}</td> |
|||
<td>${row.survey_id || ''}</td> |
|||
<td>${row.child_name || ''}</td> |
|||
<td>${row.gender || ''}</td> |
|||
<td>${row.age || ''}</td> |
|||
<td>${row.mobile_number || ''}</td> |
|||
<td>${row.area || ''}</td> |
|||
<td>${row.education || ''}</td> |
|||
<td> |
|||
<button class="btn btn-sm btn-info" onclick="viewSurvey('${row.survey_id}')"> |
|||
<i class="fa fa-eye"></i> |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
`; |
|||
}); |
|||
|
|||
// 🔥 Destroy old DataTable if exists |
|||
if ($.fn.DataTable.isDataTable('#surveyTable')) { |
|||
$('#surveyTable').DataTable().clear().destroy(); |
|||
} |
|||
|
|||
// Set new data |
|||
$("#surveyTable tbody").html(tbody); |
|||
|
|||
// 🔥 Reinitialize DataTable WITH BUTTONS |
|||
$('#surveyTable').DataTable({ |
|||
dom: 'Bfrtip', |
|||
buttons: [ |
|||
{ |
|||
extend: 'pageLength', |
|||
className: 'btn btn-warning' |
|||
}, |
|||
{ |
|||
extend: 'excelHtml5', |
|||
text: 'Excel', |
|||
className: 'btn btn-success' |
|||
}, |
|||
{ |
|||
extend: 'pdfHtml5', |
|||
text: 'PDF', |
|||
className: 'btn btn-secondary', |
|||
orientation: 'landscape', |
|||
pageSize: 'A4' |
|||
} |
|||
], |
|||
responsive: true, |
|||
destroy: true |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
function loadDropdowns() { |
|||
|
|||
// Gender |
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/gender", |
|||
type: "GET", |
|||
success: function (data) { |
|||
|
|||
let options = '<option value="">Gender</option>'; |
|||
|
|||
data.forEach(function (g) { |
|||
options += `<option value="${g.id}">${g.english_name}</option>`; |
|||
}); |
|||
|
|||
$("#gender").html(options); |
|||
} |
|||
}); |
|||
|
|||
// Area |
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/location", |
|||
type: "GET", |
|||
success: function (data) { |
|||
|
|||
let options = '<option value="">Area</option>'; |
|||
|
|||
data.forEach(function (a) { |
|||
options += `<option value="${a.id}">${a.english_name}</option>`; |
|||
}); |
|||
|
|||
$("#area").html(options); |
|||
} |
|||
}); |
|||
|
|||
// Education |
|||
$.ajax({ |
|||
url: "/gcc/api/children-survey/education", |
|||
type: "GET", |
|||
success: function (data) { |
|||
|
|||
let options = '<option value="">Education</option>'; |
|||
|
|||
data.forEach(function (e) { |
|||
options += `<option value="${e.id}">${e.english_name}</option>`; |
|||
}); |
|||
|
|||
$("#education").html(options); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
|
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
|||
@ -0,0 +1,668 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en" dir=""> |
|||
<html xmlns:th="http://www.thymeleaf.org"> |
|||
|
|||
<head th:replace="~{fragments/modules/base/head :: head}"> |
|||
<link rel="stylesheet" th:href="@{/assets/css/bootstrap.min.css}"> |
|||
|
|||
<link rel="stylesheet" th:href="@{/assets/css/style.css}"> |
|||
|
|||
<script th:src="@{/assets/js/jquery.min.js}"></script> |
|||
|
|||
<script th:src="@{/assets/js/bootstrap.bundle.min.js}"></script> |
|||
|
|||
<style> |
|||
.report-card { |
|||
border-radius: 12px; |
|||
padding: 20px; |
|||
background: #fff; |
|||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08); |
|||
height: 100%; |
|||
} |
|||
|
|||
.report-title { |
|||
font-size: 12px; |
|||
color: #777; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
.report-count { |
|||
font-size: 32px; |
|||
font-weight: 700; |
|||
color: #222; |
|||
} |
|||
|
|||
.section-box { |
|||
border-radius: 12px; |
|||
background: #fff; |
|||
padding: 20px; |
|||
margin-top: 20px; |
|||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08); |
|||
} |
|||
|
|||
.section-title { |
|||
font-size: 18px; |
|||
font-weight: 600; |
|||
margin-bottom: 15px; |
|||
} |
|||
|
|||
.progress { |
|||
height: 10px; |
|||
border-radius: 20px; |
|||
} |
|||
|
|||
.report-row { |
|||
margin-bottom: 15px; |
|||
} |
|||
|
|||
.container-fluid { |
|||
padding: 25px; |
|||
} |
|||
|
|||
.report-card { |
|||
min-height: 130px; |
|||
} |
|||
|
|||
.report-count { |
|||
margin-top: 10px; |
|||
} |
|||
|
|||
.section-box { |
|||
min-height: 100%; |
|||
} |
|||
|
|||
.progress-bar { |
|||
border-radius: 20px; |
|||
} |
|||
|
|||
body { |
|||
background: #f5f7fb; |
|||
} |
|||
|
|||
.dashboard-card { |
|||
border-radius: 12px; |
|||
background: #fff; |
|||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08); |
|||
min-height: 160px; |
|||
height: 160px; |
|||
} |
|||
|
|||
.dashboard-card .card-body { |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 100%; |
|||
} |
|||
|
|||
.dashboard-card .card-title { |
|||
font-size: 18px; |
|||
font-weight: 500; |
|||
min-height: 48px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
text-align: center; |
|||
line-height: 1.3; |
|||
} |
|||
|
|||
.dashboard-count { |
|||
font-size: 48px; |
|||
font-weight: 700; |
|||
margin-top: 10px; |
|||
} |
|||
</style> |
|||
</head> |
|||
|
|||
<body> |
|||
<div class="wrapper"> |
|||
<header th:replace="~{fragments/modules/base/header :: header}"></header> |
|||
|
|||
<div class="page-wrap"> |
|||
<div th:replace="~{fragments/modules/base/menu :: menu}"></div> |
|||
<div class="main-content"> |
|||
<div class="container-fluid"> |
|||
<div class="page-header"> |
|||
<div class="row align-items-center mb-4"> |
|||
|
|||
<div class="col-lg-6"> |
|||
|
|||
<div class="page-header-title"> |
|||
|
|||
<i class="ik ik-thumbs-up bg-blue"></i> |
|||
|
|||
<div class="d-inline"> |
|||
|
|||
<h3 class="mb-0"> |
|||
Survey Analytics & Reports |
|||
</h3> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-lg-6 text-right"> |
|||
|
|||
<nav class="breadcrumb-container" aria-label="breadcrumb"> |
|||
|
|||
<ol class="breadcrumb justify-content-end"> |
|||
|
|||
<li class="breadcrumb-item"> |
|||
|
|||
<a href="/index"> |
|||
|
|||
<i class="ik ik-home"></i> |
|||
|
|||
</a> |
|||
|
|||
</li> |
|||
|
|||
<li class="breadcrumb-item active"> |
|||
|
|||
Survey Reports |
|||
|
|||
</li> |
|||
|
|||
</ol> |
|||
|
|||
</nav> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
<!-- TOP COUNTS --> |
|||
|
|||
<div class="row"> |
|||
|
|||
<div class="col-lg-2 col-md-4 col-sm-6 mb-4 d-flex"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h6 class="card-title"> |
|||
Total Surveyed Children |
|||
</h6> |
|||
|
|||
<h1 id="totalChildren" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-md-2 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h6 class="card-title"> |
|||
Areas Covered |
|||
</h6> |
|||
|
|||
<h1 id="areasCovered" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-md-2 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h6 class="card-title"> |
|||
Gender - Male |
|||
</h6> |
|||
|
|||
<h1 id="maleCount" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-md-2 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h6 class="card-title"> |
|||
Gender - Female |
|||
</h6> |
|||
|
|||
<h1 id="femaleCount" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-md-2 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h6 class="card-title"> |
|||
Currently Studying |
|||
</h6> |
|||
|
|||
<h1 id="currentlyStudying" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
|
|||
<!-- AGE DISTRIBUTION --> |
|||
|
|||
<div class="row"> |
|||
|
|||
<div class="col-md-4 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h5>4 - 8 Years</h5> |
|||
|
|||
<h1 id="age4to8" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-md-4 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h5>9 - 13 Years</h5> |
|||
|
|||
<h1 id="age9to13" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="col-md-4 mb-4"> |
|||
|
|||
<div class="card dashboard-card text-center"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h5>14 - 18 Years</h5> |
|||
|
|||
<h1 id="age14to18" class="dashboard-count"> |
|||
0 |
|||
</h1> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<div class="row mt-3"> |
|||
|
|||
<!-- AREA WISE --> |
|||
|
|||
<div class="col-md-6"> |
|||
|
|||
<div class="card dashboard-card"> |
|||
|
|||
|
|||
|
|||
<h5 class="section-title"> |
|||
Area-wise Distribution |
|||
</h5> |
|||
<div class="card-body"> |
|||
|
|||
<div id="areaWiseDiv"></div> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<!-- VULNERABILITY --> |
|||
|
|||
<div class="col-md-6"> |
|||
|
|||
<div class="card dashboard-card"> |
|||
|
|||
<h5 class="section-title"> |
|||
Vulnerability Assessment |
|||
</h5> |
|||
<div class="card-body"> |
|||
<div id="vulnerabilityDiv"></div> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
|
|||
|
|||
<!-- EDUCATION --> |
|||
|
|||
<div class="row mt-4 align-items-stretch"> |
|||
|
|||
<!-- EDUCATION STATUS --> |
|||
<div class="col-lg-4 mb-4"> |
|||
|
|||
<div class="card dashboard-card h-100"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h5 class="section-title"> |
|||
Education Status |
|||
</h5> |
|||
|
|||
<div id="educationDiv"></div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<!-- HEALTH OVERVIEW --> |
|||
<div class="col-lg-4 mb-4"> |
|||
|
|||
<div class="card dashboard-card h-100"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h5 class="section-title"> |
|||
Health Overview |
|||
</h5> |
|||
|
|||
<div id="healthDiv"></div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<!-- CERTIFICATE --> |
|||
<div class="col-lg-4 mb-4"> |
|||
|
|||
<div class="card dashboard-card h-100"> |
|||
|
|||
<div class="card-body"> |
|||
|
|||
<h5 class="section-title"> |
|||
Certificate |
|||
</h5> |
|||
|
|||
<div class="d-flex justify-content-between mb-2"> |
|||
<span>Aadhar Card</span> |
|||
<span> |
|||
Yes : |
|||
<span id="aadharYes">0</span> |
|||
|
|||
No : |
|||
<span id="aadharNo">0</span> |
|||
</span> |
|||
</div> |
|||
|
|||
<div class="d-flex justify-content-between mb-2"> |
|||
<span>Community</span> |
|||
<span> |
|||
Yes : |
|||
<span id="communityYes">0</span> |
|||
|
|||
No : |
|||
<span id="communityNo">0</span> |
|||
</span> |
|||
</div> |
|||
|
|||
<div class="d-flex justify-content-between"> |
|||
<span>Birth Certificate</span> |
|||
<span> |
|||
Yes : |
|||
<span id="birthYes">0</span> |
|||
|
|||
No : |
|||
<span id="birthNo">0</span> |
|||
</span> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
|
|||
|
|||
</div> |
|||
|
|||
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer> |
|||
</div> |
|||
</div> |
|||
|
|||
<div th:replace="~{fragments/modules/base/script :: script}"></div> |
|||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> |
|||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> |
|||
<!-- DataTables --> |
|||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/dataTables.bootstrap5.min.css"> |
|||
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.bootstrap5.min.css"> |
|||
|
|||
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script> |
|||
<script src="https://cdn.datatables.net/1.13.8/js/dataTables.bootstrap5.min.js"></script> |
|||
<script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script> |
|||
|
|||
<!-- DataTable Buttons --> |
|||
<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.bootstrap5.min.js"></script> |
|||
<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 src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script> |
|||
|
|||
|
|||
<script th:inline="javascript"> |
|||
$(document).ready(function () { |
|||
|
|||
loadDashboard(); |
|||
|
|||
}); |
|||
|
|||
function loadDashboard() { |
|||
|
|||
$.ajax({ |
|||
|
|||
url: "/gcc/api/children-survey/dashboard", |
|||
|
|||
type: "GET", |
|||
|
|||
success: function (data) { |
|||
|
|||
$("#totalChildren").text(data.totalChildren); |
|||
|
|||
$("#areasCovered").text(data.areasCovered); |
|||
|
|||
$("#maleCount").text(data.maleCount); |
|||
|
|||
$("#femaleCount").text(data.femaleCount); |
|||
|
|||
//$("#currentlyStudying").text(data.currentlyStudying); |
|||
$("#currentlyStudying").text( |
|||
data.currentlyStudying + "%" |
|||
); |
|||
|
|||
$("#age4to8").text(data.age4to8); |
|||
|
|||
$("#age9to13").text(data.age9to13); |
|||
|
|||
$("#age14to18").text(data.age14to18); |
|||
$("#aadharYes").text(data.certificateDetails.aadhar_yes || 0); |
|||
$("#aadharNo").text(data.certificateDetails.aadhar_no || 0); |
|||
|
|||
$("#communityYes").text(data.certificateDetails.community_yes || 0); |
|||
$("#communityNo").text(data.certificateDetails.community_no || 0); |
|||
|
|||
$("#birthYes").text(data.certificateDetails.birth_yes || 0); |
|||
$("#birthNo").text(data.certificateDetails.birth_no || 0); |
|||
|
|||
|
|||
// AREA WISE |
|||
|
|||
let areaHtml = ""; |
|||
|
|||
$.each(data.areaWise, function (i, row) { |
|||
|
|||
areaHtml += ` |
|||
<div class="report-row"> |
|||
|
|||
<div class="d-flex justify-content-between"> |
|||
|
|||
<span>${row.area}</span> |
|||
|
|||
<span>${row.total_children} children</span> |
|||
|
|||
</div> |
|||
|
|||
<div class="progress mt-2"> |
|||
|
|||
<div class="progress-bar bg-success" |
|||
style="width:${row.total_children}%"> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
</div> |
|||
`; |
|||
}); |
|||
|
|||
$("#areaWiseDiv").html(areaHtml); |
|||
|
|||
// VULNERABILITY |
|||
|
|||
let vulnerabilityHtml = ""; |
|||
|
|||
$.each(data.vulnerability, function (i, row) { |
|||
|
|||
vulnerabilityHtml += ` |
|||
<div class="d-flex justify-content-between mb-2"> |
|||
|
|||
<span>${row.vulnerability}</span> |
|||
|
|||
<span>${row.total}</span> |
|||
|
|||
</div> |
|||
`; |
|||
}); |
|||
|
|||
$("#vulnerabilityDiv").html(vulnerabilityHtml); |
|||
|
|||
// EDUCATION |
|||
|
|||
// EDUCATION STATUS |
|||
|
|||
let educationHtml = ` |
|||
|
|||
<div class="d-flex justify-content-between mb-2"> |
|||
|
|||
<span>Currently Studying</span> |
|||
|
|||
<span>${data.educationStatus.currently_studying || 0}</span> |
|||
|
|||
</div> |
|||
|
|||
<div class="d-flex justify-content-between mb-2"> |
|||
|
|||
<span>Not Studying</span> |
|||
|
|||
<span>${data.educationStatus.not_studying || 0}</span> |
|||
|
|||
</div> |
|||
|
|||
<div class="d-flex justify-content-between mb-2"> |
|||
|
|||
<span>Continue Education Intent</span> |
|||
|
|||
<span>${data.educationStatus.continue_education_intent || 0}</span> |
|||
|
|||
</div> |
|||
|
|||
`; |
|||
|
|||
$("#educationDiv").html(educationHtml); |
|||
|
|||
// HEALTH |
|||
|
|||
let healthHtml = ""; |
|||
|
|||
$.each(data.healthOverview, function (i, row) { |
|||
|
|||
healthHtml += ` |
|||
<div class="d-flex justify-content-between mb-2"> |
|||
|
|||
<span>${row.status}</span> |
|||
|
|||
<span>${row.total}</span> |
|||
|
|||
</div> |
|||
`; |
|||
}); |
|||
|
|||
$("#healthDiv").html(healthHtml); |
|||
|
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue