├── .gitignore ├── AI MedLab.pptx ├── AI-MedLab-Documentation.doc ├── LICENSE ├── backend ├── Controllers │ ├── adminController.js │ ├── authController.js │ ├── bookingController.js │ ├── doctorController.js │ ├── helathPredict.js │ ├── predictionControler.js │ ├── reviewContoller.js │ └── userController.js ├── HealthPredict │ ├── Symptom-severity.csv │ ├── Training.csv │ ├── description.csv │ ├── diets.csv │ ├── medications.csv │ ├── precautions_df.csv │ ├── symtoms_df.csv │ └── workout_df.csv ├── Routes │ ├── admin.js │ ├── auth.js │ ├── booking.js │ ├── contact.js │ ├── disease.js │ ├── doctor.js │ ├── forgot-password.js │ ├── healthPredict.js │ ├── review.js │ └── user.js ├── aimodels │ ├── LiverDisease.pkl │ ├── breast_cancer.pkl │ ├── diabetes.pkl │ ├── heart.pkl │ ├── kidney.pkl │ ├── liver.pkl │ ├── malaria.h5 │ ├── pneumonia.h5 │ └── svc.pkl ├── auth │ └── verifyToken.js ├── breast-cancer.py ├── db-models │ ├── BookingSchema.js │ ├── DoctorSchema.js │ ├── ReviewSchema.js │ └── UserSchema.js ├── heart.py ├── index.js ├── kidney.py ├── liver.py ├── malaria.py ├── models │ ├── BookingSchema.js │ ├── DoctorSchema.js │ ├── ReviewSchema.js │ └── UserSchema.js ├── package-lock.json ├── package.json ├── pneumonia.py ├── predict.py ├── public │ └── uploads │ │ ├── 1711177594413-NORMAL (8).jpeg │ │ ├── 1711189602609-NORMAL (2).jpeg │ │ ├── 1711191105737-PNEUMONIA (11).jpeg │ │ ├── 1711191128466-PNEUMONIA (12).jpeg │ │ ├── 1711192334463-NORMAL (3).jpeg │ │ ├── 1711192351061-PNEUMONIA (11).jpeg │ │ ├── 1711192719082-p1.png │ │ ├── 1711192798526-p2.png │ │ ├── 1711192902686-p2.png │ │ └── 1711192929321-u3.png ├── requirements.txt └── symptoms.py ├── frontend ├── .eslintrc.cjs ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── img │ │ ├── background-image.png │ │ ├── bruce-mars.jpeg │ │ ├── devto.svg │ │ ├── favicon.png │ │ ├── github.svg │ │ ├── home-decor-1.jpeg │ │ ├── home-decor-2.jpeg │ │ ├── home-decor-3.jpeg │ │ ├── home-decor-4.jpeg │ │ ├── logo-asana.svg │ │ ├── logo-atlassian.svg │ │ ├── logo-ct-dark.png │ │ ├── logo-ct.png │ │ ├── logo-invision.svg │ │ ├── logo-jira.svg │ │ ├── logo-slack.svg │ │ ├── logo-spotify.svg │ │ ├── logo-xd.svg │ │ ├── pattern.png │ │ ├── team-1.jpeg │ │ ├── team-2.jpeg │ │ ├── team-3.jpeg │ │ ├── team-4.jpeg │ │ └── twitter-logo.svg │ └── vite.svg ├── src │ ├── App.css │ ├── App.jsx │ ├── Dashboard │ │ ├── doctor-account │ │ │ ├── Appointments.jsx │ │ │ ├── Dashboard.jsx │ │ │ ├── Profile.jsx │ │ │ └── Tabs.jsx │ │ └── user-account │ │ │ ├── MyAccount.jsx │ │ │ ├── MyBookings.jsx │ │ │ └── Profile.jsx │ ├── assets │ │ ├── data │ │ │ ├── doctors.js │ │ │ ├── faqs.js │ │ │ └── services.js │ │ ├── images │ │ │ ├── Blur.png │ │ │ ├── Logo1.png │ │ │ ├── Star.png │ │ │ ├── about-card.png │ │ │ ├── about.png │ │ │ ├── avatar-icon.png │ │ │ ├── default.avif │ │ │ ├── doctor-img01.png │ │ │ ├── doctor-img02.png │ │ │ ├── doctor-img03.png │ │ │ ├── faq-img.png │ │ │ ├── feature-img.png │ │ │ ├── femaleD.png │ │ │ ├── header-bg.png │ │ │ ├── hero-bg.png │ │ │ ├── hero-img01.png │ │ │ ├── hero-img02.png │ │ │ ├── hero-img03.png │ │ │ ├── icon01.png │ │ │ ├── icon02.png │ │ │ ├── icon03.png │ │ │ ├── image-tools.svg │ │ │ ├── logo.png │ │ │ ├── mask.png │ │ │ ├── p1.jpg │ │ │ ├── p2.jpg │ │ │ ├── p3.jpg │ │ │ ├── p4.jpg │ │ │ ├── p5.jpg │ │ │ ├── p6.jpg │ │ │ ├── p7.jpg │ │ │ ├── patient-avatar.png │ │ │ ├── signup.gif │ │ │ └── video-icon.png │ │ └── react.svg │ ├── components │ │ ├── About │ │ │ └── About.jsx │ │ ├── DoctorDropDown │ │ │ └── DoctorDropDown.jsx │ │ ├── Doctors │ │ │ ├── DoctorCard.jsx │ │ │ └── DoctorList.jsx │ │ ├── Error │ │ │ └── Error.jsx │ │ ├── Faq │ │ │ ├── FaqItem.jsx │ │ │ └── FaqList.jsx │ │ ├── Footer │ │ │ └── Footer.jsx │ │ ├── Header │ │ │ └── Header.jsx │ │ ├── Loader │ │ │ └── Loading.jsx │ │ ├── Services │ │ │ ├── Disease │ │ │ │ ├── BreastCancerDiseaseTest.jsx │ │ │ │ ├── DiabetesTest.jsx │ │ │ │ ├── DiseasePage.jsx │ │ │ │ ├── HeartDiseaseTest.jsx │ │ │ │ ├── KidneyDiseaseTest.jsx │ │ │ │ ├── LiverDiseaseTest.jsx │ │ │ │ ├── MalariaDiseaseTest.jsx │ │ │ │ ├── PneumoniaDiseaseTest.jsx │ │ │ │ └── ResultComponent.jsx │ │ │ ├── ServiceCard.jsx │ │ │ └── ServiceList.jsx │ │ └── Testimonial │ │ │ └── Testimonial.jsx │ ├── config.js │ ├── configs │ │ ├── charts-config.js │ │ └── index.js │ ├── context │ │ └── AuthContext.jsx │ ├── data │ │ ├── authors-table-data.js │ │ ├── conversations-data.js │ │ ├── index.js │ │ ├── orders-overview-data.js │ │ ├── platform-settings-data.js │ │ ├── projects-data.js │ │ ├── projects-table-data.js │ │ ├── statistics-cards-data.js │ │ └── statistics-charts-data.js │ ├── hooks │ │ └── useFetchData.jsx │ ├── index.css │ ├── layout │ │ ├── Admin-Layout.jsx │ │ ├── Layout.jsx │ │ └── pages │ │ │ └── Admin-Update.jsx │ ├── main.jsx │ ├── pages │ │ ├── Admin-Bookings.jsx │ │ ├── Admin-Doctors.jsx │ │ ├── Admin-Home.jsx │ │ ├── Admin-Users.jsx │ │ ├── CheckoutSuccess.jsx │ │ ├── Contact.jsx │ │ ├── DeleteDoctor.jsx │ │ ├── DeleteUser.jsx │ │ ├── Doctors │ │ │ ├── DoctorAbout.jsx │ │ │ ├── DoctorDetails.jsx │ │ │ ├── Doctors.jsx │ │ │ ├── Feedback.jsx │ │ │ ├── FeedbackForm.jsx │ │ │ └── SidePanel.jsx │ │ ├── ForgotPassword.jsx │ │ ├── Home.jsx │ │ ├── Login.jsx │ │ ├── ResetPassword.jsx │ │ ├── Services.jsx │ │ ├── Signup.jsx │ │ └── Symptomchk.jsx │ ├── routes │ │ ├── ProtectedRoute.jsx │ │ └── Routers.jsx │ ├── utils │ │ ├── convertTime.js │ │ ├── formatDate.js │ │ └── uploadCloudinary.js │ └── widgets │ │ ├── cards │ │ ├── index.js │ │ └── statistics-card.jsx │ │ ├── charts │ │ ├── index.js │ │ └── statistics-chart.jsx │ │ └── layout │ │ ├── configurator.jsx │ │ ├── dashboard-navbar.jsx │ │ ├── footer.jsx │ │ ├── index.js │ │ ├── navbar.jsx │ │ └── sidenav.jsx ├── tailwind.config.js └── vite.config.js ├── readme.md └── run commands.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # frontend 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | .env.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | 27 | # backend 28 | /node_modules 29 | .env -------------------------------------------------------------------------------- /AI MedLab.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/AI MedLab.pptx -------------------------------------------------------------------------------- /AI-MedLab-Documentation.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/AI-MedLab-Documentation.doc -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Abdul Wahab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /backend/Controllers/adminController.js: -------------------------------------------------------------------------------- 1 | import User from "../models/UserSchema.js"; 2 | import Doctor from "../models/DoctorSchema.js"; 3 | import Booking from "../models/BookingSchema.js"; 4 | 5 | export const getAllUsers = async (req, res) => { 6 | try { 7 | const users = await User.find({}).select("-password"); 8 | res.status(200).json({ 9 | success: true, 10 | message: "Users Found", 11 | data: users, 12 | }); 13 | } catch (err) { 14 | res.status(404).json({ 15 | success: false, 16 | message: "No Users found", 17 | }); 18 | } 19 | }; 20 | 21 | export const deleteUserById = async (req, res) => { 22 | try { 23 | const id = req.params.id; 24 | // Log received user ID 25 | console.log("Received User ID:", id); 26 | 27 | const deletedUser = await User.findByIdAndDelete(id); // Find and delete user by ID 28 | if (!deletedUser) { 29 | return res 30 | .status(404) 31 | .json({ success: false, message: "User not found" }); 32 | } 33 | res 34 | .status(200) 35 | .json({ success: true, message: "User deleted successfully" }); 36 | } catch (error) { 37 | console.error("Error deleting user:", error); 38 | res.status(500).json({ success: false, message: "Internal Server Error" }); 39 | } 40 | }; 41 | export const deleteDoctorById = async (req, res) => { 42 | try { 43 | const id = req.params.id; 44 | // Log received user ID 45 | console.log("Received User ID:", id); 46 | 47 | const deletedUser = await Doctor.findByIdAndDelete(id); // Find and delete user by ID 48 | if (!deletedUser) { 49 | return res 50 | .status(404) 51 | .json({ success: false, message: "User not found" }); 52 | } 53 | res 54 | .status(200) 55 | .json({ success: true, message: "User deleted successfully" }); 56 | } catch (error) { 57 | console.error("Error deleting user:", error); 58 | res.status(500).json({ success: false, message: "Internal Server Error" }); 59 | } 60 | }; 61 | 62 | export const getAllDoctors = async (req, res) => { 63 | try { 64 | const doctors = await Doctor.find({}).select("-password"); 65 | res.status(200).json({ 66 | success: true, 67 | message: "Doctors Found", 68 | data: doctors, 69 | }); 70 | } catch (err) { 71 | res.status(404).json({ 72 | success: false, 73 | message: "No Doctors found", 74 | }); 75 | } 76 | }; 77 | export const getAllBookings = async (req, res) => { 78 | try { 79 | const bookings = await Booking.find({}); 80 | 81 | res.status(200).json({ 82 | counts: bookings.length, 83 | success: true, 84 | message: "Bookings Found", 85 | data: bookings, 86 | }); 87 | } catch (err) { 88 | res.status(404).json({ 89 | success: false, 90 | message: "No Bookings Found", 91 | }); 92 | } 93 | }; 94 | 95 | export const updateDoctorApprovalStatus = async (req, res) => { 96 | const { id } = req.params; 97 | const { isApproved } = req.body; 98 | 99 | if (!["pending", "approved", "cancelled"].includes(isApproved)) { 100 | return res.status(400).json({ message: "Invalid approval status" }); 101 | } 102 | 103 | try { 104 | const doctor = await Doctor.findById(id); 105 | if (!doctor) { 106 | return res.status(404).json({ message: "Doctor not found" }); 107 | } 108 | 109 | doctor.isApproved = isApproved; 110 | await doctor.save(); 111 | 112 | res 113 | .status(200) 114 | .json({ message: "Approval status updated successfully", doctor }); 115 | } catch (error) { 116 | res.status(500).json({ message: "Server error", error }); 117 | } 118 | }; 119 | -------------------------------------------------------------------------------- /backend/Controllers/authController.js: -------------------------------------------------------------------------------- 1 | import User from "../models/UserSchema.js"; 2 | import Doctor from "../models/DoctorSchema.js"; 3 | import jwt from "jsonwebtoken"; 4 | import bcrypt from "bcryptjs"; 5 | 6 | const generateToken = (user) => { 7 | return jwt.sign( 8 | { id: user._id, role: user.role }, 9 | process.env.JWT_SECRET_KEY, 10 | { 11 | expiresIn: "15d", 12 | } 13 | ); 14 | }; 15 | 16 | export const register = async (req, res) => { 17 | const { email, password, name, role, photo, gender } = req.body; 18 | 19 | try { 20 | let user = null; 21 | 22 | if (role === "patient") { 23 | user = await User.findOne({ email }); 24 | } else if (role === "doctor") { 25 | user = await Doctor.findOne({ email }); 26 | } 27 | 28 | //check if user exist 29 | if (user) { 30 | return res.status(400).json({ message: "User already exist" }); 31 | } 32 | 33 | //hash password 34 | const salt = await bcrypt.genSalt(10); 35 | const hashPassword = await bcrypt.hash(password, salt); 36 | 37 | if (role === "patient") { 38 | user = new User({ 39 | name, 40 | email, 41 | password: hashPassword, 42 | photo, 43 | gender, 44 | role, 45 | }); 46 | } 47 | 48 | if (role === "doctor") { 49 | user = new Doctor({ 50 | name, 51 | email, 52 | password: hashPassword, 53 | photo, 54 | gender, 55 | role, 56 | }); 57 | } 58 | 59 | await user.save(); 60 | res 61 | .status(200) 62 | .json({ success: true, message: "User Successfully created" }); 63 | } catch (error) { 64 | res 65 | .status(500) 66 | .json({ success: false, message: "Internal server error, Try again" }); 67 | } 68 | }; 69 | 70 | export const login = async (req, res) => { 71 | const { email, password } = req.body; 72 | 73 | try { 74 | let user = null; 75 | 76 | const patient = await User.findOne({ email }); 77 | const doctor = await Doctor.findOne({ email }); 78 | const admin = await User.findOne({ email, role: "admin" }); // Add admin check 79 | 80 | if (patient) { 81 | user = patient; 82 | } 83 | if (doctor) { 84 | user = doctor; 85 | } 86 | if (admin) { 87 | // Handle admin login 88 | user = admin; 89 | } 90 | 91 | //check if user exist 92 | if (!user) { 93 | return res.status(404).json({ message: "User not found" }); 94 | } 95 | 96 | //compare password 97 | const isPasswordMatch = await bcrypt.compare(password, user.password); 98 | 99 | if (!isPasswordMatch) { 100 | return res 101 | .status(404) 102 | .json({ status: false, message: "Invalid Credentials, try again" }); 103 | } 104 | 105 | // get token 106 | const token = generateToken(user); 107 | const { password: userPassword, role, appointments, ...rest } = user._doc; 108 | res.status(200).json({ 109 | status: true, 110 | message: "Successfully login", 111 | token, 112 | data: { ...rest }, 113 | role, 114 | }); 115 | } catch (error) { 116 | console.error(error); 117 | res.status(500).json({ status: false, message: "Failed to login" }); 118 | } 119 | }; 120 | -------------------------------------------------------------------------------- /backend/Controllers/bookingController.js: -------------------------------------------------------------------------------- 1 | import User from "../models/UserSchema.js"; 2 | import Doctor from "../models/DoctorSchema.js"; 3 | import Booking from "../models/BookingSchema.js"; 4 | import Stripe from "stripe"; 5 | 6 | export const getCheckoutSession = async (req, res) => { 7 | try { 8 | //get currently booked doctor 9 | const doctor = await Doctor.findById(req.params.doctorId); 10 | const user = await User.findById(req.userId); 11 | 12 | // console.log("Doctor ticket price:", doctor.ticketPrice); 13 | 14 | const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); 15 | 16 | const session = await stripe.checkout.sessions.create({ 17 | payment_method_types: ["card"], 18 | mode: "payment", 19 | success_url: `${process.env.CLIENT_SITE_URL}/checkout-success`, 20 | cancel_url: `${req.protocol}://${req.get("host")}/doctors/${doctor.id}`, 21 | customer_email: user.email, 22 | client_reference_id: req.params.doctorId, 23 | line_items: [ 24 | { 25 | price_data: { 26 | currency: "usd", 27 | unit_amount: doctor.ticketPrice * 100, 28 | product_data: { 29 | name: doctor.name, 30 | description: doctor.bio, 31 | images: [doctor.photo], 32 | }, 33 | }, 34 | quantity: 1, 35 | }, 36 | ], 37 | }); 38 | 39 | const booking = new Booking({ 40 | doctor: doctor._id, 41 | user: user._id, 42 | ticketPrice: doctor.ticketPrice, 43 | session: session.id, 44 | }); 45 | await booking.save(); 46 | res 47 | .status(200) 48 | .json({ success: true, message: "Successfully paid", session }); 49 | } catch (err) { 50 | console.log(err); 51 | res 52 | .status(500) 53 | .json({ success: false, message: "Error creating checkout session" }); 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /backend/Controllers/doctorController.js: -------------------------------------------------------------------------------- 1 | import Booking from "../models/BookingSchema.js"; 2 | import Doctor from "../models/DoctorSchema.js"; 3 | 4 | export const updateDoctor = async (req, res) => { 5 | const id = req.params.id; 6 | try { 7 | const updateDoctor = await Doctor.findByIdAndUpdate( 8 | id, 9 | { $set: req.body }, 10 | { new: true } 11 | ); 12 | if (!updateDoctor) { 13 | return res.status(404).json({ 14 | success: false, 15 | message: "Doctor not found", 16 | }); 17 | } 18 | res.status(200).json({ 19 | success: true, 20 | message: "Successfully updated", 21 | data: updateDoctor, 22 | }); 23 | } catch (error) { 24 | console.error("Error updating Doctor:", error); 25 | res.status(500).json({ 26 | success: false, 27 | message: "Failed to update doctor", 28 | error: error.message, // Include error message in the response 29 | }); 30 | } 31 | }; 32 | 33 | export const deleteDoctor = async (req, res) => { 34 | const id = req.params.id; 35 | try { 36 | await Doctor.findById(id); 37 | res.status(200).json({ 38 | success: true, 39 | message: "Successfully deleted", 40 | data: deleteDoctor, 41 | }); 42 | } catch (error) { 43 | res.status(500).json({ 44 | success: false, 45 | message: "Failed to delete", 46 | }); 47 | } 48 | }; 49 | 50 | export const getSingleDoctor = async (req, res) => { 51 | const id = req.params.id; 52 | try { 53 | const doctor = await Doctor.findById(id) 54 | .populate("reviews") 55 | .select("-password"); 56 | res.status(200).json({ 57 | success: true, 58 | message: "Doctor Found", 59 | data: doctor, 60 | }); 61 | } catch (error) { 62 | res.status(404).json({ 63 | success: false, 64 | message: "Failed to find Doctor", 65 | }); 66 | } 67 | }; 68 | 69 | export const getAllDoctors = async (req, res) => { 70 | const id = req.params.id; 71 | try { 72 | const { query } = req.query; 73 | let doctors; 74 | 75 | if (query) { 76 | doctors = await Doctor.find({ 77 | isApproved: "approved", 78 | $or: [ 79 | { name: { $regex: query, $options: "i" } }, 80 | { specialization: { $regex: query, $options: "i" } }, 81 | ], 82 | }).select("-password"); 83 | } else { 84 | doctors = await Doctor.find({ isApproved: "approved" }).select( 85 | "-password" 86 | ); 87 | } 88 | 89 | res.status(200).json({ 90 | success: true, 91 | message: "Doctors Found", 92 | data: doctors, 93 | }); 94 | } catch (error) { 95 | res.status(404).json({ 96 | success: false, 97 | message: "No Doctors found", 98 | }); 99 | } 100 | }; 101 | 102 | export const getDoctorProfile = async (req, res) => { 103 | const doctorId = req.doctorId; 104 | // console.log("Doctor ID:", doctorId); 105 | 106 | try { 107 | const doctor = await Doctor.findById(doctorId); 108 | // console.log("Retrieved doctor profile:", doctor); 109 | 110 | if (!doctor) { 111 | return res 112 | .status(404) 113 | .json({ success: false, message: "Doctor not found" }); 114 | } 115 | 116 | const { password, ...rest } = doctor._doc; 117 | const appointments = await Booking.find({ doctor: doctorId }); 118 | 119 | res.status(200).json({ 120 | success: true, 121 | message: "Profile info is getting", 122 | data: { ...rest, appointments }, 123 | }); 124 | } catch (error) { 125 | // console.error("Error fetching doctor profile:", error); 126 | res.status(500).json({ 127 | success: false, 128 | message: "Someting went wrong, cannot get this", 129 | error: error.message, 130 | }); 131 | } 132 | }; 133 | -------------------------------------------------------------------------------- /backend/Controllers/predictionControler.js: -------------------------------------------------------------------------------- 1 | import pickle from "pickle"; 2 | import fs from "fs"; 3 | import PythonShell from "python-shell"; 4 | 5 | const modelPath = "aimodels/diabetes.pkl"; 6 | 7 | // const diabetesModel = pickle.loads(diabetesModelBuffer); 8 | 9 | // Function to load the diabetes model 10 | // const diabetesModelBuffer = fs.readFileSync("aimodels/diabetes.pkl"); 11 | // const diabetesModel = nodePickle.loads(diabetesModelBuffer); 12 | 13 | // Load the diabetes model 14 | // const diabetesModel = loadDiabetesModel(); 15 | // const tf = require("@tensorflow/tfjs-node"); 16 | 17 | // process.env.PYTHON = 18 | // "C:\\Users\\Gujrat laptops\\AppData\\Local\\Programs\\Python\\Python37\\python.exe"; 19 | // Load machine learning models 20 | // const diabetesModelBuffer = fs.readFileSync("models/diabetes.pkl"); 21 | // const diabetesModel = pickle.loads(diabetesModelBuffer); 22 | 23 | // const diabetesModel = pickle.loads("models/diabetes.pkl"); 24 | // const cancerModel = pickle.loads("models/breast_cancer.pkl"); 25 | // const heartModel = pickle.loads("models/heart.pkl"); 26 | // const kidneyModel = pickle.loads("models/kidney.pkl"); 27 | // const liverModel = pickle.loads("models/LiverDisease.pkl"); 28 | // const malariaModel = tf.loadLayersModel("models/malaria.h5"); 29 | // const pneumoniaModel = tf.loadLayersModel("models/pneumonia.h5"); 30 | 31 | // Route handler functions 32 | export const predictDiabetes = (req, res) => { 33 | const data = req.body; 34 | console.log("data: ", data); 35 | let options = { 36 | mode: "text", 37 | // pythonPath:'C:/Users/Gujrat laptops/.pyenv/pyenv-win/versions/3.7.4/python.exe', 38 | args: [JSON.stringify(data)], 39 | pythonOptions: ["-u"], 40 | }; 41 | 42 | // Use PythonShell to run the Python script 43 | PythonShell.run("predict.py", options, (err, result) => { 44 | if (err) { 45 | console.error(err); 46 | res.status(500).send("Internal Server Error"); 47 | } else { 48 | // Parse the result and send it back to the client 49 | const prediction = JSON.parse(result); 50 | res.json({ prediction }); 51 | } 52 | }); 53 | // Handle diabetes prediction 54 | // const input = req.body.input; // Assuming input data is passed in the request body 55 | // const prediction = diabetesModel.predict(input); 56 | // res.json({ prediction }); 57 | }; 58 | 59 | export const predictCancer = (req, res) => { 60 | // Handle cancer prediction 61 | const input = req.body.input; 62 | const prediction = cancerModel.predict(input); 63 | res.json({ prediction }); 64 | }; 65 | 66 | export const predictHeart = (req, res) => { 67 | // Handle heart prediction 68 | const input = req.body.input; 69 | const prediction = heartModel.predict(input); 70 | res.json({ prediction }); 71 | }; 72 | 73 | export const predictKidney = (req, res) => { 74 | // Handle kidney prediction 75 | const input = req.body.input; 76 | const prediction = kidneyModel.predict(input); 77 | res.json({ prediction }); 78 | }; 79 | 80 | export const predictLiver = (req, res) => { 81 | // Handle liver prediction 82 | const input = req.body.input; 83 | const prediction = liverModel.predict(input); 84 | res.json({ prediction }); 85 | }; 86 | 87 | export const predictMalaria = (req, res) => { 88 | // Handle malaria prediction 89 | }; 90 | 91 | export const predictPneumonia = (req, res) => { 92 | // Handle pneumonia prediction 93 | }; 94 | -------------------------------------------------------------------------------- /backend/Controllers/reviewContoller.js: -------------------------------------------------------------------------------- 1 | import Review from "../models/ReviewSchema.js"; 2 | import Doctor from "../models/DoctorSchema.js"; 3 | 4 | // get all reviews 5 | export const getAllReviews = async (req, res) => { 6 | try { 7 | const reviews = await Review.find({}); 8 | 9 | res 10 | .status(200) 11 | .json({ success: true, message: "Successful", data: reviews }); 12 | } catch (error) { 13 | res.status(200).json({ success: false, message: "Not Found" }); 14 | } 15 | }; 16 | 17 | // create review 18 | export const createReview = async (req, res) => { 19 | if (!req.body.doctor) req.body.doctor = req.params.doctorId; 20 | if (!req.body.user) req.body.user = req.params.userId; 21 | 22 | const newReview = new Review(req.body); 23 | 24 | try { 25 | const savedReview = await newReview.save(); 26 | await Doctor.findByIdAndUpdate(req.body.doctor, { 27 | $push: { reviews: savedReview._id }, 28 | }); 29 | 30 | res 31 | .status(200) 32 | .json({ success: true, message: "Review Submitted", data: savedReview }); 33 | } catch (error) { 34 | res.status(500).json({ success: false, message: error.message }); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /backend/HealthPredict/Symptom-severity.csv: -------------------------------------------------------------------------------- 1 | Symptom,weight 2 | itching,1 3 | skin_rash,3 4 | nodal_skin_eruptions,4 5 | continuous_sneezing,4 6 | shivering,5 7 | chills,3 8 | joint_pain,3 9 | stomach_pain,5 10 | acidity,3 11 | ulcers_on_tongue,4 12 | muscle_wasting,3 13 | vomiting,5 14 | burning_micturition,6 15 | spotting_urination,6 16 | fatigue,4 17 | weight_gain,3 18 | anxiety,4 19 | cold_hands_and_feets,5 20 | mood_swings,3 21 | weight_loss,3 22 | restlessness,5 23 | lethargy,2 24 | patches_in_throat,6 25 | irregular_sugar_level,5 26 | cough,4 27 | high_fever,7 28 | sunken_eyes,3 29 | breathlessness,4 30 | sweating,3 31 | dehydration,4 32 | indigestion,5 33 | headache,3 34 | yellowish_skin,3 35 | dark_urine,4 36 | nausea,5 37 | loss_of_appetite,4 38 | pain_behind_the_eyes,4 39 | back_pain,3 40 | constipation,4 41 | abdominal_pain,4 42 | diarrhoea,6 43 | mild_fever,5 44 | yellow_urine,4 45 | yellowing_of_eyes,4 46 | acute_liver_failure,6 47 | fluid_overload,6 48 | swelling_of_stomach,7 49 | swelled_lymph_nodes,6 50 | malaise,6 51 | blurred_and_distorted_vision,5 52 | phlegm,5 53 | throat_irritation,4 54 | redness_of_eyes,5 55 | sinus_pressure,4 56 | runny_nose,5 57 | congestion,5 58 | chest_pain,7 59 | weakness_in_limbs,7 60 | fast_heart_rate,5 61 | pain_during_bowel_movements,5 62 | pain_in_anal_region,6 63 | bloody_stool,5 64 | irritation_in_anus,6 65 | neck_pain,5 66 | dizziness,4 67 | cramps,4 68 | bruising,4 69 | obesity,4 70 | swollen_legs,5 71 | swollen_blood_vessels,5 72 | puffy_face_and_eyes,5 73 | enlarged_thyroid,6 74 | brittle_nails,5 75 | swollen_extremeties,5 76 | excessive_hunger,4 77 | extra_marital_contacts,5 78 | drying_and_tingling_lips,4 79 | slurred_speech,4 80 | knee_pain,3 81 | hip_joint_pain,2 82 | muscle_weakness,2 83 | stiff_neck,4 84 | swelling_joints,5 85 | movement_stiffness,5 86 | spinning_movements,6 87 | loss_of_balance,4 88 | unsteadiness,4 89 | weakness_of_one_body_side,4 90 | loss_of_smell,3 91 | bladder_discomfort,4 92 | foul_smell_ofurine,5 93 | continuous_feel_of_urine,6 94 | passage_of_gases,5 95 | internal_itching,4 96 | toxic_look_(typhos),5 97 | depression,3 98 | irritability,2 99 | muscle_pain,2 100 | altered_sensorium,2 101 | red_spots_over_body,3 102 | belly_pain,4 103 | abnormal_menstruation,6 104 | dischromic_patches,6 105 | watering_from_eyes,4 106 | increased_appetite,5 107 | polyuria,4 108 | family_history,5 109 | mucoid_sputum,4 110 | rusty_sputum,4 111 | lack_of_concentration,3 112 | visual_disturbances,3 113 | receiving_blood_transfusion,5 114 | receiving_unsterile_injections,2 115 | coma,7 116 | stomach_bleeding,6 117 | distention_of_abdomen,4 118 | history_of_alcohol_consumption,5 119 | fluid_overload,4 120 | blood_in_sputum,5 121 | prominent_veins_on_calf,6 122 | palpitations,4 123 | painful_walking,2 124 | pus_filled_pimples,2 125 | blackheads,2 126 | scurring,2 127 | skin_peeling,3 128 | silver_like_dusting,2 129 | small_dents_in_nails,2 130 | inflammatory_nails,2 131 | blister,4 132 | red_sore_around_nose,2 133 | yellow_crust_ooze,3 134 | prognosis,5 135 | -------------------------------------------------------------------------------- /backend/HealthPredict/precautions_df.csv: -------------------------------------------------------------------------------- 1 | ,Disease,Precaution_1,Precaution_2,Precaution_3,Precaution_4 2 | 0,Drug Reaction,stop irritation,consult nearest hospital,stop taking drug,follow up 3 | 1,Malaria,Consult nearest hospital,avoid oily food,avoid non veg food,keep mosquitos out 4 | 2,Allergy,apply calamine,cover area with bandage,,use ice to compress itching 5 | 3,Hypothyroidism,reduce stress,exercise,eat healthy,get proper sleep 6 | 4,Psoriasis,wash hands with warm soapy water,stop bleeding using pressure,consult doctor,salt baths 7 | 5,GERD,avoid fatty spicy food,avoid lying down after eating,maintain healthy weight,exercise 8 | 6,Chronic cholestasis,cold baths,anti itch medicine,consult doctor,eat healthy 9 | 7,hepatitis A,Consult nearest hospital,wash hands through,avoid fatty spicy food,medication 10 | 8,Osteoarthristis,acetaminophen,consult nearest hospital,follow up,salt baths 11 | 9,(vertigo) Paroymsal Positional Vertigo,lie down,avoid sudden change in body,avoid abrupt head movment,relax 12 | 10,Hypoglycemia,lie down on side,check in pulse,drink sugary drinks,consult doctor 13 | 11,Acne,bath twice,avoid fatty spicy food,drink plenty of water,avoid too many products 14 | 12,Diabetes ,have balanced diet,exercise,consult doctor,follow up 15 | 13,Impetigo,soak affected area in warm water,use antibiotics,remove scabs with wet compressed cloth,consult doctor 16 | 14,Hypertension ,meditation,salt baths,reduce stress,get proper sleep 17 | 15,Peptic ulcer diseae,avoid fatty spicy food,consume probiotic food,eliminate milk,limit alcohol 18 | 16,Dimorphic hemmorhoids(piles),avoid fatty spicy food,consume witch hazel,warm bath with epsom salt,consume alovera juice 19 | 17,Common Cold,drink vitamin c rich drinks,take vapour,avoid cold food,keep fever in check 20 | 18,Chicken pox,use neem in bathing ,consume neem leaves,take vaccine,avoid public places 21 | 19,Cervical spondylosis,use heating pad or cold pack,exercise,take otc pain reliver,consult doctor 22 | 20,Hyperthyroidism,eat healthy,massage,use lemon balm,take radioactive iodine treatment 23 | 21,Urinary tract infection,drink plenty of water,increase vitamin c intake,drink cranberry juice,take probiotics 24 | 22,Varicose veins,lie down flat and raise the leg high,use oinments,use vein compression,dont stand still for long 25 | 23,AIDS,avoid open cuts,wear ppe if possible,consult doctor,follow up 26 | 24,Paralysis (brain hemorrhage),massage,eat healthy,exercise,consult doctor 27 | 25,Typhoid,eat high calorie vegitables,antiboitic therapy,consult doctor,medication 28 | 26,Hepatitis B,consult nearest hospital,vaccination,eat healthy,medication 29 | 27,Fungal infection,bath twice,use detol or neem in bathing water,keep infected area dry,use clean cloths 30 | 28,Hepatitis C,Consult nearest hospital,vaccination,eat healthy,medication 31 | 29,Migraine,meditation,reduce stress,use poloroid glasses in sun,consult doctor 32 | 30,Bronchial Asthma,switch to loose cloothing,take deep breaths,get away from trigger,seek help 33 | 31,Alcoholic hepatitis,stop alcohol consumption,consult doctor,medication,follow up 34 | 32,Jaundice,drink plenty of water,consume milk thistle,eat fruits and high fiberous food,medication 35 | 33,Hepatitis E,stop alcohol consumption,rest,consult doctor,medication 36 | 34,Dengue,drink papaya leaf juice,avoid fatty spicy food,keep mosquitos away,keep hydrated 37 | 35,Hepatitis D,consult doctor,medication,eat healthy,follow up 38 | 36,Heart attack,call ambulance,chew or swallow asprin,keep calm, 39 | 37,Pneumonia,consult doctor,medication,rest,follow up 40 | 38,Arthritis,exercise,use hot and cold therapy,try acupuncture,massage 41 | 39,Gastroenteritis,stop eating solid food for while,try taking small sips of water,rest,ease back into eating 42 | 40,Tuberculosis,cover mouth,consult doctor,medication,rest 43 | -------------------------------------------------------------------------------- /backend/Routes/admin.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { authenticate, restrict } from "./../auth/verifyToken.js"; 3 | import { 4 | getAllUsers, 5 | getAllDoctors, 6 | getAllBookings, 7 | deleteUserById, 8 | deleteDoctorById, 9 | updateDoctorApprovalStatus, 10 | } from "../Controllers/adminController.js"; 11 | 12 | const router = express.Router(); 13 | 14 | router.route("/users").get(authenticate, restrict(["admin"]), getAllUsers); 15 | router.delete( 16 | "/users/delete/:id", 17 | authenticate, 18 | restrict(["admin"]), 19 | deleteUserById 20 | ); 21 | router.delete( 22 | "/doctors/delete/:id", 23 | authenticate, 24 | restrict(["admin"]), 25 | deleteDoctorById 26 | ); 27 | 28 | router.route("/doctors").get(authenticate, restrict(["admin"]), getAllDoctors); 29 | router 30 | .route("/doctors/:id") 31 | .put(authenticate, restrict(["admin"]), updateDoctorApprovalStatus); 32 | router 33 | .route("/bookings") 34 | .get(authenticate, restrict(["admin"]), getAllBookings); 35 | 36 | export default router; 37 | -------------------------------------------------------------------------------- /backend/Routes/auth.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { register, login } from "../Controllers/authController.js"; 3 | 4 | const router = express.Router(); 5 | 6 | router.post("/register", register); 7 | router.post("/login", login); 8 | 9 | export default router; 10 | -------------------------------------------------------------------------------- /backend/Routes/booking.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { authenticate } from "./../auth/verifyToken.js"; 3 | import { getCheckoutSession } from "../Controllers/bookingController.js"; 4 | 5 | const router = express.Router(); 6 | 7 | router.post("/checkout-session/:doctorId", authenticate, getCheckoutSession); 8 | 9 | export default router; 10 | -------------------------------------------------------------------------------- /backend/Routes/contact.js: -------------------------------------------------------------------------------- 1 | import nodemailer from "nodemailer"; 2 | import dotEnv from "dotenv"; 3 | import express from "express"; 4 | 5 | const router = express.Router(); 6 | dotEnv.config(); 7 | 8 | const transporter = nodemailer.createTransport({ 9 | service: "gmail", 10 | host: "smtp.gmail.com", 11 | port: 587, 12 | secure: false, // Use `true` for port 465, `false` for all other ports 13 | auth: { 14 | user: process.env.USER, 15 | pass: process.env.APP_PASS, 16 | }, 17 | }); 18 | 19 | // POST route for form submission 20 | router.post("/contact", async (req, res) => { 21 | const { email, subject, message } = req.body; 22 | 23 | try { 24 | // Send email using the transporter 25 | let info = await transporter.sendMail({ 26 | from: { 27 | name: "Abdul Wahab", 28 | address: process.env.USER, 29 | }, 30 | to: "awminhas619@gmail.com", 31 | subject: subject, 32 | text: `Email: ${email}\n\nMessage: ${message}`, 33 | }); 34 | 35 | // Send response with email info and success message 36 | res.status(200).json({ info, message: "Email sent successfully" }); 37 | } catch (error) { 38 | console.error("Error sending email:", error); 39 | res.status(500).json({ message: "Failed to send email" }); 40 | } 41 | }); 42 | 43 | export default router; 44 | -------------------------------------------------------------------------------- /backend/Routes/doctor.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | updateDoctor, 4 | deleteDoctor, 5 | getAllDoctors, 6 | getSingleDoctor, 7 | getDoctorProfile, 8 | } from "../Controllers/doctorController.js"; 9 | import { authenticate, restrict } from "../auth/verifyToken.js"; 10 | import reviewRouter from "./review.js"; 11 | 12 | const router = express.Router(); 13 | 14 | //nested route 15 | router.use("/:doctorId/reviews", reviewRouter); 16 | 17 | // Get doctor's profile 18 | router.get("/profile/me", authenticate, restrict(["doctor"]), (req, res) => { 19 | getDoctorProfile(req, res); // Call the controller function 20 | }); 21 | 22 | router.get("/:id", getSingleDoctor); // Fetch a single Doctor 23 | router.get("/", getAllDoctors); // Fetch all Doctors 24 | router.delete("/:id", authenticate, restrict(["doctor"]), deleteDoctor); // Delete a Doctor 25 | router.put("/:id", authenticate, restrict(["doctor"]), updateDoctor); // Update a doctor 26 | 27 | export default router; 28 | -------------------------------------------------------------------------------- /backend/Routes/forgot-password.js: -------------------------------------------------------------------------------- 1 | import nodemailer from "nodemailer"; 2 | import dotEnv from "dotenv"; 3 | import express from "express"; 4 | import jwt from "jsonwebtoken"; 5 | import bcrypt from "bcryptjs"; 6 | import User from "../models/UserSchema.js"; 7 | const router = express.Router(); 8 | dotEnv.config(); 9 | 10 | // POST route for form submission 11 | router.post("/forgot-password", async (req, res) => { 12 | const { email } = req.body; 13 | User.findOne({ email: email }).then((user) => { 14 | if (!user) { 15 | return res.send({ status: "User not exists." }); 16 | } 17 | const token = jwt.sign({ id: user._id }, "JWT_secret_key", { 18 | expiresIn: "1d", 19 | }); 20 | const transporter = nodemailer.createTransport({ 21 | service: "gmail", 22 | host: "smtp.gmail.com", 23 | port: 587, 24 | secure: false, 25 | auth: { 26 | user: process.env.USER, 27 | pass: process.env.APP_PASS, 28 | }, 29 | }); 30 | const mailOptions = { 31 | from: { 32 | name: "Abdul Wahab", 33 | user: process.env.USER, 34 | }, 35 | to: "awminhas619@gmail.com", 36 | subject: "Sending Email for Reset Password", 37 | text: `http://localhost:5173/reset-password/${user._id}/${token}`, 38 | }; 39 | transporter.sendMail(mailOptions, function (error, info) { 40 | if (error) { 41 | res.status(500).json({ message: "Failed to send email" }); 42 | } else { 43 | res.status(200).json({ message: "Success" }); 44 | } 45 | }); 46 | }); 47 | }); 48 | 49 | router.post("/reset-password/:id/:token", (req, res) => { 50 | const { id, token } = req.params; 51 | const { password } = req.body; 52 | 53 | jwt.verify(token, "JWT_secret_key", (err, decoded) => { 54 | if (err) { 55 | return res.json({ message: "Error with token" }); 56 | } else { 57 | bcrypt 58 | .hash(password, 10) 59 | .then((hash) => { 60 | User.findOneAndUpdate({ _id: id }, { password: hash }) 61 | .then((u) => res.send({ message: "Success" })) 62 | .catch((err) => res.send({ message: err })); 63 | }) 64 | .catch((err) => res.send({ message: err })); 65 | } 66 | }); 67 | }); 68 | 69 | export default router; 70 | -------------------------------------------------------------------------------- /backend/Routes/healthPredict.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { spawn } from "child_process"; 3 | const router = express.Router({ mergeParams: true }); 4 | 5 | const pythonScriptPathForSymptoms = "D:\\AI-MedLab\\backend\\symptoms.py"; 6 | const symptomsModel = "D:\\AI-MedLab\\backend\\aimodels\\svc.pkl"; 7 | 8 | router.post("/symptoms", (req, res) => { 9 | let responseSent = false; // Flag to track if response has been sent 10 | try { 11 | const data = req.body.data; 12 | console.log({ dataInString: JSON.stringify({ data }) }); 13 | const pythonProcess = spawn("python", [ 14 | pythonScriptPathForSymptoms, 15 | "--loads", 16 | symptomsModel, 17 | JSON.stringify({ data }), 18 | ]); 19 | let prediction; 20 | pythonProcess.stdout.on("data", (data) => { 21 | const dataString = data.toString(); 22 | console.log("Python script output===========:", JSON.parse(dataString)); 23 | prediction = JSON.parse(dataString); 24 | }); 25 | 26 | pythonProcess.stderr.on("data", (data) => { 27 | console.error("Python script error:", data.toString()); 28 | }); 29 | 30 | pythonProcess.on("close", (code) => { 31 | console.log("Python process closed with code:", code); 32 | console.log("Prediction:", prediction); 33 | if (!responseSent) { 34 | res.json({ data: prediction }); 35 | responseSent = true; 36 | } 37 | }); 38 | pythonProcess.on("error", (error) => { 39 | console.error("Python process error:", error); 40 | if (!responseSent) { 41 | res.status(500).send("Internal Server Error"); 42 | responseSent = true; 43 | } 44 | }); 45 | } catch (error) { 46 | console.error("Error:", error); 47 | if (!responseSent) { 48 | responseSent = true; 49 | return res.status(500).send("Internal Server Error"); 50 | } 51 | } 52 | }); 53 | 54 | export default router; 55 | -------------------------------------------------------------------------------- /backend/Routes/review.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | import { getAllReviews, createReview } from "../Controllers/reviewContoller.js"; 4 | import { authenticate, restrict } from "../auth/verifyToken.js"; 5 | 6 | const router = express.Router({ mergeParams: true }); 7 | 8 | router 9 | .route("/") 10 | .get(getAllReviews) 11 | .post(authenticate, restrict(["patient"]), createReview); 12 | 13 | export default router; 14 | -------------------------------------------------------------------------------- /backend/Routes/user.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | updateUser, 4 | deleteUser, 5 | getAllUsers, 6 | getSingleUser, 7 | getUserProfile, 8 | getMyAppointments, 9 | createAppointment, 10 | } from "../Controllers/userController.js"; 11 | import { authenticate, restrict } from "../auth/verifyToken.js"; 12 | 13 | const router = express.Router(); 14 | 15 | router.get("/:id", authenticate, restrict(["patient"]), getSingleUser); // Fetch a single user 16 | router.get("/", authenticate, restrict(["admin"]), getAllUsers); // Fetch all users 17 | router.delete("/:id", authenticate, restrict(["patient"]), deleteUser); // Delete a user 18 | router.put("/:id", authenticate, restrict(["patient"]), updateUser); // Update a user 19 | router.get("/profile/me", authenticate, restrict(["patient"]), getUserProfile); // get userProfile 20 | router.get( 21 | "/appointments/my-appointments", 22 | authenticate, 23 | restrict(["patient"]), 24 | getMyAppointments 25 | ); // get myappointments 26 | router.post( 27 | "/appointments/create-appointment", 28 | authenticate, 29 | restrict(["patient"]), 30 | createAppointment 31 | ); // create appointment 32 | 33 | export default router; 34 | -------------------------------------------------------------------------------- /backend/aimodels/LiverDisease.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/LiverDisease.pkl -------------------------------------------------------------------------------- /backend/aimodels/breast_cancer.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/breast_cancer.pkl -------------------------------------------------------------------------------- /backend/aimodels/diabetes.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/diabetes.pkl -------------------------------------------------------------------------------- /backend/aimodels/heart.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/heart.pkl -------------------------------------------------------------------------------- /backend/aimodels/kidney.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/kidney.pkl -------------------------------------------------------------------------------- /backend/aimodels/liver.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/liver.pkl -------------------------------------------------------------------------------- /backend/aimodels/malaria.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/malaria.h5 -------------------------------------------------------------------------------- /backend/aimodels/pneumonia.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/pneumonia.h5 -------------------------------------------------------------------------------- /backend/aimodels/svc.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/aimodels/svc.pkl -------------------------------------------------------------------------------- /backend/auth/verifyToken.js: -------------------------------------------------------------------------------- 1 | // Import necessary modules 2 | import jwt from "jsonwebtoken"; 3 | import Doctor from "../models/DoctorSchema.js"; 4 | import User from "../models/UserSchema.js"; 5 | 6 | export const authenticate = async (req, res, next) => { 7 | // Get token from headers 8 | const authToken = req.headers.authorization; 9 | // console.log("authToken", authToken); 10 | 11 | // Check if token exists 12 | if (!authToken || !authToken.startsWith("Bearer")) { 13 | return res 14 | .status(401) 15 | .json({ success: false, message: "No token, authorization denied" }); 16 | } 17 | 18 | try { 19 | // Extract token string and decode it 20 | const token = authToken.split(" ")[1]; 21 | const decoded = jwt.verify(token, process.env.JWT_SECRET_KEY); 22 | 23 | // Attach decoded user information to the request object 24 | req.userId = decoded.id; 25 | req.role = decoded.role; 26 | // Check token expiration 27 | if (decoded.exp < Date.now() / 1000) { 28 | return res.status(401).json({ message: "Token is expired" }); 29 | } 30 | 31 | // Check if the user is a doctor and attach doctorId to the request object 32 | if (req.role === "doctor") { 33 | const doctor = await Doctor.findById(req.userId); 34 | if (!doctor) { 35 | return res 36 | .status(404) 37 | .json({ success: false, message: "Doctor not found" }); 38 | } 39 | req.doctorId = doctor._id; // Attach doctorId to the request object 40 | } 41 | 42 | next(); // Call next middleware 43 | } catch (error) { 44 | // Handle token verification errors 45 | return res.status(401).json({ success: false, message: "Invalid token" }); 46 | } 47 | }; 48 | 49 | export const restrict = (roles) => async (req, res, next) => { 50 | const userId = req.userId; 51 | 52 | try { 53 | let user; 54 | 55 | const patient = await User.findById(userId); 56 | const doctor = await Doctor.findById(userId); 57 | 58 | if (patient) { 59 | user = patient; 60 | } 61 | if (doctor) { 62 | user = doctor; 63 | } 64 | 65 | if (!user || !roles.includes(user.role)) { 66 | return res 67 | .status(401) 68 | .json({ success: false, message: "You are not authorized" }); 69 | } 70 | 71 | next(); 72 | } catch (error) { 73 | return res.status(401).json({ success: false, message: "Invalid user ID" }); 74 | } 75 | }; 76 | -------------------------------------------------------------------------------- /backend/breast-cancer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import pickle 4 | import json 5 | print("Python version:", sys.version) 6 | print("Python executable path:", sys.executable) 7 | 8 | with open('./ai-models/breast_cancer.pkl', 'rb') as model_fileL: 9 | model = pickle.load(model_fileL) 10 | 11 | data = list(json.loads(sys.argv[3]).values()) 12 | data_array = np.array(data).reshape(1, -1) 13 | prediction = model.predict(data_array) 14 | values = np.asarray(data) 15 | model.predict(values.reshape(1, -1))[0] 16 | print(json.dumps(prediction.tolist())) -------------------------------------------------------------------------------- /backend/db-models/BookingSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const bookingSchema = new mongoose.Schema( 4 | { 5 | doctor: { 6 | type: mongoose.Types.ObjectId, 7 | ref: "Doctor", 8 | required: true, 9 | }, 10 | user: { 11 | type: mongoose.Types.ObjectId, 12 | ref: "User", 13 | required: true, 14 | }, 15 | ticketPrice: { type: String, required: true }, 16 | status: { 17 | type: String, 18 | enum: ["pending", "approved", "cancelled"], 19 | default: "pending", 20 | }, 21 | isPaid: { 22 | type: Boolean, 23 | default: true, 24 | }, 25 | }, 26 | { timestamps: true } 27 | ); 28 | 29 | bookingSchema.pre(/^find/, function (next) { 30 | this.populate("user").populate({ 31 | path: "doctor", 32 | select: "name", 33 | }); 34 | next(); 35 | }); 36 | 37 | export default mongoose.model("Booking", bookingSchema); 38 | -------------------------------------------------------------------------------- /backend/db-models/DoctorSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const DoctorSchema = new mongoose.Schema({ 4 | email: { type: String, required: true, unique: true }, 5 | password: { type: String, required: true }, 6 | name: { type: String, required: true }, 7 | phone: { type: Number }, 8 | photo: { type: String }, 9 | ticketPrice: { type: Number }, 10 | role: { 11 | type: String, 12 | }, 13 | 14 | // Fields for doctors only 15 | specialization: { type: String }, 16 | qualifications: { 17 | type: Array, 18 | }, 19 | 20 | experiences: { 21 | type: Array, 22 | }, 23 | 24 | bio: { type: String, maxLength: 50 }, 25 | about: { type: String }, 26 | timeSlots: { type: Array }, 27 | reviews: [{ type: mongoose.Types.ObjectId, ref: "Review" }], 28 | averageRating: { 29 | type: Number, 30 | default: 0, 31 | }, 32 | totalRating: { 33 | type: Number, 34 | default: 0, 35 | }, 36 | isApproved: { 37 | type: String, 38 | enum: ["pending", "approved", "cancelled"], 39 | default: "pending", 40 | }, 41 | appointments: [{ type: mongoose.Types.ObjectId, ref: "Appointment" }], 42 | }); 43 | 44 | export default mongoose.model("Doctor", DoctorSchema); 45 | -------------------------------------------------------------------------------- /backend/db-models/ReviewSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import Doctor from "./DoctorSchema.js"; 3 | const reviewSchema = new mongoose.Schema( 4 | { 5 | doctor: { 6 | type: mongoose.Types.ObjectId, 7 | ref: "Doctor", 8 | }, 9 | user: { 10 | type: mongoose.Types.ObjectId, 11 | ref: "User", 12 | }, 13 | reviewText: { 14 | type: String, 15 | required: true, 16 | }, 17 | rating: { 18 | type: Number, 19 | required: true, 20 | min: 0, 21 | max: 5, 22 | default: 0, 23 | }, 24 | }, 25 | { timestamps: true } 26 | ); 27 | 28 | reviewSchema.pre(/^find/, function (next) { 29 | this.populate({ 30 | path: "user", 31 | select: "name photo", 32 | }); 33 | 34 | next(); 35 | }); 36 | 37 | reviewSchema.statics.calcAverageRatings = async function (doctorId) { 38 | // this points the current review 39 | const stats = await this.aggregate([ 40 | { 41 | $match: { doctor: doctorId }, 42 | }, 43 | { 44 | $group: { 45 | _id: "$doctor", 46 | numOfRating: { $sum: 1 }, 47 | avgRating: { $avg: "$rating" }, 48 | }, 49 | }, 50 | ]); 51 | await Doctor.findByIdAndUpdate(doctorId, { 52 | totalRating: stats[0].numOfRating, 53 | averageRating: stats[0].avgRating, 54 | }); 55 | }; 56 | 57 | reviewSchema.post("save", function () { 58 | this.constructor.calcAverageRatings(this.doctor); 59 | }); 60 | 61 | export default mongoose.model("Review", reviewSchema); 62 | -------------------------------------------------------------------------------- /backend/db-models/UserSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const UserSchema = new mongoose.Schema({ 4 | email: { type: String, required: true, unique: true }, 5 | password: { type: String, required: true }, 6 | name: { type: String, required: true }, 7 | phone: { type: Number }, 8 | photo: { type: String }, 9 | role: { 10 | type: String, 11 | enum: ["patient", "doctor", "admin"], 12 | default: "patient", 13 | }, 14 | gender: { type: String, enum: ["male", "female", "other"] }, 15 | bloodType: { type: String }, 16 | appointments: [{ type: mongoose.Types.ObjectId, ref: "Appointment" }], 17 | }); 18 | 19 | export default mongoose.model("User", UserSchema); 20 | -------------------------------------------------------------------------------- /backend/heart.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import pickle 4 | import json 5 | print("Python version:", sys.version) 6 | print("Python executable path:", sys.executable) 7 | 8 | with open('./ai-models/heart.pkl', 'rb') as model_fileL: 9 | model = pickle.load(model_fileL) 10 | 11 | data = list(json.loads(sys.argv[3]).values()) 12 | data_array = np.array(data).reshape(1, -1) 13 | prediction = model.predict(data_array) 14 | values = np.asarray(data) 15 | model.predict(values.reshape(1, -1))[0] 16 | print(json.dumps(prediction.tolist())) -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import cookieParser from "cookie-parser"; 3 | import cors from "cors"; 4 | import mongoose from "mongoose"; 5 | import dotenv from "dotenv"; 6 | import authRoute from "./Routes/auth.js"; 7 | import userRoute from "./Routes/user.js"; 8 | import doctorRoute from "./Routes/doctor.js"; 9 | import reviewRoute from "./Routes/review.js"; 10 | import bookingRoute from "./Routes/booking.js"; 11 | import diseaseRoute from "./Routes/disease.js"; 12 | import adminRoute from "./Routes/admin.js"; 13 | import contactRoute from "./Routes/contact.js"; 14 | import forgotPassRoute from "./Routes/forgot-password.js"; 15 | import healthRoute from "./Routes/healthPredict.js"; 16 | 17 | dotenv.config(); 18 | 19 | const app = express(); 20 | const port = process.env.PORT || 8000; 21 | 22 | const corsOptions = { 23 | origin: true, 24 | }; 25 | 26 | app.get("/", (req, res) => { 27 | res.send("Api is working"); 28 | }); 29 | 30 | //database connection 31 | mongoose.set("strictQuery", false); 32 | const connectDB = async () => { 33 | try { 34 | await mongoose.connect(process.env.MONGO_URL, { 35 | // useNewUrlParser: true, 36 | // useUnifiedTopology: true, 37 | }); 38 | console.log("Mongoose connected"); 39 | } catch (error) { 40 | console.log("Mongoose connection failed"); 41 | } 42 | }; 43 | 44 | //middleware 45 | app.use(express.json()); 46 | app.use(cookieParser()); 47 | app.use(cors(corsOptions)); 48 | app.use("/api/v1/auth", authRoute); //domain/api/v1/auth/register or any other request 49 | app.use("/api/v1/users", userRoute); 50 | app.use("/api/v1/doctors", doctorRoute); 51 | app.use("/api/v1/reviews", reviewRoute); 52 | app.use("/api/v1/bookings", bookingRoute); 53 | app.use("/api/v1/", diseaseRoute); 54 | app.use("/api/v1/admin", adminRoute); 55 | app.use("/api/v1/", contactRoute); 56 | app.use("/api/v1/", forgotPassRoute); 57 | app.use("/api/v1/", healthRoute); 58 | 59 | app.listen(port, () => { 60 | connectDB(); 61 | console.log("Server is running on port " + port); 62 | }); 63 | -------------------------------------------------------------------------------- /backend/kidney.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import pickle 4 | import json 5 | print("Python version:", sys.version) 6 | print("Python executable path:", sys.executable) 7 | 8 | with open('./ai-models/kidney.pkl', 'rb') as model_fileL: 9 | model = pickle.load(model_fileL) 10 | 11 | data = list(json.loads(sys.argv[3]).values()) 12 | data_array = np.array(data).reshape(1, -1) 13 | prediction = model.predict(data_array) 14 | values = np.asarray(data) 15 | model.predict(values.reshape(1, -1))[0] 16 | print(json.dumps(prediction.tolist())) -------------------------------------------------------------------------------- /backend/liver.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import pickle 4 | import json 5 | print("Python version:", sys.version) 6 | print("Python executable path:", sys.executable) 7 | 8 | with open('./ai-models/liver.pkl', 'rb') as model_fileL: 9 | model = pickle.load(model_fileL) 10 | 11 | data = list(json.loads(sys.argv[3]).values()) 12 | data_array = np.array(data).reshape(1, -1) 13 | prediction = model.predict(data_array) 14 | values = np.asarray(data) 15 | model.predict(values.reshape(1, -1))[0] 16 | print(json.dumps(prediction.tolist())) -------------------------------------------------------------------------------- /backend/malaria.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | from tensorflow.keras.models import load_model 4 | from PIL import Image 5 | 6 | def preprocess_image(image_path): 7 | img = Image.open(image_path) 8 | img = img.resize((36, 36)) 9 | img_array = np.asarray(img) 10 | img_array = img_array.reshape((1, 36, 36, 3)) 11 | img_array = img_array / 255.0 12 | return img_array 13 | 14 | if __name__ == "__main__": 15 | if len(sys.argv) != 2: 16 | print("Usage: python predict_pneumonia.py ") 17 | sys.exit(1) 18 | 19 | image_path = sys.argv[1] 20 | 21 | try: 22 | img_array = preprocess_image(image_path) 23 | model = load_model("./aimodels/malaria.h5") 24 | prediction = model.predict(img_array)[0] 25 | print(prediction.tolist()) 26 | except Exception as e: 27 | print("Error:", e) 28 | sys.exit(1) 29 | -------------------------------------------------------------------------------- /backend/models/BookingSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const bookingSchema = new mongoose.Schema( 4 | { 5 | doctor: { 6 | type: mongoose.Types.ObjectId, 7 | ref: "Doctor", 8 | required: true, 9 | }, 10 | user: { 11 | type: mongoose.Types.ObjectId, 12 | ref: "User", 13 | required: true, 14 | }, 15 | ticketPrice: { type: String, required: true }, 16 | status: { 17 | type: String, 18 | enum: ["pending", "approved", "cancelled"], 19 | default: "pending", 20 | }, 21 | isPaid: { 22 | type: Boolean, 23 | default: true, 24 | }, 25 | }, 26 | { timestamps: true } 27 | ); 28 | 29 | bookingSchema.pre(/^find/, function (next) { 30 | this.populate("user").populate({ 31 | path: "doctor", 32 | select: "name", 33 | }); 34 | next(); 35 | }); 36 | 37 | export default mongoose.model("Booking", bookingSchema); 38 | -------------------------------------------------------------------------------- /backend/models/DoctorSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from "mongoose"; 2 | 3 | const Appointment = new Schema({ 4 | patientName: String, 5 | patientGender: { type: String, enum: ["male", "female", "other"] }, 6 | payment: String, 7 | price: String, 8 | bookedOn: String, 9 | testName: String, 10 | }); 11 | 12 | const DoctorSchema = new mongoose.Schema({ 13 | email: { type: String, required: true, unique: true }, 14 | password: { type: String, required: true }, 15 | name: { type: String, required: true }, 16 | phone: { type: Number }, 17 | photo: { type: String }, 18 | ticketPrice: { type: Number }, 19 | role: { 20 | type: String, 21 | }, 22 | 23 | // Fields for doctors only 24 | specialization: { type: String }, 25 | qualifications: { 26 | type: Array, 27 | }, 28 | 29 | experiences: { 30 | type: Array, 31 | }, 32 | 33 | bio: { type: String, maxLength: 50 }, 34 | about: { type: String }, 35 | timeSlots: { type: Array }, 36 | reviews: [{ type: mongoose.Types.ObjectId, ref: "Review" }], 37 | averageRating: { 38 | type: Number, 39 | default: 0, 40 | }, 41 | totalRating: { 42 | type: Number, 43 | default: 0, 44 | }, 45 | isApproved: { 46 | type: String, 47 | enum: ["pending", "approved", "cancelled"], 48 | default: "pending", 49 | }, 50 | appointments: [Appointment], 51 | }); 52 | 53 | export default mongoose.model("Doctor", DoctorSchema); 54 | -------------------------------------------------------------------------------- /backend/models/ReviewSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import Doctor from "./DoctorSchema.js"; 3 | const reviewSchema = new mongoose.Schema( 4 | { 5 | doctor: { 6 | type: mongoose.Types.ObjectId, 7 | ref: "Doctor", 8 | }, 9 | user: { 10 | type: mongoose.Types.ObjectId, 11 | ref: "User", 12 | }, 13 | reviewText: { 14 | type: String, 15 | required: true, 16 | }, 17 | rating: { 18 | type: Number, 19 | required: true, 20 | min: 0, 21 | max: 5, 22 | default: 0, 23 | }, 24 | }, 25 | { timestamps: true } 26 | ); 27 | 28 | reviewSchema.pre(/^find/, function (next) { 29 | this.populate({ 30 | path: "user", 31 | select: "name photo", 32 | }); 33 | 34 | next(); 35 | }); 36 | 37 | reviewSchema.statics.calcAverageRatings = async function (doctorId) { 38 | // this points the current review 39 | const stats = await this.aggregate([ 40 | { 41 | $match: { doctor: doctorId }, 42 | }, 43 | { 44 | $group: { 45 | _id: "$doctor", 46 | numOfRating: { $sum: 1 }, 47 | avgRating: { $avg: "$rating" }, 48 | }, 49 | }, 50 | ]); 51 | await Doctor.findByIdAndUpdate(doctorId, { 52 | totalRating: stats[0].numOfRating, 53 | averageRating: stats[0].avgRating, 54 | }); 55 | }; 56 | 57 | reviewSchema.post("save", function () { 58 | this.constructor.calcAverageRatings(this.doctor); 59 | }); 60 | 61 | export default mongoose.model("Review", reviewSchema); 62 | -------------------------------------------------------------------------------- /backend/models/UserSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const UserSchema = new mongoose.Schema({ 4 | email: { type: String, required: true, unique: true }, 5 | password: { type: String, required: true }, 6 | name: { type: String, required: true }, 7 | phone: { type: Number }, 8 | photo: { type: String }, 9 | role: { 10 | type: String, 11 | enum: ["patient", "doctor", "admin"], 12 | default: "patient", 13 | }, 14 | gender: { type: String, enum: ["male", "female", "other"] }, 15 | bloodType: { type: String }, 16 | appointments: [{ type: mongoose.Types.ObjectId, ref: "Appointment" }], 17 | }); 18 | 19 | export default mongoose.model("User", UserSchema); 20 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ai-medlab", 3 | "version": "1.0.0", 4 | "description": "", 5 | "type": "module", 6 | "main": "index.js", 7 | "scripts": { 8 | "install-python-dependencies": "pip install -r requirements.txt", 9 | "test": "echo \"Error: no test specified\" && exit 1", 10 | "start": "node index.js", 11 | "start-dev": "nodemon index.js" 12 | }, 13 | "author": "Abdul Wahab", 14 | "license": "ISC", 15 | "dependencies": { 16 | "bcryptjs": "^2.4.3", 17 | "body-parser": "^1.20.2", 18 | "cookie-parser": "^1.4.6", 19 | "cors": "^2.8.5", 20 | "dotenv": "^16.4.4", 21 | "express": "^4.18.2", 22 | "jsonwebtoken": "^9.0.2", 23 | "mongodb": "^6.3.0", 24 | "mongoose": "^8.1.2", 25 | "multer": "^1.4.5-lts.1", 26 | "nodemailer": "^6.9.13", 27 | "pickle": "^0.2.0", 28 | "python-shell": "^5.0.0", 29 | "scikit-learn": "^0.1.0", 30 | "stripe": "^14.17.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /backend/pneumonia.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | from tensorflow.keras.models import load_model 4 | from PIL import Image 5 | 6 | def preprocess_image(image_path): 7 | img = Image.open(image_path).convert('L') # Open the image and convert to grayscale 8 | img = img.resize((36, 36)) # Resize the image to the desired dimensions 9 | img_array = np.asarray(img) # Convert the image to a numpy array 10 | img_array = img_array.reshape((1, 36, 36, 1)) # Reshape to match model input shape 11 | img_array = img_array / 255.0 # Normalize pixel values 12 | return img_array 13 | 14 | if __name__ == "__main__": 15 | if len(sys.argv) != 2: 16 | print("Usage: python predict_pneumonia.py ") 17 | sys.exit(1) 18 | 19 | image_path = sys.argv[1] 20 | 21 | try: 22 | img_array = preprocess_image(image_path) # Preprocess the image 23 | model = load_model("./aimodels/pneumonia.h5") # Load the trained model 24 | prediction = model.predict(img_array)[0] # Perform prediction 25 | print(prediction.tolist()) # Print the prediction as a list 26 | except Exception as e: 27 | print("Error:", e) 28 | sys.exit(1) 29 | -------------------------------------------------------------------------------- /backend/predict.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import pickle 4 | import json 5 | 6 | with open('./aimodels/diabetes.pkl', 'rb') as model_fileL: 7 | model = pickle.load(model_fileL) 8 | 9 | data = list(json.loads(sys.argv[3]).values()) 10 | data_array = np.array(data).reshape(1, -1) 11 | prediction = model.predict(data_array) 12 | values = np.asarray(data) 13 | model.predict(values.reshape(1, -1))[0] 14 | print(json.dumps(prediction.tolist())) 15 | 16 | # import sys 17 | # import numpy as np 18 | # import pickle 19 | # import json 20 | 21 | # def load_model(disease): 22 | # try: 23 | # model_path = f'./ai-models/{disease}.pkl' 24 | # with open(model_path, 'rb') as model_file: 25 | # model = pickle.load(model_file) 26 | # return model 27 | # except Exception as e: 28 | # print(f"Error loading model for {disease}: {e}") 29 | # return None 30 | 31 | # def predict(disease, data): 32 | # model = load_model(disease) 33 | # if model: 34 | # try: 35 | # data_array = np.array(data).reshape(1, -1) 36 | # prediction = model.predict(data_array) 37 | # return prediction.tolist() 38 | # except Exception as e: 39 | # print(f"Error predicting {disease}: {e}") 40 | # return None 41 | 42 | # if __name__ == "__main__": 43 | # if len(sys.argv) < 3: 44 | # print("Usage: python predict.py ") 45 | # sys.exit(1) 46 | 47 | # disease = sys.argv[1] 48 | # input_data = sys.argv[2] 49 | 50 | # prediction = predict(disease, json.loads(input_data)) 51 | # if prediction: 52 | # print(json.dumps(prediction)) 53 | # else: 54 | # print("Error occurred during prediction.") 55 | -------------------------------------------------------------------------------- /backend/public/uploads/1711177594413-NORMAL (8).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711177594413-NORMAL (8).jpeg -------------------------------------------------------------------------------- /backend/public/uploads/1711189602609-NORMAL (2).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711189602609-NORMAL (2).jpeg -------------------------------------------------------------------------------- /backend/public/uploads/1711191105737-PNEUMONIA (11).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711191105737-PNEUMONIA (11).jpeg -------------------------------------------------------------------------------- /backend/public/uploads/1711191128466-PNEUMONIA (12).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711191128466-PNEUMONIA (12).jpeg -------------------------------------------------------------------------------- /backend/public/uploads/1711192334463-NORMAL (3).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711192334463-NORMAL (3).jpeg -------------------------------------------------------------------------------- /backend/public/uploads/1711192351061-PNEUMONIA (11).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711192351061-PNEUMONIA (11).jpeg -------------------------------------------------------------------------------- /backend/public/uploads/1711192719082-p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711192719082-p1.png -------------------------------------------------------------------------------- /backend/public/uploads/1711192798526-p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711192798526-p2.png -------------------------------------------------------------------------------- /backend/public/uploads/1711192902686-p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711192902686-p2.png -------------------------------------------------------------------------------- /backend/public/uploads/1711192929321-u3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/backend/public/uploads/1711192929321-u3.png -------------------------------------------------------------------------------- /backend/requirements.txt: -------------------------------------------------------------------------------- 1 | absl-py==0.13.0 2 | astor==0.8.1 3 | cached-property==1.5.2 4 | cachetools==4.2.2 5 | certifi==2021.5.30 6 | chardet==4.0.0 7 | click==8.0.1 8 | colorama==0.4.4 9 | dataclasses==0.6 10 | Flask==1.1.1 11 | gast==0.2.2 12 | google-auth==1.31.0 13 | google-auth-oauthlib==0.4.4 14 | google-pasta==0.2.0 15 | grpcio==1.38.0 16 | h5py==2.10.0 17 | idna==2.10 18 | importlib-metadata==4.5.0 19 | itsdangerous==2.0.1 20 | Jinja2==3.0.1 21 | joblib==1.0.1 22 | Keras-Applications==1.0.8 23 | Keras-Preprocessing==1.1.2 24 | Markdown==3.3.4 25 | MarkupSafe==2.0.1 26 | numpy==1.19.5 27 | oauthlib==3.1.1 28 | opt-einsum==3.3.0 29 | pickle-mixin==1.0.2 30 | Pillow==7.2.0 31 | protobuf==3.17.3 32 | pyasn1==0.4.8 33 | pyasn1-modules==0.2.8 34 | requests==2.25.1 35 | requests-oauthlib==1.3.0 36 | rsa==4.7.2 37 | scikit-learn==0.21.3 38 | scipy==1.4.1 39 | six==1.16.0 40 | tensorboard==2.1.1 41 | tensorflow==2.1.0 42 | tensorflow-estimator==2.1.0 43 | termcolor==1.1.0 44 | typing-extensions==3.10.0.0 45 | urllib3==1.26.5 46 | Werkzeug==2.0.1 47 | wrapt==1.12.1 48 | zipp==3.4.1 -------------------------------------------------------------------------------- /frontend/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react/jsx-no-target-blank': 'off', 16 | 'react-refresh/only-export-components': [ 17 | 'warn', 18 | { allowConstantExport: true }, 19 | ], 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | AI-MedLab 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@heroicons/react": "2.0.18", 14 | "@material-tailwind/react": "2.1.4", 15 | "apexcharts": "3.44.0", 16 | "axios": "^1.6.7", 17 | "prop-types": "15.8.1", 18 | "react": "^18.2.0", 19 | "react-apexcharts": "1.4.1", 20 | "react-dom": "^18.2.0", 21 | "react-icons": "^5.0.1", 22 | "react-router-dom": "^6.22.0", 23 | "react-spinners": "^0.13.8", 24 | "react-toastify": "^10.0.4", 25 | "stripe": "^14.17.0", 26 | "swiper": "^11.0.6", 27 | "vite-plugin-rewrite-all": "^1.0.2" 28 | }, 29 | "devDependencies": { 30 | "@types/react": "^18.2.55", 31 | "@types/react-dom": "^18.2.19", 32 | "@vitejs/plugin-react": "^4.2.1", 33 | "autoprefixer": "^10.4.17", 34 | "eslint": "^8.56.0", 35 | "eslint-plugin-react": "^7.33.2", 36 | "eslint-plugin-react-hooks": "^4.6.0", 37 | "eslint-plugin-react-refresh": "^0.4.5", 38 | "postcss": "^8.4.35", 39 | "tailwindcss": "^3.4.1", 40 | "vite": "^4.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/img/background-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/background-image.png -------------------------------------------------------------------------------- /frontend/public/img/bruce-mars.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/bruce-mars.jpeg -------------------------------------------------------------------------------- /frontend/public/img/devto.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | devto 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/favicon.png -------------------------------------------------------------------------------- /frontend/public/img/home-decor-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/home-decor-1.jpeg -------------------------------------------------------------------------------- /frontend/public/img/home-decor-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/home-decor-2.jpeg -------------------------------------------------------------------------------- /frontend/public/img/home-decor-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/home-decor-3.jpeg -------------------------------------------------------------------------------- /frontend/public/img/home-decor-4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/home-decor-4.jpeg -------------------------------------------------------------------------------- /frontend/public/img/logo-asana.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /frontend/public/img/logo-atlassian.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /frontend/public/img/logo-ct-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/logo-ct-dark.png -------------------------------------------------------------------------------- /frontend/public/img/logo-ct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/logo-ct.png -------------------------------------------------------------------------------- /frontend/public/img/logo-invision.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /frontend/public/img/logo-jira.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /frontend/public/img/logo-slack.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /frontend/public/img/logo-spotify.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /frontend/public/img/logo-xd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logos 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /frontend/public/img/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/pattern.png -------------------------------------------------------------------------------- /frontend/public/img/team-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/team-1.jpeg -------------------------------------------------------------------------------- /frontend/public/img/team-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/team-2.jpeg -------------------------------------------------------------------------------- /frontend/public/img/team-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/team-3.jpeg -------------------------------------------------------------------------------- /frontend/public/img/team-4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/public/img/team-4.jpeg -------------------------------------------------------------------------------- /frontend/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap"); 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | body { 8 | font-family: "Manrope", sans-serif; 9 | } 10 | .swiper-pagination-bullet { 11 | width: 12px !important; 12 | height: 12px !important; 13 | border: 1px solid #101a1e !important; 14 | opacity: 100% !important; 15 | background: #fff !important; 16 | } 17 | .swiper-pagination-bullet-active { 18 | background: #0067ff !important; 19 | border: none !important; 20 | } 21 | .swiper { 22 | padding-bottom: 70px !important; 23 | } 24 | .swiper-slide.swiper-slide-next { 25 | background: #0067ff; 26 | border-radius: 12px; 27 | box-shadow: 0px 20px 70px rgba(0, 103, 155, 0.3) !important; 28 | } 29 | .swiper-slide.swiper-slide-next h4, 30 | .swiper-slide.swiper-slide-next p { 31 | color: #fff; 32 | } 33 | .swiper-pagination { 34 | top: 90% !important; 35 | } 36 | .sticky__header { 37 | width: 100%; 38 | height: 80px; 39 | line-height: 80px; 40 | position: sticky; 41 | top: 0; 42 | left: 0; 43 | z-index: 99999; 44 | background: white; 45 | box-shadow: 3px 3px -8px 3px #ddd; 46 | } 47 | 48 | @media only screen and (max-width: 768px) { 49 | .navigation { 50 | width: 100%; 51 | height: 100%; 52 | position: fixed; 53 | top: 0; 54 | left: 100%; 55 | z-index: 100; 56 | background: #00000084; 57 | transition: left 0.3s ease-in-out; 58 | } 59 | .navigation.show__menu { 60 | left: 0; 61 | } 62 | .menu { 63 | width: 15rem; 64 | height: 100%; 65 | position: absolute; 66 | top: 0; 67 | right: 0; 68 | background: #fff; 69 | z-index: 200; 70 | flex-direction: column; 71 | justify-content: center; 72 | align-items: center; 73 | line-height: 30px; 74 | padding: 1rem; 75 | display: flex; 76 | } 77 | .close-menu-icon { 78 | position: absolute; 79 | top: 1.5rem; 80 | right: 2rem; 81 | z-index: 300; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /frontend/src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect } from "react"; 2 | import Layout from "./layout/Layout"; 3 | import Admin from "./layout/Admin-Layout.jsx"; 4 | import { authContext } from "./context/AuthContext"; 5 | 6 | function App() { 7 | const { user, role, token } = useContext(authContext); 8 | 9 | useEffect(() => { 10 | console.log("User: ", user); 11 | console.log("role: ", role); 12 | console.log("token: ", token); 13 | }, [user, role, token]); 14 | 15 | return <>{token && role === "admin" ? : }; 16 | } 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /frontend/src/Dashboard/doctor-account/Appointments.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { formateDate } from "../../utils/formatDate.js"; 3 | 4 | const Appointments = ({ appointments }) => { 5 | console.log("appointments: ", appointments); 6 | return ( 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {appointments?.map((item) => ( 21 | 25 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | ))} 43 | 44 |
NameGenderPaymentPriceBooked onTest name
26 |
27 |
28 |
29 | {item.user.name} 30 |
31 |
32 |
33 |
{item.user.gender}{item.status}{item.ticketPrice} 38 | {formateDate(item.updatedAt)} 39 | {item.testName ||'Pneumonia'}
45 |
46 | ); 47 | }; 48 | 49 | export default Appointments; 50 | -------------------------------------------------------------------------------- /frontend/src/Dashboard/doctor-account/Tabs.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BiMenu } from "react-icons/bi"; 3 | import { useContext } from "react"; 4 | import { authContext } from "../../context/AuthContext"; 5 | import { useNavigate } from "react-router-dom"; 6 | 7 | const Tabs = ({ tab, setTab }) => { 8 | const { dispatch } = useContext(authContext); 9 | const navigate = useNavigate(); 10 | 11 | const handleLogout = () => { 12 | dispatch({ type: "LOGOUT" }, navigate("/")); 13 | }; 14 | return ( 15 |
16 | 17 | 18 | 19 |
20 | 30 | 31 | 41 | 42 | 52 | 53 |
54 | 60 | 63 |
64 |
65 |
66 | ); 67 | }; 68 | 69 | export default Tabs; 70 | -------------------------------------------------------------------------------- /frontend/src/Dashboard/user-account/MyBookings.jsx: -------------------------------------------------------------------------------- 1 | import useFetchData from "../../hooks/useFetchData"; 2 | import { BASE_URL } from "../../config.js"; 3 | import DoctorCard from "./../../components/Doctors/DoctorCard"; 4 | import Loading from "../../components/Loader/Loading.jsx"; 5 | import Error from "../../components/Error/Error.jsx"; 6 | 7 | const MyBookings = () => { 8 | const { 9 | data: appointments, 10 | error, 11 | loading, 12 | } = useFetchData(`${BASE_URL}/users/appointments/my-appointments`); 13 | return ( 14 |
15 | {loading && !error && } 16 | {error && !loading && } 17 | {!loading && !error && ( 18 |
19 | {appointments.map((doctor) => ( 20 | 21 | ))} 22 |
23 | )} 24 | {!loading && !error && appointments.length === 0 && ( 25 |

26 | You did not any doctor yet! 27 |

28 | )} 29 |
30 | ); 31 | }; 32 | 33 | export default MyBookings; 34 | -------------------------------------------------------------------------------- /frontend/src/assets/data/doctors.js: -------------------------------------------------------------------------------- 1 | import doctorImg01 from "../images/doctor-img01.png"; 2 | import doctorImg02 from "../images/doctor-img02.png"; 3 | import doctorImg03 from "../images/doctor-img03.png"; 4 | 5 | export const doctors = [ 6 | { 7 | id: "01", 8 | name: "Dr. Alfaz Ahmed", 9 | specialty: "Surgeon", 10 | avgRating: 4.8, 11 | totalRating: 272, 12 | photo: doctorImg01, 13 | totalPatients: 1500, 14 | hospital: "Mount Adora Hospital, Sylhet.", 15 | }, 16 | { 17 | id: "02", 18 | name: "Dr. Saleh Mahmud", 19 | specialty: "Neurologist", 20 | avgRating: 4.8, 21 | totalRating: 272, 22 | photo: doctorImg02, 23 | totalPatients: 1500, 24 | hospital: "Mount Adora Hospital, Sylhet.", 25 | }, 26 | { 27 | id: "03", 28 | name: "Dr. Farid Uddin", 29 | specialty: "Dermatologist", 30 | avgRating: 4.8, 31 | totalRating: 272, 32 | photo: doctorImg03, 33 | totalPatients: 1500, 34 | hospital: "Mount Adora Hospital, Sylhet.", 35 | }, 36 | ]; 37 | -------------------------------------------------------------------------------- /frontend/src/assets/data/faqs.js: -------------------------------------------------------------------------------- 1 | export const faqs = [ 2 | { 3 | question: "What is our Ai-MedLab?", 4 | content: 5 | "Our medical care encompasses a comprehensive healthcare platform designed to address critical aspects of patient well-being. We provide services for the diagnosis, treatment, and management of seven major diseases, aiming to enhance patients' quality of life through personalized treatment plans and ongoing support.", 6 | }, 7 | { 8 | question: "What happens if I need to go a hospital?", 9 | content: 10 | "If you need to go to a hospital, our healthcare platform can assist you by providing relevant medical information and helping you understand your condition better. We can also support you in coordinating with the hospital staff and ensuring continuity of care throughout your hospital stay. Additionally, our platform may offer resources and guidance to help you navigate the hospital admission process smoothly.", 11 | }, 12 | { 13 | question: "How efficient our diseases models?", 14 | content: 15 | "Our disease models are highly efficient, leveraging advanced algorithms and data analytics to accurately diagnose, treat, and manage seven major diseases. Through continuous refinement and validation, we ensure the reliability and effectiveness of our models in providing timely and personalized care to patients.", 16 | }, 17 | { 18 | question: "Can I consult with doctors?", 19 | content: 20 | "You can consult with qualified doctors through our platform, ensuring personalized advice and guidance on managing your health condition effectively.", 21 | }, 22 | { 23 | question: "Does the facility offer telehealth or virtual appointments?", 24 | content: 25 | "Yes, our facility offers telehealth and virtual appointments, providing convenient access to medical professionals for personalized consultations and guidance on managing your health.", 26 | }, 27 | ]; 28 | -------------------------------------------------------------------------------- /frontend/src/assets/data/services.js: -------------------------------------------------------------------------------- 1 | export const services = [ 2 | { 3 | id: "1", 4 | name: "Diabetes Test", 5 | desc: "It is caused by an insufficient amount of insulin being produced or the body's inability to effectively use insulin. The pancreas produces insulin to facilitate the use of glucose, which is the primary energy source for the cells. Glucose accumulates in the bloodstream when insulin is insufficient or inefficient.", 6 | bgColor: "rgba(254, 182, 13, .2)", 7 | textColor: "#FEB60D", 8 | }, 9 | { 10 | id: "2", 11 | name: "Heart Disease Test", 12 | desc: "Heart disease includes conditions that affect the heart's function and structure, causing symptoms like chest pain, shortness of breath, and fatigue. Risk factors include high blood pressure, high cholesterol, smoking, obesity, and inactivity. Serious complications like heart attack or stroke can arise, highlighting the importance of timely detection and management.", 13 | bgColor: "rgba(151, 113, 255, .2)", 14 | textColor: "#9771FF", 15 | }, 16 | { 17 | id: "3", 18 | name: "Kidney Disease Test", 19 | desc: "Chronic kidney disease, or CKD, is the progressive decline in kidney function. Kidneys filter blood, removing waste and excess fluid for excretion in the urine. In advanced stages, CKD leads to a dangerous accumulation of fluids, electrolytes, and waste in the body, posing serious health risks.", 20 | bgColor: "rgba(1, 181, 197, .2)", 21 | textColor: "#01B5C5", 22 | }, 23 | { 24 | id: "4", 25 | name: "Liver Disease Test", 26 | desc: "Liver disease symptoms vary and may include abdominal swelling, easy bruising, stool and urine color changes, and jaundice. Some cases are asymptomatic. Diagnostic tests like imaging and liver function tests are essential for detection and diagnosis.", 27 | bgColor: "rgba(1, 181, 197, .2)", 28 | textColor: "#01B5C5", 29 | }, 30 | { 31 | id: "5", 32 | name: "Breast Cancer Test", 33 | desc: "Breast cancer occurs when cells in the breasts become cancerous. U.S. women are most likely to be diagnosed with breast cancer after skin cancer. In women, breast cancer is more common than in men.", 34 | bgColor: "rgba(254, 182, 13, .2)", 35 | textColor: "#FEB60D", 36 | }, 37 | { 38 | id: "6", 39 | name: "Malaria Test", 40 | desc: "Malaria, transmitted by mosquitoes, affects both humans and animals, leading to symptoms like fever, fatigue, vomiting, and headaches. Severe cases may entail yellow skin, seizures, coma, or death. Symptoms typically emerge 10-15 days post-mosquito bite. Without adequate treatment, recurrences can occur months later.", 41 | bgColor: "rgba(151, 113, 255, .2)", 42 | textColor: "#9771FF", 43 | }, 44 | { 45 | id: "7", 46 | name: "Pneumonia Test", 47 | desc: "Pneumonia inflames air sacs in the lungs, leading to fluid or pus accumulation, coughing with phlegm or pus, fever, chills, and breathing difficulties. Bacteria, viruses, and fungi are common culprits.", 48 | bgColor: "rgba(151, 113, 255, .2)", 49 | textColor: "#9771FF", 50 | }, 51 | ]; 52 | -------------------------------------------------------------------------------- /frontend/src/assets/images/Blur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/Blur.png -------------------------------------------------------------------------------- /frontend/src/assets/images/Logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/Logo1.png -------------------------------------------------------------------------------- /frontend/src/assets/images/Star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/Star.png -------------------------------------------------------------------------------- /frontend/src/assets/images/about-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/about-card.png -------------------------------------------------------------------------------- /frontend/src/assets/images/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/about.png -------------------------------------------------------------------------------- /frontend/src/assets/images/avatar-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/avatar-icon.png -------------------------------------------------------------------------------- /frontend/src/assets/images/default.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/default.avif -------------------------------------------------------------------------------- /frontend/src/assets/images/doctor-img01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/doctor-img01.png -------------------------------------------------------------------------------- /frontend/src/assets/images/doctor-img02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/doctor-img02.png -------------------------------------------------------------------------------- /frontend/src/assets/images/doctor-img03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/doctor-img03.png -------------------------------------------------------------------------------- /frontend/src/assets/images/faq-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/faq-img.png -------------------------------------------------------------------------------- /frontend/src/assets/images/feature-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/feature-img.png -------------------------------------------------------------------------------- /frontend/src/assets/images/femaleD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/femaleD.png -------------------------------------------------------------------------------- /frontend/src/assets/images/header-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/header-bg.png -------------------------------------------------------------------------------- /frontend/src/assets/images/hero-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/hero-bg.png -------------------------------------------------------------------------------- /frontend/src/assets/images/hero-img01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/hero-img01.png -------------------------------------------------------------------------------- /frontend/src/assets/images/hero-img02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/hero-img02.png -------------------------------------------------------------------------------- /frontend/src/assets/images/hero-img03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/hero-img03.png -------------------------------------------------------------------------------- /frontend/src/assets/images/icon01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/icon01.png -------------------------------------------------------------------------------- /frontend/src/assets/images/icon02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/icon02.png -------------------------------------------------------------------------------- /frontend/src/assets/images/icon03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/icon03.png -------------------------------------------------------------------------------- /frontend/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/logo.png -------------------------------------------------------------------------------- /frontend/src/assets/images/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/mask.png -------------------------------------------------------------------------------- /frontend/src/assets/images/p1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p1.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/p2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p2.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/p3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p3.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/p4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p4.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/p5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p5.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/p6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p6.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/p7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/p7.jpg -------------------------------------------------------------------------------- /frontend/src/assets/images/patient-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/patient-avatar.png -------------------------------------------------------------------------------- /frontend/src/assets/images/signup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/signup.gif -------------------------------------------------------------------------------- /frontend/src/assets/images/video-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdul-wahab619/AI-MedLab/4bb8d5f31c69787b6abe4291772c19519d9e1240/frontend/src/assets/images/video-icon.png -------------------------------------------------------------------------------- /frontend/src/components/About/About.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import aboutimg from "../../assets/images/about.png"; 3 | import aboutCardImg from "../../assets/images/about-card.png"; 4 | import { Link } from "react-router-dom"; 5 | const About = () => { 6 | return ( 7 |
8 |
9 |
10 |
11 | {/* ========== about image ========== */} 12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 | 20 | {/* ========== About Content ========== */} 21 |
22 |

Proud to be one of the nation best

23 |

24 | Proud to be one of the nation's best, we excel in addressing 25 | diverse healthcare challenges. Our comprehensive approach 26 | effectively tackles issues from diagnosis to management, 27 | ensuring patients receive exceptional care and support 28 | throughout their treatment journey. By integrating advanced 29 | medical practices with personalized care, we aim to improve 30 | patient outcomes and quality of life. 31 |

32 |

33 | By integrating advanced medical practices with personalized 34 | care, we aim to improve patient outcomes and quality of life. 35 | Our commitment to excellence drives us to continuously innovate 36 | and provide solutions for even the most complex medical 37 | conditions. 38 |

39 | 40 | 41 | 42 |
43 |
44 |
45 |
46 |
47 | ); 48 | }; 49 | 50 | export default About; 51 | -------------------------------------------------------------------------------- /frontend/src/components/DoctorDropDown/DoctorDropDown.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import useFetchData from "../../hooks/useFetchData"; 3 | import { BASE_URL } from "../../config"; 4 | import Loader from "../../components/Loader/Loading"; 5 | import axios from "axios"; 6 | import { toast } from "react-toastify"; 7 | 8 | function DoctorsDropDown({ testName, testResult = null }) { 9 | const loginUser = JSON.parse(localStorage.getItem("user")); 10 | const token = localStorage.getItem("token"); // Assuming you store your token in localStorage 11 | const [selectedDoctor, setSelectedDoctor] = useState(""); 12 | 13 | const { data: doctors, loading, error } = useFetchData(`${BASE_URL}/doctors`); 14 | 15 | const handleSelectChange = (event) => { 16 | setSelectedDoctor(event.target.value); 17 | }; 18 | 19 | const bookAppointment = async () => { 20 | console.log({ testResult }); 21 | const payload = { 22 | doctorId: selectedDoctor, 23 | testName: testName.testName, 24 | testResult: testResult.testResult, 25 | payment: "Pending", 26 | price: "100", 27 | patientGender: loginUser.gender, 28 | patientName: loginUser.name, 29 | bookedOn: `${new Date()}`, 30 | }; 31 | 32 | try { 33 | await axios.post( 34 | `${BASE_URL}/users/appointments/create-appointment`, 35 | payload, 36 | { 37 | headers: { 38 | Authorization: `Bearer ${token}`, // Include the token in the headers 39 | }, 40 | } 41 | ); 42 | toast.success("Appointment booking done"); 43 | } catch (error) { 44 | toast.error("Failed to book appointment"); 45 | console.error(error); 46 | } 47 | }; 48 | 49 | return ( 50 |
51 | {loading && } 52 | {error && } 53 | 54 |
55 |
56 |

Select a Doctor:

57 |
58 | 72 | {selectedDoctor &&

Selected Doctor ID : {selectedDoctor}

} 73 |
74 |
75 |
76 |
77 | 85 | 91 |
92 |
93 |
94 |
95 | ); 96 | } 97 | 98 | export default DoctorsDropDown; 99 | -------------------------------------------------------------------------------- /frontend/src/components/Doctors/DoctorCard.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import starIcon from "../../assets/images/Star.png"; 3 | import { Link } from "react-router-dom"; 4 | import { BsArrowRight } from "react-icons/bs"; 5 | 6 | const DoctorCard = ({ doctor }) => { 7 | const { 8 | name, 9 | avgRating, 10 | totalRating, 11 | photo, 12 | specialization, 13 | experiences, 14 | // totalPatients, 15 | // hospital, 16 | } = doctor; 17 | return ( 18 |
19 |
20 | 21 |
22 |

23 | {name} 24 |

25 | 26 |
27 | 28 | {specialization} 29 | 30 |
31 | 32 | {avgRating} 33 | 34 | 35 | ({totalRating}) 36 | 37 |
38 |
39 | 40 |
41 |
42 | {/*

43 | {totalPatients} + patients 44 |

*/} 45 |

46 | At {experiences && experiences[0]?.hospital} 47 |

48 |
49 | 53 | 56 | 57 |
58 |
59 | ); 60 | }; 61 | 62 | export default DoctorCard; 63 | -------------------------------------------------------------------------------- /frontend/src/components/Doctors/DoctorList.jsx: -------------------------------------------------------------------------------- 1 | import { doctors } from "./../../assets/data/doctors"; 2 | import DoctorCard from "./DoctorCard"; 3 | 4 | import { BASE_URL } from "../../config"; 5 | import useFetchData from "../../hooks/useFetchData"; 6 | import Loader from "../../components/Loader/Loading"; 7 | import Error from "../Error/Error"; 8 | 9 | const DoctorList = () => { 10 | const { data: doctors, loading, error } = useFetchData(`${BASE_URL}/doctors`); 11 | return ( 12 | <> 13 | {loading && } 14 | {error && } 15 | 16 | {!loading && !error && ( 17 |
18 | {doctors.map((doctor) => ( 19 | 20 | ))} 21 |
22 | )} 23 | 24 | ); 25 | }; 26 | 27 | export default DoctorList; 28 | -------------------------------------------------------------------------------- /frontend/src/components/Error/Error.jsx: -------------------------------------------------------------------------------- 1 | const Error = ({ errMessage }) => { 2 | return ( 3 |
4 |

5 | {errMessage} 6 |

7 |
8 | ); 9 | }; 10 | 11 | export default Error; 12 | -------------------------------------------------------------------------------- /frontend/src/components/Faq/FaqItem.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { AiOutlineMenu, AiOutlinePlus } from "react-icons/ai"; 3 | 4 | const FaqItem = ({ item }) => { 5 | const [isOpen, setIsOpen] = useState(false); 6 | 7 | const toggleAccording = () => { 8 | setIsOpen(!isOpen); // Toggle isOpen between true and false 9 | }; 10 | 11 | return ( 12 |
13 |
17 |

18 | {item.question} 19 |

20 |
25 | {isOpen ? : } 26 |
27 |
28 | {isOpen && ( 29 |
30 |

31 | {item.content} 32 |

33 |
34 | )} 35 |
36 | ); 37 | }; 38 | 39 | export default FaqItem; 40 | -------------------------------------------------------------------------------- /frontend/src/components/Faq/FaqList.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { faqs } from "./../../assets/data/faqs"; 3 | import FaqItem from "./FaqItem"; 4 | const FaqList = () => { 5 | return ( 6 |
    7 | {faqs.map((item, index) => ( 8 | 9 | ))} 10 |
11 | ); 12 | }; 13 | 14 | export default FaqList; 15 | -------------------------------------------------------------------------------- /frontend/src/components/Loader/Loading.jsx: -------------------------------------------------------------------------------- 1 | import HashLoader from "react-spinners/HashLoader"; 2 | const Loading = () => { 3 | return ( 4 |
5 | 6 |
7 | ); 8 | }; 9 | 10 | export default Loading; 11 | -------------------------------------------------------------------------------- /frontend/src/components/Services/Disease/DiabetesTest.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import axios from "axios"; 3 | import { BASE_URL } from "../../../config"; 4 | import DcotorsDropDown from "../../DoctorDropDown/DoctorDropDown"; 5 | 6 | const DiabetesTest = () => { 7 | const [inputData, setInputData] = useState({ 8 | "Number of Pregnancies eg. 0": "", 9 | "Glucose (mg/dL) eg. 80": "", 10 | "Blood Pressure (mmHg) eg. 80": "", 11 | "Skin Thickness (mm) eg. 20": "", 12 | "Insulin Level (IU/mL) eg. 80": "", 13 | "Body Mass Index (kg/m²) eg. 23.1": "", 14 | "Diabetes Pedigree Function eg. 0.52": "", 15 | "Age (years) eg. 34": "", 16 | }); 17 | const [prediction, setPrediction] = useState(null); 18 | const [formError, setFormError] = useState(""); 19 | 20 | const handleInputChange = (e) => { 21 | const { name, value } = e.target; 22 | setInputData({ ...inputData, [name]: value }); 23 | setFormError(""); 24 | }; 25 | 26 | const handleSubmit = async (e) => { 27 | e.preventDefault(); 28 | // Check if any field is empty 29 | const isFormFilled = Object.values(inputData).every( 30 | (value) => value.trim() !== "" 31 | ); 32 | if (!isFormFilled) { 33 | setFormError("Please fill out all fields."); 34 | return; 35 | } 36 | try { 37 | const response = await axios.post(`${BASE_URL}/diabetes`, { 38 | data: inputData, 39 | }); 40 | setPrediction(response.data.prediction); 41 | } catch (error) { 42 | console.error("Error:", error); 43 | } 44 | }; 45 | 46 | return ( 47 |
48 |
49 |
50 |

Diabetes Predictor

51 |
52 |
53 | {/* Input fields */} 54 | {Object.entries(inputData).map(([name, value]) => ( 55 |
56 | 64 |
65 | ))} 66 | {/* Form error message */} 67 | {formError && ( 68 |
{formError}
69 | )} 70 | {/* Submit button */} 71 | 76 |
77 |
78 | {/* Prediction result */} 79 | {prediction !== null && ( 80 |
85 |

86 | {prediction.includes("[1]") 87 | ? "Sorry! Please consult your doctor." 88 | : "Great! You are HEALTHY."} 89 |

90 |
91 | )} 92 |
93 |
94 | 98 |
99 | ); 100 | }; 101 | 102 | export default DiabetesTest; -------------------------------------------------------------------------------- /frontend/src/components/Services/Disease/DiseasePage.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import DiabetesTest from "./DiabetesTest"; 3 | import HeartDiseaseTest from "./HeartDiseaseTest"; 4 | import KidneyDiseaseTest from "./KidneyDiseaseTest.jsx"; 5 | import LiverDiseaseTest from "./LiverDiseaseTest.jsx"; 6 | import BreastCancerDiseaseTest from "./BreastCancerDiseaseTest.jsx"; 7 | import MalariaDiseaseTest from "./MalariaDiseaseTest.jsx"; 8 | import PneumoniaDiseaseTest from "./PneumoniaDiseaseTest.jsx"; 9 | import ResultComponent from "./ResultComponent"; 10 | 11 | const DiseasePage = ({ service }) => { 12 | const [prediction, setPrediction] = useState(null); 13 | const handlePrediction = (pred) => { 14 | setPrediction(pred); 15 | }; 16 | 17 | console.log(service.id); 18 | 19 | // Render the appropriate disease component based on the URL parameter 20 | switch (service.id) { 21 | case "1": 22 | return ; 23 | case "2": 24 | return ; 25 | case "3": 26 | return ; 27 | case "4": 28 | return ; 29 | case "5": 30 | return ; 31 | case "6": 32 | return ( 33 | <> 34 | 35 | {prediction !== null && } 36 | 37 | ); 38 | case "7": 39 | return ( 40 | <> 41 | 42 | {prediction !== null && } 43 | 44 | ); 45 | default: 46 | return
No such disease found
; 47 | } 48 | }; 49 | 50 | export default DiseasePage; 51 | -------------------------------------------------------------------------------- /frontend/src/components/Services/Disease/KidneyDiseaseTest.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import axios from "axios"; 3 | import { BASE_URL } from "../../../config"; 4 | import DcotorsDropDown from "../../DoctorDropDown/DoctorDropDown"; 5 | 6 | const KidneyDiseaseTest = () => { 7 | const [inputData, setInputData] = useState({ 8 | Age: "", 9 | BP: "", 10 | AL: "", 11 | SU: "", 12 | RBC: "", 13 | PC: "", 14 | PCC: "", 15 | BA: "", 16 | BGR: "", 17 | BU: "", 18 | SC: "", 19 | POT: "", 20 | WC: "", 21 | HTN: "", 22 | DM: "", 23 | CAD: "", 24 | PE: "", 25 | ANE: "", 26 | }); 27 | const [prediction, setPrediction] = useState(null); 28 | const [formError, setFormError] = useState(""); 29 | 30 | const handleInputChange = (e) => { 31 | const { name, value } = e.target; 32 | setInputData({ ...inputData, [name]: value }); 33 | setFormError(""); 34 | }; 35 | 36 | const handleSubmit = async (e) => { 37 | e.preventDefault(); 38 | // Check if any field is empty 39 | const isFormFilled = Object.values(inputData).every( 40 | (value) => value.trim() !== "" 41 | ); 42 | if (!isFormFilled) { 43 | setFormError("Please fill out all fields."); 44 | return; 45 | } 46 | try { 47 | const response = await axios.post(`${BASE_URL}/kidney`, { 48 | data: inputData, 49 | }); 50 | setPrediction(response.data.prediction); 51 | } catch (error) { 52 | console.error("Error:", error); 53 | } 54 | }; 55 | 56 | return ( 57 |
58 |
59 |
60 |

61 | Kidney Disease Predictor 62 |

63 |
64 |
65 |
66 | {Object.entries(inputData).map(([name, value]) => ( 67 |
68 | 76 |
77 | ))} 78 | {/* Form error message */} 79 | {formError && ( 80 |
{formError}
81 | )} 82 |
83 | {/* Submit button */} 84 | 89 |
90 | {/* Prediction result */} 91 | {prediction !== null && ( 92 |
97 |

98 | {prediction.includes("[1]") 99 | ? "Sorry! Please consult your doctor." 100 | : "Great! You are HEALTHY."} 101 |

102 |
103 | )} 104 |
105 |
106 | 110 |
111 | ); 112 | }; 113 | 114 | export default KidneyDiseaseTest; 115 | -------------------------------------------------------------------------------- /frontend/src/components/Services/Disease/ResultComponent.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | 4 | const ResultComponent = ({ prediction }) => { 5 | const navigate = useNavigate(); 6 | 7 | const handleNavigateHome = () => { 8 | navigate.push("/"); // Navigate to the home page 9 | }; 10 | 11 | return ( 12 |
13 |
14 |
15 | {prediction === 1 ? ( 16 |
17 |
18 | This X-Ray is predicted to have Pneumonia, Please Consult Doctor. 19 |
20 |
21 | ) : ( 22 |
23 |
This X-Ray does not have Pneumonia.
24 |
25 | )} 26 |
27 |
28 |
29 | 35 |
36 |
37 |
38 |
39 |
40 |
41 | ); 42 | }; 43 | 44 | export default ResultComponent; 45 | -------------------------------------------------------------------------------- /frontend/src/components/Services/ServiceCard.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link, useNavigate } from "react-router-dom"; 3 | import { BsArrowRight } from "react-icons/bs"; 4 | 5 | const ServiceCard = ({ item }) => { 6 | const navigate = useNavigate(); 7 | 8 | const handleClick = (id) => { 9 | // Navigate to the corresponding disease page based on the id 10 | navigate(`/disease/${id}`); 11 | }; 12 | 13 | const { id, name, desc, bgColor, textColor } = item; 14 | 15 | return ( 16 |
17 |

18 | {name} 19 |

20 |

21 | {desc} 22 |

23 | 24 |
25 |
handleClick(id)} 27 | className="w-[44px] h-[44px] rounded-full border border-solid border-[#181A1E] flex items-center justify-center group hover:bg-primaryColor hover:border-none cursor-pointer" 28 | > 29 | 30 |
31 | 32 | 41 | {id} 42 | 43 |
44 |
45 | ); 46 | }; 47 | 48 | export default ServiceCard; 49 | -------------------------------------------------------------------------------- /frontend/src/components/Services/ServiceList.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { services } from "./../../assets/data/services"; 3 | import ServiceCard from "./ServiceCard"; 4 | const ServiceList = () => { 5 | return ( 6 |
7 | {services.map((item, index) => ( 8 | 9 | ))} 10 |
11 | ); 12 | }; 13 | 14 | export default ServiceList; 15 | -------------------------------------------------------------------------------- /frontend/src/config.js: -------------------------------------------------------------------------------- 1 | export const BASE_URL = "http://localhost:5000/api/v1"; 2 | export const token = localStorage.getItem("token"); 3 | -------------------------------------------------------------------------------- /frontend/src/configs/charts-config.js: -------------------------------------------------------------------------------- 1 | export const chartsConfig = { 2 | chart: { 3 | toolbar: { 4 | show: false, 5 | }, 6 | }, 7 | title: { 8 | show: "", 9 | }, 10 | dataLabels: { 11 | enabled: false, 12 | }, 13 | xaxis: { 14 | axisTicks: { 15 | show: false, 16 | }, 17 | axisBorder: { 18 | show: false, 19 | }, 20 | labels: { 21 | style: { 22 | colors: "#37474f", 23 | fontSize: "13px", 24 | fontFamily: "inherit", 25 | fontWeight: 300, 26 | }, 27 | }, 28 | }, 29 | yaxis: { 30 | labels: { 31 | style: { 32 | colors: "#37474f", 33 | fontSize: "13px", 34 | fontFamily: "inherit", 35 | fontWeight: 300, 36 | }, 37 | }, 38 | }, 39 | grid: { 40 | show: true, 41 | borderColor: "#dddddd", 42 | strokeDashArray: 5, 43 | xaxis: { 44 | lines: { 45 | show: true, 46 | }, 47 | }, 48 | padding: { 49 | top: 5, 50 | right: 20, 51 | }, 52 | }, 53 | fill: { 54 | opacity: 0.8, 55 | }, 56 | tooltip: { 57 | theme: "dark", 58 | }, 59 | }; 60 | 61 | export default chartsConfig; 62 | -------------------------------------------------------------------------------- /frontend/src/configs/index.js: -------------------------------------------------------------------------------- 1 | export * from "@/configs/charts-config"; 2 | -------------------------------------------------------------------------------- /frontend/src/context/AuthContext.jsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext, useEffect, useReducer } from "react"; 2 | 3 | const parseJSON = (value) => { 4 | try { 5 | return JSON.parse(value); 6 | } catch (e) { 7 | return null; 8 | } 9 | }; 10 | 11 | const getUserFromLocalStorage = () => { 12 | const user = localStorage.getItem("user"); 13 | return user ? parseJSON(user) : null; 14 | }; 15 | 16 | const initialState = { 17 | user: getUserFromLocalStorage(), 18 | role: localStorage.getItem("role") || null, 19 | token: localStorage.getItem("token") || null, 20 | }; 21 | 22 | export const authContext = createContext(initialState); 23 | 24 | const authReducer = (state, action) => { 25 | switch (action.type) { 26 | case "LOGIN_START": 27 | return { 28 | user: null, 29 | role: null, 30 | token: null, 31 | }; 32 | case "LOGIN_SUCCESS": 33 | return { 34 | user: action.payload.user, 35 | token: action.payload.token, 36 | role: action.payload.role, 37 | }; 38 | case "LOGOUT": 39 | return { 40 | user: null, 41 | role: null, 42 | token: null, 43 | }; 44 | 45 | default: 46 | return state; 47 | } 48 | }; 49 | 50 | export const AuthContextProvider = ({ children }) => { 51 | const [state, dispatch] = useReducer(authReducer, initialState); 52 | 53 | useEffect(() => { 54 | localStorage.setItem("user", JSON.stringify(state.user)); 55 | localStorage.setItem("token", state.token); 56 | localStorage.setItem("role", state.role); 57 | }, [state]); 58 | 59 | return ( 60 | 68 | {children} 69 | 70 | ); 71 | }; 72 | -------------------------------------------------------------------------------- /frontend/src/data/authors-table-data.js: -------------------------------------------------------------------------------- 1 | export const authorsTableData = [ 2 | { 3 | img: "/img/team-2.jpeg", 4 | name: "John Michael", 5 | email: "john@creative-tim.com", 6 | job: ["Manager", "Organization"], 7 | online: true, 8 | date: "23/04/18", 9 | }, 10 | { 11 | img: "/img/team-1.jpeg", 12 | name: "Alexa Liras", 13 | email: "alexa@creative-tim.com", 14 | job: ["Programator", "Developer"], 15 | online: false, 16 | date: "11/01/19", 17 | }, 18 | { 19 | img: "/img/team-4.jpeg", 20 | name: "Laurent Perrier", 21 | email: "laurent@creative-tim.com", 22 | job: ["Executive", "Projects"], 23 | online: true, 24 | date: "19/09/17", 25 | }, 26 | { 27 | img: "/img/team-3.jpeg", 28 | name: "Michael Levi", 29 | email: "michael@creative-tim.com", 30 | job: ["Programator", "Developer"], 31 | online: true, 32 | date: "24/12/08", 33 | }, 34 | { 35 | img: "/img/bruce-mars.jpeg", 36 | name: "Bruce Mars", 37 | email: "bruce@creative-tim.com", 38 | job: ["Manager", "Executive"], 39 | online: false, 40 | date: "04/10/21", 41 | }, 42 | { 43 | img: "/img/team-2.jpeg", 44 | name: "Alexander", 45 | email: "alexander@creative-tim.com", 46 | job: ["Programator", "Developer"], 47 | online: false, 48 | date: "14/09/20", 49 | }, 50 | ]; 51 | 52 | export default authorsTableData; 53 | -------------------------------------------------------------------------------- /frontend/src/data/conversations-data.js: -------------------------------------------------------------------------------- 1 | export const conversationsData = [ 2 | { 3 | img: "/img/team-1.jpeg", 4 | name: "Sophie B.", 5 | message: "Hi! I need more information...", 6 | }, 7 | { 8 | img: "/img/team-2.jpeg", 9 | name: "Alexander", 10 | message: "Awesome work, can you...", 11 | }, 12 | { 13 | img: "/img/team-3.jpeg", 14 | name: "Ivanna", 15 | message: "About files I can...", 16 | }, 17 | { 18 | img: "/img/team-4.jpeg", 19 | name: "Peterson", 20 | message: "Have a great afternoon...", 21 | }, 22 | { 23 | img: "/img/bruce-mars.jpeg", 24 | name: "Bruce Mars", 25 | message: "Hi! I need more information...", 26 | }, 27 | ]; 28 | 29 | export default conversationsData; 30 | -------------------------------------------------------------------------------- /frontend/src/data/index.js: -------------------------------------------------------------------------------- 1 | export * from "@/data/statistics-cards-data"; 2 | export * from "@/data/statistics-charts-data"; 3 | export * from "@/data/projects-table-data"; 4 | export * from "@/data/orders-overview-data"; 5 | export * from "@/data/platform-settings-data"; 6 | export * from "@/data/conversations-data"; 7 | export * from "@/data/projects-data"; 8 | export * from "@/data/authors-table-data"; 9 | -------------------------------------------------------------------------------- /frontend/src/data/orders-overview-data.js: -------------------------------------------------------------------------------- 1 | import { 2 | BellIcon, 3 | PlusCircleIcon, 4 | ShoppingCartIcon, 5 | CreditCardIcon, 6 | LockOpenIcon, 7 | BanknotesIcon, 8 | } from "@heroicons/react/24/solid"; 9 | 10 | export const ordersOverviewData = [ 11 | { 12 | icon: BellIcon, 13 | color: "text-blue-gray-300", 14 | title: "$2400, Design changes", 15 | description: "22 DEC 7:20 PM", 16 | }, 17 | { 18 | icon: PlusCircleIcon, 19 | color: "text-blue-gray-300", 20 | title: "New order #1832412", 21 | description: "21 DEC 11 PM", 22 | }, 23 | { 24 | icon: ShoppingCartIcon, 25 | color: "text-blue-gray-300", 26 | title: "Server payments for April", 27 | description: "21 DEC 9:34 PM", 28 | }, 29 | { 30 | icon: CreditCardIcon, 31 | color: "text-blue-gray-300", 32 | title: "New card added for order #4395133", 33 | description: "20 DEC 2:20 AM", 34 | }, 35 | { 36 | icon: LockOpenIcon, 37 | color: "text-blue-gray-300", 38 | title: "Unlock packages for development", 39 | description: "18 DEC 4:54 AM", 40 | }, 41 | { 42 | icon: BanknotesIcon, 43 | color: "text-blue-gray-300", 44 | title: "New order #9583120", 45 | description: "17 DEC", 46 | }, 47 | ]; 48 | 49 | export default ordersOverviewData; 50 | -------------------------------------------------------------------------------- /frontend/src/data/platform-settings-data.js: -------------------------------------------------------------------------------- 1 | export const platformSettingsData = [ 2 | { 3 | title: "account", 4 | options: [ 5 | { 6 | checked: true, 7 | label: "Email me when someone follows me", 8 | }, 9 | { 10 | checked: false, 11 | label: "Email me when someone answers on my post", 12 | }, 13 | { 14 | checked: true, 15 | label: "Email me when someone mentions me", 16 | }, 17 | ], 18 | }, 19 | { 20 | title: "application", 21 | options: [ 22 | { 23 | checked: false, 24 | label: "New launches and projects", 25 | }, 26 | { 27 | checked: true, 28 | label: "Monthly product updates", 29 | }, 30 | { 31 | checked: false, 32 | label: "Subscribe to newsletter", 33 | }, 34 | ], 35 | }, 36 | ]; 37 | 38 | export default platformSettingsData; 39 | -------------------------------------------------------------------------------- /frontend/src/data/projects-data.js: -------------------------------------------------------------------------------- 1 | export const projectsData = [ 2 | { 3 | img: "/img/home-decor-1.jpeg", 4 | title: "Modern", 5 | tag: "Project #1", 6 | description: 7 | "As Uber works through a huge amount of internal management turmoil.", 8 | route: "/dashboard/profile", 9 | members: [ 10 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 11 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 12 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 13 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 14 | ], 15 | }, 16 | { 17 | img: "/img/home-decor-2.jpeg", 18 | title: "Scandinavian", 19 | tag: "Project #2", 20 | description: 21 | "Music is something that every person has his or her own specific opinion about.", 22 | route: "/dashboard/profile", 23 | members: [ 24 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 25 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 26 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 27 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 28 | ], 29 | }, 30 | { 31 | img: "/img/home-decor-3.jpeg", 32 | title: "Minimalist", 33 | tag: "Project #3", 34 | description: 35 | "Different people have different taste, and various types of music.", 36 | route: "/dashboard/profile", 37 | members: [ 38 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 39 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 40 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 41 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 42 | ], 43 | }, 44 | { 45 | img: "/img/home-decor-4.jpeg", 46 | title: "Gothic", 47 | tag: "Project #4", 48 | description: 49 | "Why would anyone pick blue over pink? Pink is obviously a better color.", 50 | route: "/dashboard/profile", 51 | members: [ 52 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 53 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 54 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 55 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 56 | ], 57 | }, 58 | ]; 59 | 60 | export default projectsData; 61 | -------------------------------------------------------------------------------- /frontend/src/data/projects-table-data.js: -------------------------------------------------------------------------------- 1 | export const projectsTableData = [ 2 | { 3 | img: "/img/logo-xd.svg", 4 | name: "Material XD Version", 5 | members: [ 6 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 7 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 8 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 9 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 10 | ], 11 | budget: "$14,000", 12 | completion: 60, 13 | }, 14 | { 15 | img: "/img/logo-atlassian.svg", 16 | name: "Add Progress Track", 17 | members: [ 18 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 19 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 20 | ], 21 | budget: "$3,000", 22 | completion: 10, 23 | }, 24 | { 25 | img: "/img/logo-slack.svg", 26 | name: "Fix Platform Errors", 27 | members: [ 28 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 29 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 30 | ], 31 | budget: "Not set", 32 | completion: 100, 33 | }, 34 | { 35 | img: "/img/logo-spotify.svg", 36 | name: "Launch our Mobile App", 37 | members: [ 38 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 39 | { img: "/img/team-3.jpeg", name: "Jessica Doe" }, 40 | { img: "/img/team-2.jpeg", name: "Ryan Tompson" }, 41 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 42 | ], 43 | budget: "$20,500", 44 | completion: 100, 45 | }, 46 | { 47 | img: "/img/logo-jira.svg", 48 | name: "Add the New Pricing Page", 49 | members: [{ img: "/img/team-4.jpeg", name: "Alexander Smith" }], 50 | budget: "$500", 51 | completion: 25, 52 | }, 53 | { 54 | img: "/img/logo-invision.svg", 55 | name: "Redesign New Online Shop", 56 | members: [ 57 | { img: "/img/team-1.jpeg", name: "Romina Hadid" }, 58 | { img: "/img/team-4.jpeg", name: "Alexander Smith" }, 59 | ], 60 | budget: "$2,000", 61 | completion: 40, 62 | }, 63 | ]; 64 | 65 | export default projectsTableData; 66 | -------------------------------------------------------------------------------- /frontend/src/data/statistics-cards-data.js: -------------------------------------------------------------------------------- 1 | import { 2 | BanknotesIcon, 3 | UserPlusIcon, 4 | UsersIcon, 5 | ChartBarIcon, 6 | } from "@heroicons/react/24/solid"; 7 | 8 | export const statisticsCardsData = [ 9 | { 10 | color: "gray", 11 | icon: BanknotesIcon, 12 | title: "Today's Money", 13 | value: "$53k", 14 | footer: { 15 | color: "text-green-500", 16 | value: "+55%", 17 | label: "than last week", 18 | }, 19 | }, 20 | { 21 | color: "gray", 22 | icon: UsersIcon, 23 | title: "Today's Users", 24 | value: "2,300", 25 | footer: { 26 | color: "text-green-500", 27 | value: "+3%", 28 | label: "than last month", 29 | }, 30 | }, 31 | { 32 | color: "gray", 33 | icon: UserPlusIcon, 34 | title: "New Clients", 35 | value: "3,462", 36 | footer: { 37 | color: "text-red-500", 38 | value: "-2%", 39 | label: "than yesterday", 40 | }, 41 | }, 42 | { 43 | color: "gray", 44 | icon: ChartBarIcon, 45 | title: "Sales", 46 | value: "$103,430", 47 | footer: { 48 | color: "text-green-500", 49 | value: "+5%", 50 | label: "than yesterday", 51 | }, 52 | }, 53 | ]; 54 | 55 | export default statisticsCardsData; 56 | -------------------------------------------------------------------------------- /frontend/src/data/statistics-charts-data.js: -------------------------------------------------------------------------------- 1 | import { chartsConfig } from "@/configs"; 2 | 3 | const websiteViewsChart = { 4 | type: "bar", 5 | height: 220, 6 | series: [ 7 | { 8 | name: "Views", 9 | data: [50, 20, 10, 22, 50, 10, 40], 10 | }, 11 | ], 12 | options: { 13 | ...chartsConfig, 14 | colors: "#388e3c", 15 | plotOptions: { 16 | bar: { 17 | columnWidth: "16%", 18 | borderRadius: 5, 19 | }, 20 | }, 21 | xaxis: { 22 | ...chartsConfig.xaxis, 23 | categories: ["M", "T", "W", "T", "F", "S", "S"], 24 | }, 25 | }, 26 | }; 27 | 28 | const dailySalesChart = { 29 | type: "line", 30 | height: 220, 31 | series: [ 32 | { 33 | name: "Sales", 34 | data: [50, 40, 300, 320, 500, 350, 200, 230, 500], 35 | }, 36 | ], 37 | options: { 38 | ...chartsConfig, 39 | colors: ["#0288d1"], 40 | stroke: { 41 | lineCap: "round", 42 | }, 43 | markers: { 44 | size: 5, 45 | }, 46 | xaxis: { 47 | ...chartsConfig.xaxis, 48 | categories: [ 49 | "Apr", 50 | "May", 51 | "Jun", 52 | "Jul", 53 | "Aug", 54 | "Sep", 55 | "Oct", 56 | "Nov", 57 | "Dec", 58 | ], 59 | }, 60 | }, 61 | }; 62 | 63 | const completedTaskChart = { 64 | type: "line", 65 | height: 220, 66 | series: [ 67 | { 68 | name: "Sales", 69 | data: [50, 40, 300, 320, 500, 350, 200, 230, 500], 70 | }, 71 | ], 72 | options: { 73 | ...chartsConfig, 74 | colors: ["#388e3c"], 75 | stroke: { 76 | lineCap: "round", 77 | }, 78 | markers: { 79 | size: 5, 80 | }, 81 | xaxis: { 82 | ...chartsConfig.xaxis, 83 | categories: [ 84 | "Apr", 85 | "May", 86 | "Jun", 87 | "Jul", 88 | "Aug", 89 | "Sep", 90 | "Oct", 91 | "Nov", 92 | "Dec", 93 | ], 94 | }, 95 | }, 96 | }; 97 | const completedTasksChart = { 98 | ...completedTaskChart, 99 | series: [ 100 | { 101 | name: "Tasks", 102 | data: [50, 40, 300, 220, 500, 250, 400, 230, 500], 103 | }, 104 | ], 105 | }; 106 | 107 | export const statisticsChartsData = [ 108 | { 109 | color: "white", 110 | title: "Website View", 111 | description: "Last Campaign Performance", 112 | footer: "campaign sent 2 days ago", 113 | chart: websiteViewsChart, 114 | }, 115 | { 116 | color: "white", 117 | title: "Daily Sales", 118 | description: "15% increase in today sales", 119 | footer: "updated 4 min ago", 120 | chart: dailySalesChart, 121 | }, 122 | { 123 | color: "white", 124 | title: "Completed Tasks", 125 | description: "Last Campaign Performance", 126 | footer: "just updated", 127 | chart: completedTasksChart, 128 | }, 129 | ]; 130 | 131 | export default statisticsChartsData; 132 | -------------------------------------------------------------------------------- /frontend/src/hooks/useFetchData.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { token } from "../config.js"; 3 | 4 | const useFetchData = (url) => { 5 | const [data, setData] = useState([]); 6 | const [loading, setLoading] = useState(false); 7 | const [error, setError] = useState(null); 8 | 9 | useEffect(() => { 10 | const fetchData = async () => { 11 | setLoading(true); 12 | try { 13 | const res = await fetch(url, { 14 | headers: { Authorization: `Bearer ${token}` }, 15 | }); 16 | const result = await res.json(); 17 | 18 | if (!res.ok) { 19 | throw new Error(result.message + "🤢"); 20 | } 21 | setData(result.data); 22 | setLoading(false); 23 | } catch (err) { 24 | setLoading(false); 25 | setError(err.message); 26 | } 27 | }; 28 | fetchData(); 29 | }, [url]); 30 | return { data, loading, error }; 31 | }; 32 | 33 | export default useFetchData; 34 | -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | section { 7 | @apply py-[75px]; 8 | } 9 | } 10 | 11 | @layer components { 12 | .container { 13 | @apply max-w-full w-[1440px] px-5 mx-auto; 14 | } 15 | .btn { 16 | @apply bg-primaryColor py-[15px] px-[35px] rounded-[50px] text-white font-[600] mt-[38px]; 17 | } 18 | .heading { 19 | @apply text-[44px] leading-[54px] font-[700] text-headingColor; 20 | } 21 | .text__para { 22 | @apply text-[18px] leading-[30px] font-[400] text-textColor mt-[18px]; 23 | } 24 | .header { 25 | @apply bg-[url('./assets/images/mask.png')] bg-no-repeat bg-center bg-cover w-full h-[70px] leading-[50px]; 26 | } 27 | .hero__section { 28 | @apply bg-[url('./assets/images/hero-bg.png')] bg-no-repeat bg-center bg-cover; 29 | } 30 | .form__label { 31 | @apply text-textColor font-semibold text-[16px] leading-7 mb-2; 32 | } 33 | .form__input { 34 | @apply w-full px-4 py-3 border border-solid border-[#0066ff61] focus:outline-none focus:border-primaryColor text-[16px] leading-7 text-headingColor placeholder:text-textColor cursor-pointer rounded-md; 35 | } 36 | } 37 | @media only screen and (max-width: 1024px) { 38 | .container { 39 | @apply w-full; 40 | } 41 | section { 42 | @apply py-[35px]; 43 | } 44 | } 45 | @media only screen and (max-width: 768px) { 46 | .heading { 47 | @apply text-[26px] leading-[36px]; 48 | } 49 | .text__para { 50 | @apply text-[16px] leading-7 mt-3; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /frontend/src/layout/Admin-Layout.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { NavLink, Outlet, Routes, Route } from "react-router-dom"; 3 | import { FaUser, FaHome } from "react-icons/fa"; 4 | import { FaUserDoctor } from "react-icons/fa6"; 5 | import { BsFillTicketDetailedFill } from "react-icons/bs"; 6 | import AdminUsers from "../pages/Admin-Users"; 7 | import AdminDoctors from "../pages/Admin-Doctors"; 8 | import AdminBookings from "../pages/Admin-Bookings"; 9 | import AdminUpdate from "./pages/Admin-Update"; 10 | import { authContext } from "../context/AuthContext"; 11 | import AdminHome from "../pages/Admin-Home"; 12 | import DeleteUser from "../pages/DeleteUser"; 13 | import DeleteDoctor from "../pages/DeleteDoctor"; 14 | 15 | const AdminLayout = () => { 16 | const { user, dispatch } = useContext(authContext); 17 | const handleLogout = () => { 18 | dispatch({ type: "LOGOUT" }); 19 | }; 20 | 21 | return ( 22 | <> 23 | 69 |
70 | 71 |
72 | 73 | } /> 74 | } /> 75 | } /> 76 | } /> 77 | } /> 78 | } /> 79 | } /> 80 | 81 | 82 | ); 83 | }; 84 | 85 | export default AdminLayout; 86 | -------------------------------------------------------------------------------- /frontend/src/layout/Layout.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../components/Header/Header"; 3 | import Routers from "../routes/Routers"; 4 | import Footer from "../components/Footer/Footer"; 5 | const Layout = () => { 6 | return ( 7 |
8 |
9 |
10 | 11 |
12 |
13 |
14 | ); 15 | }; 16 | 17 | export default Layout; 18 | -------------------------------------------------------------------------------- /frontend/src/layout/pages/Admin-Update.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const AdminUpdate = () => { 4 | return
AdminUpdate
; 5 | }; 6 | 7 | export default AdminUpdate; 8 | -------------------------------------------------------------------------------- /frontend/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App.jsx"; 4 | import "./index.css"; 5 | import { BrowserRouter } from "react-router-dom"; 6 | import { ToastContainer } from "react-toastify"; 7 | import "react-toastify/dist/ReactToastify.css"; 8 | import { AuthContextProvider } from "./context/AuthContext.jsx"; 9 | 10 | ReactDOM.createRoot(document.getElementById("root")).render( 11 | 12 | 13 | 14 | 21 | 22 | 23 | 24 | 25 | ); 26 | -------------------------------------------------------------------------------- /frontend/src/pages/Admin-Users.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { BASE_URL, token } from "../config.js"; 3 | import useFetchData from "../hooks/useFetchData.jsx"; 4 | import defaultImg from "../assets/images/default.avif"; 5 | import { BiEditAlt } from "react-icons/bi"; 6 | import { MdDelete } from "react-icons/md"; 7 | import { MdOutlinePersonPin } from "react-icons/md"; 8 | import { PiGenderFemaleBold } from "react-icons/pi"; 9 | import { FaUser } from "react-icons/fa6"; 10 | import { MdMarkEmailUnread } from "react-icons/md"; 11 | import { Link } from "react-router-dom"; 12 | import Loading from "../components/Loader/Loading.jsx"; 13 | import Error from "../components/Error/Error.jsx"; 14 | 15 | const AdminUsers = () => { 16 | const { 17 | data: users, 18 | loading, 19 | error, 20 | } = useFetchData(`${BASE_URL}/admin/users`); 21 | 22 | console.log("call users"); 23 | 24 | const getAllUsersData = async () => { 25 | try { 26 | const response = await fetch(`${BASE_URL}/admin/users`, { 27 | method: "GET", 28 | headers: { 29 | Authorization: `Bearer ${token}`, 30 | }, 31 | }); 32 | const data = await response.json(); 33 | console.log("Users data:", data); 34 | // setUsers(data); 35 | } catch (error) { 36 | console.log("Error fetching users:", error); 37 | } 38 | }; 39 | 40 | useEffect(() => { 41 | getAllUsersData(); 42 | }, []); 43 | 44 | return ( 45 | <> 46 | {loading && } 47 | {error && } 48 | {!loading && !error && ( 49 |
50 | {users.map((user, index) => ( 51 |
55 |
56 | 57 | 62 |
63 |
64 | {user._id} 69 |
70 |
71 | 72 |

{user.name}

73 |
74 |
75 | 76 |

{user.email}

77 |
78 |
79 | 80 |

Role: {user.role || "Unknown Author"}

81 |
82 |
83 | 84 |

{user.gender}

85 |
86 |
87 | ))} 88 |
89 | )} 90 | 91 | ); 92 | }; 93 | 94 | export default AdminUsers; 95 | -------------------------------------------------------------------------------- /frontend/src/pages/CheckoutSuccess.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | const CheckoutSuccess = () => { 5 | return ( 6 |
7 |
8 | 12 | 16 | 17 |
18 |

19 | Payment Done! 20 |

21 |

22 | Thank you for completing your secure online payment. 23 |

24 |

Have a great day!

25 |
26 | 30 | Go Back To Home 31 | 32 |
33 |
34 |
35 |
36 | ); 37 | }; 38 | 39 | export default CheckoutSuccess; 40 | -------------------------------------------------------------------------------- /frontend/src/pages/Contact.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { BASE_URL } from "../config"; 3 | import { toast } from "react-toastify"; 4 | 5 | const Contact = () => { 6 | const [formData, setFormData] = useState({ 7 | email: "", 8 | subject: "", 9 | message: "", 10 | }); 11 | 12 | const handleChange = (e) => { 13 | const { name, value } = e.target; 14 | setFormData({ 15 | ...formData, 16 | [name]: value, 17 | }); 18 | }; 19 | 20 | const handleSubmit = async (e) => { 21 | e.preventDefault(); 22 | try { 23 | const response = await fetch(`${BASE_URL}/contact`, { 24 | method: "POST", 25 | headers: { 26 | "Content-Type": "application/json", 27 | }, 28 | body: JSON.stringify(formData), 29 | }); 30 | if (response.ok) { 31 | toast.success("Email Send Successfully"); 32 | } else { 33 | toast.error("Try Again...!"); 34 | } 35 | } catch (error) { 36 | toast.error("Error submitting form:", error); 37 | } 38 | }; 39 | 40 | return ( 41 |
42 |
43 |

Contact Us

44 |

45 | Got a technical issue? want to send feedback about a beta feature? Let 46 | us know. 47 |

48 |
49 |
50 | 53 | 63 |
64 |
65 | 68 | 78 |
79 |
80 | 83 | 92 |
93 | 101 |
102 | ); 103 | }; 104 | 105 | export default FeedbackForm; 106 | -------------------------------------------------------------------------------- /frontend/src/pages/Doctors/SidePanel.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import convertTime from "../../utils/convertTime.js"; 3 | 4 | import { BASE_URL, token } from "./../../config.js"; 5 | import { toast } from "react-toastify"; 6 | 7 | const SidePanel = ({ doctorId, ticketPrice, timeSlots }) => { 8 | const bookingHandler = async () => { 9 | console.log("call"); 10 | try { 11 | const res = await fetch( 12 | `${BASE_URL}/bookings/checkout-session/${doctorId}`, 13 | { 14 | method: "post", 15 | headers: { 16 | Authorization: `Bearer ${token}`, 17 | }, 18 | } 19 | ); 20 | 21 | const data = await res.json(); 22 | 23 | if (!res.ok) { 24 | throw new Error(data.message + "Please try again"); 25 | } 26 | 27 | if (data.session.url) { 28 | window.location.href = data.session.url; 29 | } 30 | } catch (err) { 31 | toast.error(err.message); 32 | } 33 | }; 34 | 35 | return ( 36 |
37 |
38 |

Ticket Price

39 | 40 | {ticketPrice} USD 41 | 42 |
43 | 44 |
45 |

46 | Available Time Slots: 47 |

48 | 49 |
    50 | {timeSlots?.map((item, index) => ( 51 |
  • 52 |

    53 | {item.day.charAt(0).toUpperCase() + item.day.slice(1)} 54 |

    55 |

    56 | {convertTime(item.startingTime)} -{" "} 57 | {convertTime(item.endingTime)} 58 |

    59 |
  • 60 | ))} 61 |
62 |
63 | 66 |
67 | ); 68 | }; 69 | 70 | export default SidePanel; 71 | -------------------------------------------------------------------------------- /frontend/src/pages/ForgotPassword.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | import { BASE_URL } from "../config"; 4 | import { toast } from "react-toastify"; 5 | import { authContext } from "../context/AuthContext.jsx"; 6 | 7 | const ForgotPassword = () => { 8 | const [loading, setLoading] = useState(false); 9 | const navigate = useNavigate(); 10 | const { dispatch } = useContext(authContext); 11 | 12 | const [formData, setFormData] = useState({ 13 | email: "", 14 | }); 15 | 16 | const handleInputChange = (e) => { 17 | setFormData({ ...formData, [e.target.name]: e.target.value }); 18 | }; 19 | 20 | const submitHandler = async (event) => { 21 | event.preventDefault(); 22 | setLoading(true); 23 | 24 | try { 25 | const res = await fetch(`${BASE_URL}/forgot-password`, { 26 | method: "post", 27 | headers: { 28 | "Content-Type": "application/json", 29 | }, 30 | body: JSON.stringify(formData), 31 | }); 32 | const result = await res.json(); 33 | if (!res.ok) { 34 | throw new Error(result.message); 35 | } 36 | 37 | dispatch({ 38 | type: "LOGIN_SUCCESS", 39 | payload: { 40 | user: result.data, 41 | token: result.token, 42 | role: result.role, 43 | }, 44 | }); 45 | 46 | setLoading(false); 47 | toast.success(result.message); 48 | navigate("/login"); 49 | } catch (err) { 50 | toast.error(err.message); 51 | setLoading(false); 52 | } 53 | }; 54 | 55 | return ( 56 |
57 |
58 |

59 | Forgot 60 | Password ❗ 61 |

62 |
63 |
64 | 73 |
74 | 75 |
76 | 82 |
83 |
84 |
85 |
86 | ); 87 | }; 88 | 89 | export default ForgotPassword; 90 | -------------------------------------------------------------------------------- /frontend/src/pages/ResetPassword.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useContext } from "react"; 2 | import { useNavigate, useParams } from "react-router-dom"; 3 | import { BASE_URL } from "../config"; 4 | import { toast } from "react-toastify"; 5 | import { authContext } from "../context/AuthContext.jsx"; 6 | 7 | const ResetPassword = () => { 8 | const [loading, setLoading] = useState(false); 9 | const navigate = useNavigate(); 10 | const { dispatch } = useContext(authContext); 11 | const { id, token } = useParams(); 12 | 13 | const [formData, setFormData] = useState({ 14 | password: "", 15 | }); 16 | 17 | const handleInputChange = (e) => { 18 | setFormData({ ...formData, [e.target.name]: e.target.value }); 19 | }; 20 | 21 | const submitHandler = async (event) => { 22 | event.preventDefault(); 23 | setLoading(true); 24 | 25 | try { 26 | const res = await fetch(`${BASE_URL}/reset-password/${id}/${token}`, { 27 | method: "post", 28 | headers: { 29 | "Content-Type": "application/json", 30 | }, 31 | body: JSON.stringify(formData), 32 | }); 33 | const result = await res.json(); 34 | if (!res.ok) { 35 | throw new Error(result.message); 36 | } 37 | 38 | dispatch({ 39 | type: "LOGIN_SUCCESS", 40 | payload: { 41 | user: result.data, 42 | token: result.token, 43 | role: result.role, 44 | }, 45 | }); 46 | 47 | setLoading(false); 48 | toast.success(result.message); 49 | navigate("/login"); 50 | } catch (err) { 51 | toast.error(err.message); 52 | setLoading(false); 53 | } 54 | }; 55 | 56 | return ( 57 |
58 |
59 |

60 | Reset 61 | Password ❗ 62 |

63 |
64 |
65 | 74 |
75 | 76 |
77 | 83 |
84 |
85 |
86 |
87 | ); 88 | }; 89 | 90 | export default ResetPassword; 91 | -------------------------------------------------------------------------------- /frontend/src/pages/Services.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { services } from "../assets/data/services"; 3 | import ServiceCard from "../components/Services/ServiceCard"; 4 | 5 | const Services = () => { 6 | return ( 7 |
8 |
9 |
10 | {services.map((item, index) => ( 11 | 12 | ))} 13 |
14 |
15 |
16 | ); 17 | }; 18 | 19 | export default Services; 20 | -------------------------------------------------------------------------------- /frontend/src/routes/ProtectedRoute.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Navigate } from "react-router-dom"; 3 | import { useContext } from "react"; 4 | import { authContext } from "../context/AuthContext"; 5 | 6 | const ProtectedRoute = ({ children, allowedRoles }) => { 7 | const { token, role } = useContext(authContext); 8 | 9 | const isAllowed = allowedRoles.includes(role); 10 | const accessibleRoute = 11 | token && isAllowed ? children : ; 12 | 13 | return accessibleRoute; 14 | }; 15 | 16 | export default ProtectedRoute; 17 | -------------------------------------------------------------------------------- /frontend/src/routes/Routers.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Home from "../pages/Home"; 3 | import Services from "../pages/Services"; 4 | import Signup from "../pages/Signup"; 5 | import Symptomchk from "../pages/Symptomchk"; 6 | import Login from "../pages/Login"; 7 | import Contact from "../pages/Contact"; 8 | import Doctors from "../pages/Doctors/Doctors"; 9 | import DoctorDetails from "../pages/Doctors/DoctorDetails"; 10 | import { Routes, Route } from "react-router-dom"; 11 | import MyAccount from "../Dashboard/user-account/MyAccount"; 12 | import Dashboard from "../Dashboard/doctor-account/Dashboard"; 13 | import ProtectedRoute from "./ProtectedRoute"; 14 | import CheckoutSuccess from "../pages/CheckoutSuccess"; 15 | import { services } from "../assets/data/services.js"; 16 | import DiseasePage from "../components/Services/Disease/DiseasePage.jsx"; 17 | import ForgotPassword from "../pages/ForgotPassword.jsx"; 18 | import ResetPassword from "../pages/ResetPassword.jsx"; 19 | 20 | const Routers = () => { 21 | return ( 22 | 23 | } /> 24 | } /> 25 | } /> 26 | } /> 27 | } /> 28 | } /> 29 | } /> 30 | } /> 31 | } /> 32 | } /> 33 | 34 | 35 | 39 | 40 | 41 | } 42 | /> 43 | } /> 44 | 48 | 49 | 50 | } 51 | /> 52 | 56 | 57 | 58 | } 59 | /> 60 | {/* Dynamically create routes for each disease */} 61 | {services.map((service) => ( 62 | } // Pass the service data to the DiseasePage component 66 | /> 67 | ))} 68 | 69 | ); 70 | }; 71 | 72 | export default Routers; 73 | -------------------------------------------------------------------------------- /frontend/src/utils/convertTime.js: -------------------------------------------------------------------------------- 1 | const convertTime = (time) => { 2 | // Check if the time string contains the colon character 3 | if (!time.includes(":")) { 4 | // If the colon is not present, return an error message or handle it as per your requirement 5 | return "Invalid time format"; 6 | } 7 | const timeParts = time.split(":"); 8 | 9 | let hours = parseInt(timeParts[0]); 10 | const minutes = parseInt(timeParts[1]); 11 | 12 | let meridiem = "am"; 13 | 14 | if (hours >= 12) { 15 | meridiem = "pm"; 16 | 17 | if (hours > 12) { 18 | hours -= 12; 19 | } 20 | } 21 | 22 | return ( 23 | hours.toString().padStart(2, "0") + 24 | ":" + // Ensure hours are always 2 digits 25 | minutes.toString().padStart(2, "0") + 26 | " " + 27 | meridiem 28 | ); 29 | }; 30 | 31 | export default convertTime; 32 | -------------------------------------------------------------------------------- /frontend/src/utils/formatDate.js: -------------------------------------------------------------------------------- 1 | export const formateDate = (date, config) => { 2 | const defaultOptions = { day: "numeric", month: "long", year: "numeric" }; 3 | const options = config ? config : defaultOptions; 4 | 5 | return new Date(date).toLocaleDateString("en-US", options); 6 | }; 7 | -------------------------------------------------------------------------------- /frontend/src/utils/uploadCloudinary.js: -------------------------------------------------------------------------------- 1 | const cloud_name = import.meta.env.VITE_CLOUD_NAME; 2 | const upload_preset = import.meta.env.VITE_UPLOAD_PRESET; 3 | 4 | const uploadImageToCloudinary = async (file) => { 5 | const uploadData = new FormData(); 6 | 7 | uploadData.append("file", file); 8 | uploadData.append("upload_preset", upload_preset); 9 | uploadData.append("cloud_name", cloud_name); 10 | 11 | const res = await fetch( 12 | `https://api.cloudinary.com/v1_1/${cloud_name}/image/upload`, 13 | { 14 | method: "post", 15 | body: uploadData, 16 | } 17 | ); 18 | 19 | const data = await res.json(); 20 | return data; 21 | }; 22 | 23 | export default uploadImageToCloudinary; 24 | -------------------------------------------------------------------------------- /frontend/src/widgets/cards/index.js: -------------------------------------------------------------------------------- 1 | export * from "@/widgets/cards/statistics-card"; -------------------------------------------------------------------------------- /frontend/src/widgets/cards/statistics-card.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | Card, 3 | CardHeader, 4 | CardBody, 5 | CardFooter, 6 | Typography, 7 | } from "@material-tailwind/react"; 8 | import PropTypes from "prop-types"; 9 | 10 | export function StatisticsCard({ color, icon, title, value, footer }) { 11 | return ( 12 | 13 | 20 | {icon} 21 | 22 | 23 | 24 | {title} 25 | 26 | 27 | {value} 28 | 29 | 30 | {footer && ( 31 | 32 | {footer} 33 | 34 | )} 35 | 36 | ); 37 | } 38 | 39 | StatisticsCard.defaultProps = { 40 | color: "blue", 41 | footer: null, 42 | }; 43 | 44 | StatisticsCard.propTypes = { 45 | color: PropTypes.oneOf([ 46 | "white", 47 | "blue-gray", 48 | "gray", 49 | "brown", 50 | "deep-orange", 51 | "orange", 52 | "amber", 53 | "yellow", 54 | "lime", 55 | "light-green", 56 | "green", 57 | "teal", 58 | "cyan", 59 | "light-blue", 60 | "blue", 61 | "indigo", 62 | "deep-purple", 63 | "purple", 64 | "pink", 65 | "red", 66 | ]), 67 | icon: PropTypes.node.isRequired, 68 | title: PropTypes.node.isRequired, 69 | value: PropTypes.node.isRequired, 70 | footer: PropTypes.node, 71 | }; 72 | 73 | StatisticsCard.displayName = "/src/widgets/cards/statistics-card.jsx"; 74 | 75 | export default StatisticsCard; 76 | -------------------------------------------------------------------------------- /frontend/src/widgets/charts/index.js: -------------------------------------------------------------------------------- 1 | export * from "@/widgets/charts/statistics-chart"; 2 | -------------------------------------------------------------------------------- /frontend/src/widgets/charts/statistics-chart.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | Card, 3 | CardHeader, 4 | CardBody, 5 | CardFooter, 6 | Typography, 7 | } from "@material-tailwind/react"; 8 | import PropTypes from "prop-types"; 9 | import Chart from "react-apexcharts"; 10 | 11 | export function StatisticsChart({ color, chart, title, description, footer }) { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | {title} 20 | 21 | 22 | {description} 23 | 24 | 25 | {footer && ( 26 | 27 | {footer} 28 | 29 | )} 30 | 31 | ); 32 | } 33 | 34 | StatisticsChart.defaultProps = { 35 | color: "blue", 36 | footer: null, 37 | }; 38 | 39 | StatisticsChart.propTypes = { 40 | color: PropTypes.oneOf([ 41 | "white", 42 | "blue-gray", 43 | "gray", 44 | "brown", 45 | "deep-orange", 46 | "orange", 47 | "amber", 48 | "yellow", 49 | "lime", 50 | "light-green", 51 | "green", 52 | "teal", 53 | "cyan", 54 | "light-blue", 55 | "blue", 56 | "indigo", 57 | "deep-purple", 58 | "purple", 59 | "pink", 60 | "red", 61 | ]), 62 | chart: PropTypes.object.isRequired, 63 | title: PropTypes.node.isRequired, 64 | description: PropTypes.node.isRequired, 65 | footer: PropTypes.node, 66 | }; 67 | 68 | StatisticsChart.displayName = "/src/widgets/charts/statistics-chart.jsx"; 69 | 70 | export default StatisticsChart; 71 | -------------------------------------------------------------------------------- /frontend/src/widgets/layout/footer.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from "prop-types"; 2 | import { Typography } from "@material-tailwind/react"; 3 | import { HeartIcon } from "@heroicons/react/24/solid"; 4 | 5 | export function Footer({ brandName, brandLink, routes }) { 6 | const year = new Date().getFullYear(); 7 | 8 | return ( 9 |
10 |
11 | 12 | © {year}, made with{" "} 13 | by{" "} 14 | 19 | {brandName} 20 | {" "} 21 | for a better web. 22 | 23 |
    24 | {routes.map(({ name, path }) => ( 25 |
  • 26 | 33 | {name} 34 | 35 |
  • 36 | ))} 37 |
38 |
39 |
40 | ); 41 | } 42 | 43 | Footer.defaultProps = { 44 | brandName: "Creative Tim", 45 | brandLink: "https://www.creative-tim.com", 46 | routes: [ 47 | { name: "Creative Tim", path: "https://www.creative-tim.com" }, 48 | { name: "About Us", path: "https://www.creative-tim.com/presentation" }, 49 | { name: "Blog", path: "https://www.creative-tim.com/blog" }, 50 | { name: "License", path: "https://www.creative-tim.com/license" }, 51 | ], 52 | }; 53 | 54 | Footer.propTypes = { 55 | brandName: PropTypes.string, 56 | brandLink: PropTypes.string, 57 | routes: PropTypes.arrayOf(PropTypes.object), 58 | }; 59 | 60 | Footer.displayName = "/src/widgets/layout/footer.jsx"; 61 | 62 | export default Footer; 63 | -------------------------------------------------------------------------------- /frontend/src/widgets/layout/index.js: -------------------------------------------------------------------------------- 1 | export * from "@/widgets/layout/sidenav"; 2 | export * from "@/widgets/layout/dashboard-navbar"; 3 | export * from "@/widgets/layout/configurator"; 4 | export * from "@/widgets/layout/footer"; 5 | export * from "@/widgets/layout/navbar"; 6 | -------------------------------------------------------------------------------- /frontend/src/widgets/layout/navbar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Link } from "react-router-dom"; 4 | import { 5 | Navbar as MTNavbar, 6 | Collapse, 7 | Typography, 8 | Button, 9 | IconButton, 10 | } from "@material-tailwind/react"; 11 | import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline"; 12 | 13 | export function Navbar({ brandName, routes, action }) { 14 | const [openNav, setOpenNav] = React.useState(false); 15 | 16 | React.useEffect(() => { 17 | window.addEventListener( 18 | "resize", 19 | () => window.innerWidth >= 960 && setOpenNav(false) 20 | ); 21 | }, []); 22 | 23 | const navList = ( 24 |
    25 | {routes.map(({ name, path, icon }) => ( 26 | 33 | 34 | {icon && 35 | React.createElement(icon, { 36 | className: "w-[18px] h-[18px] opacity-50 mr-1", 37 | })} 38 | {name} 39 | 40 | 41 | ))} 42 |
43 | ); 44 | 45 | return ( 46 | 47 |
48 | 49 | 53 | {brandName} 54 | 55 | 56 |
{navList}
57 | {React.cloneElement(action, { 58 | className: "hidden lg:inline-block", 59 | })} 60 | setOpenNav(!openNav)} 65 | > 66 | {openNav ? ( 67 | 68 | ) : ( 69 | 70 | )} 71 | 72 |
73 | 74 |
75 | {navList} 76 | {React.cloneElement(action, { 77 | className: "w-full block lg:hidden", 78 | })} 79 |
80 |
81 |
82 | ); 83 | } 84 | 85 | Navbar.defaultProps = { 86 | brandName: "Material Tailwind React", 87 | action: ( 88 | 92 | 95 | 96 | ), 97 | }; 98 | 99 | Navbar.propTypes = { 100 | brandName: PropTypes.string, 101 | routes: PropTypes.arrayOf(PropTypes.object).isRequired, 102 | action: PropTypes.node, 103 | }; 104 | 105 | Navbar.displayName = "/src/widgets/layout/navbar.jsx"; 106 | 107 | export default Navbar; 108 | -------------------------------------------------------------------------------- /frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ["./src/**/*.{html,js,ts,jsx,tsx}"], 4 | theme: { 5 | extend: { 6 | colors: { 7 | primaryColor: "#0067FF", 8 | yellowColor: "#FEB60D", 9 | purpleColor: "#9771FF", 10 | irisBlueColor: "#01B5C5", 11 | headingColor: "#181A1E", 12 | textColor: "#4E545F", 13 | }, 14 | boxShadow: { 15 | panelShadow: "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px;", 16 | }, 17 | }, 18 | }, 19 | plugins: [], 20 | }; 21 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react"; 3 | import vitepluginrewriteall from "vite-plugin-rewrite-all"; 4 | 5 | export default defineConfig({ 6 | plugins: [react(), vitepluginrewriteall()], 7 | resolve: { 8 | alias: [{ find: "@", replacement: "/src" }], 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # AI-based Medical Laboratory 2 | 3 | ## Project Overview 4 | 5 | The AI-based Medical Laboratory project aims to revolutionize laboratory medicine through the use of artificial intelligence (AI) and machine learning (ML). By enhancing the precision and speed of laboratory processes, the project seeks to reduce human errors, cut costs, and ultimately improve patient outcomes and satisfaction. 6 | 7 | ### Features 8 | 9 | - **Customer Module**: Allows patients to submit samples and receive results. 10 | - **Doctor Module**: Provides doctors with tools to analyze lab results and make informed decisions. 11 | - **Lab Assistant Module**: Assists lab technicians with managing samples and running analyses using AI/ML tools. 12 | 13 | ### Pros and Cons 14 | 15 | #### Pros 16 | 17 | - Enhances precision and speed of laboratory medicine. 18 | - Reduces human errors and operational costs. 19 | - Improves patient outcomes and satisfaction. 20 | 21 | #### Cons 22 | 23 | - Challenges with data quality and availability. 24 | - Requires significant computing power. 25 | - Issues of trust, acceptance, and the need for education. 26 | 27 | ### Technologies Used 28 | 29 | - **Frontend**: React, Redux, HTML, CSS, JavaScript 30 | - **Backend**: Node.js, Express, MongoDB 31 | - **AI/ML Tools**: Python, R, TensorFlow, PyTorch, scikit-learn, pandas, NumPy, matplotlib, seaborn 32 | 33 | ## Project Structure 34 | 35 | The project is structured into two main directories: 36 | 37 | - `frontend`: Contains the frontend code built with React. 38 | - `backend`: Contains the backend code built with Node.js and Express. 39 | 40 | ## Installation 41 | 42 | ### Prerequisites 43 | 44 | - Node.js and npm installed on your machine. 45 | - MongoDB installed and running. 46 | 47 | ### Steps 48 | 49 | 1. **Clone the repository** 50 | 51 | ```bash 52 | git clone https://github.com/your-username/ai-medical-lab.git 53 | cd ai-medical-lab 54 | ``` 55 | 56 | 2. **Install dependencies for backend** 57 | 58 | ```bash 59 | cd backend 60 | npm install 61 | ``` 62 | 63 | 3. **Install dependencies for frontend** 64 | 65 | ```bash 66 | cd ../frontend 67 | npm install 68 | ``` 69 | 70 | 4. **Set up environment variables** 71 | 72 | - Create a `.env` file in the `backend` directory and add the following: 73 | 74 | ```text 75 | MONGO_URI=your_mongodb_uri 76 | PORT=5000 77 | ``` 78 | 79 | 5. **Run the backend server** 80 | 81 | ```bash 82 | cd ../backend 83 | npm start or nodemon 84 | ``` 85 | 86 | 6. **Run the frontend server** 87 | 88 | ```bash 89 | cd ../frontend 90 | npm start 91 | ``` 92 | 93 | ## Usage 94 | 95 | - Access the application at `http://localhost:5173`. 96 | - Use the frontend interface to interact with the different modules (Customer, Doctor, Lab Assistant). 97 | 98 | ## Contributors 99 | 100 | - **[Abdul Wahab](https://github.com/abdul-wahab619)** - Full Stack Developer 101 | - **[Nafeesa Shehzadi](https://github.com/nafeesa-shehzadi)** - Frontend Developer 102 | 103 | ## Collaboration 104 | 105 | We welcome contributions from everyone! If you are interested in contributing to this project, please follow these steps: 106 | 107 | 1. Fork the repository. 108 | 2. Create a new branch (`git checkout -b feature-branch`). 109 | 3. Make your changes. 110 | 4. Commit your changes (`git commit -m 'Add new feature'`). 111 | 5. Push to the branch (`git push origin feature-branch`). 112 | 6. Create a Pull Request. 113 | 114 | For major changes, please open an issue first to discuss what you would like to change. 115 | 116 | Feel free to reach out to us with any questions or suggestions. Let's collaborate to extend the exposure and impact of this project! 117 | 118 | 119 | ## License 120 | 121 | This project is licensed under the [MIT License](https://github.com/abdul-wahab619/AI-MedLab/blob/main/LICENSE). -------------------------------------------------------------------------------- /run commands.txt: -------------------------------------------------------------------------------- 1 | //frontend 2 | npm create vite@latest 3 | npm install -D tailwindcss postcss autoprefixer 4 | npx tailwindcss init -p 5 | npm i react-router-dom react-icons react-spinners react-toastify swiper 6 | 7 | //backend 8 | npm i express mongodb mongoose cors jsonwebtoken cookie-parser dotenv bcryptjs --------------------------------------------------------------------------------