├── .gitignore ├── README.md ├── app ├── (route) │ ├── details │ │ ├── [recordId] │ │ │ └── page.js │ │ └── _components │ │ │ ├── BookAppointment.jsx │ │ │ ├── DoctorDetail.jsx │ │ │ └── DoctorSuggestionList.jsx │ ├── my-booking │ │ ├── _components │ │ │ ├── BookingList.jsx │ │ │ └── CancelAppointment.jsx │ │ └── page.jsx │ └── search │ │ ├── [cname] │ │ └── page.js │ │ ├── _components │ │ └── CategoryList.jsx │ │ └── layout.js ├── _components │ ├── CategorySearch.jsx │ ├── DoctorList.jsx │ ├── Footer.jsx │ ├── Header.jsx │ └── Hero.jsx ├── _utils │ └── GlobalApi.jsx ├── api │ ├── auth │ │ └── [kindeAuth] │ │ │ └── route.js │ └── sendEmail │ │ └── route.js ├── favicon.ico ├── globals.css ├── layout.js └── page.js ├── components.json ├── components └── ui │ ├── alert-dialog.jsx │ ├── button.jsx │ ├── calendar.jsx │ ├── command.jsx │ ├── dialog.jsx │ ├── input.jsx │ ├── popover.jsx │ ├── sonner.jsx │ ├── tabs.jsx │ └── textarea.jsx ├── emails └── index.jsx ├── jsconfig.json ├── lib └── utils.js ├── middleware.js ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── doctors.jpg ├── facebook.png ├── linkedin.png ├── logo.svg ├── next.svg ├── twitter.png ├── vercel.svg └── youtube.png └── tailwind.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Build Deploy Full Stack NextJs Appointment Booking App Using ReactJs](https://github.com/rrs301/Doctor-Appointment-Booking-Web-Nextjs/assets/20216436/17bce550-ef15-4ca1-bb98-ce8186f82d49) 3 | 4 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 5 | 6 | ## Getting Started 7 | 8 | First, run the development server: 9 | 10 | ```bash 11 | npm run dev 12 | # or 13 | yarn dev 14 | # or 15 | pnpm dev 16 | # or 17 | bun dev 18 | ``` 19 | 20 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 21 | 22 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. 23 | 24 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 25 | 26 | ## Learn More 27 | 28 | To learn more about Next.js, take a look at the following resources: 29 | 30 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 31 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 32 | 33 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 34 | 35 | ## Deploy on Vercel 36 | 37 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 38 | 39 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 40 | -------------------------------------------------------------------------------- /app/(route)/details/[recordId]/page.js: -------------------------------------------------------------------------------- 1 | "use client" 2 | import GlobalApi from '@/app/_utils/GlobalApi' 3 | import React, { useEffect, useState } from 'react' 4 | import DoctorDetail from '../_components/DoctorDetail'; 5 | import DoctorSuggestionList from '../_components/DoctorSuggestionList'; 6 | 7 | function Details({params}) { 8 | 9 | const [doctor,setDoctor]=useState(); 10 | useEffect(()=>{ 11 | getDoctorById(); 12 | },[]) 13 | const getDoctorById=()=>{ 14 | GlobalApi.getDoctorById(params.recordId).then(resp=>{ 15 | setDoctor(resp.data.data); 16 | }) 17 | } 18 | return ( 19 |
20 |

Details

21 | 22 |
23 | {/* Doctor Detail */} 24 |
25 | {doctor&& } 26 | 27 |
28 | {/* Doctor Suggestion */} 29 |
30 | 31 |
32 |
33 |
34 | ) 35 | } 36 | 37 | export default Details -------------------------------------------------------------------------------- /app/(route)/details/_components/BookAppointment.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { 3 | Dialog, 4 | DialogClose, 5 | DialogContent, 6 | DialogDescription, 7 | DialogFooter, 8 | DialogHeader, 9 | DialogTitle, 10 | DialogTrigger, 11 | } from "@/components/ui/dialog" 12 | import { Button } from '@/components/ui/button' 13 | import { Calendar } from "@/components/ui/calendar" 14 | import { CalendarDays, Clock } from 'lucide-react' 15 | import { Textarea } from '@/components/ui/textarea' 16 | import { useKindeBrowserClient } from '@kinde-oss/kinde-auth-nextjs' 17 | import GlobalApi from '@/app/_utils/GlobalApi' 18 | import { toast } from 'sonner' 19 | 20 | function BookAppointment({doctor}) { 21 | const [date, setDate]=useState(new Date()); 22 | const [timeSlot,setTimeSlot]=useState(); 23 | const [selectedTimeSlot,setSelectedTimeSlot]=useState(); 24 | const [note,setNote]=useState(); 25 | const {user}=useKindeBrowserClient(); 26 | useEffect(()=>{ 27 | getTime(); 28 | },[]) 29 | 30 | const getTime = () => { 31 | const timeList = []; 32 | for (let i = 10; i <= 12; i++) { 33 | timeList.push({ 34 | time: i + ':00 AM' 35 | }) 36 | timeList.push({ 37 | time: i + ':30 AM' 38 | }) 39 | } 40 | for (let i = 1; i <= 6; i++) { 41 | timeList.push({ 42 | time: i + ':00 PM' 43 | }) 44 | timeList.push({ 45 | time: i + ':30 PM' 46 | }) 47 | } 48 | 49 | setTimeSlot(timeList) 50 | } 51 | 52 | const saveBooking=()=>{ 53 | const data={ 54 | data:{ 55 | UserName:user.given_name+" "+user.family_name, 56 | Email:user.email, 57 | Time:selectedTimeSlot, 58 | Date:date, 59 | doctor:doctor.id, 60 | Note:note 61 | } 62 | } 63 | // console.log(data) 64 | GlobalApi.bookAppointment(data).then(resp=>{ 65 | console.log(resp); 66 | if(resp) 67 | { 68 | GlobalApi.sendEmail(data).then(resp=>{ 69 | console.log(resp) 70 | }) 71 | toast("Booking Confirmation sent on Email") 72 | } 73 | }) 74 | } 75 | 76 | const isPastDay=(day)=>{ 77 | return day<=new Date(); 78 | } 79 | return ( 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | Book Appointment 88 | 89 |
90 |
91 | {/* Calender */} 92 |
93 |

94 | 95 | Select Date 96 |

97 | 104 |
105 | {/* Time Slot */} 106 |
107 |

108 | 109 | Select Time Slot 110 |

111 |
113 | {timeSlot?.map((item,index)=>( 114 |

setSelectedTimeSlot(item.time)} 116 | className={`p-2 border cursor-pointer 117 | text-center hover:bg-primary hover:text-white 118 | rounded-full 119 | ${item.time==selectedTimeSlot&&'bg-primary text-white'}`}>{item.time}

120 | ))} 121 |
122 |
123 |
124 |