Completed Developing Services and Utilities

This commit is contained in:
2025-11-06 17:54:02 +01:00
parent c19d40e88c
commit 7f968413b3
5 changed files with 227 additions and 165 deletions

View File

@@ -1,3 +1,14 @@
<html lang="en">
<body>
<script type="module" src="js/services/index.js" defer></script>
</body>
</html>
<!-- index.html -->
<!--

View File

@@ -1,72 +1,56 @@
/*
This script handles the admin dashboard functionality for managing doctors:
- Loads all doctor cards
- Filters doctors by name, time, or specialty
- Adds a new doctor via modal form
import openModal from "../components/modals.js";
import { getDoctors, filterDoctors, saveDoctor } from "./services/doctorServices.js";
import createDoctorCard from "./components/doctorCard.js";
window.onload = function () {
document.getElementById("searchBar").addEventListener("input", filterDoctorsOnChange);
document.getElementById("filterTime").addEventListener("change", filterDoctorsOnChange);
document.getElementById("filterSpecialty").addEventListener("change", filterDoctorsOnChange);
document.getElementById('addDocBtn').addEventListener('click', () => { openModal('addDoctor'); });
Attach a click listener to the "Add Doctor" button
When clicked, it opens a modal form using openModal('addDoctor')
loadDoctorCards();
};
export async function loadDoctorCards() {
try {
const doctors = await getDoctors();
renderDoctorCards(doctors);
} catch (error) {
console.error("Error: ", error);
}
}
When the DOM is fully loaded:
- Call loadDoctorCards() to fetch and display all doctors
export async function filterDoctorsOnChange() {
const name = document.getElementById("searchBar").value;
const time = document.getElementById("filterTime").value;
const specialty = document.getElementById("filterSpecialty").value;
const doctors = filterDoctors(name, time, specialty);
renderDoctorCards(doctors);
}
export async function renderDoctorCards(doctors) {
const contentDiv = document.getElementById("content");
contentDiv.innerHTML = "";
for (doctor : doctors) {
const card = createDoctorCard(doctor);
contentDiv.appendChild(card);
}
}
Function: loadDoctorCards
Purpose: Fetch all doctors and display them as cards
export async function adminAddDoctor() {
const doctor = {
"name": document.getElementById("doctorName").value,
"email": document.getElementById("doctorEmail").value,
"password": document.getElementById("doctorPassword").value,
"speciality": document.getElementById("specialization").value,
"phone": document.getElementById("doctorPhone").value,
"availability": document.querySelectorAll('input[name=availability]:checked').map(e => e.value)
}
Call getDoctors() from the service layer
Clear the current content area
For each doctor returned:
- Create a doctor card using createDoctorCard()
- Append it to the content div
const token = localStorage.getItem("TOKEN");
if (token == 'undefined') {
throw Error("No Authentication token found!");
}
Handle any fetch errors by logging them
Attach 'input' and 'change' event listeners to the search bar and filter dropdowns
On any input change, call filterDoctorsOnChange()
Function: filterDoctorsOnChange
Purpose: Filter doctors based on name, available time, and specialty
Read values from the search bar and filters
Normalize empty values to null
Call filterDoctors(name, time, specialty) from the service
If doctors are found:
- Render them using createDoctorCard()
If no doctors match the filter:
- Show a message: "No doctors found with the given filters."
Catch and display any errors with an alert
Function: renderDoctorCards
Purpose: A helper function to render a list of doctors passed to it
Clear the content area
Loop through the doctors and append each card to the content area
Function: adminAddDoctor
Purpose: Collect form data and add a new doctor to the system
Collect input values from the modal form
- Includes name, email, phone, password, specialty, and available times
Retrieve the authentication token from localStorage
- If no token is found, show an alert and stop execution
Build a doctor object with the form values
Call saveDoctor(doctor, token) from the service
If save is successful:
- Show a success message
- Close the modal and reload the page
If saving fails, show an error message
*/
saveDoctor(doctor, token);
}

View File

@@ -1,3 +1,51 @@
import getAllAppointments from "./services/appointmentRecordService.js";
import createPatientRow from "./components/patientRows.js";
const patientTable = document.getElementById("patientTableBody");
const token = localStorage.getItem("TOKEN");
var selectedDate = new Date();
var patientName = null;
window.onload = function () {
document.getElementById("searchBar").addEventListener("input", filterPatientsOnChange);
document.getElementById('todayButton').addEventListener('click', () => {
selectedDate = new Date();
document.getElementById('datePicker').value = selectedDate;
loadAppointments();
});
document.getElementById('datePicker').addEventListener('click', () => {
selectedDate = document.getElementById('datePicker').value;
loadAppointments();
});
}
export async function filterPatientsOnChange() {
patientName = document.getElementById("searchBar").value.trim();
if (patientName == "") {
patientName = null;
}
loadAppointments();
}
export async loadAppointments() {
try {
const appointments = await getAllAppointments(selectedDate, patientName, token);
if (appointments.length == 0) {
patientTable.innerHTML = "<tr><td>No Appointments found for today</td></tr>”;
return;
}
patientTable.innerHTML = "";
for (appointment : appointments) {
const row = createPatientRow(appointment.patient, appointment.id, appointment.doctorId);
patientTable.appendChild(row);
}
} catch (error) {
console.error("Error: ", error);
patientTable.innerHTML = "<tr><td>Failed to load appointments</td></tr>;
}
}
/*
Import getAllAppointments to fetch appointments from the backend
Import createPatientRow to generate a table row for each patient appointment

View File

@@ -1,53 +1,72 @@
/*
Import the base API URL from the config file
Define a constant DOCTOR_API to hold the full endpoint for doctor-related actions
import { API_BASE_URL } from "../config/config.js";
const DOCTOR_API = API_BASE_URL + '/doctor'
Function: getDoctors
Purpose: Fetch the list of all doctors from the API
export async function getDoctors() {
try {
const response = await fetch(DOCTOR_API, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
const result = await response.json();
if (!response.ok) {
throw new Error(result.message);
}
return response.doctors;
} catch (error) {
console.log("Error fetching doctors:", error);
return [];
}
}
Use fetch() to send a GET request to the DOCTOR_API endpoint
Convert the response to JSON
Return the 'doctors' array from the response
If there's an error (e.g., network issue), log it and return an empty array
export async function deleteDoctor(id, token) {
try {
const response = await fetch(`${DOCTOR_API}/${id}/{token}`, {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' }
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.message);
}
return { success: response.ok, message: result.message }
} catch (error) {
console.error("Error :: deleteDoctor :: ", error)
return { success: false, message: error.message }
}
}
export async function saveDoctor(doctor, token) {
try {
const response = await fetch(`${DOCTOR_API}/${token}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(doctor)
})
const result = await response.json();
if (!response.ok) {
throw new Error(result.message);
}
return { success: response.ok, message: result.message }
} catch (error) {
console.error("Error :: saveDoctor :: ", error)
return { success: false, message: error.message }
}
}
Function: deleteDoctor
Purpose: Delete a specific doctor using their ID and an authentication token
Use fetch() with the DELETE method
- The URL includes the doctor ID and token as path parameters
Convert the response to JSON
Return an object with:
- success: true if deletion was successful
- message: message from the server
If an error occurs, log it and return a default failure response
Function: saveDoctor
Purpose: Save (create) a new doctor using a POST request
Use fetch() with the POST method
- URL includes the token in the path
- Set headers to specify JSON content type
- Convert the doctor object to JSON in the request body
Parse the JSON response and return:
- success: whether the request succeeded
- message: from the server
Catch and log errors
- Return a failure response if an error occurs
Function: filterDoctors
Purpose: Fetch doctors based on filtering criteria (name, time, and specialty)
Use fetch() with the GET method
- Include the name, time, and specialty as URL path parameters
Check if the response is OK
- If yes, parse and return the doctor data
- If no, log the error and return an object with an empty 'doctors' array
Catch any other errors, alert the user, and return a default empty result
*/
export async function filterDoctors(name ,time ,specialty) {
try {
const response = await fetch(`${DOCTOR_API}?name=${name}&time=${time}&specialty=${specialty}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
})
const result = await response.json();
if (!response.ok) {
throw new Error(result.message);
}
return response.doctors;
} catch (error) {
console.error("Error :: filterDoctors :: ", error)
return [];
}
}

View File

@@ -1,58 +1,58 @@
/*
Import the openModal function to handle showing login popups/modals
Import the base API URL from the config file
Define constants for the admin and doctor login API endpoints using the base URL
import openModal from "../components/modals.js";
import { API_BASE_URL } from "../config/config.js"
Use the window.onload event to ensure DOM elements are available after page load
Inside this function:
- Select the "adminLogin" and "doctorLogin" buttons using getElementById
- If the admin login button exists:
- Add a click event listener that calls openModal('adminLogin') to show the admin login modal
- If the doctor login button exists:
- Add a click event listener that calls openModal('doctorLogin') to show the doctor login modal
const ADMIN_API = API_BASE_URL + '/admin';
const DOCTOR_API = API_BASE_URL + '/doctor/login'
window.onload = function () {
Define a function named adminLoginHandler on the global window object
This function will be triggered when the admin submits their login credentials
const adminBtn = document.getElementById('adminLogin');
if (adminBtn) {
adminBtn.addEventListener('click', () => {
openModal('adminLogin');
});
}
Step 1: Get the entered username and password from the input fields
Step 2: Create an admin object with these credentials
const doctorBtn = document.getElementById('doctorLogin');
if (doctorBtn) {
doctorBtn.addEventListener('click', () => {
openModal('doctorLogin');
});
}
}
Step 3: Use fetch() to send a POST request to the ADMIN_API endpoint
- Set method to POST
- Add headers with 'Content-Type: application/json'
- Convert the admin object to JSON and send in the body
export async function adminLoginHandler() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const admin = { username, password };
try {
await fetch(ADMIN_API, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(admin)
})
.then(response => response.json())
.then(json => localStorage.setItem("TOKEN", json))
.then(item -> selectRole('admin'))
} catch (error) {
alert("Invalid credentials!");
}
}
Step 4: If the response is successful:
- Parse the JSON response to get the token
- Store the token in localStorage
- Call selectRole('admin') to proceed with admin-specific behavior
Step 5: If login fails or credentials are invalid:
- Show an alert with an error message
Step 6: Wrap everything in a try-catch to handle network or server errors
- Show a generic error message if something goes wrong
Define a function named doctorLoginHandler on the global window object
This function will be triggered when a doctor submits their login credentials
Step 1: Get the entered email and password from the input fields
Step 2: Create a doctor object with these credentials
Step 3: Use fetch() to send a POST request to the DOCTOR_API endpoint
- Include headers and request body similar to admin login
Step 4: If login is successful:
- Parse the JSON response to get the token
- Store the token in localStorage
- Call selectRole('doctor') to proceed with doctor-specific behavior
Step 5: If login fails:
- Show an alert for invalid credentials
Step 6: Wrap in a try-catch block to handle errors gracefully
- Log the error to the console
- Show a generic error message
*/
export async function doctorLoginHandler() {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
const doctor = { email, password };
try {
await fetch(DOCTOR_API, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(doctor)
})
.then(response => response.json())
.then(json => localStorage.setItem("TOKEN", json))
.then(item -> selectRole('doctor'))
} catch (error) {
alert("Invalid credentials!");
}
}