Skip to content
Snippets Groups Projects
Commit c3bb12e5 authored by Burhan Akbar's avatar Burhan Akbar
Browse files

approved hospitals shown only

See merge request !78
parent ea5a1b1a
No related branches found
No related tags found
1 merge request!82Resolve "As a user I would like to be able to add nursing homes information, so that the system can record new facilities."
......@@ -3,18 +3,24 @@ package com.cardiff.client_project.controller.nursinghome;
import com.cardiff.client_project.pojo.dto.HospitalDTO;
import com.cardiff.client_project.service.NursingHomeService;
import com.cardiff.client_project.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/hospitals")
@CrossOrigin(origins = "*")
public class NursingHomeController {
private final NursingHomeService nursingHomeService;
@Autowired
private NursingHomeService nursingHomeService;
public NursingHomeController(NursingHomeService nursingHomeService) {
this.nursingHomeService = nursingHomeService;
}
// READ - Get available beds
@GetMapping("/available")
......@@ -58,4 +64,41 @@ public class NursingHomeController {
return Result.error("Error deleting hospital: " + e.getMessage());
}
}
@GetMapping("/search")
public Result<List<HospitalDTO>> searchHospitals(@RequestParam(required = false) String name) {
try {
if (name == null || name.trim().isEmpty()) {
return nursingHomeService.getAvailableBeds();
}
return nursingHomeService.searchHospitals(name.trim());
} catch (Exception e) {
log.error("Search error: ", e);
return Result.error("Search failed: " + e.getMessage());
}
}
@PutMapping("/{id}/approval")
public Result<String> updateApprovalStatus(
@PathVariable Integer id,
@RequestParam String status) {
try {
log.info("Updating approval status for hospital {}: {}", id, status);
return nursingHomeService.updateApprovalStatus(id, status);
} catch (Exception e) {
log.error("Error updating approval status: ", e);
return Result.error("Failed to update approval status");
}
}
@GetMapping("/pending")
public Result<List<HospitalDTO>> getPendingApprovals() {
try {
log.info("Fetching pending approvals");
return nursingHomeService.getPendingApprovals();
} catch (Exception e) {
log.error("Error fetching pending approvals: ", e);
return Result.error("Failed to fetch pending approvals");
}
}
}
......@@ -5,6 +5,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
......@@ -13,33 +15,64 @@ public class NursingHomeMapper {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<HospitalDTO> searchHospitals(String name) {
String sql = """
SELECT
id, name, address, phone, maxAmount,
amountPatient, status, approval_status
FROM hospital
WHERE status = 1
AND name LIKE CONCAT('%', ?, '%')
ORDER BY name ASC
""";
return jdbcTemplate.query(sql,
ps -> ps.setString(1, name),
this::mapToDTO);
}
public List<HospitalDTO> findAllNursingHomes() {
String sql = """
SELECT
id,
name,
address,
phone,
maxAmount,
amountPatient,
status
id, name, address, phone, maxAmount,
amountPatient, status, approval_status
FROM hospital
WHERE status = 1
""";
return jdbcTemplate.query(sql, (rs, rowNum) -> {
HospitalDTO dto = new HospitalDTO();
dto.setId(rs.getInt("id"));
dto.setName(rs.getString("name"));
dto.setLocation(rs.getString("address"));
dto.setPhone(rs.getString("phone"));
dto.setTotalBeds(rs.getInt("maxAmount"));
int maxAmount = rs.getInt("maxAmount");
int amountPatient = rs.getInt("amountPatient");
dto.setAvailableBeds(maxAmount - amountPatient);
dto.setOccupancyRate(calculateOccupancy(maxAmount, amountPatient));
return dto;
});
return jdbcTemplate.query(sql, this::mapToDTO);
}
public List<HospitalDTO> getPendingApprovals() {
String sql = """
SELECT
id, name, address, phone, maxAmount,
amountPatient, status, approval_status
FROM hospital
WHERE approval_status = 'PENDING'
""";
return jdbcTemplate.query(sql, this::mapToDTO);
}
public int updateApprovalStatus(int id, String status) {
String sql = "UPDATE hospital SET approval_status = ? WHERE id = ?";
return jdbcTemplate.update(sql, status, id);
}
private HospitalDTO mapToDTO(ResultSet rs, int rowNum) throws SQLException {
HospitalDTO dto = new HospitalDTO();
dto.setId(rs.getInt("id"));
dto.setName(rs.getString("name"));
dto.setLocation(rs.getString("address"));
dto.setPhone(rs.getString("phone"));
int maxAmount = rs.getInt("maxAmount");
int amountPatient = rs.getInt("amountPatient");
dto.setTotalBeds(maxAmount);
dto.setAvailableBeds(maxAmount - amountPatient);
dto.setOccupancyRate(calculateOccupancy(maxAmount, amountPatient));
dto.setApprovalStatus(rs.getString("approval_status"));
return dto;
}
private double calculateOccupancy(int maxAmount, int amountPatient) {
......@@ -49,15 +82,10 @@ public class NursingHomeMapper {
public int insertHospital(HospitalDTO dto) {
String sql = """
INSERT INTO hospital (
name,
address,
phone,
maxAmount,
amountPatient,
status,
type,
roleId
) VALUES (?, ?, ?, ?, ?, 1, 'hospital', 3)
name, address, phone, maxAmount,
amountPatient, status, type, roleId,
approval_status
) VALUES (?, ?, ?, ?, ?, 1, 'hospital', 3, 'PENDING')
""";
return jdbcTemplate.update(sql,
......
......@@ -12,4 +12,5 @@ public class HospitalDTO {
private int totalBeds;
private int availableBeds;
private double occupancyRate;
private String approvalStatus;
}
\ No newline at end of file
......@@ -15,4 +15,6 @@ public class HospitalVO {
private String status_str;
private int maxAmount;
private int amountPatient;
private String approvalStatus;
private String approvalStatus_str;
}
......@@ -11,4 +11,7 @@ public interface NursingHomeService {
Result<String> deletePatientById(List<Integer> ids);
Result<List<HospitalDTO>> getAllPatients();
Result<String> updateBedCount(int hospitalId, int currentPatients);
Result<List<HospitalDTO>> searchHospitals(String name);
Result<String> updateApprovalStatus(Integer hospitalId, String status);
Result<List<HospitalDTO>> getPendingApprovals();
}
\ No newline at end of file
......@@ -7,27 +7,40 @@ import com.cardiff.client_project.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class NursingHomeServiceImp implements NursingHomeService {
private final NursingHomeMapper nursingHomeMapper;
@Autowired
private NursingHomeMapper nursingHomeMapper;
public NursingHomeServiceImp(NursingHomeMapper nursingHomeMapper) {
this.nursingHomeMapper = nursingHomeMapper;
}
@Override
public Result<List<HospitalDTO>> getAvailableBeds() {
try {
List<HospitalDTO> hospitals = nursingHomeMapper.findAllNursingHomes();
if (hospitals == null || hospitals.isEmpty()) {
return Result.error("No hospitals available");
hospitals = hospitals.stream()
.filter(h -> "APPROVED".equals(h.getApprovalStatus()))
.collect(Collectors.toList());
if (hospitals.isEmpty()) {
return Result.error("No approved hospitals available");
}
return Result.success(hospitals);
} catch (DataAccessException e) {
return Result.error("Database error: " + e.getMessage());
} catch (Exception e) {
return Result.error("Internal server error");
log.error("Error fetching available beds: {}", e.getMessage(), e);
return Result.error("Failed to fetch available beds");
}
}
......@@ -96,6 +109,80 @@ public class NursingHomeServiceImp implements NursingHomeService {
}
}
@Override
@Transactional(readOnly = true)
public Result<List<HospitalDTO>> searchHospitals(String name) {
try {
if (name == null || name.trim().isEmpty()) {
return Result.error("Search term cannot be empty");
}
List<HospitalDTO> hospitals = nursingHomeMapper.searchHospitals(name);
return hospitals.isEmpty() ?
Result.error("No hospitals found") :
Result.success(hospitals);
} catch (Exception e) {
log.error("Search error: ", e);
return Result.error("Search failed");
}
}
@Override
@Transactional
public Result<String> updateApprovalStatus(Integer hospitalId, String status) {
try {
log.info("Updating approval status for hospital {}: {}", hospitalId, status);
if (hospitalId == null || hospitalId <= 0) {
log.warn("Invalid hospital ID: {}", hospitalId);
return Result.error("Invalid hospital ID");
}
if (!isValidApprovalStatus(status)) {
log.warn("Invalid approval status: {}", status);
return Result.error("Invalid approval status");
}
int result = nursingHomeMapper.updateApprovalStatus(hospitalId, status);
if (result > 0) {
log.info("Successfully updated approval status for hospital {}", hospitalId);
return Result.success("Approval status updated successfully");
}
log.warn("Hospital not found with ID: {}", hospitalId);
return Result.error("Hospital not found");
} catch (DataAccessException e) {
log.error("Database error while updating approval status: {}", e.getMessage(), e);
return Result.error("Database error occurred");
} catch (Exception e) {
log.error("Unexpected error while updating approval status: {}", e.getMessage(), e);
return Result.error("Failed to update approval status");
}
}
@Override
@Transactional(readOnly = true)
public Result<List<HospitalDTO>> getPendingApprovals() {
try {
log.info("Fetching pending approval hospitals");
List<HospitalDTO> pendingHospitals = nursingHomeMapper.getPendingApprovals();
if (pendingHospitals.isEmpty()) {
log.info("No pending approvals found");
return Result.error("No pending approvals");
}
log.info("Found {} pending approvals", pendingHospitals.size());
return Result.success(pendingHospitals);
} catch (DataAccessException e) {
log.error("Database error while fetching pending approvals: {}", e.getMessage(), e);
return Result.error("Database error occurred");
} catch (Exception e) {
log.error("Unexpected error while fetching pending approvals: {}", e.getMessage(), e);
return Result.error("Failed to fetch pending approvals");
}
}
private boolean validateHospitalData(HospitalDTO hospitalDTO) {
if (hospitalDTO == null) return false;
return hospitalDTO.getName() != null &&
......@@ -108,4 +195,17 @@ public class NursingHomeServiceImp implements NursingHomeService {
hospitalDTO.getAvailableBeds() >= 0 &&
hospitalDTO.getAvailableBeds() <= hospitalDTO.getTotalBeds();
}
private boolean isValidStatus(String status) {
return status != null &&
(status.equals("APPROVED") ||
status.equals("REJECTED") ||
status.equals("PENDING"));
}
private boolean isValidApprovalStatus(String status) {
if (status == null) return false;
return List.of("PENDING", "APPROVED", "REJECTED")
.contains(status.toUpperCase());
}
}
\ No newline at end of file
......@@ -342,3 +342,20 @@ footer {
padding: 1rem;
}
.approval-pending {
background-color: var(--warning-color);
color: white;
padding: 0.25rem 0.5rem;
border-radius: 4px;
}
.approval-rejected {
background-color: var(--danger-color);
color: white;
}
.approval-approved {
background-color: var(--success-color);
color: white;
}
......@@ -13,10 +13,10 @@ $(document).ready(function () {
<nav class="top-nav">
<div class="nav-brand">Digital Insight for Health</div>
<div class="nav-items">
<a href="/dashboard" class="nav-link">
<a href="/superAdminView.html?type=hospital" class="nav-link">
<i class="fas fa-home"></i> Home
</a>
<a href="/beds" class="nav-link active">
<a href="/beds.html" class="nav-link active">
<i class="fas fa-bed"></i> Beds
</a>
<button class="nav-link sign-out" onclick="handleSignOut()">
......@@ -52,35 +52,46 @@ $(document).ready(function () {
function updateTable(hospitals) {
const tbody = $('#hospitalTable tbody');
tbody.empty();
if (!hospitals || hospitals.length === 0) {
showNoDataMessage();
return;
}
hospitals.forEach(function(hospital) {
const tr = `
<tr>
<td>${hospital.id}</td>
<td>${hospital.name || ''}</td>
<td>${hospital.location || ''}</td>
<td>${hospital.phone || ''}</td>
<td>${hospital.totalBeds || 0}</td>
<td>${hospital.availableBeds || 0}</td>
<td>${Math.round(hospital.occupancyRate)}%</td>
<td>
<button class="btn edit-btn" data-id="${hospital.id}">
<i class="fas fa-edit"></i>
</button>
<button class="btn delete-btn" data-id="${hospital.id}">
<i class="fas fa-trash"></i>
</button>
</td>
</tr>
`;
tbody.append(tr);
// Only show approved hospitals
if (hospital.approvalStatus === 'APPROVED') {
const tr = $('<tr>').append(
$('<td>').text(hospital.name),
$('<td>').text(hospital.location),
$('<td>').text(hospital.phone),
$('<td>').text(hospital.totalBeds),
$('<td>').text(hospital.availableBeds),
$('<td>').text(hospital.occupancyRate + '%'),
$('<td>').append(
$('<span>')
.addClass('status-badge')
.addClass('approval-' + hospital.approvalStatus.toLowerCase())
.text(hospital.approvalStatus)
)
);
tbody.append(tr);
}
});
if (tbody.children().length === 0) {
tbody.append(
$('<tr>').append(
$('<td>')
.attr('colspan', '7')
.addClass('no-data')
.text('No approved hospitals found')
)
);
}
}
function initializeEventHandlers() {
// Search Handler
$("#searchButton").click(handleSearch);
// Add Hospital Handler
$("#addHospitalBtn").click(function() {
$("#hospitalModal").fadeIn();
......@@ -159,17 +170,23 @@ $(document).ready(function () {
});
}
});
// Update event handler binding
$("#searchButton").click(handleSearch);
}
function handleSearch(event) {
event.preventDefault();
const searchTerm = $("#searchName").val().trim();
if (!searchTerm) {
loadHospitals();
return;
}
$.ajax({
url: `${API_BASE_URL}/search`,
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({ name: searchTerm }),
url: `${API_BASE_URL}/search?name=${encodeURIComponent(searchTerm)}`,
method: 'GET',
success: function(response) {
if(response && response.code === 1) {
updateTable(response.data || []);
......@@ -177,7 +194,10 @@ $(document).ready(function () {
showError('No hospitals found');
}
},
error: handleAjaxError
error: function(xhr) {
console.error('Search Error:', xhr);
showError('Search failed');
}
});
}
......@@ -326,11 +346,26 @@ $(document).ready(function () {
$('<style>').text(styles).appendTo('head');
// Initialize tooltips and other UI enhancements
$('[data-toggle="tooltip"]').tooltip();
// Add fade effects for smoother transitions
$('.table-container').hide().fadeIn();
// Add new function for admin approval handling
function handleApproval(hospitalId, status) {
$.ajax({
url: `${API_BASE_URL}/approval/${hospitalId}`,
method: 'PUT',
data: { status: status },
success: function(response) {
if(response.code === 1) {
showSuccess(`Hospital ${status.toLowerCase()} successfully`);
loadHospitals();
} else {
showError(response.msg || DEFAULT_ERROR);
}
},
error: handleAjaxError
});
}
});
function handleSignOut() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment