diff --git a/client/components/doctor/appointments/AppointmentTabContent.tsx b/client/components/doctor/appointments/AppointmentTabContent.tsx
index e388a9c6..c3dfc66f 100644
--- a/client/components/doctor/appointments/AppointmentTabContent.tsx
+++ b/client/components/doctor/appointments/AppointmentTabContent.tsx
@@ -1,6 +1,12 @@
-import React from 'react'
+'use client'
+
+import { useGetAppointmentsDoctor } from "@/lib/hooks/appointment/useAppointment"
+import { AppointmentStatus } from "@/types"
const AppointmentTabContent = () => {
+ const {data,isLoading} = useGetAppointmentsDoctor(AppointmentStatus.PENDING,0,10);
+ console.log(data);
+
return (
AppointmentTabContent {}
)
diff --git a/client/components/forms/actions/userValidation.ts b/client/components/forms/actions/userValidation.ts
index e9ab154a..59ff35ff 100644
--- a/client/components/forms/actions/userValidation.ts
+++ b/client/components/forms/actions/userValidation.ts
@@ -1,4 +1,3 @@
-import { AppointmentType } from "@/types";
import { z } from "zod";
export const signinFormValidation = z.object({
@@ -86,10 +85,7 @@ export const appointmentFormValidation = z.object({
}).trim().min(5, "Reason must be at least 5 characters long")
.max(500, "Reason must not exceed 500 characters"),
- note: z.string().trim()
- .min(5, "Notes must be at least 5 characters long")
- .max(1000, "Notes must not exceed 1000 characters")
- .optional(),
+ note: z.string(),
date: z.coerce.date(),
diff --git a/client/components/forms/patient/AppointmentForm.tsx b/client/components/forms/patient/AppointmentForm.tsx
index 9cda2104..b66a8114 100644
--- a/client/components/forms/patient/AppointmentForm.tsx
+++ b/client/components/forms/patient/AppointmentForm.tsx
@@ -170,7 +170,7 @@ const AppointmentForm = () => {
showTimeSelect={false}
name="date"
showDateText="Appointment date must be in the future"
- label="Expected appointment date"
+ label="Expected appointment date *"
isLimited
dateFormat="dd/MM/yyyy"
/>
@@ -179,7 +179,7 @@ const AppointmentForm = () => {
fieldType={FormFieldType.SELECT}
control={form.control}
name="appointmentType"
- label="Appointment Type"
+ label="Appointment Type *"
placeholder="Select an Appointment"
>
{AppointmentTypes.map((appointment, i) => (
@@ -202,7 +202,7 @@ const AppointmentForm = () => {
fieldType={FormFieldType.SELECT}
control={form.control}
name="doctor"
- label="Doctor"
+ label="Doctor *"
>
{!isDoctorsLoading && doctorsData?.items ? (
doctorsData.items.map((doctor) => (
@@ -231,7 +231,7 @@ const AppointmentForm = () => {
name="slotId"
render={({ field }) => (
- Time Slot
+ Time Slot *
{isDoctorSelected && (
@@ -275,14 +275,14 @@ const AppointmentForm = () => {
fieldType={FormFieldType.TEXTAREA}
control={form.control}
name="reason"
- label="Reason for Appointment"
+ label="Reason for Appointment *"
placeholder="Annual monthly check-up"
/>
diff --git a/client/lib/api/appointment/index.ts b/client/lib/api/appointment/index.ts
index 5ed4e734..162d1886 100644
--- a/client/lib/api/appointment/index.ts
+++ b/client/lib/api/appointment/index.ts
@@ -1,6 +1,6 @@
+import axios from "axios";
import { withTempBaseUrl } from "@/lib/utils/withTempBaseUrl";
import IAppointment, { AppointmentStatus } from "@/types";
-import axios from "axios";
import patientAxiosInstance from "../patient/authorizedRoutes";
import doctorAxiosInstance from "../doctor/authorizedRoutes";
@@ -10,18 +10,16 @@ export type verifyPaymentProps = {
}
-const { doctorInstance, patientInstance, baseUrl } = {
- doctorInstance: doctorAxiosInstance,
- patientInstance: patientAxiosInstance,
- baseUrl: `${process.env.NEXT_PUBLIC_API_URL}/appointments`
-}
+ const baseUrl = `${process.env.NEXT_PUBLIC_API_URL}/appointments`
+
export const getDoctorsList = async () => {
const response = await axios.get(`${process.env.NEXT_PUBLIC_API_URL}/doctors`);
return response.data;
};
+
export const createAppointment = async (appointment: IAppointment) => {
- const response = await withTempBaseUrl(patientInstance, baseUrl, {
+ const response = await withTempBaseUrl(patientAxiosInstance, baseUrl, {
method: 'POST',
url: '/',
data: {
@@ -32,7 +30,7 @@ export const createAppointment = async (appointment: IAppointment) => {
};
export const verifyPayment = async ({ appointmentId, paymentData }: verifyPaymentProps) => {
- const response = await withTempBaseUrl(patientInstance, baseUrl, {
+ const response = await withTempBaseUrl(patientAxiosInstance, baseUrl, {
method: 'POST',
url: '/verify-payment',
data: {
@@ -43,10 +41,10 @@ export const verifyPayment = async ({ appointmentId, paymentData }: verifyPaymen
};
-export const getAppointmentsDoctor = async (status: AppointmentStatus) => {
- const response = await withTempBaseUrl(doctorInstance, baseUrl, {
+export const getAppointmentsDoctor = async (status: AppointmentStatus,offset: number, limit: number,) => {
+ const response = await withTempBaseUrl(doctorAxiosInstance, baseUrl, {
method: 'GET',
- url: `/doctor?status=${status}`,
+ url: `/doctor?status=${status}&${offset}&${limit}`,
})
return response.data;
}
\ No newline at end of file
diff --git a/client/lib/hooks/appointment/useAppointment.ts b/client/lib/hooks/appointment/useAppointment.ts
index 5f52c78a..25d170ea 100644
--- a/client/lib/hooks/appointment/useAppointment.ts
+++ b/client/lib/hooks/appointment/useAppointment.ts
@@ -1,5 +1,5 @@
-import { verifyPayment, createAppointment, getDoctorsList, verifyPaymentProps } from "@/lib/api/appointment"
-import IAppointment, { ErrorResponse, IDoctor, IPatient, MessageResponse, PaginatedResult } from "@/types"
+import { verifyPayment, createAppointment, getDoctorsList, verifyPaymentProps, getAppointmentsDoctor } from "@/lib/api/appointment"
+import IAppointment, { AppointmentStatus, ErrorResponse, IDoctor, IPatient, MessageResponse, PaginatedResult } from "@/types"
import { useMutation, useQuery } from "@tanstack/react-query"
import { AxiosError } from "axios"
@@ -12,7 +12,7 @@ export const useGetDoctorsList = () => {
};
export const useCreateAppointment = () => {
- return useMutation<{ orderId: string, appointmentId: string, patient:IPatient }, AxiosError, { appointment: IAppointment }>({
+ return useMutation<{ orderId: string, appointmentId: string, patient: IPatient }, AxiosError, { appointment: IAppointment }>({
mutationFn: ({ appointment }) => createAppointment(appointment),
onError: (error) => {
console.log("Error in creating appointment", error);
@@ -27,4 +27,11 @@ export const useVerifyPaymentAppointment = () => {
console.log("Error in Verifying payment ", error);
}
})
+}
+
+export const useGetAppointmentsDoctor = (status: AppointmentStatus, offset: number, limit: number,) => {
+ return useQuery, AxiosError>({
+ queryKey: ["appointments", status, offset, limit,],
+ queryFn: () => getAppointmentsDoctor(status, offset, limit,)
+ })
}
\ No newline at end of file
diff --git a/server/src/domain/interface/repositories/IAppointmentRepository.ts b/server/src/domain/interface/repositories/IAppointmentRepository.ts
index 1abccf35..94999421 100644
--- a/server/src/domain/interface/repositories/IAppointmentRepository.ts
+++ b/server/src/domain/interface/repositories/IAppointmentRepository.ts
@@ -1,3 +1,4 @@
+import { PaginatedResult } from "../../../types";
import IAppointment, { AppointmentStatus } from "../../entities/IAppointment";
export default interface IAppointmentRepository {
@@ -7,5 +8,5 @@ export default interface IAppointmentRepository {
findByDateAndSlot(appointmentDate: string, slotId: string): Promise;
findManyByDateAndDoctorId(appointmentDate: string, doctorId: string): Promise;
updateAppointmentStatusToConfirmed(appointmentId: string): Promise;
- findManyByDoctorId(doctorId: string, status:AppointmentStatus): Promise
+ findManyByDoctorId(doctorId: string, status:AppointmentStatus,offset:number,limit:number): Promise | null>
}
diff --git a/server/src/infrastructure/repositories/AppointmentRepository.ts b/server/src/infrastructure/repositories/AppointmentRepository.ts
index 712ab900..839335e2 100644
--- a/server/src/infrastructure/repositories/AppointmentRepository.ts
+++ b/server/src/infrastructure/repositories/AppointmentRepository.ts
@@ -1,5 +1,6 @@
import IAppointment, { AppointmentStatus } from "../../domain/entities/IAppointment";
import IAppointmentRepository from "../../domain/interface/repositories/IAppointmentRepository";
+import { PaginatedResult } from "../../types";
import AppointmentModel from "../database/AppointmentModel";
export default class AppointmentRepository implements IAppointmentRepository {
@@ -12,8 +13,24 @@ export default class AppointmentRepository implements IAppointmentRepository {
await this.model.findByIdAndUpdate(appointment._id, appointment, { new: true })
}
- async findManyByDoctorId(doctorId: string, status: AppointmentStatus): Promise {
- return await this.model.find({ doctorId, status });
+ async findManyByDoctorId(doctorId: string, status: AppointmentStatus, offset: number, limit: number): Promise | null> {
+ const totalItems = await this.model.countDocuments({ doctorId, status });
+ const items = await this.model.find({ doctorId, status })
+ .skip(offset)
+ .limit(limit)
+ .exec();
+ const currentPage = Math.floor(offset / limit) + 1;
+ const totalPages = Math.ceil(totalItems / limit);
+ const hasNextPage = currentPage < totalPages;
+ const hasPreviousPage = currentPage > 1;
+ return {
+ currentPage,
+ hasNextPage,
+ hasPreviousPage,
+ items,
+ totalItems,
+ totalPages,
+ };
}
async findManyByDateAndDoctorId(appointmentDate: string, doctorId: string): Promise {
diff --git a/server/src/presentation/controllers/appointment/AppointmentControllers.ts b/server/src/presentation/controllers/appointment/AppointmentControllers.ts
index 519d8f8b..fd86a682 100644
--- a/server/src/presentation/controllers/appointment/AppointmentControllers.ts
+++ b/server/src/presentation/controllers/appointment/AppointmentControllers.ts
@@ -35,8 +35,14 @@ export default class AppointmentController {
try {
const doctorId = req.doctor?.id;
const status = req.query.status as AppointmentStatus;
- const appointments = await this.getAppointmentUseCase.getAppointmentsByDoctorId(doctorId!,status);
- res.status(StatusCode.Success).json({appointments})
+ let offset = parseInt(req.query.offset as string);
+ let limit = parseInt(req.query.limit as string);
+
+ offset = isNaN(offset) || offset < 0 ? 0 : offset;
+ limit = isNaN(limit) || limit < 0 ? 10 : Math.min(limit, 100);
+
+ const data = await this.getAppointmentUseCase.getAppointmentsByDoctorId(doctorId!,offset,limit,status);
+ res.status(StatusCode.Success).json(data)
} catch (error) {
next(error)
}
diff --git a/server/src/use_case/appointment/GetAppointmentUseCase.ts b/server/src/use_case/appointment/GetAppointmentUseCase.ts
index a4282376..24befcd0 100644
--- a/server/src/use_case/appointment/GetAppointmentUseCase.ts
+++ b/server/src/use_case/appointment/GetAppointmentUseCase.ts
@@ -1,6 +1,7 @@
import IAppointmentRepository from "../../domain/interface/repositories/IAppointmentRepository";
import IAppointment, { AppointmentStatus } from "../../domain/entities/IAppointment";
import IValidatorService from "../../domain/interface/services/IValidatorService";
+import { PaginatedResult } from "../../types";
export default class GetAppointmentUseCase {
constructor(
@@ -8,12 +9,12 @@ export default class GetAppointmentUseCase {
private validatorService: IValidatorService
) { }
- async getAppointmentsByDoctorId(doctorId: string, status?: AppointmentStatus): Promise {
+ async getAppointmentsByDoctorId(doctorId: string,offset:number,limit:number, status?: AppointmentStatus): Promise | null> {
this.validatorService.validateIdFormat(doctorId);
if(status){
this.validatorService.validateEnum(status,Object.values(AppointmentStatus))
}
- return await this.appointmentRepository.findManyByDoctorId(doctorId, status ?? AppointmentStatus.CONFIRMED)
+ return await this.appointmentRepository.findManyByDoctorId(doctorId, status ?? AppointmentStatus.CONFIRMED, offset,limit)
}
}
\ No newline at end of file