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 --> <!-- index.html -->
<!-- <!--

View File

@@ -1,72 +1,56 @@
/* import openModal from "../components/modals.js";
This script handles the admin dashboard functionality for managing doctors: import { getDoctors, filterDoctors, saveDoctor } from "./services/doctorServices.js";
- Loads all doctor cards import createDoctorCard from "./components/doctorCard.js";
- Filters doctors by name, time, or specialty
- Adds a new doctor via modal form
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 loadDoctorCards();
When clicked, it opens a modal form using openModal('addDoctor') };
export async function loadDoctorCards() {
try {
const doctors = await getDoctors();
renderDoctorCards(doctors);
} catch (error) {
console.error("Error: ", error);
}
}
When the DOM is fully loaded: export async function filterDoctorsOnChange() {
- Call loadDoctorCards() to fetch and display all doctors 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 export async function adminAddDoctor() {
Purpose: Fetch all doctors and display them as cards 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 const token = localStorage.getItem("TOKEN");
Clear the current content area if (token == 'undefined') {
For each doctor returned: throw Error("No Authentication token found!");
- Create a doctor card using createDoctorCard() }
- Append it to the content div
Handle any fetch errors by logging them saveDoctor(doctor, token);
}
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
*/

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 getAllAppointments to fetch appointments from the backend
Import createPatientRow to generate a table row for each patient appointment Import createPatientRow to generate a table row for each patient appointment

View File

@@ -1,53 +1,72 @@
/* import { API_BASE_URL } from "../config/config.js";
Import the base API URL from the config file
Define a constant DOCTOR_API to hold the full endpoint for doctor-related actions
const DOCTOR_API = API_BASE_URL + '/doctor'
Function: getDoctors export async function getDoctors() {
Purpose: Fetch the list of all doctors from the API 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 export async function deleteDoctor(id, token) {
Convert the response to JSON try {
Return the 'doctors' array from the response const response = await fetch(`${DOCTOR_API}/${id}/{token}`, {
If there's an error (e.g., network issue), log it and return an empty array 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 export async function filterDoctors(name ,time ,specialty) {
Purpose: Delete a specific doctor using their ID and an authentication token try {
const response = await fetch(`${DOCTOR_API}?name=${name}&time=${time}&specialty=${specialty}`, {
Use fetch() with the DELETE method method: 'GET',
- The URL includes the doctor ID and token as path parameters headers: { 'Content-Type': 'application/json' },
Convert the response to JSON })
Return an object with: const result = await response.json();
- success: true if deletion was successful if (!response.ok) {
- message: message from the server throw new Error(result.message);
If an error occurs, log it and return a default failure response }
return response.doctors;
} catch (error) {
Function: saveDoctor console.error("Error :: filterDoctors :: ", error)
Purpose: Save (create) a new doctor using a POST request return [];
}
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
*/

View File

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