Completed Developing Services and Utilities
This commit is contained in:
@@ -1,3 +1,14 @@
|
|||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="module" src="js/services/index.js" defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- index.html -->
|
<!-- index.html -->
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
*/
|
|
||||||
@@ -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
|
||||||
@@ -51,4 +99,4 @@
|
|||||||
When the page is fully loaded (DOMContentLoaded):
|
When the page is fully loaded (DOMContentLoaded):
|
||||||
- Call renderContent() (assumes it sets up the UI layout)
|
- Call renderContent() (assumes it sets up the UI layout)
|
||||||
- Call loadAppointments() to display today's appointments by default
|
- Call loadAppointments() to display today's appointments by default
|
||||||
*/
|
*/
|
||||||
@@ -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
|
|
||||||
*/
|
|
||||||
@@ -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
|
|
||||||
*/
|
|
||||||
Reference in New Issue
Block a user