├── .gitignore ├── .prettierrc ├── README.md ├── images └── 7fc6075cfe7a0e74bbac0b29a1ccb304 ├── jsconfig.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── server ├── .gitignore ├── Middleware │ ├── Admin.js │ └── Auth.js ├── Utils │ ├── Email.js │ ├── Errors.js │ ├── TokenGenerator.js │ ├── catchAsyncError.js │ └── cloudinary.js ├── app.js ├── controllers │ ├── Admin.js │ ├── Auth.js │ ├── Chat.js │ ├── Common.js │ ├── Doctor.js │ ├── Patient.js │ └── review.js ├── db.js ├── index.js ├── joi │ ├── DoctorJoi.js │ └── PatientJoi.js ├── models │ ├── Admin.js │ ├── Chat.js │ ├── Query.js │ ├── Schedule.js │ ├── doctor.js │ ├── patient.js │ └── review.js ├── package.json └── routes │ ├── Admin.js │ ├── Auth.js │ ├── Chat.js │ ├── Common.js │ ├── Doctor.js │ ├── Patient.js │ └── Review.js ├── src ├── App.css ├── App.js ├── App.test.js ├── assets │ ├── Krish.png │ ├── Services.avif │ ├── holistic_health.png │ ├── nutrition.jpg │ ├── physiotherapy.png │ ├── service.png │ ├── wellbeing.png │ ├── wellcarelogo.png │ └── yoga.png ├── components │ ├── AdminDashboard │ │ ├── Admin.js │ │ ├── AdminNav.js │ │ ├── Expert.js │ │ ├── ExpertVerify.js │ │ ├── GetQuery.js │ │ ├── Modal.css │ │ ├── Query.js │ │ ├── QueryHeading.js │ │ ├── StatHeading.js │ │ └── VerifyHeading.js │ ├── AdminLogin │ │ ├── LeftLogin.js │ │ └── RightLogin.js │ ├── Chat │ │ ├── Chat.js │ │ ├── ChatHome.js │ │ ├── ChatInput.js │ │ ├── ChatMessage.js │ │ ├── Contacts.js │ │ └── DocChat.js │ ├── DocNotverified │ │ └── Notverified.js │ ├── DoctorRegistration │ │ ├── DoctorRegistration.js │ │ ├── Final.js │ │ ├── Step1.js │ │ ├── Step2.js │ │ ├── Step3.js │ │ ├── Step4.js │ │ ├── Step5.js │ │ ├── Stepper.js │ │ ├── StepperControl.js │ │ └── contexts │ │ │ └── StepperContext.js │ ├── GymSearch │ │ ├── Filter.js │ │ ├── GymSearch.js │ │ ├── Heading.js │ │ ├── Home.js │ │ └── Result.js │ ├── Home │ │ ├── Appointment.js │ │ ├── Categories.js │ │ ├── Center.js │ │ ├── Home.js │ │ └── RightSidebar.js │ ├── Icons │ │ ├── Bold │ │ │ ├── calendarCheck.js │ │ │ ├── chat.js │ │ │ ├── contactUs.js │ │ │ ├── ellipis.js │ │ │ ├── experience.js │ │ │ ├── eyeOff.js │ │ │ ├── fullEye.js │ │ │ ├── fullStar.js │ │ │ ├── gym.js │ │ │ ├── halfStar.js │ │ │ ├── home.js │ │ │ ├── licence.js │ │ │ ├── location.js │ │ │ ├── lock.js │ │ │ ├── mail.js │ │ │ ├── money.js │ │ │ ├── myAccount.js │ │ │ ├── nutritionist.js │ │ │ ├── paperClip.js │ │ │ ├── paperPlane.js │ │ │ ├── physio.js │ │ │ ├── query.js │ │ │ ├── settings.js │ │ │ ├── smile.js │ │ │ ├── stat.js │ │ │ ├── thumbsUp.js │ │ │ ├── user.js │ │ │ ├── verified.js │ │ │ ├── verify.js │ │ │ └── yoga.js │ │ └── Light │ │ │ ├── chat.js │ │ │ ├── contact.js │ │ │ ├── contactUs.js │ │ │ ├── home.js │ │ │ ├── leftArrow.js │ │ │ ├── logout.js │ │ │ ├── myAccount.js │ │ │ ├── query.js │ │ │ ├── rightArrow.js │ │ │ ├── star.js │ │ │ ├── stat.js │ │ │ ├── userName.js │ │ │ └── verify.js │ ├── Landing │ │ ├── About.js │ │ ├── Footer.js │ │ ├── Hero.js │ │ ├── Landing.js │ │ ├── Navbar.js │ │ └── Service.js │ ├── Login │ │ ├── LeftLogin.js │ │ └── RightLogin.js │ ├── MyAccount │ │ ├── Form.js │ │ └── Header.js │ ├── NutriSearch │ │ ├── Filter.js │ │ ├── Heading.js │ │ ├── Home.js │ │ ├── NutriSearch.js │ │ └── Result.js │ ├── PaymentCheckout │ │ ├── Checkout.js │ │ └── Head.js │ ├── PaymentGateway │ │ ├── Gateway.js │ │ └── Heading.js │ ├── PaymentSuccess │ │ └── Success.js │ ├── PhysioSearch │ │ ├── Filter.js │ │ ├── Heading.js │ │ ├── Home.js │ │ ├── Pagination.js │ │ ├── PhysioSearch.js │ │ └── Result.js │ ├── Profile │ │ ├── Header.js │ │ └── Main.js │ ├── ProtectRoute │ │ └── ProtectRoute.js │ ├── ReachUs │ │ └── ContactUs.js │ ├── Review │ │ └── Review.js │ ├── ScheduledAppointments │ │ └── Main.js │ ├── Signup │ │ ├── LeftSignup.js │ │ └── RightSignup.js │ ├── SlotBooking │ │ ├── SlotBooking.js │ │ └── Title.js │ ├── TAC │ │ ├── Tac.js │ │ └── TacHeading.js │ ├── TopRated │ │ ├── Heading.js │ │ ├── TopGym.js │ │ ├── TopNutri.js │ │ ├── TopPhysio.js │ │ └── TopRated.js │ ├── UpdatePassword │ │ ├── Form.js │ │ └── Header.js │ ├── Utils │ │ ├── LoginNavbar.js │ │ ├── Navbar.js │ │ └── NavigateBack.js │ └── VerifySuccess │ │ └── VerifySuccess.js ├── context │ └── UserContext.js ├── index.css ├── index.js ├── logo.svg ├── pages │ ├── AdminLogin.js │ ├── ExpertProfile.js │ ├── ExpertScheduledAppointments.js │ ├── ForgotPassword.js │ ├── Landing.js │ ├── Login.js │ ├── MyAccount.js │ ├── PendingPayment.js │ ├── Rating.js │ ├── ReachUs.js │ ├── ResetPassword.js │ ├── Signup.js │ ├── TopRated.js │ ├── UpdatePassword.js │ └── VideoCall.js ├── reportWebVitals.js └── setupTests.js └── tailwind.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | src/components/Utils/videocreds.js 4 | 5 | # dependencies 6 | node_modules 7 | package-lock.json 8 | /.pnp 9 | .pnp.js 10 | 11 | # testing 12 | /coverage 13 | 14 | # production 15 | /build 16 | 17 | # misc 18 | .DS_Store 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser. 13 | 14 | The page will reload when you make changes.\ 15 | You may also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!** 35 | 36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. 39 | 40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /images/7fc6075cfe7a0e74bbac0b29a1ccb304: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/images/7fc6075cfe7a0e74bbac0b29a1ccb304 -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./src", 4 | "target": "es6" 5 | }, 6 | "include": ["src"] 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wellcare", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@heroicons/react": "^1.0.6", 7 | "@material-tailwind/react": "^1.2.5", 8 | "@syncfusion/ej2-react-calendars": "^20.4.48", 9 | "@testing-library/jest-dom": "^5.16.5", 10 | "@testing-library/react": "^13.4.0", 11 | "@testing-library/user-event": "^13.5.0", 12 | "@zegocloud/zego-uikit-prebuilt": "^1.8.0", 13 | "axios": "^1.2.0", 14 | "concurrently": "^7.6.0", 15 | "creds": "^1.0.0", 16 | "date-fns": "^2.29.3", 17 | "emoji-picker-react": "^4.4.7", 18 | "flowbite": "^1.6.2", 19 | "flowbite-datepicker": "^1.2.2", 20 | "flowbite-react": "^0.3.7", 21 | "install": "^0.13.0", 22 | "moment": "^2.29.4", 23 | "nodemon": "^2.0.20", 24 | "query-string": "^8.1.0", 25 | "react": "^18.2.0", 26 | "react-calendar": "^4.0.0", 27 | "react-copy-to-clipboard": "^5.1.0", 28 | "react-custom-scrollbars-2": "^4.5.0", 29 | "react-datepicker": "^4.10.0", 30 | "react-dom": "^18.2.0", 31 | "react-hook-form": "^7.40.0", 32 | "react-icons": "^4.8.0", 33 | "react-moment": "^1.1.3", 34 | "react-paginate": "^8.1.4", 35 | "react-router": "^6.8.0", 36 | "react-router-dom": "^6.8.0", 37 | "react-scripts": "5.0.1", 38 | "react-scroll": "^1.8.8", 39 | "react-tailwindcss-datepicker": "^1.4.0", 40 | "sentiment": "^5.0.2", 41 | "simple-peer": "^9.11.1", 42 | "socket.io-client": "^4.6.1", 43 | "sweetalert2": "^11.6.14", 44 | "web-vitals": "^2.1.4" 45 | }, 46 | "scripts": { 47 | "start": "react-scripts start", 48 | "build": "react-scripts build", 49 | "test": "react-scripts test", 50 | "eject": "react-scripts eject", 51 | "both": "concurrently \"npm start\" \"nodemon server/app.js\"" 52 | }, 53 | "eslintConfig": { 54 | "extends": [ 55 | "react-app", 56 | "react-app/jest" 57 | ] 58 | }, 59 | "browserslist": { 60 | "production": [ 61 | ">0.2%", 62 | "not dead", 63 | "not op_mini all" 64 | ], 65 | "development": [ 66 | "last 1 chrome version", 67 | "last 1 firefox version", 68 | "last 1 safari version" 69 | ] 70 | }, 71 | "proxy": "http://localhost:4000", 72 | "devDependencies": { 73 | "autoprefixer": "^10.4.13", 74 | "eslint": "^8.27.0", 75 | "eslint-config-airbnb": "^19.0.4", 76 | "eslint-config-prettier": "^8.5.0", 77 | "eslint-plugin-import": "^2.26.0", 78 | "eslint-plugin-jsx-a11y": "^6.6.1", 79 | "eslint-plugin-node": "^11.1.0", 80 | "eslint-plugin-prettier": "^4.2.1", 81 | "eslint-plugin-react": "^7.31.10", 82 | "postcss": "^8.4.18", 83 | "prettier": "^2.7.1", 84 | "tailwind-scrollbar": "^3.0.0", 85 | "tailwindcss": "^3.2.2" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | WellCare - Must for Healthcare 22 | 23 | 24 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /config.env -------------------------------------------------------------------------------- /server/Middleware/Admin.js: -------------------------------------------------------------------------------- 1 | const { ClientError } = require("../Utils/Errors"); 2 | // Middleware to check the user is Admin 3 | const isAdmin = async (req, _res, next) => { 4 | if(req.user.type !== "Admin"){ 5 | throw new ClientError("Only Admin Allowed"); 6 | } 7 | next(); 8 | } 9 | module.exports = isAdmin; -------------------------------------------------------------------------------- /server/Middleware/Auth.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const { AuthenticationError } = require("../Utils/Errors"); 3 | const { promisify } = require('util'); 4 | const Patient = require('../models/Patient'); 5 | const Doctor = require("../models/Doctor"); 6 | const Admin = require("../models/Admin"); 7 | 8 | //it will be executed on every request.If the token is not found then the user will need to login into the system. 9 | const Auth = async (req, _res, next) => { 10 | try { 11 | let token = req.cookies.s_Id; 12 | if (!token) { 13 | throw new AuthenticationError("Please login!"); 14 | } 15 | const decoder = await promisify(jwt.verify)(token, process.env.JWT_SECRET); 16 | let user = await Patient.findById(decoder.id); 17 | if (!user) { 18 | user = await Doctor.findById(decoder.id); 19 | if (!user) { 20 | user = await Admin.findById(decoder.id); 21 | if (!user) { 22 | throw new AuthenticationError("Something went wrong...!!"); 23 | } 24 | } 25 | } 26 | req.user = user; 27 | next(); 28 | 29 | } catch (err) { 30 | console.log("error auth middleware : ", err); 31 | return next(err); 32 | } 33 | } 34 | module.exports = Auth; -------------------------------------------------------------------------------- /server/Utils/Email.js: -------------------------------------------------------------------------------- 1 | const nodemailer = require("nodemailer"); 2 | 3 | const {ServerError} = require("./Errors"); 4 | 5 | //sending mail to the client 6 | const SendEmail = (options,next) => { 7 | return new Promise((resolve,reject)=>{ 8 | console.log(process.env.MAIL_USERNAME) 9 | const transporter = nodemailer.createTransport({ 10 | host: process.env.MAIL_HOST, 11 | port: process.env.MAIL_PORT, 12 | secure: true, 13 | auth: { 14 | user: process.env.MAIL_USERNAME, 15 | pass: process.env.MAIL_PASSWORD, 16 | }, 17 | }); 18 | 19 | const mailOptions = { 20 | from: process.env.MAIL_USERNAME, 21 | to: options.to, 22 | subject: options.subject, 23 | html: options.html, 24 | }; 25 | 26 | transporter.sendMail(mailOptions, function (error, info) { 27 | if (error) { 28 | console.log("error in nodemailer : ",error); 29 | reject(new ServerError("Something went wrong!")); 30 | } else { 31 | console.log("info : ",info); 32 | resolve(); 33 | } 34 | }); 35 | }); 36 | }; 37 | 38 | module.exports = SendEmail; -------------------------------------------------------------------------------- /server/Utils/Errors.js: -------------------------------------------------------------------------------- 1 | //this is the list of all the errors 2 | 3 | class ClientError extends Error{ 4 | constructor(msg){ 5 | super(msg); 6 | this.msg = msg; 7 | this.statusCode = 400; 8 | this.name = "ClientError"; 9 | Error.captureStackTrace(this, this.constructor); 10 | } 11 | } 12 | 13 | class NotFoundError extends Error{ 14 | constructor(msg){ 15 | super(msg); 16 | this.msg = msg; 17 | this.statusCode = 404; 18 | this.name = "NotFoundError"; 19 | Error.captureStackTrace(this, this.constructor); 20 | } 21 | } 22 | 23 | class AuthenticationError extends Error{ 24 | constructor(msg){ 25 | super(msg); 26 | this.msg = msg; 27 | this.statusCode = 401; 28 | this.name = "AuthenticationError"; 29 | Error.captureStackTrace(this, this.constructor); 30 | } 31 | } 32 | 33 | class AuthorizationError extends Error{ 34 | constructor(msg){ 35 | super(msg); 36 | this.msg = msg; 37 | this.statusCode = 403; 38 | this.name = "AuthorizationError"; 39 | Error.captureStackTrace(this, this.constructor); 40 | } 41 | } 42 | 43 | class ServerError extends Error{ 44 | constructor(msg){ 45 | super(msg); 46 | this.msg = msg; 47 | this.statusCode = 500; 48 | this.name = "ServerError"; 49 | Error.captureStackTrace(this, this.constructor); 50 | } 51 | } 52 | 53 | module.exports = { 54 | AuthenticationError, 55 | AuthorizationError, 56 | ClientError, 57 | NotFoundError, 58 | ServerError 59 | } -------------------------------------------------------------------------------- /server/Utils/TokenGenerator.js: -------------------------------------------------------------------------------- 1 | const crypto = require("crypto"); 2 | 3 | const TokenGenerator = () => { 4 | let token = crypto.randomBytes(64).toString("hex"); 5 | return { token }; 6 | } 7 | 8 | module.exports = TokenGenerator; -------------------------------------------------------------------------------- /server/Utils/catchAsyncError.js: -------------------------------------------------------------------------------- 1 | // catch Async Error with a single function 2 | module.exports = (func) => { 3 | return (req, res, next) => { 4 | func(req, res, next).catch((err) => next(err)); 5 | console.log("Catch Async Error chalu hai"); 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /server/Utils/cloudinary.js: -------------------------------------------------------------------------------- 1 | const dotenv = require('dotenv'); 2 | dotenv.config({path:"./config.env"}); 3 | const cloudinary = require('cloudinary').v2; 4 | const { CloudinaryStorage } = require('multer-storage-cloudinary'); 5 | 6 | cloudinary.config({ 7 | cloud_name: process.env.CLOUDINARY_CLOUD_NAME, 8 | api_key: process.env.CLOUDINARY_KEY, 9 | api_secret:process.env.CLOUDINARY_SECRET 10 | }) 11 | const storage = new CloudinaryStorage({ 12 | cloudinary:cloudinary, 13 | params: { 14 | folder: 'Well Care', 15 | allowed_formats:['jpg','png','jpeg','jfif'] 16 | }, 17 | }); 18 | 19 | module.exports={ 20 | cloudinary, 21 | storage 22 | } -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | //requiring the main file which consists of all the routes of the application 2 | const app = require("./index"); 3 | const dotenv = require("dotenv"); 4 | dotenv.config({ path: "./config.env" }); 5 | const connectToMongo = require("./db"); 6 | const socket = require("socket.io"); 7 | //connecting to the database 8 | connectToMongo(); 9 | const port = process.env.PORT || 3001; 10 | 11 | function runFuncContinuous() { 12 | console.log("continuous running script!"); 13 | } 14 | 15 | setInterval(runFuncContinuous, 1000 * 60); 16 | 17 | //listening to the server 18 | const server = app.listen(port, () => { 19 | console.log(`App listening at http://localhost:${port}`); 20 | }); 21 | 22 | //initialized the socket 23 | const io = socket(server, { 24 | cors: { 25 | origin: "http://localhost:3000", 26 | credentials: true, 27 | }, 28 | }); 29 | 30 | //list of online users 31 | let onlineusers = new Map(); 32 | 33 | //creating socket connection 34 | io.on("connection", (socket) => { 35 | console.log("new connection : ", socket.id); 36 | socket.on("add-user", (userId) => { 37 | onlineusers.set(userId, socket.id); 38 | }); 39 | 40 | socket.on("send-msg", (data) => { 41 | // To find receiver users socket 42 | const findSocketUser = onlineusers.get(data.to); 43 | if (findSocketUser) { 44 | //emitting the message to a particular client 45 | socket.to(findSocketUser).emit("msg-receive", data.message); 46 | } 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /server/controllers/Admin.js: -------------------------------------------------------------------------------- 1 | const Admin = require("../models/Admin"); 2 | const Doctor = require("../models/Doctor"); 3 | const Patient = require("../models/Patient"); 4 | const Schedule = require("../models/Schedule"); 5 | const bcrypt = require("bcrypt"); 6 | const SendEmail = require("../utils/Email"); 7 | 8 | exports.Register = async (req, res, next) => { 9 | try { 10 | let user = req.body; 11 | //hashing the password 12 | const salt = await bcrypt.genSalt(10); 13 | let newpassword = await bcrypt.hash(user.password, salt); 14 | //creating new doctor object 15 | let admin = new Admin({ 16 | name: user.name, 17 | email: user.email, 18 | username: user.username, 19 | password: newpassword, 20 | }); 21 | await admin.save(); 22 | 23 | return res.status(201).json({ 24 | message: "Successfully registered", 25 | success: true, 26 | }); 27 | } catch (err) { 28 | console.log("Error in the register admin route : ", err); 29 | return next(err); 30 | } 31 | }; 32 | 33 | // router to get all doctors that are not verified by admin 34 | exports.getAllDoctors = async (req, res, next) => { 35 | try { 36 | const doctors = await Doctor.find({ adminVerified: false }).select( 37 | "name age gender category email licenseNumber phoneNumber locality clinic_name specialization" 38 | ); 39 | // const doctors= await Doctor.find({adminVerified:false}) 40 | 41 | return res.status(200).json({ 42 | success: true, 43 | data: { 44 | doctors, 45 | }, 46 | }); 47 | } catch (err) { 48 | return next(err); 49 | } 50 | }; 51 | 52 | // router to veirfy the particular doctor 53 | exports.verifyDoctor = async (req, res, next) => { 54 | try { 55 | const doctor = await Doctor.findByIdAndUpdate( 56 | req.params.id, 57 | { adminVerified: true }, 58 | { 59 | new: true, 60 | runValidators: true, 61 | } 62 | ); 63 | // console.log("Doctor is",doctor); 64 | let mail1 = { 65 | to: doctor.email, 66 | subject: "Congratulations! You are Verified", 67 | html: `
Hello ${doctor.name},

68 | Your profile has been verified by our admin team. You are now a verified expert registered onto our portal.

69 | Go ahead and log onto our portal now! Cheers!

70 | Click on this link : http://localhost:3000/login 71 |
`, 72 | }; 73 | try { 74 | await SendEmail(mail1, next); 75 | } catch (err) { 76 | throw err; 77 | } 78 | return res.status(200).json({ 79 | message: "Doctor is verified successfully", 80 | success: true, 81 | }); 82 | } catch (err) { 83 | return next(err); 84 | } 85 | }; 86 | 87 | // router to display all the statistics 88 | exports.statistics = async (req, res, next) => { 89 | try { 90 | const physio = await Doctor.find({ 91 | category: "Physiotherapist", 92 | }).countDocuments(); 93 | const nutri = await Doctor.find({ 94 | category: "Nutritionist", 95 | }).countDocuments(); 96 | const gym = await Doctor.find({ category: "Gym Trainer" }).countDocuments(); 97 | const patients = await Patient.countDocuments(); 98 | const appointments = await Schedule.countDocuments(); 99 | const avgSessions = appointments / patients; 100 | 101 | return res.status(200).json({ 102 | success: true, 103 | data: { 104 | physio, 105 | nutri, 106 | gym, 107 | patients, 108 | appointments, 109 | avgSessions, 110 | }, 111 | }); 112 | } catch (err) { 113 | console.log("Err", err); 114 | return next(err); 115 | } 116 | }; 117 | -------------------------------------------------------------------------------- /server/controllers/Chat.js: -------------------------------------------------------------------------------- 1 | const Chat = require('../models/Chat'); 2 | 3 | //storing the messages onto the server 4 | exports.SendMessage = async (req, res, next) => { 5 | try { 6 | const { message, from, to } = req.body; 7 | let msg = String(message); 8 | //if doctor 9 | if (req.user.type === 'Doctor') { 10 | await Chat.create({ 11 | message: msg, 12 | users: [from, to], 13 | doctorSender: from 14 | }) 15 | } 16 | //if patient 17 | else { 18 | await Chat.create({ 19 | message: msg, 20 | users: [from, to], 21 | patientSender: from 22 | }) 23 | } 24 | return res.json({ 25 | status: true, 26 | }) 27 | } 28 | catch (err) { 29 | console.log("in the send message : ", err); 30 | return next(err); 31 | } 32 | } 33 | 34 | //getting the messages from the server 35 | exports.GetMessage = async (req, res, next) => { 36 | try { 37 | const { from, to } = req.body; 38 | const messages = await Chat.find({ 39 | users: { 40 | $all: [from, to] 41 | } 42 | }).sort({ updatedAt: 1 }); 43 | 44 | 45 | return res.json({ 46 | status: true, 47 | data: messages 48 | }) 49 | } 50 | catch (err) { 51 | console.log("in the get message : ", err); 52 | return next(err); 53 | } 54 | } -------------------------------------------------------------------------------- /server/controllers/review.js: -------------------------------------------------------------------------------- 1 | const Review = require("../models/review"); 2 | const Sentiment = require("sentiment"); 3 | 4 | // const reviews = [ 5 | // 'This product is amazing!', 6 | // 'I am very happy with my purchase.', 7 | // 'The customer service was terrible.', 8 | // 'I would not recommend this product to anyone.' 9 | // ]; 10 | 11 | // reviews.forEach(review => { 12 | 13 | // console.log(`${review} | Score: ${score} | Comparative: ${comparative}`); 14 | // }); 15 | 16 | module.exports.createReview = async (req, res, next) => { 17 | try { 18 | const sentiment = new Sentiment(); 19 | const { score, comparative } = sentiment.analyze(String(req.body.review)); 20 | await Review.create({ 21 | review: String(req.body.review), 22 | patient: req.user.id, 23 | doctor: req.body.doctor, 24 | score: score, 25 | accuracy: comparative, 26 | }); 27 | res.status(201).json({ 28 | success: true, 29 | msg: "Your review has been added successfully!", 30 | }); 31 | } catch (err) { 32 | console.log("in the create reviews : ", err); 33 | return next(err); 34 | } 35 | }; 36 | 37 | //getting the reviews for a particular doctor 38 | // module.exports.getReviews = async (req, res, next) => { 39 | // try { 40 | // const reviews = await Review.find(); 41 | // res.status(200).json({ 42 | // status: "success", 43 | // data: { 44 | // reviews 45 | // } 46 | // }); 47 | // } 48 | // catch (err) { 49 | // console.log("in the get reviews : ", err); 50 | // return next(err); 51 | // } 52 | // } 53 | 54 | module.exports.updateReview = async (req, res, next) => { 55 | try { 56 | await Review.findByIdAndUpdate(req.params.id, { 57 | review: String(req.body.review), 58 | }); 59 | res.status(200).json({ 60 | success: true, 61 | msg: "Your review has been updated successfully!", 62 | }); 63 | } catch (err) { 64 | return next(err); 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /server/db.js: -------------------------------------------------------------------------------- 1 | // connecting to db 2 | const mongoose = require("mongoose"); 3 | const mongoURI = process.env.MONGODB_URL; 4 | 5 | const connectToMongo = () => { 6 | mongoose 7 | .connect(mongoURI) 8 | .then(()=> console.log("Connected to mongo succesfully!")) 9 | .catch((err) => { 10 | console.log("Error!: ",err); 11 | }); 12 | }; 13 | 14 | module.exports = connectToMongo; 15 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { NotFoundError, ClientError } = require("./Utils/Errors"); 3 | const app = express(); 4 | const helmet = require("helmet"); 5 | const cors = require("cors"); 6 | const cookieParser = require("cookie-parser"); 7 | 8 | //middlewares 9 | app.use(cookieParser()); 10 | app.use(helmet()); 11 | 12 | //cors used to prevent requests from unknown origins 13 | app.use( 14 | cors({ 15 | origin: 'http://localhost:3000', 16 | credentials: true, 17 | }) 18 | ); 19 | 20 | app.use((_req, _res, next) => { 21 | if (process.env.ENV === "development") { 22 | console.log("in the development mode...."); 23 | } 24 | next(); 25 | }); 26 | //it will help in attaching the content to the body of the request 27 | app.use(express.json()); 28 | app.use(express.urlencoded({ extended: false })); 29 | 30 | //API 31 | //for login,forgot passwords,verifying the accounts,passwords etc - common for both doctor and patient 32 | app.use("/auth", require("./routes/Auth")); 33 | 34 | //requests related to patients will be redirected here 35 | app.use("/patient", require("./routes/Patient")); 36 | 37 | //requests related to doctor will be redirected here 38 | app.use("/doctor", require("./routes/Doctor")); 39 | 40 | //requests related to reviews will be redirected here 41 | app.use("/review", require("./routes/Review")); 42 | 43 | // requests that common for both doctor and patient 44 | app.use("/common", require("./routes/Common")); 45 | 46 | // requests related to chat 47 | app.use("/chat", require("./routes/Chat")); 48 | 49 | // requests related to admin 50 | app.use("/admin", require("./routes/Admin")); 51 | 52 | //request for serving the favicon 53 | app.get("/favicon.ico", (_req, res) => { 54 | return res.sendStatus(204); 55 | }); 56 | 57 | 58 | 59 | 60 | //any unknown route will be executed here throwing not found error 61 | app.all("*", (req, _res, next) => { 62 | // console.log("path : ", req.originalUrl); 63 | // console.log(new NotFoundError("Sorry,this page does not exists").stack); 64 | return next(new NotFoundError("Sorry,this page does not exists")); 65 | }); 66 | 67 | 68 | 69 | //handling mongoserver errors 70 | const handleDuplicateError = (error) => { 71 | let errStr = Object.keys(error.keyPattern).join(",").concat(" already exists!"); 72 | return new ClientError(errStr); 73 | } 74 | 75 | //global error middleware 76 | app.use((error, _req, res, _) => { 77 | console.log("entered the global error middleware..."); 78 | let err = { ...error }; 79 | 80 | if (err.code === 11000) { 81 | err = handleDuplicateError(err); 82 | } else { 83 | err.statusCode = err.statusCode || 500; 84 | err.msg = err.statusCode === 500 ? "Sorry,something went wrong!" : err.msg; 85 | } 86 | 87 | console.log("Error : ", err); 88 | //sending the error response 89 | res.status(err.statusCode).json({ 90 | status: "Failed", 91 | error: err.msg, 92 | name: err.name, 93 | }); 94 | }); 95 | 96 | module.exports = app; 97 | -------------------------------------------------------------------------------- /server/joi/DoctorJoi.js: -------------------------------------------------------------------------------- 1 | //joi validations 2 | const joi = require('joi'); 3 | const { ClientError } = require("../Utils/Errors"); 4 | 5 | //using joi for validating the user entered fields 6 | exports.RegisterDoctorJoi = async (body) => { 7 | const schema = joi.object({ 8 | name: joi.string().required(), 9 | // email: joi.string().regex(/^[a-z]+\d*\.?[a-z\d]*@(gmail|hotmail|yahoo|somaiya)\.(com|in|edu)$/).required(), 10 | email: joi.string().required(), 11 | username: joi.string().min(5).max(25).required(), 12 | password: joi.string().min(8).max(15).regex(/^[a-zA-Z]+[a-zA-Z\d]*[@$#]+[a-zA-Z@$#\d]*\d+$/).required(), 13 | phoneNumber: joi.string().length(10).pattern(/^[0-9]+$/).required(), 14 | age: joi.number().required(), 15 | gender: joi.string().required(), 16 | licenseNumber: joi.string().length(10).required(), 17 | locality: joi.string().required(), 18 | specialization: joi.string(), 19 | years_Of_Experience: joi.number().required(), 20 | fees: joi.number().required(), 21 | bio: joi.string().required(), 22 | address: joi.string(), 23 | have_clinic: joi.boolean(), 24 | category: joi.string().required(), 25 | clinic_name:joi.string().required() 26 | }); 27 | 28 | try { 29 | return await schema.validateAsync(body); 30 | } catch (err) { 31 | console.log("register Doctor joi : ", err); 32 | if (err.details[0].message.includes('email')) { 33 | throw new ClientError("Invalid Email ID"); 34 | } else if (err.details[0].message.includes('password')) { 35 | throw new ClientError("Please enter the password as mentioned"); 36 | } else if (err.details[0].message.includes('licenseNumber' && '10')) { 37 | throw new ClientError("Invalid License Number"); 38 | } 39 | else { 40 | throw new ClientError(err.details[0].message.replace(/"/g, "")); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /server/joi/PatientJoi.js: -------------------------------------------------------------------------------- 1 | //joi validations 2 | const joi = require('joi'); 3 | joi.objectId = require('joi-objectid')(joi); 4 | 5 | const {ClientError} = require("../Utils/Errors"); 6 | 7 | //using joi for validating the user entered fields 8 | exports.RegisterJoi = async (body)=>{ 9 | const schema = joi.object({ 10 | name: joi.string().required(), 11 | // email : joi.string().regex(/^[a-z]+\d*\.?[a-z\d]*@(mail|gmail|hotmail|yahoo|somaiya)\.(com|in|edu)$/).required(), 12 | email : joi.string().required(), 13 | username: joi.string().min(6).max(25).regex(/^[a-z]+[a-z\d]*$/).required(), 14 | password : joi.string().min(8).max(15).regex(/^[a-zA-Z]+[a-zA-Z\d]*[@$#]+[a-zA-Z@$#\d]*\d+$/).required(), 15 | phoneNumber: joi.string().length(10).pattern(/^[0-9]+$/).required(), 16 | age: joi.number().required(), 17 | gender: joi.string().required(), 18 | }); 19 | 20 | try{ 21 | return await schema.validateAsync(body); 22 | }catch(err){ 23 | console.log("register patient joi : ",err); 24 | if(err.details[0].message.includes('email')){ 25 | throw new ClientError("Invalid Email ID"); 26 | }else if(err.details[0].message.includes('password')){ 27 | throw new ClientError("Please enter the password as mentioned"); 28 | } else if (err.details[0].message.includes('username' && 'fails')) { 29 | throw new ClientError("No special characters or only digits allowed"); 30 | } 31 | else { 32 | throw new ClientError(err.details[0].message.replace(/"/g,"")); 33 | } 34 | } 35 | } 36 | 37 | //using joi for validating the book appointment fields 38 | exports.BookAppointmentJoi = async (body) => { 39 | const schema = joi.object({ 40 | startTime: joi.number().required(), 41 | endTime: joi.number().required(), 42 | isOnline: joi.boolean().required(), 43 | reason: joi.string().required(), 44 | isBookedByDoc: joi.boolean(), 45 | date: joi.date().required(), 46 | doctor_id: joi.objectId().required(), 47 | }); 48 | 49 | try { 50 | return await schema.validateAsync(body); 51 | } catch (err) { 52 | console.log("book appointment joi : ", err); 53 | throw new ClientError(err.details[0].message.replace(/"/g, "")); 54 | } 55 | } -------------------------------------------------------------------------------- /server/models/Admin.js: -------------------------------------------------------------------------------- 1 | const mongoose=require("mongoose"); 2 | const adminSchema=new mongoose.Schema({ 3 | email: { 4 | type: String, 5 | required: [true, "User should have a Email"], 6 | unique: true, 7 | }, 8 | username: { 9 | type: String, 10 | required: [true, "User should have a username"], 11 | unique: true, 12 | }, 13 | name: { 14 | type: String, 15 | required: [true, "User should have a name"] 16 | }, 17 | password: { 18 | type: String, 19 | required: [true, "User should have a password"], 20 | }, 21 | mailVerified: { 22 | type: Boolean, 23 | default: true 24 | }, 25 | profile_pic: { 26 | image_url: { 27 | type: String, 28 | // required: [true, "User should have a image url"], 29 | default: "https://res.cloudinary.com/dprscch9k/image/upload/v1677739579/Well%20Care/k6njbwcuucgeqkmv9sft.png", 30 | }, 31 | file_name: { 32 | type: String, 33 | // required: [true, "User should have a image file_name"] 34 | } 35 | }, 36 | type: { 37 | type: String, 38 | default: "Admin" 39 | }, 40 | }) 41 | 42 | const Admin = mongoose.model("Admin", adminSchema); 43 | 44 | module.exports = Admin; -------------------------------------------------------------------------------- /server/models/Chat.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const chatSchema = new mongoose.Schema({ 4 | message: { 5 | type: String, 6 | required: [true, 'It should have review'] 7 | }, 8 | users: Array, 9 | patientSender: { 10 | type: mongoose.Schema.Types.ObjectId, 11 | ref: 'Patient' 12 | }, 13 | doctorSender: { 14 | type: mongoose.Schema.Types.ObjectId, 15 | ref: 'Doctor' 16 | } 17 | }, { 18 | timestamps: true 19 | }); 20 | 21 | const Chat = mongoose.model('Chat', chatSchema); 22 | module.exports = Chat; 23 | -------------------------------------------------------------------------------- /server/models/Query.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const querySchema = new mongoose.Schema({ 4 | name: { 5 | type: String, 6 | }, 7 | subject: { 8 | type: String, 9 | required: [true, "Please provide a subject"], 10 | }, 11 | desc: { 12 | type: String, 13 | required: [true, "Please mention the query"], 14 | }, 15 | profile_pic_link: { 16 | type: String, 17 | }, 18 | tag: { 19 | type: String, 20 | }, 21 | }); 22 | 23 | const Query = mongoose.model("Query", querySchema); 24 | 25 | module.exports = Query; 26 | -------------------------------------------------------------------------------- /server/models/Schedule.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | //for now not considering multiple booking of time slots in a row by one person 3 | 4 | const ScheduleSchema = new mongoose.Schema({ 5 | doctor_id: { 6 | type: mongoose.Schema.Types.ObjectId, 7 | ref: "Doctor" 8 | }, 9 | reason: { 10 | type: String, 11 | required: [true, "Please mention the reason"], 12 | default: "Appointment" 13 | }, 14 | slot_blocked_by: { 15 | type: mongoose.Schema.Types.ObjectId, 16 | ref: "Patient" 17 | }, 18 | isBookedByDoc: { 19 | type: Boolean, 20 | default: false 21 | }, 22 | date: { 23 | type: String, 24 | required: [true, "Please enter the date"] 25 | }, 26 | startTime: { 27 | type: Number, 28 | required: [true, "Please enter the start time"] 29 | }, 30 | endTime: { 31 | type: Number, 32 | required: [true, "Please enter the end time"] 33 | }, 34 | //apointment type 35 | isOnline: { 36 | type: Boolean, 37 | required: [true, "Please enter the mode"], 38 | default: true, 39 | }, 40 | timestamp: { 41 | type: Date, 42 | default: new Date() 43 | }, 44 | // initially it will be false when booked but after the session completes it will be set to true and will be considered as a part of history. 45 | status: { 46 | type: Boolean, 47 | default: false 48 | } 49 | }); 50 | 51 | const Schedule = mongoose.model("Schedule", ScheduleSchema); 52 | 53 | module.exports = Schedule; -------------------------------------------------------------------------------- /server/models/doctor.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | //doctor model 3 | const doctorSchema = new mongoose.Schema({ 4 | name: { 5 | type: String, 6 | required: [true, "User should have a name"] 7 | }, 8 | age: { 9 | type: Number, 10 | required: [true, "User should have a Age"] 11 | }, 12 | gender: { 13 | type: String, 14 | required: [true, "User should have a Gender"] 15 | }, 16 | licenseNumber: { 17 | type: String, 18 | required: [true, "User should have a license Number"] 19 | }, 20 | locality: { 21 | type: String, 22 | required: [true, "User should have a locality"] 23 | }, 24 | specialization: { 25 | type: String, 26 | default: " " 27 | // required: [true, "User should have a specialization"] 28 | }, 29 | years_Of_Experience: { 30 | type: Number, 31 | required: [true, "User should have a license Number"] 32 | }, 33 | phoneNumber: { 34 | type: String, 35 | required: [true, "User should have a Phone Number"] 36 | }, 37 | fees: { 38 | type: Number, 39 | required: [true, "User should have a Fees"] 40 | }, 41 | profile_pic: { 42 | image_url: { 43 | type: String, 44 | // required: [true, "User should have a image url"], 45 | default: "https://res.cloudinary.com/dprscch9k/image/upload/v1677739579/Well%20Care/k6njbwcuucgeqkmv9sft.png", 46 | }, 47 | file_name: { 48 | type: String, 49 | // required: [true, "User should have a image file_name"] 50 | } 51 | }, 52 | email: { 53 | type: String, 54 | required: [true, "User should have a Email"], 55 | unique: true 56 | }, 57 | clinic_name:{ 58 | type:String 59 | }, 60 | address: { 61 | type: String 62 | }, 63 | have_clinic: { 64 | type: Boolean, 65 | default: false 66 | }, 67 | username: { 68 | type: String, 69 | required: [true, "User should have a username"], 70 | unique: true 71 | }, 72 | password: { 73 | type: String, 74 | required: [true, "User should have a password"] 75 | }, 76 | category: { 77 | type: String, 78 | required: [true, "User should have a category"] 79 | }, 80 | bio: { 81 | type: String, 82 | required: [true, "User should have a bio"] 83 | }, 84 | time_registered: { 85 | type: Date, 86 | default: Date.now 87 | }, 88 | adminVerified:{ 89 | type:Boolean, 90 | default:false, 91 | }, 92 | mailVerified: { 93 | type: Boolean, 94 | default: false 95 | }, 96 | verifyToken: { 97 | type: String, 98 | default: null 99 | }, 100 | verifyTokenExpiry: { 101 | type: Date, 102 | default: null 103 | }, 104 | type: { 105 | type: String, 106 | default: "Doctor" 107 | }, 108 | rating: { 109 | type: Number, 110 | default: 0 111 | } 112 | }, 113 | { 114 | toJSON: { virtuals: true }, 115 | toObject: { virtuals: true } 116 | }); 117 | 118 | doctorSchema.index({category:1}); 119 | 120 | const Doctor = mongoose.model("Doctor", doctorSchema); 121 | 122 | module.exports = Doctor; -------------------------------------------------------------------------------- /server/models/patient.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | //patient model 4 | const patientSchema = new mongoose.Schema({ 5 | name: { 6 | type: String, 7 | required: [true, "User should have a name"], 8 | }, 9 | email: { 10 | type: String, 11 | required: [true, "User should have a Email"], 12 | unique: true, 13 | }, 14 | phoneNumber: { 15 | type: String, 16 | required: [true, "User should have a Phone Number"], 17 | }, 18 | username: { 19 | type: String, 20 | required: [true, "User should have a username"], 21 | unique: true, 22 | }, 23 | password: { 24 | type: String, 25 | required: [true, "User should have a password"], 26 | }, 27 | gender: { 28 | type: String, 29 | required: [true, "User should have a Gender"], 30 | }, 31 | age: { 32 | type: Number, 33 | required: [true, "User should have a Age"], 34 | }, 35 | profile_pic: { 36 | image_url: { 37 | type: String, 38 | // required:[true, "User should have a image url"], 39 | default: 40 | "https://res.cloudinary.com/dprscch9k/image/upload/v1677739579/Well%20Care/k6njbwcuucgeqkmv9sft.png", 41 | }, 42 | file_name: { 43 | type: String, 44 | // required: [true, "User should have a image file_name"] 45 | }, 46 | }, 47 | time_registered: { 48 | type: Date, 49 | default: Date.now, 50 | }, 51 | mailVerified: { 52 | type: Boolean, 53 | default: false, 54 | }, 55 | verifyToken: { 56 | type: String, 57 | default: null, 58 | }, 59 | verifyTokenExpiry: { 60 | type: Date, 61 | default: null, 62 | }, 63 | type: { 64 | type: String, 65 | default: "Patient" 66 | } 67 | }); 68 | 69 | const Patient = mongoose.model("Patient", patientSchema); 70 | 71 | module.exports = Patient; 72 | -------------------------------------------------------------------------------- /server/models/review.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const reviewSchema = new mongoose.Schema( 3 | { 4 | review: { 5 | type: String, 6 | required: [true, "It should have review"], 7 | }, 8 | patient: { 9 | type: mongoose.Schema.Types.ObjectId, 10 | ref: "Patient", 11 | required: [true, "It should have a patient Id"], 12 | }, 13 | doctor: { 14 | type: mongoose.Schema.Types.ObjectId, 15 | ref: "Doctor", 16 | required: [true, "It should have a patient Id"], 17 | }, 18 | accuracy: { 19 | type: Number, 20 | }, 21 | score: { 22 | type: Number, 23 | }, 24 | }, 25 | { 26 | toJSON: { virtuals: true }, 27 | toObject: { virtuals: true }, 28 | } 29 | ); 30 | 31 | // setting up an unique index 32 | // reviewSchema.index({ patient: 1, doctor: 1 }, { unique: true }); 33 | 34 | // Query Middlewares 35 | 36 | // Middleware to populate reviews 37 | // reviewSchema.pre(/^find/,function(next){ 38 | // // this.populate({ 39 | // // path:'patient', 40 | // // select:'username' 41 | // // }).populate({ 42 | // // path:'doctor', 43 | // // select:'username' 44 | // // }); 45 | // this.populate({ 46 | // path:'patient', 47 | // select:'username' 48 | // }); 49 | // next(); 50 | // }) 51 | 52 | const Review = mongoose.model("Review", reviewSchema); 53 | module.exports = Review; 54 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "nodemon app.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcrypt": "^5.1.0", 14 | "cloudinary": "^1.32.0", 15 | "cookie-parser": "^1.4.6", 16 | "cors": "^2.8.5", 17 | "crypto": "^1.0.1", 18 | "dotenv": "^16.0.3", 19 | "express": "^4.18.2", 20 | "helmet": "^6.0.0", 21 | "joi": "^17.7.0", 22 | "joi-objectid": "^4.0.2", 23 | "jsonwebtoken": "^8.5.1", 24 | "mongoose": "^6.7.2", 25 | "multer": "^1.4.5-lts.1", 26 | "multer-storage-cloudinary": "^4.0.0", 27 | "nodemailer": "^6.8.0", 28 | "nodemon": "^2.0.20", 29 | "sentiment": "^5.0.2", 30 | "socket.io": "^4.6.1", 31 | "stripe": "^11.10.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /server/routes/Admin.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const { login, getAllDoctors, verifyDoctor, statistics, Register, } = require('../controllers/Admin'); 3 | const Auth = require('../Middleware/Auth'); 4 | const isAdmin = require('../Middleware/Admin'); 5 | 6 | const router = express.Router(); 7 | 8 | 9 | // route to register the admin 10 | router.post('/signup',Register) 11 | 12 | // route to get all doctors that are not verified 13 | router.get('/getAllDoctors',Auth,isAdmin ,getAllDoctors) 14 | 15 | // route to verify the particular doctor 16 | router.patch('/verifyDoctor/:id',Auth,isAdmin,verifyDoctor) 17 | 18 | // route to get number of physiotherapist that are registered into portal 19 | router.get('/stats',Auth, isAdmin, statistics) 20 | 21 | 22 | module.exports = router; -------------------------------------------------------------------------------- /server/routes/Auth.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const Auth = require("../Middleware/Auth"); 3 | const router = express.Router(); 4 | const { 5 | VerifyAccount, 6 | Login, 7 | GeneratePasswordLink, 8 | SetPassword, 9 | Logout, 10 | ResetPassword, 11 | } = require("../controllers/Auth"); 12 | 13 | //email verify route - This is common for both patient as well as doctor 14 | router.get("/verifyAccount/:token", VerifyAccount); 15 | 16 | //login route 17 | router.post("/login", Login); 18 | 19 | //forgot password 20 | router.post("/forgotpassword", GeneratePasswordLink); 21 | 22 | //setting the password 23 | router.post("/setpassword/:token", SetPassword); 24 | 25 | //reset password 26 | router.post("/resetpassword", Auth, ResetPassword); 27 | 28 | //logout route 29 | router.get("/logout", Auth, Logout); 30 | 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /server/routes/Chat.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const Auth = require('../Middleware/Auth'); 3 | 4 | const router = express.Router(); 5 | const { SendMessage, GetMessage } = require("../controllers/Chat"); 6 | // Route to send message 7 | router.post("/sendMessage", Auth, SendMessage); 8 | 9 | // Route to get message 10 | router.post("/getMessage", Auth, GetMessage); 11 | 12 | module.exports = router; -------------------------------------------------------------------------------- /server/routes/Common.js: -------------------------------------------------------------------------------- 1 | //this file consists of all the common routes for doctor and patient 2 | const express = require('express'); 3 | const Auth = require('../Middleware/Auth'); 4 | const router = express.Router(); 5 | const { GetUser, GetContacts, PostQuery ,GetQuery,mail} = require("../controllers/Common"); 6 | 7 | //profile route 8 | router.get('/profile', Auth, GetUser); 9 | 10 | //for fetching contact list 11 | router.get('/contacts', Auth, GetContacts); 12 | 13 | //for posting queries 14 | router.post('/query',Auth, PostQuery); 15 | 16 | //for posting queries 17 | router.post('/sendMail',Auth, mail); 18 | //for getting queries 19 | router.get('/getQuery',Auth, GetQuery); 20 | 21 | module.exports = router; -------------------------------------------------------------------------------- /server/routes/Doctor.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { Register, getDoctors, getDoctor ,createReviews} = require("../controllers/Doctor"); 4 | const Auth = require('../Middleware/Auth'); 5 | const multer=require('multer') 6 | const {storage} = require('../Utils/cloudinary') 7 | const upload = multer({ storage }); 8 | 9 | 10 | //register route 11 | router.post('/register', upload.single('profile_pic'), Register); 12 | // router.post('/register', Register); 13 | 14 | // get all Doctors route 15 | router.get('/', Auth, getDoctors); 16 | 17 | // get a particular Doctor route 18 | router.get('/:id', Auth, getDoctor); 19 | 20 | module.exports = router; -------------------------------------------------------------------------------- /server/routes/Patient.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const Auth = require('../Middleware/Auth'); 4 | const { Register, GetAppointments, BookAppointment, getCheckoutSession, getHighestRatedDoctors, DeleteAppointment } = require("../controllers/Patient"); 5 | 6 | //highest rated docs 7 | router.get('/getTopRatedDocs',Auth,getHighestRatedDoctors); 8 | 9 | //register route 10 | router.post('/register', Register); 11 | 12 | //get appointments 13 | //please shift to the doctor side 14 | router.get('/getAppointments/:doc_id', Auth, GetAppointments); 15 | 16 | //book an appointment 17 | router.post('/bookAppointment/', Auth, BookAppointment); 18 | 19 | //book an appointment 20 | router.delete('/deleteAppointment/:id', Auth, DeleteAppointment); 21 | 22 | // Payments : checkout session 23 | router.post('/checkoutSession/:doc_id', Auth, getCheckoutSession); 24 | 25 | 26 | module.exports = router; 27 | 28 | -------------------------------------------------------------------------------- /server/routes/Review.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const { createReview, getReviews ,updateReview} = require("../controllers/review"); 4 | const Auth = require("../Middleware/Auth"); 5 | 6 | // THINGS TO DO 7 | //1. implement logic to delete a review by an user 8 | 9 | //Create Review Route 10 | router.post('/', Auth,createReview); 11 | 12 | // Read all reviews route 13 | // router.get('/',getReviews) 14 | 15 | // Update Review Route 16 | router.patch('/:id',Auth,updateReview); 17 | 18 | 19 | module.exports = router; -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap"); 17 | 18 | .App-header { 19 | background-color: #282c34; 20 | min-height: 100vh; 21 | display: flex; 22 | flex-direction: column; 23 | align-items: center; 24 | justify-content: center; 25 | font-size: calc(10px + 2vmin); 26 | color: white; 27 | } 28 | 29 | .App-link { 30 | color: #61dafb; 31 | } 32 | 33 | @keyframes App-logo-spin { 34 | from { 35 | transform: rotate(0deg); 36 | } 37 | to { 38 | transform: rotate(360deg); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/assets/Krish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/Krish.png -------------------------------------------------------------------------------- /src/assets/Services.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/Services.avif -------------------------------------------------------------------------------- /src/assets/holistic_health.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/holistic_health.png -------------------------------------------------------------------------------- /src/assets/nutrition.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/nutrition.jpg -------------------------------------------------------------------------------- /src/assets/physiotherapy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/physiotherapy.png -------------------------------------------------------------------------------- /src/assets/service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/service.png -------------------------------------------------------------------------------- /src/assets/wellbeing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/wellbeing.png -------------------------------------------------------------------------------- /src/assets/wellcarelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/wellcarelogo.png -------------------------------------------------------------------------------- /src/assets/yoga.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shubhgosalia/WellCare/5defe77820802572b287987a2b3d89ebe62503b8/src/assets/yoga.png -------------------------------------------------------------------------------- /src/components/AdminDashboard/GetQuery.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import AdminNav from "components/AdminDashboard/AdminNav"; 3 | import QueryHeading from "components/AdminDashboard/QueryHeading"; 4 | import axios from "axios"; 5 | import Query from "./Query"; 6 | import Swal from "sweetalert2"; 7 | const GetQuery = () => { 8 | const [queries, setQueries] = useState([]); 9 | const [load, setLoad] = useState(false); 10 | const fetchQueries = async () => { 11 | try { 12 | setLoad(true); 13 | const res = await axios.get("http://localhost:4000/common/getQuery", { 14 | withCredentials: true, 15 | }); 16 | console.log("resp : ", res.data.data); 17 | setLoad(false); 18 | setQueries(res.data.data); 19 | } catch (err) { 20 | console.log("error : ", err); 21 | Swal.fire({ 22 | icon: "error", 23 | title: "Oops...", 24 | text: err.response.data.error, 25 | }); 26 | } 27 | }; 28 | 29 | useEffect(() => { 30 | fetchQueries(); 31 | }, []); 32 | 33 | return ( 34 |
35 | {/* Navbar */} 36 |
37 | 38 |
39 |
40 |
41 | {/* Title */} 42 | 43 |
44 | {/* Expert list table format */} 45 |
46 |
47 | 48 | 49 | 50 | 53 | 54 | 57 | 60 | 61 | 62 | 63 | {load ? ( 64 |

Loading...

65 | ) : queries.length !== 0 ? ( 66 | queries.map((item) => { 67 | return ; 68 | }) 69 | ) : ( 70 |
No Queries ....
71 | )} 72 |
73 |
51 | User 52 | 55 | Subject 56 | 58 | Message 59 |
74 |
75 |
76 |
77 |
78 | ); 79 | }; 80 | 81 | export default GetQuery; 82 | -------------------------------------------------------------------------------- /src/components/AdminDashboard/Modal.css: -------------------------------------------------------------------------------- 1 | body.active-modal { 2 | overflow-y: hidden; 3 | } 4 | 5 | .btn-modal { 6 | padding: 10px 20px; 7 | display: block; 8 | margin: 100px auto 0; 9 | font-size: 18px; 10 | } 11 | 12 | .modal, 13 | .overlay { 14 | width: 115vw; 15 | height: 100vh; 16 | top: 0; 17 | left: 0; 18 | right: 0; 19 | bottom: 0; 20 | position: fixed; 21 | } 22 | 23 | .overlay { 24 | background: rgba(49, 49, 49, 0.3); 25 | } 26 | .modal-content { 27 | position: absolute; 28 | top: 50%; 29 | left: 50%; 30 | transform: translate(-50%, -50%); 31 | line-height: 1.4; 32 | background: #f1f1f1; 33 | padding: 14px 28px; 34 | border-radius: 3px; 35 | min-width: 400px; 36 | min-height: 100px; 37 | } 38 | 39 | .close-modal { 40 | position: absolute; 41 | top: 10px; 42 | right: 10px; 43 | padding: 5px 7px; 44 | } 45 | -------------------------------------------------------------------------------- /src/components/AdminDashboard/Query.js: -------------------------------------------------------------------------------- 1 | import React,{useState} from 'react' 2 | import "./Modal.css" 3 | 4 | const Query = (props) => { 5 | const [modal, setModal] = useState(false); 6 | const toggleModal = () => { 7 | setModal(!modal); 8 | }; 9 | return ( 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
{props.info.name}
22 |

23 | {props.info.tag} 24 |

25 |
26 |
27 | 28 | 29 | 30 |
31 | {props.info.subject} 32 |
33 | 34 | 35 | 38 | {modal && ( 39 |
40 |
41 |
42 |
Query Message
43 |

44 | {props.info.desc} 45 |

46 | 52 |
53 |
54 |
55 | )} 56 | 57 | 58 | ) 59 | } 60 | 61 | export default Query 62 | -------------------------------------------------------------------------------- /src/components/AdminDashboard/QueryHeading.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const StatHeading = () => { 4 | return ( 5 |
6 |
7 | User/Expert Query 8 |
9 | 10 |
11 | Here are some of the user/expert queries we got! 12 |
13 |
14 | ); 15 | }; 16 | 17 | export default StatHeading; 18 | -------------------------------------------------------------------------------- /src/components/AdminDashboard/StatHeading.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const StatHeading = () => { 4 | return ( 5 |
6 |
7 | WellCare Statistics 8 |
9 | 10 |
Some stats that matter!
11 |
12 | ); 13 | }; 14 | 15 | export default StatHeading; 16 | -------------------------------------------------------------------------------- /src/components/AdminDashboard/VerifyHeading.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const VerifyHeading = () => { 4 | return ( 5 |
6 |
7 | Expert Verification 8 |
9 | 10 |
11 | Verify the experts whom you want on the WellCare portal! 12 |
13 |
14 | ); 15 | }; 16 | 17 | export default VerifyHeading; 18 | -------------------------------------------------------------------------------- /src/components/AdminLogin/LeftLogin.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const LeftLogin = () => { 4 | return ( 5 |
6 | {/* heading */} 7 |
8 |
9 | WellCare 10 |
11 |
12 | Must for HealthCare 13 |
14 |
15 | 16 | {/* Center Tagline */} 17 |
18 |
19 | Start your journey with us 20 | . 21 |
22 |
23 | 24 | Discover the health portal full of of doctors and trainers who are 25 | waiting to help you on making your health journey easier. 26 | 27 |
28 |
29 | 30 | {/* Container 3 */} 31 |
32 | 33 | Being healthy has countless benefits. So what is stopping you? Just 34 | connect with us and take a step towards improving your health... 35 | 36 |
37 |
38 | ); 39 | }; 40 | 41 | export default LeftLogin; 42 | -------------------------------------------------------------------------------- /src/components/Chat/ChatHome.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useCallback, useEffect,useRef,useContext } from 'react'; 2 | import Chat from './Chat'; 3 | import Contacts from './Contacts'; 4 | import Navbar from 'components/Utils/Navbar'; 5 | import {io} from "socket.io-client"; 6 | import { UserContext } from 'context/UserContext'; 7 | import { useNavigate } from "react-router-dom"; 8 | 9 | const ChatHome = () => { 10 | 11 | // ADD 12 | // change the style of the contact div which is currently active 13 | 14 | const [currentChat, setCurrentChat] = useState(null); 15 | // currentchat -> name,id,profile_pic 16 | 17 | const {isLoggedIn,profile} = useContext(UserContext); 18 | const navigate = useNavigate(); 19 | useEffect(() => { 20 | console.log("chathome mounted..."); 21 | }); 22 | 23 | //checking if the user is logged in or not 24 | useEffect(() => { 25 | if (!isLoggedIn) { 26 | navigate('/login'); 27 | } 28 | }, [isLoggedIn]); 29 | 30 | // using ref to preserve the socket info across re-renders 31 | const socket = useRef(); 32 | //emitting event to let the server know that an user is online 33 | useEffect(()=>{ 34 | if(profile.id){ 35 | console.log("abey andar kyu nai aata : ",profile.id); 36 | socket.current = io("http://localhost:4000"); 37 | socket.current.emit("add-user",profile.id); 38 | } 39 | },[profile]); 40 | 41 | const currentChatContact = useCallback((contact) => { 42 | setCurrentChat(contact); 43 | }, []); 44 | 45 | 46 | return ( 47 | <> 48 |
49 | 50 |
51 |
52 | 53 |
54 |
55 | 56 |
57 |
58 |
59 | 60 | ) 61 | } 62 | 63 | export default ChatHome; -------------------------------------------------------------------------------- /src/components/Chat/ChatInput.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import BoldSmileIcon from "components/Icons/Bold/smile" 3 | import BoldPlaneIcon from "components/Icons/Bold/paperPlane"; 4 | import BoldPaperClip from "components/Icons/Bold/paperClip"; 5 | import Picker from "emoji-picker-react"; 6 | 7 | const ChatInput = ({ sendMsg }) => { 8 | //for either showing or hiding the emoji picker 9 | const [showPicker, setShowPicker] = useState(false); 10 | const [msg, setMsg] = useState(""); 11 | //handling the text 12 | const handleChange = (e) => { 13 | setMsg(e.target.value); 14 | }; 15 | //to show or not the emoji picker 16 | const handleEmojiPicker = () => { 17 | setShowPicker(!showPicker); 18 | }; 19 | //appending the emoji to the text 20 | const handleEmojiClick = (emoji, e) => { 21 | let message = msg; 22 | message += emoji.emoji; 23 | setMsg(message); 24 | }; 25 | 26 | const onSubmit = () => { 27 | sendMsg(msg); 28 | setMsg(""); 29 | }; 30 | return ( 31 | <> 32 | 39 |
40 |
44 | 45 |
46 | {showPicker ? ( 47 |
48 | 53 |
54 | ) : null} 55 |
56 | 57 |
58 | 59 |
60 |
64 | 65 |
66 | 67 | ); 68 | }; 69 | 70 | export default ChatInput; 71 | -------------------------------------------------------------------------------- /src/components/Chat/ChatMessage.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const ChatMessage = ({ msg, time, self }) => { 4 | //will convert the time into respective localestrings for displaying it on the UI 5 | if (!time) { 6 | time = new Date(); 7 | } else { 8 | time = new Date(time); 9 | } 10 | 11 | let dateString = time.toLocaleDateString(); 12 | let timeString = time.toLocaleTimeString(); 13 | timeString = timeString.slice(0, timeString.length - 6); 14 | 15 | //append 0 to hour if its a single digit 16 | if (timeString[1] === ":") { 17 | timeString = "0" + timeString; 18 | } 19 | 20 | return ( 21 | <> 22 |
27 |
28 |
29 |
35 | {msg} 36 |
37 |
{dateString}
38 |
{timeString}
39 |
40 |
41 | 42 | ); 43 | }; 44 | 45 | export default ChatMessage; 46 | -------------------------------------------------------------------------------- /src/components/Chat/DocChat.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const DocChat = ({ image, name, id, currentChatContact }) => { 4 | //on clicking it will get the details of that contact 5 | const changeChat = () => { 6 | let user = { 7 | image, name, id 8 | } 9 | currentChatContact(user); 10 | } 11 | 12 | return ( 13 | <> 14 |
15 |
16 |
17 | DP 22 |
23 | 24 |
25 |
26 |
{name}
27 | {/*
12:00 AM
*/} 28 |
29 | {/*
30 | Just do the exercises told to you.. 31 |
*/} 32 |
33 |
34 |
35 | 36 | ) 37 | } 38 | 39 | export default DocChat; -------------------------------------------------------------------------------- /src/components/DocNotverified/Notverified.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | 3 | const Notverified = () => { 4 | return ( 5 |
6 |
7 |
8 |
9 |
13 | 19 | 24 | 25 | 26 |

OOPS!

27 |

28 | You are not verified yet by our admin! You will receive a mail 29 | once verified! 30 |

31 |
32 | 51 |
52 |
53 |
54 |
55 |
56 |
57 | ); 58 | }; 59 | 60 | export default Notverified; 61 | -------------------------------------------------------------------------------- /src/components/DoctorRegistration/Final.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import { useStepperContext } from "components/DoctorRegistration/contexts/StepperContext"; 3 | import axios from "axios"; 4 | import Swal from "sweetalert2"; 5 | 6 | export default function Final() { 7 | const [load, setLoad] = useState(false); 8 | const { userData } = useStepperContext(); 9 | 10 | useEffect(() => { 11 | console.log("userData in registration is ",userData) 12 | registerDoctor(); 13 | }, []); 14 | 15 | const registerDoctor = async () => { 16 | //send the data to the backend 17 | try { 18 | let postData = { 19 | name: userData.name, 20 | age: userData.age, 21 | gender: userData.gender, 22 | licenseNumber: userData.licenseNumber, 23 | locality: userData.locality, 24 | specialization: userData.specialization, 25 | years_Of_Experience: userData.years_Of_Experience, 26 | phoneNumber: userData.phoneNumber, 27 | fees: userData.fees, 28 | profile_pic: userData.profile_pic, 29 | // certi_proof: userData.certi_proof, 30 | email: userData.email, 31 | address: userData.address, 32 | have_clinic: userData.have_clinic, 33 | username: userData.username, 34 | password: userData.password, 35 | category: userData.category, 36 | bio: userData.bio, 37 | clinic_name: userData.c_name 38 | }; 39 | 40 | setLoad(true); 41 | console.log("Post Data is ",postData ); 42 | console.log("postinggg..."); 43 | let res = await axios.post( 44 | "http://localhost:4000/doctor/register", 45 | postData, 46 | { 47 | headers: { 48 | "Content-Type": "multipart/form-data", 49 | }, 50 | } 51 | ); 52 | if (res.data.success === true) { 53 | Swal.fire({ 54 | icon: "success", 55 | title: res.data.message, 56 | }); 57 | } 58 | setLoad(false); 59 | } catch (err) { 60 | setLoad(false); 61 | console.log("error in login : ", err); 62 | Swal.fire({ 63 | icon: "error", 64 | title: "Oops...", 65 | text: err.response.data.error, 66 | }); 67 | } 68 | }; 69 | 70 | return ( 71 |
72 |
73 |
74 | 79 | 86 | 91 | 92 |
93 | 94 | 100 | 101 |
102 |
103 | ); 104 | } 105 | -------------------------------------------------------------------------------- /src/components/DoctorRegistration/Step1.js: -------------------------------------------------------------------------------- 1 | import React, { forwardRef, useImperativeHandle } from "react"; 2 | import { useStepperContext } from "components/DoctorRegistration/contexts/StepperContext"; 3 | 4 | const Step1 = forwardRef((props, ref) => { 5 | const { userData, setUserData } = useStepperContext(); 6 | 7 | const handleChange = (e) => { 8 | const { name, value } = e.target; 9 | setUserData({ ...userData, [name]: value }); 10 | }; 11 | 12 | //exposing functions to the parent 13 | useImperativeHandle(ref, () => ({ 14 | checkFields() { 15 | if (!userData.name) { 16 | console.log("fname"); 17 | return false; 18 | } 19 | // if (userData.male || userData.female) { 20 | // console.log("gender"); 21 | // return true; 22 | // } 23 | if (!userData.age) { 24 | console.log("age"); 25 | return false; 26 | } 27 | return true; 28 | }, 29 | })); 30 | 31 | return ( 32 |
33 |
34 | 37 |
38 | 47 |
48 |
49 | 50 |
51 | 54 |
55 | 64 | 70 |
71 |
72 | 81 | 87 |
88 | 89 |
90 | 93 |
94 | 103 |
104 |
105 |
106 |
107 | ); 108 | }); 109 | 110 | export default Step1; 111 | -------------------------------------------------------------------------------- /src/components/DoctorRegistration/Step5.js: -------------------------------------------------------------------------------- 1 | import React, { forwardRef, useImperativeHandle } from "react"; 2 | import { useStepperContext } from "components/DoctorRegistration/contexts/StepperContext"; 3 | 4 | const Step5 = forwardRef((props, ref) => { 5 | const { userData, setUserData } = useStepperContext(); 6 | 7 | const handleChange = (e) => { 8 | const { name, value } = e.target; 9 | console.log("name : ", name); 10 | console.log("value : ", value); 11 | setUserData({ ...userData, [name]: value }); 12 | }; 13 | 14 | const updateImage = (e) => { 15 | setUserData({ ...userData, profile_pic: e.target.files[0] }); 16 | }; 17 | 18 | useImperativeHandle(ref, () => ({ 19 | checkFields() { 20 | if (!userData.bio) { 21 | return false; 22 | } 23 | if (!userData.username) { 24 | return false; 25 | } 26 | if (!userData.password) { 27 | return false; 28 | } 29 | if (!userData.profile_pic) { 30 | return false; 31 | } 32 | return true; 33 | }, 34 | })); 35 | 36 | return ( 37 |
38 |
39 | 50 |
51 | 52 |
53 | 56 |
57 |