diff --git a/.github/workflows/test-and-deploy.yml b/.github/workflows/test-and-deploy.yml index b948854e..252091a5 100644 --- a/.github/workflows/test-and-deploy.yml +++ b/.github/workflows/test-and-deploy.yml @@ -2,9 +2,9 @@ name: CI/CD Pipeline For Playwright Tests and Vercel Deployment on: push: - branches: [main, "feature/**"] + branches: [main, "feature/**", "fix-**"] pull_request: - branches: [main, "feature/**"] + branches: [main, "feature/**", "fix-**"] jobs: test: @@ -43,7 +43,7 @@ jobs: deploy-preview: needs: test - if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature/')) + if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature/') || startsWith(github.ref, 'refs/heads/fix-')) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/app/(pages)/(auth)/login/page.tsx b/app/(pages)/(auth)/login/page.tsx index e8dfaf97..02cf5760 100644 --- a/app/(pages)/(auth)/login/page.tsx +++ b/app/(pages)/(auth)/login/page.tsx @@ -85,10 +85,11 @@ export default function Login() { position: "bottom-center", }); - const isValidUser = await loginAction(formData); + const response = await loginAction(formData); toast.dismiss(); - if (isValidUser?.unauthorized) { - toast.error("Invalid username | email or password. Please try again."); + + if (response.error) { + toast.error(`${response.error.message}`); } else { const userRole = formData.get("role"); setUserData({ @@ -103,7 +104,9 @@ export default function Login() { setShowOtp(true); } } catch (error) { - toast.error("Invalid username | email or password. Please try again."); + toast.dismiss(); + console.error("Login failed:", error); + toast.error("An unexpected error occurred. Please try again later."); } } diff --git a/app/(pages)/(auth)/signup/page.tsx b/app/(pages)/(auth)/signup/page.tsx index 31e3ff7d..78371ba3 100644 --- a/app/(pages)/(auth)/signup/page.tsx +++ b/app/(pages)/(auth)/signup/page.tsx @@ -95,11 +95,11 @@ export default function Signup() { position: "bottom-center", }); - const signUpSuccess = await signupAction(formData); + const response = await signupAction(formData); toast.dismiss(); - if (signUpSuccess.failure) { - toast.error(signUpSuccess.msg); + if (response.error) { + toast.error(`${response.error.message}`); } else { const userRole = formData.get("role"); @@ -119,8 +119,9 @@ export default function Signup() { setShowOtp(true); } } catch (error) { - console.error("Error signing up"); - toast.error("Error signing up. Please try again!"); + toast.dismiss(); + console.error("Signup failed:", error); + toast.error("An unexpected error occurred. Please try again later."); } } diff --git a/app/(pages)/admin/add-admin/page.tsx b/app/(pages)/admin/add-admin/page.tsx index 54440e09..edb9a4ee 100644 --- a/app/(pages)/admin/add-admin/page.tsx +++ b/app/(pages)/admin/add-admin/page.tsx @@ -66,7 +66,10 @@ export default function AddAdmin() { const result = await addAdmin(formDataToSend); if (result.error) { - toast.error(result.error, { id: toastId, position: "top-center" }); + toast.error(result.error.message, { + id: toastId, + position: "top-center", + }); } else { toast.success("Admin added successfully!", { id: toastId }); setFormData({ diff --git a/app/(pages)/admin/components/LoginForm/index.tsx b/app/(pages)/admin/components/LoginForm/index.tsx index 7a6216e7..820f9f93 100644 --- a/app/(pages)/admin/components/LoginForm/index.tsx +++ b/app/(pages)/admin/components/LoginForm/index.tsx @@ -69,11 +69,12 @@ export default function LoginForm() { try { toast.loading("Please wait ...", { position: "bottom-center" }); - const isValidUser = await loginAction(formData); + + const response = await loginAction(formData); toast.dismiss(); - if (isValidUser?.unauthorized) { - toast.error("Invalid username or email & password. Please try again."); + if (response.error) { + toast.error(`${response.error.message}`); } else { setUserData({ usernameOrEmail, @@ -86,7 +87,9 @@ export default function LoginForm() { setShowOtp(true); } } catch (error) { - toast.error("An error occurred. Please try again."); + toast.dismiss(); + console.error("Admin Login failed:", error); + toast.error("An unexpected error occurred. Please try again later."); } } diff --git a/app/(pages)/admin/hospitals/[id]/page.tsx b/app/(pages)/admin/hospitals/[id]/page.tsx index 1c90de33..337d3a31 100644 --- a/app/(pages)/admin/hospitals/[id]/page.tsx +++ b/app/(pages)/admin/hospitals/[id]/page.tsx @@ -23,35 +23,17 @@ import { AiOutlineStop as BlockIcon, } from "react-icons/ai"; import SpinnerLoader from "@components/SpinnerLoader"; -import { getHospitalDetails } from "@/lib/admin"; +import { getHospitalDetails } from "@lib/admin"; import { FaExclamationCircle } from "react-icons/fa"; - -interface UserData { - id: string; - name: string; - role: string; - username: string; - profile: string; - gender: string; - contact: string; - city: string; - state: string; -} - -interface PaginationMetadata { - currentPage: number; - pageSize: number; - totalPages: number; - totalCount: number; -} +import { HospitalUserData, PaginationMetadata } from "@pft-types/admin"; function UserManagement({ params }: { params: { id: string } }) { - const [users, setUsers] = useState([]); + const [users, setUsers] = useState([]); const [loading, setLoading] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [selectedRole, setSelectedRole] = useState("All"); - const [currentUser, setCurrentUser] = useState(null); + const [currentUser, setCurrentUser] = useState(null); const [pagination, setPagination] = useState({ currentPage: 1, pageSize: 10, diff --git a/app/(pages)/admin/hospitals/page.tsx b/app/(pages)/admin/hospitals/page.tsx index 0a64c9d5..62ba9b87 100644 --- a/app/(pages)/admin/hospitals/page.tsx +++ b/app/(pages)/admin/hospitals/page.tsx @@ -24,23 +24,7 @@ import SpinnerLoader from "@components/SpinnerLoader"; import Link from "next/link"; import { getHospitalsList } from "@lib/admin/getHospitals"; import { FaExclamationCircle } from "react-icons/fa"; - -interface HospitalData { - id: string; - name: string; - username: string; - profile: string; - contact: string; - city: string; - state: string; -} - -interface PaginationMetadata { - currentPage: number; - pageSize: number; - totalPages: number; - totalCount: number; -} +import { HospitalData, PaginationMetadata } from "@pft-types/admin"; const HospitalManagement: React.FC = () => { const [hospitals, setHospitals] = useState([]); diff --git a/app/(pages)/admin/layout.tsx b/app/(pages)/admin/layout.tsx index 7055be8b..9fc5de52 100644 --- a/app/(pages)/admin/layout.tsx +++ b/app/(pages)/admin/layout.tsx @@ -1,6 +1,5 @@ import type { Metadata } from "next"; import { Sidebar, Header } from "./components"; -import { Admin } from "@pft-types/index"; import { getAdminData } from "@lib/admin"; export const metadata: Metadata = { @@ -13,7 +12,7 @@ export default async function AdminLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const admin: Admin = await getAdminData(); + const admin = await getAdminData(); return (
diff --git a/app/(pages)/admin/transactions/page.tsx b/app/(pages)/admin/transactions/page.tsx index 8d02f316..5357748f 100644 --- a/app/(pages)/admin/transactions/page.tsx +++ b/app/(pages)/admin/transactions/page.tsx @@ -1,9 +1,8 @@ -import { TransactionDetails } from "@pft-types/index"; import Transactions from "../components/Transactions"; import getTransactions from "@lib/admin/getTransactions"; export default async function TransactionsPage() { - const transactions: TransactionDetails[] = await getTransactions(); + const transactions = await getTransactions(); return ; } diff --git a/app/(pages)/doctor/layout.tsx b/app/(pages)/doctor/layout.tsx index 84b4a37c..4fffd0e5 100644 --- a/app/(pages)/doctor/layout.tsx +++ b/app/(pages)/doctor/layout.tsx @@ -1,6 +1,5 @@ import { Sidebar, Headbar } from "@components/index"; import { getDoctorData } from "@lib/doctor"; -import { Doctor } from "@pft-types/index"; import type { Metadata } from "next"; @@ -14,7 +13,7 @@ export default async function DoctorLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const doctor: Doctor = await getDoctorData(); + const doctor = await getDoctorData(); return (
diff --git a/app/(pages)/hospital/layout.tsx b/app/(pages)/hospital/layout.tsx index cb1ccd73..71b8a414 100644 --- a/app/(pages)/hospital/layout.tsx +++ b/app/(pages)/hospital/layout.tsx @@ -1,6 +1,5 @@ import { Sidebar, Headbar } from "@components/index"; import { getHospitalData } from "@lib/hospital"; -import { Hospital } from "@pft-types/index"; import type { Metadata } from "next"; @@ -14,7 +13,7 @@ export default async function HospitalLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const hospital: Hospital = await getHospitalData(); + const hospital = await getHospitalData(); return (
diff --git a/app/(pages)/patient/appointments/page.tsx b/app/(pages)/patient/appointments/page.tsx index 1cecaccb..ec2430eb 100644 --- a/app/(pages)/patient/appointments/page.tsx +++ b/app/(pages)/patient/appointments/page.tsx @@ -1,10 +1,9 @@ import { Card, Image } from "@nextui-org/react"; import { BookAppointment } from "../components"; -import { Patient } from "@pft-types/index"; import { getPatientData } from "@lib/patient"; export default async function Appointments() { - const patient: Patient = await getPatientData(); + const patient = await getPatientData(); const { _id, firstname, lastname, email } = patient; diff --git a/app/(pages)/patient/components/BookAppointment/index.tsx b/app/(pages)/patient/components/BookAppointment/index.tsx index 395586e8..c4acff75 100644 --- a/app/(pages)/patient/components/BookAppointment/index.tsx +++ b/app/(pages)/patient/components/BookAppointment/index.tsx @@ -29,18 +29,10 @@ import { getHospitals, getStates, } from "@lib/patient/misc"; - -type Hospital = { - hospital_id: string; - hospital_name: string; - appointment_charge: string; -}; - -type BookAppointmentProps = { - patientId: string; - name: string; - email: string; -}; +import { + BookAppointmentHospital, + BookAppointmentProps, +} from "@pft-types/patient"; export default function BookAppointment({ patientId, @@ -51,11 +43,12 @@ export default function BookAppointment({ const [selectedState, setSelectedState] = useState(""); const [cities, setCities] = useState([]); const [selectedCity, setSelectedCity] = useState(""); - const [selectedHospital, setSelectedHospital] = useState({ - hospital_id: "", - hospital_name: "", - appointment_charge: "", - }); + const [selectedHospital, setSelectedHospital] = + useState({ + hospital_id: "", + hospital_name: "", + appointment_charge: "", + }); const [selectedDisease, setSelectedDisease] = useState(""); const [loadingStates, setLoadingStates] = useState(false); const [loadingCities, setLoadingCities] = useState(false); @@ -64,9 +57,7 @@ export default function BookAppointment({ const [isOpenPopover, setIsOpenPopover] = useState(false); const [isOpenHospitalPopover, setIsOpenHospitalPopover] = useState(false); const [isOpenDiseasePopover, setIsOpenDiseasePopover] = useState(false); - const [hospitals, setHospitals] = useState< - { hospital_id: string; hospital_name: string; appointment_charge: string }[] - >([]); + const [hospitals, setHospitals] = useState([]); const [diseases, setDiseases] = useState([]); const [additionalNote, setAdditionalNote] = useState(""); const [noteError, setNoteError] = useState(""); @@ -171,9 +162,8 @@ export default function BookAppointment({ function handleHospitalChange(e: ChangeEvent): void { const selectedId = e.target.value; - const selectedHospitalObj: Hospital | undefined = hospitals.find( - (hospital) => hospital.hospital_id === selectedId - ); + const selectedHospitalObj: BookAppointmentHospital | undefined = + hospitals.find((hospital) => hospital.hospital_id === selectedId); if (selectedHospitalObj) { setSelectedHospital({ @@ -255,7 +245,7 @@ export default function BookAppointment({ return; } clearSelected(); - toast.success(response.msg); + toast.success(response.message); } function clearSelected() { diff --git a/app/(pages)/patient/components/MedicalDetails/index.tsx b/app/(pages)/patient/components/MedicalDetails/index.tsx index a97c5060..70e68b6a 100644 --- a/app/(pages)/patient/components/MedicalDetails/index.tsx +++ b/app/(pages)/patient/components/MedicalDetails/index.tsx @@ -1,6 +1,6 @@ "use client"; -import { MedicalHistory } from "@pft-types/index"; +import { MedicalDetailsProps } from "@pft-types/index"; import { Chip, Spinner, @@ -14,10 +14,6 @@ import { } from "@nextui-org/react"; import { getFormattedDate } from "@utils/getDate"; -type MedicalDetailsProps = { - medicalDetails: MedicalHistory[]; -}; - export default function MedicalDetails({ medicalDetails, }: MedicalDetailsProps) { diff --git a/app/(pages)/patient/components/PaymentDetails/index.tsx b/app/(pages)/patient/components/PaymentDetails/index.tsx index ef6fa83f..af76f961 100644 --- a/app/(pages)/patient/components/PaymentDetails/index.tsx +++ b/app/(pages)/patient/components/PaymentDetails/index.tsx @@ -10,24 +10,7 @@ import { TransactionsTable, } from "@components/index"; import useFilterTransaction from "@hooks/useFilterTransaction"; - -type Hospital = { - name: string; - profile: string; -}; - -type Payment = { - hospital: Hospital; - disease: string; - description: string; - date: string; - amount: number; - status: "Success" | "Failed"; -}; - -type PaymentDetailsProps = { - paymentHistory: Payment[]; -}; +import { Payment, PaymentDetailsProps } from "@pft-types/patient"; const statusColorMap: any = { Failed: "danger", diff --git a/app/(pages)/patient/layout.tsx b/app/(pages)/patient/layout.tsx index 184e38b3..236da89c 100644 --- a/app/(pages)/patient/layout.tsx +++ b/app/(pages)/patient/layout.tsx @@ -1,6 +1,5 @@ import Script from "next/script"; import { Sidebar, Headbar } from "@components/index"; -import { Patient } from "@pft-types/index"; import { getPatientData } from "@lib/patient"; import type { Metadata } from "next"; @@ -15,7 +14,7 @@ export default async function PatientLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const patient: Patient = await getPatientData(); + const patient = await getPatientData(); return (
diff --git a/app/(pages)/patient/page.tsx b/app/(pages)/patient/page.tsx index 21659f56..b45f6418 100644 --- a/app/(pages)/patient/page.tsx +++ b/app/(pages)/patient/page.tsx @@ -5,14 +5,12 @@ import { MedicineDetails, HealthConditions, } from "./components"; -import { Patient, bookedAppointments } from "@pft-types/index"; import { getPatientData, getUpcomingAppointments } from "@lib/patient"; export default async function PatientPage() { - const patient: Patient = await getPatientData(); + const patient = await getPatientData(); - const upcomingAppointments: bookedAppointments = - await getUpcomingAppointments(); + const upcomingAppointments = await getUpcomingAppointments(); return (
diff --git a/app/(pages)/patient/qrcode/page.tsx b/app/(pages)/patient/qrcode/page.tsx index ba9aeae5..b86d771b 100644 --- a/app/(pages)/patient/qrcode/page.tsx +++ b/app/(pages)/patient/qrcode/page.tsx @@ -1,10 +1,9 @@ import { getPatientData } from "@lib/patient"; -import { Patient } from "@pft-types/index"; import { Card, Link, User } from "@nextui-org/react"; import { QRCode } from "../components"; export default async function QRCodePage() { - const patient: Patient = await getPatientData(); + const patient = await getPatientData(); return ( diff --git a/app/(pages)/receptionist/components/PatientTabs/index.tsx b/app/(pages)/receptionist/components/PatientTabs/index.tsx index c005fb64..dd266af0 100644 --- a/app/(pages)/receptionist/components/PatientTabs/index.tsx +++ b/app/(pages)/receptionist/components/PatientTabs/index.tsx @@ -54,11 +54,9 @@ export default function PatientTabs({ pendingAppointments }: PatientTabsProps) { try { const response = await approveAppointment(selectedPatient?._id ?? ""); - if (response.error) { - throw new Error(response.error); + if (response) { + toast.success("Appointment approved successfully"); } - - toast.success("Appointment approved successfully"); } catch (error) { console.error("Error approving appointment:", error); } diff --git a/app/(pages)/receptionist/page.tsx b/app/(pages)/receptionist/page.tsx index 67d38027..246878df 100644 --- a/app/(pages)/receptionist/page.tsx +++ b/app/(pages)/receptionist/page.tsx @@ -17,7 +17,6 @@ import { BsClock, BsCalendarCheck, } from "react-icons/bs"; -import { Receptionist } from "@pft-types/index"; import { getReceptionistData, getPendingAppointments } from "@lib/receptionist"; import { MonthlyVisitors, @@ -28,22 +27,8 @@ import { } from "./components/Graphs"; export default async function ReceptionistPage() { - interface PatientDetail { - id: string; - name: string; - appointmentTime: string; - reason: string; - contactNumber: string; - email?: string; - } - - interface PendingPatients { - patientDetails: PatientDetail[]; - totalCount: number; - } - - const receptionist: Receptionist = await getReceptionistData(); - const pendingPatients: PendingPatients = await getPendingAppointments(); + const receptionist = await getReceptionistData(); + const pendingPatients = await getPendingAppointments(); const pendingAppointments = pendingPatients.patientDetails.length; const approvedAppointments = receptionist.dailyCount.approved; diff --git a/app/(pages)/session-expired/page.tsx b/app/(pages)/session-expired/page.tsx index 62d86211..9603fa2e 100644 --- a/app/(pages)/session-expired/page.tsx +++ b/app/(pages)/session-expired/page.tsx @@ -1,15 +1,30 @@ "use client"; -import React, { useState, useEffect, Suspense } from "react"; -import { useRouter, useSearchParams } from "next/navigation"; -import { Image } from "@nextui-org/react"; +import React, { useState, useEffect } from "react"; +import { useRouter } from "next/navigation"; +import Image from "next/image"; +import { Suspense } from "react"; import SpinnerLoader from "@components/SpinnerLoader"; export default function SessionExpired() { + return ( + }> + + + ); +} + +function SessionExpiredContent() { const router = useRouter(); - const searchParams = useSearchParams(); const [secondsRemaining, setSecondsRemaining] = useState(5); - const role = searchParams.get("role"); + const [role, setRole] = useState(null); + + useEffect(() => { + // fetch the role from URL parameters + const params = new URLSearchParams(window.location.search); + const roleParam = params.get("role"); + setRole(roleParam); + }, []); useEffect(() => { if (secondsRemaining <= 0) { @@ -30,36 +45,36 @@ export default function SessionExpired() { }; return ( - }> -
-
- error-image -
-
-

SESSION EXPIRED

-

- {secondsRemaining > 0 ? ( - <> - You will be redirected to the login page in {secondsRemaining}{" "} - second{secondsRemaining !== 1 ? "s" : ""}.{" "} - - ) : ( - "Redirecting to login page... " - )} - {" "} - if not redirected. -

-
+
+
+ error-image
- +
+

SESSION EXPIRED

+

+ {secondsRemaining > 0 ? ( + <> + You will be redirected to the login page in {secondsRemaining}{" "} + second{secondsRemaining !== 1 ? "s" : ""}.{" "} + + ) : ( + "Redirecting to login page... " + )} + {" "} + if not redirected. +

+
+
); } diff --git a/app/api/admin/add-admin/route.ts b/app/api/admin/add-admin/route.ts index 34d900e3..7474a02c 100644 --- a/app/api/admin/add-admin/route.ts +++ b/app/api/admin/add-admin/route.ts @@ -1,11 +1,13 @@ -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { NextResponse } from "next/server"; import Admin from "@models/admin"; -import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; -import hashPassword from "@utils/hashPassword"; -import { NewAdminTemplate } from "@lib/emails/templates"; +import { + dbConfig, + errorHandler, + hashPassword, + STATUS_CODES, +} from "@utils/index"; +import { authenticateUser, NewAdminTemplate, sendEmail } from "@lib/index"; import { render } from "@react-email/render"; -import sendEmail from "@lib/sendemail"; -import { NextResponse } from "next/server"; export async function POST(request: Request) { const authHeader = request.headers.get("Authorization"); diff --git a/app/api/admin/dashboard/recent-users/route.ts b/app/api/admin/dashboard/recent-users/route.ts index 1cc2f46c..779d85ab 100644 --- a/app/api/admin/dashboard/recent-users/route.ts +++ b/app/api/admin/dashboard/recent-users/route.ts @@ -1,16 +1,20 @@ -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { NextResponse } from "next/server"; import mongoose from "mongoose"; +import authenticateUser from "@lib/auth/authenticateUser"; import { FormattedRecentUser, RecentUserTile, RecentUserPaginatedResponse, } from "@pft-types/admin"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; -import { NextResponse } from "next/server"; export async function GET(request: Request): Promise { const authHeader = request.headers.get("Authorization"); + const url = new URL(request.url); + const page = parseInt(url.searchParams.get("page") || "1"); + const limit = parseInt(url.searchParams.get("limit") || "10"); + try { const { id, role } = await authenticateUser(authHeader); @@ -18,10 +22,6 @@ export async function GET(request: Request): Promise { return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } - const url = new URL(request.url); - const page = parseInt(url.searchParams.get("page") || "1"); - const limit = parseInt(url.searchParams.get("limit") || "10"); - await dbConfig(); const oneMonthAgo = new Date(); diff --git a/app/api/admin/dashboard/tiles/route.ts b/app/api/admin/dashboard/tiles/route.ts index 5e05ffc9..16167da7 100644 --- a/app/api/admin/dashboard/tiles/route.ts +++ b/app/api/admin/dashboard/tiles/route.ts @@ -1,8 +1,7 @@ -import dbConfig from "@utils/db"; import { Hospital, Patient, Doctor, Receptionist } from "@models/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import authenticateUser from "@lib/auth/authenticateUser"; import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; export async function GET(request: Request) { const authHeader = request.headers.get("Authorization"); diff --git a/app/api/admin/hospitals/route.ts b/app/api/admin/hospitals/route.ts index 233c9e27..d674e652 100644 --- a/app/api/admin/hospitals/route.ts +++ b/app/api/admin/hospitals/route.ts @@ -1,14 +1,20 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import Hospital from "@models/hospital"; import { HospitalDetails } from "@pft-types/admin"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; +import authenticateUser from "@lib/auth/authenticateUser"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); + + // parse query parameters for pagination + const url = new URL(request.url); + const page = parseInt(url.searchParams.get("page") || "1"); + const limit = parseInt(url.searchParams.get("limit") || "10"); + const skip = (page - 1) * limit; + try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { @@ -19,12 +25,6 @@ export async function GET(request: Request) { await dbConfig(); - // Parse query parameters for pagination - const url = new URL(request.url); - const page = parseInt(url.searchParams.get("page") || "1"); - const limit = parseInt(url.searchParams.get("limit") || "10"); - const skip = (page - 1) * limit; - // Count total hospitals before applying skip and limit const totalHospitals = await Hospital.countDocuments(); let hospitals = []; diff --git a/app/api/admin/hospitals/users/route.ts b/app/api/admin/hospitals/users/route.ts index f46f0cae..2a9eada4 100644 --- a/app/api/admin/hospitals/users/route.ts +++ b/app/api/admin/hospitals/users/route.ts @@ -1,14 +1,22 @@ -import dbConfig from "@utils/db"; import { Patient, Receptionist, Hospital, Doctor } from "@models/index"; import { HospitalUserDetails } from "@pft-types/admin"; import { Types } from "mongoose"; import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; +import authenticateUser from "@lib/auth/authenticateUser"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); + + // parse query parameters for pagination + const url = new URL(request.url); + const page = parseInt(url.searchParams.get("page") || "1"); + const limit = parseInt(url.searchParams.get("limit") || "10"); + const skip = (page - 1) * limit; + + const hospitalId = url.searchParams.get("hospitalId"); + try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { @@ -17,14 +25,6 @@ export async function GET(request: Request) { await dbConfig(); - // Parse query parameters for pagination - const url = new URL(request.url); - const page = parseInt(url.searchParams.get("page") || "1"); - const limit = parseInt(url.searchParams.get("limit") || "10"); - const skip = (page - 1) * limit; - - const hospitalId = url.searchParams.get("hospitalId"); - if (!hospitalId) { return errorHandler("hospitalId is required", STATUS_CODES.BAD_REQUEST); } diff --git a/app/api/admin/route.ts b/app/api/admin/route.ts index b704e936..ed95e328 100644 --- a/app/api/admin/route.ts +++ b/app/api/admin/route.ts @@ -1,8 +1,8 @@ -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { NextResponse } from "next/server"; +import authenticateUser from "@lib/auth/authenticateUser"; import Admin from "@models/admin"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; export async function GET(request: Request) { const authHeader = request.headers.get("Authorization"); diff --git a/app/api/admin/transactions/route.ts b/app/api/admin/transactions/route.ts index eb7f2a05..ea9bcb4e 100644 --- a/app/api/admin/transactions/route.ts +++ b/app/api/admin/transactions/route.ts @@ -1,14 +1,13 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import { Admin, Hospital, Patient, Transaction } from "@models/index"; import { TransactionDetails } from "@pft-types/index"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; +import authenticateUser from "@lib/auth/authenticateUser"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { diff --git a/app/api/auth/login/route.ts b/app/api/auth/login/route.ts index c46b0635..f95999f5 100644 --- a/app/api/auth/login/route.ts +++ b/app/api/auth/login/route.ts @@ -1,8 +1,14 @@ -import { OtpTemplate } from "@lib/emails/templates"; -import sendEmail from "@lib/sendemail"; +import { NextResponse } from "next/server"; +import { OtpTemplate, sendEmail } from "@lib/index"; import { render } from "@react-email/render"; -import { dbConfig, generateSecureOTP, getModelByRole } from "@utils/index"; -import { allowedRoles } from "@constants/index"; +import { + dbConfig, + errorHandler, + generateSecureOTP, + getModelByRole, + STATUS_CODES, + allowedRoles, +} from "@utils/index"; import bcrypt from "bcrypt"; type LoginBody = { @@ -12,31 +18,25 @@ type LoginBody = { }; export async function POST(req: Request) { - try { - const body: LoginBody = await req.json(); + const body: LoginBody = await req.json(); - if (!body || !body.usernameOrEmail || !body.password || !body.role) { - return Response.json( - { - error: - "Invalid request body. Please provide username or email, password, and role.", - }, - { status: 400 } - ); - } + if (!body || !body.usernameOrEmail || !body.password || !body.role) { + return errorHandler( + "Invalid request body. Please provide username or email, password, and role.", + STATUS_CODES.BAD_REQUEST + ); + } - if (!allowedRoles.includes(body.role)) { - return Response.json( - { error: "User role isn't valid." }, - { status: 400 } - ); - } + if (!allowedRoles.includes(body.role)) { + return errorHandler("User role isn't valid.", STATUS_CODES.BAD_REQUEST); + } + try { const result = await setOTP(body); return result; - } catch (error) { + } catch (error: any) { console.error("Error during login: ", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } @@ -56,18 +56,17 @@ async function setOTP(loginBody: LoginBody) { ); if (!user || !(await bcrypt.compare(loginBody.password, user.password))) { - return Response.json( - { error: "Invalid username/email or password" }, - { status: 401 } + return errorHandler( + "Invalid username/email or password", + STATUS_CODES.UNAUTHORIZED ); } const generatedOTP = generateSecureOTP(); - user.otp = generatedOTP; await user.save(); - const mailsent = await sendEmail({ + const mailSent = await sendEmail({ to: user.email, subject: "OTP Verification", html: render(OtpTemplate(user.firstname, generatedOTP)), @@ -77,6 +76,9 @@ async function setOTP(loginBody: LoginBody) { }, }); - if (!mailsent) return Response.json({ error: "Email Sending Failed" }); - return Response.json({ message: "ok" }, { status: 201 }); + if (!mailSent) { + return errorHandler("Email Sending Failed", STATUS_CODES.SERVER_ERROR); + } + + return NextResponse.json({ message: "ok" }, { status: 201 }); } diff --git a/app/api/auth/signup/route.ts b/app/api/auth/signup/route.ts index 1dc00083..44b30f0b 100644 --- a/app/api/auth/signup/route.ts +++ b/app/api/auth/signup/route.ts @@ -1,5 +1,5 @@ -import { OtpTemplate } from "@lib/emails/templates"; -import sendEmail from "@lib/sendemail"; +import { NextResponse } from "next/server"; +import { OtpTemplate, sendEmail } from "@lib/index"; import { render } from "@react-email/render"; import { allowedRoles, @@ -13,6 +13,8 @@ import { generateSecureOTP, getModelByRole, hashPassword, + STATUS_CODES, + errorHandler, } from "@utils/index"; type SignupBody = { @@ -29,24 +31,21 @@ export async function POST(req: Request) { const body: SignupBody = await req.json(); if (checkMissingElements(body)) { - return Response.json( - { error: "Missing required fields in the request body" }, - { status: 400 } + return errorHandler( + "Missing required fields in the request body", + STATUS_CODES.BAD_REQUEST ); } if (!allowedRoles.includes(body.role)) { - return Response.json( - { error: "User role isn't valid." }, - { status: 400 } - ); + return errorHandler("User role isn't valid.", STATUS_CODES.BAD_REQUEST); } const result = await createAccount(body); return result; - } catch (error) { + } catch (error: any) { console.error("Error during signup:", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } @@ -61,20 +60,15 @@ async function createAccount(signupBody: SignupBody) { if (existingUser) { if (existingUser.email === signupBody.email) { - return Response.json({ error: "Email already exists" }, { status: 409 }); + return errorHandler("Email already exists", STATUS_CODES.CONFLICT); } if (existingUser.username === signupBody.username) { - return Response.json( - { error: "Username already exists" }, - { status: 409 } - ); + return errorHandler("Username already exists", STATUS_CODES.CONFLICT); } } - // gets the additional details based on the user's role - let additionalDetails = getAdditionalDetails(signupBody.role); - + const additionalDetails = getAdditionalDetails(signupBody.role); const hashedPassword = await hashPassword(signupBody.password); const newUser = new UserModel({ @@ -84,7 +78,6 @@ async function createAccount(signupBody: SignupBody) { }); const savedUser = await newUser.save(); - const generatedOTP = generateSecureOTP(); await savedUser.updateOne( @@ -92,7 +85,7 @@ async function createAccount(signupBody: SignupBody) { { $set: { otp: generatedOTP } } ); - const mailsent = await sendEmail({ + const mailSent = await sendEmail({ to: savedUser.email, subject: "Verification of OTP for Account Creation", html: render(OtpTemplate(savedUser.firstname, generatedOTP)), @@ -102,8 +95,14 @@ async function createAccount(signupBody: SignupBody) { }, }); - if (!mailsent) return Response.json({ error: "Signup email sending failed" }); - return Response.json( + if (!mailSent) { + return errorHandler( + "Signup email sending failed", + STATUS_CODES.SERVER_ERROR + ); + } + + return NextResponse.json( { message: "Account created successfully" }, { status: 201 } ); @@ -133,5 +132,7 @@ function getAdditionalDetails(role: string) { return doctoradditionalDetails; case "hospital": return hospitaladditionalDetails; + default: + return {}; } } diff --git a/app/api/auth/verifyotp/route.ts b/app/api/auth/verifyotp/route.ts index 51dd8e82..0605a380 100644 --- a/app/api/auth/verifyotp/route.ts +++ b/app/api/auth/verifyotp/route.ts @@ -1,7 +1,13 @@ +import { NextResponse } from "next/server"; import { setSession } from "@sessions/sessionUtils"; -import { dbConfig, getModelByRole } from "@utils/index"; -import { allowedRoles } from "@constants/index"; import logUserActivity from "@lib/logs"; +import { + allowedRoles, + dbConfig, + errorHandler, + getModelByRole, + STATUS_CODES, +} from "@utils/index"; type bodyType = { usernameOrEmail: string; @@ -21,29 +27,24 @@ export async function POST(req: Request) { !body.action || !body.otp ) { - return Response.json( - { - error: - "Username/Email, OTP, action and role are required fields in the request body.", - }, - { status: 400 } + return errorHandler( + "Username/Email, OTP, action, and role are required fields in the request body.", + STATUS_CODES.BAD_REQUEST ); } if (!allowedRoles.includes(body.role)) { - return Response.json( - { error: "User role isn't valid." }, - { status: 400 } - ); + return errorHandler("User role isn't valid.", STATUS_CODES.BAD_REQUEST); } const result = await checkOTP(body, req); return result; } catch (error) { - console.error("Error during otp verification:", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + console.error("Error during OTP verification:", error); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } + async function checkOTP(body: bodyType, req: Request) { await dbConfig(); @@ -59,8 +60,9 @@ async function checkOTP(body: bodyType, req: Request) { { _id: 1, username: 1, firstname: 1, lastname: 1, otp: 1, email: 1 } ); - if (!user || user.otp !== body.otp) - return Response.json({ error: "OTP Verification Failed" }, { status: 401 }); + if (!user || user.otp !== body.otp) { + return errorHandler("OTP Verification Failed", STATUS_CODES.UNAUTHORIZED); + } await UserModel.updateOne({ email: user.email }, { $set: { otp: "" } }); @@ -78,5 +80,5 @@ async function checkOTP(body: bodyType, req: Request) { // storing user logs in db await logUserActivity(userlog, req); - return Response.json({ message: "ok" }, { status: 200 }); + return NextResponse.json({ message: "ok" }, { status: 200 }); } diff --git a/app/api/city/route.ts b/app/api/city/route.ts index a52d5e5a..eecb25cc 100644 --- a/app/api/city/route.ts +++ b/app/api/city/route.ts @@ -1,12 +1,17 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import CityStateHospital from "@models/citystate_hospitals"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; export async function GET(req: Request) { const { searchParams } = new URL(req.url); const state = searchParams.get("state"); + try { if (!state) { - return new Response("State parameter is missing", { status: 400 }); + return errorHandler( + "State parameter is missing", + STATUS_CODES.BAD_REQUEST + ); } await dbConfig(); @@ -15,19 +20,22 @@ export async function GET(req: Request) { }); if (!stateDocument) { - return new Response("State not found", { status: 404 }); + return errorHandler("State not found", STATUS_CODES.NOT_FOUND); } // Get the cities for the given state const cities = Object.keys(stateDocument.get(state)); if (cities.length === 0) { - return Response.json(cities, { status: 404 }); + return errorHandler( + "No cities found for the given state", + STATUS_CODES.NOT_FOUND + ); } - return Response.json(cities, { status: 201 }); + return NextResponse.json(cities, { status: 200 }); } catch (error) { console.error("Error fetching state and city data:", error); - return new Response("Internal Server Error", { status: 500 }); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/api/cloudinary/sign-image/route.ts b/app/api/cloudinary/sign-image/route.ts index 0ba41308..06dc1d39 100644 --- a/app/api/cloudinary/sign-image/route.ts +++ b/app/api/cloudinary/sign-image/route.ts @@ -1,5 +1,5 @@ +import { NextRequest, NextResponse } from "next/server"; import { v2 as cloudinary } from "cloudinary"; -import { NextRequest } from "next/server"; export async function POST(request: NextRequest) { const body = (await request.json()) as { @@ -12,5 +12,5 @@ export async function POST(request: NextRequest) { process.env.CLOUDINARY_API_SECRET as string ); - return Response.json({ signature }); + return NextResponse.json({ signature }); } diff --git a/app/api/demouser/route.ts b/app/api/demouser/route.ts index 6c7a5baf..f14b8843 100644 --- a/app/api/demouser/route.ts +++ b/app/api/demouser/route.ts @@ -1,8 +1,13 @@ -import dbConfig from "@utils/db"; -import logUserActivity from "@lib/logs"; +import { NextResponse } from "next/server"; import DemoUser from "@models/demouser"; -import getModelByRole from "@utils/getModelByRole"; import { setSession } from "@sessions/sessionUtils"; +import logUserActivity from "@lib/logs"; +import { + dbConfig, + errorHandler, + getModelByRole, + STATUS_CODES, +} from "@utils/index"; export async function POST(req: Request) { await dbConfig(); @@ -10,14 +15,11 @@ export async function POST(req: Request) { try { const { role } = await req.json(); - // Validate the incoming body + // validate the incoming body if (!role || typeof role !== "string") { - return Response.json( - { - success: false, - error: "Invalid request body. Please provide a valid role.", - }, - { status: 400 } + return errorHandler( + "Invalid request body. Please provide a valid role.", + STATUS_CODES.BAD_REQUEST ); } @@ -25,32 +27,23 @@ export async function POST(req: Request) { const demoUser = await DemoUser.findOne({ role }); if (!demoUser) { - return Response.json( - { - success: false, - error: "Demo user not found for this role", - }, - { status: 404 } + return errorHandler( + "Demo user not found for this role", + STATUS_CODES.NOT_FOUND ); } - // get a usermodel with matching role + // get a user model with matching role const UserModel = getModelByRole(role); - // find a user which have same ObjectId as demousers + // find a user which has the same ObjectId as demo users const userData = await UserModel.findById(demoUser.referenceId); if (!userData) { - return Response.json( - { - success: false, - error: "Demo user data not found", - }, - { status: 404 } - ); + return errorHandler("Demo user data not found", STATUS_CODES.NOT_FOUND); } - // setting session for demouser (stores jwt token in cookie named session) + // setting session for demo user (stores jwt token in cookie named session) await setSession(userData._id, role); const userLog = { @@ -64,7 +57,7 @@ export async function POST(req: Request) { // log activity await logUserActivity(userLog, req); - return Response.json( + return NextResponse.json( { success: true, message: "Demo User logged in successfully.", @@ -73,12 +66,6 @@ export async function POST(req: Request) { ); } catch (error) { console.error("Error during login: ", error); - return Response.json( - { - success: false, - error: "Internal Server Error", - }, - { status: 500 } - ); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/api/doctor/route.ts b/app/api/doctor/route.ts index d25b8c79..c450af3f 100644 --- a/app/api/doctor/route.ts +++ b/app/api/doctor/route.ts @@ -1,34 +1,32 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import Doctor from "@models/doctor"; import { Types } from "mongoose"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; +import authenticateUser from "@lib/auth/authenticateUser"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); + try { - const id = request.headers.get("x-user-id"); - const role = request.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } const doctor_id = new Types.ObjectId(id); await dbConfig(); - // const projection = {}; { projection } - const doctorData = await Doctor.findById(doctor_id); if (!doctorData) { - return Response.json({ error: "Doctor not found" }, { status: 404 }); + return NextResponse.json({ error: "Doctor not found" }, { status: 404 }); } - return Response.json(doctorData); + return NextResponse.json(doctorData); } catch (error) { console.error("Error fetching Doctor data:", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/api/gethospitals/disease/route.ts b/app/api/gethospitals/disease/route.ts index 5513b027..620495c3 100644 --- a/app/api/gethospitals/disease/route.ts +++ b/app/api/gethospitals/disease/route.ts @@ -1,5 +1,6 @@ +import { NextResponse } from "next/server"; import CommonDiseases from "@models/commonDisease"; -import dbConfig from "@utils/db"; +import { dbConfig, errorHandler, STATUS_CODES } from "@/utils"; export async function GET() { try { @@ -8,17 +9,17 @@ export async function GET() { const result = await CommonDiseases.findOne(); if (!result) { - return Response.json( - { error: "error no common diseases found" }, - { status: 200 } + return errorHandler( + "error no common diseases found", + STATUS_CODES.BAD_REQUEST ); } const commonDiseases = result.commonDiseases; - return Response.json(commonDiseases, { status: 200 }); + return NextResponse.json(commonDiseases, { status: 200 }); } catch (error) { console.error("Error while getting common diseases:", error); - return new Response("Internal Server Error", { status: 500 }); + return new NextResponse("Internal Server Error", { status: 500 }); } } diff --git a/app/api/gethospitals/route.ts b/app/api/gethospitals/route.ts index 56bbb83f..81d616da 100644 --- a/app/api/gethospitals/route.ts +++ b/app/api/gethospitals/route.ts @@ -1,16 +1,19 @@ +import { NextResponse } from "next/server"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import CityStateHospital from "@models/citystate_hospitals"; -import dbConfig from "@utils/db"; export async function GET(req: Request) { const { searchParams } = new URL(req.url); const state = searchParams.get("state"); const city = searchParams.get("city"); + try { if (!state || !city) { - return new Response("State or city parameter is missing", { - status: 400, - }); + return errorHandler( + "State or city parameter is missing", + STATUS_CODES.BAD_REQUEST + ); } await dbConfig(); @@ -20,25 +23,27 @@ export async function GET(req: Request) { }); if (!stateHospitals) { - return new Response("No hospitals found for the specified state", { - status: 404, - }); + return errorHandler( + "No hospitals found for the specified state", + STATUS_CODES.NOT_FOUND + ); } const cityHospitals = stateHospitals.get(state)[city]; if (!cityHospitals) { - return new Response("No hospitals found in the specified city", { - status: 404, - }); + return errorHandler( + "No hospitals found in the specified city", + STATUS_CODES.NOT_FOUND + ); } - return new Response(JSON.stringify(cityHospitals), { status: 200 }); + return NextResponse.json(cityHospitals, { status: 200 }); } catch (error) { console.error( - "Error while fetching hospitals for booking appointments : ", + "Error while fetching hospitals for booking appointments: ", error ); - return new Response("Internal Server Error", { status: 500 }); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/api/hospital/route.ts b/app/api/hospital/route.ts index 14c62e86..4c53feb7 100644 --- a/app/api/hospital/route.ts +++ b/app/api/hospital/route.ts @@ -1,34 +1,32 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import Hospital from "@models/hospital"; import { Types } from "mongoose"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; +import { authenticateUser } from "@lib/auth"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); + try { - const id = request.headers.get("x-user-id"); - const role = request.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } const hospital_id = new Types.ObjectId(id); await dbConfig(); - // const projection = {}; { projection } - const hospitalData = await Hospital.findById(hospital_id); if (!hospitalData) { - return Response.json({ error: "Hospital not found" }, { status: 404 }); + return errorHandler("Hospital not found", STATUS_CODES.NOT_FOUND); } - return Response.json(hospitalData); + return NextResponse.json(hospitalData, { status: 200 }); } catch (error) { console.error("Error fetching Hospital data:", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/api/patient/appointment/pending/route.ts b/app/api/patient/appointment/pending/route.ts index 4a8dbb62..a58700b1 100644 --- a/app/api/patient/appointment/pending/route.ts +++ b/app/api/patient/appointment/pending/route.ts @@ -1,13 +1,13 @@ +import { NextResponse } from "next/server"; import { Patient, BookedAppointment } from "@models/index"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { authenticateUser } from "@lib/auth"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; export async function POST(req: Request) { + const authHeader = req.headers.get("Authorization"); try { const { hospital_id }: { hospital_id: string } = await req.json(); - const authHeader = req.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); diff --git a/app/api/patient/appointment/route.ts b/app/api/patient/appointment/route.ts index 9ba5c5e9..37e895cb 100644 --- a/app/api/patient/appointment/route.ts +++ b/app/api/patient/appointment/route.ts @@ -1,18 +1,20 @@ -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { NextResponse } from "next/server"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import { Types } from "mongoose"; -import sendEmail from "@lib/sendemail"; import { render } from "@react-email/render"; -import { AppointmentBookedTemplate } from "@lib/emails/templates"; -import sendNotification from "@lib/novu"; +import { + authenticateUser, + AppointmentBookedTemplate, + sendEmail, + sendNotification, +} from "@lib/index"; import { Patient, BookedAppointment, Doctor } from "@models/index"; import { BookingAppointmentType } from "@pft-types/patient"; -import { NextResponse } from "next/server"; // getting patient's approved appointments export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { @@ -66,6 +68,8 @@ export async function GET(request: Request) { // booking an appointment export async function POST(req: Request) { + const authHeader = req.headers.get("Authorization"); + try { const { state, @@ -77,7 +81,6 @@ export async function POST(req: Request) { appointment_charge, }: BookingAppointmentType = await req.json(); - const authHeader = req.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { @@ -152,7 +155,7 @@ export async function POST(req: Request) { ); return NextResponse.json( - { msg: "Appointment request added successfully" }, + { message: "Appointment request added successfully" }, { status: 200 } ); } catch (error: any) { diff --git a/app/api/patient/medicalhistory/route.ts b/app/api/patient/medicalhistory/route.ts index 2e3da3e9..2a5a41a7 100644 --- a/app/api/patient/medicalhistory/route.ts +++ b/app/api/patient/medicalhistory/route.ts @@ -1,12 +1,13 @@ +import { NextResponse } from "next/server"; import { Patient, MedicalHistory } from "@models/index"; import { Types } from "mongoose"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; -import { NextResponse } from "next/server"; +import { authenticateUser } from "@lib/auth"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); try { - const id = request.headers.get("x-user-id"); - const role = request.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); diff --git a/app/api/patient/paymenthistory/route.ts b/app/api/patient/paymenthistory/route.ts index 7346e7c5..2f0b7303 100644 --- a/app/api/patient/paymenthistory/route.ts +++ b/app/api/patient/paymenthistory/route.ts @@ -1,12 +1,13 @@ +import { NextResponse } from "next/server"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import { Patient, Transaction } from "@models/index"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; +import { authenticateUser } from "@lib/auth"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); try { - const id = request.headers.get("x-user-id"); - const role = request.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); diff --git a/app/api/patient/route.ts b/app/api/patient/route.ts index 1c5a9ff3..1b131f50 100644 --- a/app/api/patient/route.ts +++ b/app/api/patient/route.ts @@ -1,8 +1,8 @@ +import { NextResponse } from "next/server"; import Patient from "@models/patient"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { authenticateUser } from "@lib/auth"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; export async function GET(request: Request) { const authHeader = request.headers.get("Authorization"); diff --git a/app/api/payment/create-order/route.ts b/app/api/payment/create-order/route.ts index 19261324..6ec121fe 100644 --- a/app/api/payment/create-order/route.ts +++ b/app/api/payment/create-order/route.ts @@ -1,4 +1,4 @@ -import { NextRequest } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import { razorpay } from "@lib/razorpay"; export async function POST(request: NextRequest) { @@ -13,5 +13,5 @@ export async function POST(request: NextRequest) { receipt: "rcp1", }; const order = await razorpay.orders.create(options); - return Response.json({ orderId: order.id }, { status: 200 }); + return NextResponse.json({ orderId: order.id }, { status: 200 }); } diff --git a/app/api/payment/verify/route.ts b/app/api/payment/verify/route.ts index 55f8ce62..fa5a9cf8 100644 --- a/app/api/payment/verify/route.ts +++ b/app/api/payment/verify/route.ts @@ -1,5 +1,6 @@ -import { NextRequest } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import crypto from "crypto"; +import { errorHandler, STATUS_CODES } from "@utils/index"; const generatedSignature = ( razorpayOrderId: string, @@ -11,26 +12,34 @@ const generatedSignature = ( "Razorpay key secret is not defined in environment variables." ); } - const sig = crypto + return crypto .createHmac("sha256", keySecret) - .update(razorpayOrderId + "|" + razorpayPaymentId) + .update(`${razorpayOrderId}|${razorpayPaymentId}`) .digest("hex"); - return sig; }; export async function POST(request: NextRequest) { - const { orderCreationId, razorpayPaymentId, razorpaySignature } = - await request.json(); + try { + const { orderCreationId, razorpayPaymentId, razorpaySignature } = + await request.json(); - const signature = generatedSignature(orderCreationId, razorpayPaymentId); - if (signature !== razorpaySignature) { - return Response.json( - { message: "payment verification failed", isOk: false }, - { status: 400 } + const signature = generatedSignature(orderCreationId, razorpayPaymentId); + if (signature !== razorpaySignature) { + return errorHandler( + "Payment verification failed", + STATUS_CODES.BAD_REQUEST + ); + } + + return NextResponse.json( + { message: "Payment verified successfully", isOk: true }, + { status: 200 } + ); + } catch (error: any) { + console.error("Error during payment verification:", error); + return errorHandler( + error.message || "Internal Server Error", + STATUS_CODES.SERVER_ERROR ); } - return Response.json( - { message: "payment verified successfully", isOk: true }, - { status: 200 } - ); } diff --git a/app/api/receptionist/appointments/approve/route.ts b/app/api/receptionist/appointments/approve/route.ts index 3efeb2ba..7dd9398c 100644 --- a/app/api/receptionist/appointments/approve/route.ts +++ b/app/api/receptionist/appointments/approve/route.ts @@ -1,14 +1,17 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import { BookedAppointment, Receptionist } from "@models/index"; import { Types } from "mongoose"; -import { authenticateUser } from "@lib/auth/authenticateUser"; -import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; +import { authenticateUser } from "@lib/auth"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; -// Get approved appointments +// get approved appointments export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); + + const { searchParams } = new URL(request.url); + const patient_id = searchParams.get("patient_id"); + try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { @@ -16,8 +19,6 @@ export async function GET(request: Request) { } const receptionist_id = new Types.ObjectId(id); - const { searchParams } = new URL(request.url); - const patient_id = searchParams.get("patient_id"); if (!patient_id) { return errorHandler("Patient ID is required", STATUS_CODES.BAD_REQUEST); @@ -39,11 +40,12 @@ export async function GET(request: Request) { } } -// Approving appointments +// approving appointments export async function POST(request: Request) { + const authHeader = request.headers.get("Authorization"); + try { const { patient_id } = await request.json(); - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { diff --git a/app/api/receptionist/appointments/pending/route.ts b/app/api/receptionist/appointments/pending/route.ts index a725183b..61f18e0c 100644 --- a/app/api/receptionist/appointments/pending/route.ts +++ b/app/api/receptionist/appointments/pending/route.ts @@ -1,13 +1,12 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import { Patient, BookedAppointment, Receptionist } from "@models/index"; import { Types } from "mongoose"; -import { authenticateUser } from "@lib/auth/authenticateUser"; -import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; +import { authenticateUser } from "@lib/auth"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { diff --git a/app/api/receptionist/route.ts b/app/api/receptionist/route.ts index 754ffb17..2b0a86f2 100644 --- a/app/api/receptionist/route.ts +++ b/app/api/receptionist/route.ts @@ -1,12 +1,12 @@ -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { NextResponse } from "next/server"; +import authenticateUser from "@lib/auth/authenticateUser"; import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import Receptionist from "@models/receptionist"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; export async function GET(request: Request) { + const authHeader = request.headers.get("Authorization"); try { - const authHeader = request.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { @@ -33,7 +33,7 @@ export async function GET(request: Request) { return NextResponse.json(receptionistData, { status: 200 }); } catch (error: any) { - console.error("Error fetching receptionist data:", error); + console.error("Error fetching receptionist data route:", error); return errorHandler( error.message || "Internal Server Error", STATUS_CODES.SERVER_ERROR diff --git a/app/api/receptionist/scan/route.ts b/app/api/receptionist/scan/route.ts index a52fb615..cd48fdca 100644 --- a/app/api/receptionist/scan/route.ts +++ b/app/api/receptionist/scan/route.ts @@ -1,13 +1,12 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; import { BookedAppointment, Patient } from "@models/index"; -import { authenticateUser } from "@lib/auth/authenticateUser"; +import { authenticateUser } from "@lib/auth"; import { Types } from "mongoose"; -import { NextResponse } from "next/server"; -import { errorHandler, STATUS_CODES } from "@utils/index"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; export async function POST(req: Request) { + const authHeader = req.headers.get("Authorization"); try { - const authHeader = req.headers.get("Authorization"); const { id, role } = await authenticateUser(authHeader); if (!id || !role) { diff --git a/app/api/states/route.ts b/app/api/states/route.ts index ec3be141..0630a737 100644 --- a/app/api/states/route.ts +++ b/app/api/states/route.ts @@ -1,5 +1,6 @@ +import { NextResponse } from "next/server"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import CityStateHospital from "@models/citystate_hospitals"; -import dbConfig from "@utils/db"; export async function GET(req: Request) { try { @@ -8,16 +9,19 @@ export async function GET(req: Request) { const statesArray = await CityStateHospital.find({}, { _id: 0 }); if (!statesArray || statesArray.length === 0) { - return Response.json("States not found", { status: 404 }); + return errorHandler("States not found", STATUS_CODES.NOT_FOUND); } const stateNames = statesArray .flatMap((state) => Object.keys(state.toObject())) .filter((key) => key !== "cities"); - return Response.json(stateNames, { status: 200 }); - } catch (error) { + return NextResponse.json(stateNames, { status: 200 }); + } catch (error: any) { console.error("Error fetching state data:", error); - return Response.json("Internal Server Error", { status: 500 }); + return errorHandler( + error.message || "Internal Server Error", + STATUS_CODES.SERVER_ERROR + ); } } diff --git a/app/api/test/route.ts b/app/api/test/route.ts new file mode 100644 index 00000000..759dc86e --- /dev/null +++ b/app/api/test/route.ts @@ -0,0 +1,6 @@ +import { setSession } from "@/lib/sessions/sessionUtils"; + +export async function GET() { + await setSession("66b72575fc219b2351f17180", "admin"); + return Response.json("OK"); +} diff --git a/app/api/transactions/route.ts b/app/api/transactions/route.ts index 3db9ef99..c6d646c6 100644 --- a/app/api/transactions/route.ts +++ b/app/api/transactions/route.ts @@ -1,10 +1,13 @@ -import dbConfig from "@utils/db"; +import { NextResponse } from "next/server"; +import { dbConfig, errorHandler, STATUS_CODES } from "@utils/index"; import { Transaction as TransactionType } from "@pft-types/index"; import Transaction from "@models/transaction"; import { Types } from "mongoose"; +import authenticateUser from "@lib/auth/authenticateUser"; // saving transaction details in db export async function POST(req: Request) { + const authHeader = req.headers.get("Authorization"); try { const { transaction_id, @@ -16,14 +19,10 @@ export async function POST(req: Request) { status, }: TransactionType = await req.json(); - const id = req.headers.get("x-user-id"); - const role = req.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } await dbConfig(); @@ -40,14 +39,19 @@ export async function POST(req: Request) { const res = await Transaction.create(transactionData); - if (!res) - return Response.json({ - error: "Error saving transaction details", - }); + if (!res) { + return errorHandler( + "Error saving transaction details", + STATUS_CODES.SERVER_ERROR + ); + } - return Response.json({ status: 200 }); - } catch (error) { - console.error("Error saving transaction :", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + return NextResponse.json({ status: 200 }); + } catch (error: any) { + console.error("Error saving transaction:", error); + return errorHandler( + error.message || "Internal Server Error", + STATUS_CODES.SERVER_ERROR + ); } } diff --git a/app/api/update-profile/address/route.ts b/app/api/update-profile/address/route.ts index 08bbcc87..f9cb335a 100644 --- a/app/api/update-profile/address/route.ts +++ b/app/api/update-profile/address/route.ts @@ -1,39 +1,40 @@ +import { NextResponse } from "next/server"; import { AddressBody } from "@pft-types/index"; -import { dbConfig, getModelByRole } from "@utils/index"; +import { + dbConfig, + getModelByRole, + errorHandler, + STATUS_CODES, +} from "@utils/index"; import { Types } from "mongoose"; +import { authenticateUser } from "@lib/auth"; export async function PUT(req: Request) { + const authHeader = req.headers.get("Authorization"); try { - const id = req.headers.get("x-user-id"); - const role = req.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } - // any user of system const user_id = new Types.ObjectId(id); - const addressData: AddressBody = await req.json(); await dbConfig(); - // removing undefined fields + // remove undefined fields Object.keys(addressData).forEach((key) => { if (addressData[key as keyof AddressBody] === undefined) { delete addressData[key as keyof AddressBody]; } }); - let UserModel = getModelByRole(role); - + const UserModel = getModelByRole(role); const user = await UserModel.findById(user_id); if (!user) { - return Response.json({ error: `${role} not found` }, { status: 404 }); + return errorHandler(`${role} not found`, STATUS_CODES.NOT_FOUND); } const updatedAddress = { @@ -47,12 +48,14 @@ export async function PUT(req: Request) { }; user.address = updatedAddress; - await user.save(); - return Response.json({ msg: "ok" }, { status: 200 }); - } catch (error) { + return NextResponse.json({ message: "ok" }, { status: 200 }); + } catch (error: any) { console.error("Error updating address:", error); - return Response.json({ error: "Error updating address" }, { status: 500 }); + return errorHandler( + error.message || "Error updating address", + STATUS_CODES.SERVER_ERROR + ); } } diff --git a/app/api/update-profile/personal/route.ts b/app/api/update-profile/personal/route.ts index 6c239237..318dbe1e 100644 --- a/app/api/update-profile/personal/route.ts +++ b/app/api/update-profile/personal/route.ts @@ -1,44 +1,47 @@ -import { dbConfig, getModelByRole } from "@utils/index"; +import { NextResponse } from "next/server"; +import { + dbConfig, + getModelByRole, + errorHandler, + STATUS_CODES, +} from "@utils/index"; import { PersonalInfoBody } from "@pft-types/index"; import { Types } from "mongoose"; +import { authenticateUser } from "@lib/auth"; export async function PUT(req: Request) { + const authHeader = req.headers.get("Authorization"); try { - const id = req.headers.get("x-user-id"); - const role = req.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } const user_id = new Types.ObjectId(id); - const updateData: PersonalInfoBody = await req.json(); await dbConfig(); - // remove undefined fields + // Remove undefined fields Object.keys(updateData).forEach((key) => { if (updateData[key as keyof PersonalInfoBody] === undefined) { delete updateData[key as keyof PersonalInfoBody]; } }); - let UserModel = getModelByRole(role); + const UserModel = getModelByRole(role); - // check for uniqueness of username, email, and contact + // Check for uniqueness of username, email, and contact if (updateData.username) { const existingUsername = await UserModel.findOne({ username: updateData.username, _id: { $ne: user_id }, }); if (existingUsername) { - return Response.json( - { error: "Username already exists" }, - { status: 400 } + return errorHandler( + "Username already exists", + STATUS_CODES.BAD_REQUEST ); } } @@ -46,15 +49,10 @@ export async function PUT(req: Request) { if (updateData.email) { const existingEmail = await UserModel.findOne({ email: updateData.email, - _id: { - $ne: user_id, - }, + _id: { $ne: user_id }, }); if (existingEmail) { - return Response.json( - { error: "Email already exists" }, - { status: 400 } - ); + return errorHandler("Email already exists", STATUS_CODES.BAD_REQUEST); } } @@ -64,14 +62,14 @@ export async function PUT(req: Request) { _id: { $ne: user_id }, }); if (existingContact) { - return Response.json( - { error: "Contact number already exists" }, - { status: 400 } + return errorHandler( + "Contact number already exists", + STATUS_CODES.BAD_REQUEST ); } } - // update the user + // Update the user const updatedUser = await UserModel.findByIdAndUpdate( user_id, { $set: updateData }, @@ -79,18 +77,18 @@ export async function PUT(req: Request) { ); if (!updatedUser) { - return Response.json({ error: `${role} not found` }, { status: 404 }); + return errorHandler(`${role} not found`, STATUS_CODES.NOT_FOUND); } - return Response.json( - { msg: "Profile updated successfully" }, + return NextResponse.json( + { message: "Profile updated successfully" }, { status: 200 } ); - } catch (error) { + } catch (error: any) { console.error("Error updating personal information:", error); - return Response.json( - { error: "Failed to update personal information" }, - { status: 500 } + return errorHandler( + error.message || "Failed to update personal information", + STATUS_CODES.SERVER_ERROR ); } } diff --git a/app/api/update-profile/profile/route.ts b/app/api/update-profile/profile/route.ts index 42871955..5d3ebd27 100644 --- a/app/api/update-profile/profile/route.ts +++ b/app/api/update-profile/profile/route.ts @@ -1,37 +1,46 @@ -import { dbConfig, getModelByRole } from "@utils/index"; +import { NextResponse } from "next/server"; +import { + dbConfig, + getModelByRole, + errorHandler, + STATUS_CODES, +} from "@utils/index"; import { Types } from "mongoose"; +import { authenticateUser } from "@lib/auth"; export async function PUT(request: Request) { + const authHeader = request.headers.get("Authorization"); try { const profile_pic = await request.json(); - const id = request.headers.get("x-user-id"); - const role = request.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); + // check for missing user ID or role if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } const user_id = new Types.ObjectId(id); - await dbConfig(); - let UserModel = getModelByRole(role); + const UserModel = getModelByRole(role); - const result = await UserModel.findByIdAndUpdate(user_id, { - $set: { profile: profile_pic }, - }); + const result = await UserModel.findByIdAndUpdate( + user_id, + { $set: { profile: profile_pic } }, + { new: true } + ); if (!result) { - return Response.json({ error: "Error updating profile picture" }); + return errorHandler( + "Error updating profile picture", + STATUS_CODES.NOT_FOUND + ); } - return Response.json({ msg: "ok" }); + return NextResponse.json({ message: "ok" }, { status: 200 }); } catch (error) { - console.error("Error updating profile picture :", error); - return Response.json({ error: "Internal Server Error" }, { status: 500 }); + console.error("Error updating profile picture:", error); + return errorHandler("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/api/update-profile/reset-password/route.ts b/app/api/update-profile/reset-password/route.ts index 659ee425..4e18f1e7 100644 --- a/app/api/update-profile/reset-password/route.ts +++ b/app/api/update-profile/reset-password/route.ts @@ -1,55 +1,55 @@ -import { dbConfig, getModelByRole } from "@utils/index"; +import { NextResponse } from "next/server"; +import { + dbConfig, + getModelByRole, + errorHandler, + STATUS_CODES, + hashPassword, +} from "@utils/index"; import bcrypt from "bcrypt"; import { SecurityBody } from "@pft-types/index"; import { Types } from "mongoose"; +import { authenticateUser } from "@lib/auth"; export async function PUT(req: Request) { + const authHeader = req.headers.get("Authorization"); try { - const id = req.headers.get("x-user-id"); - const role = req.headers.get("x-user-role"); + const { id, role } = await authenticateUser(authHeader); if (!id || !role) { - return Response.json( - { error: "Missing user ID or role" }, - { status: 400 } - ); + return errorHandler("Missing user ID or role", STATUS_CODES.BAD_REQUEST); } const user_id = new Types.ObjectId(id); - const { currentPassword, newPassword }: SecurityBody = await req.json(); if (!currentPassword || !newPassword) { - return Response.json( - { error: "Current password and new password are required" }, - { status: 400 } + return errorHandler( + "Current password and new password are required", + STATUS_CODES.BAD_REQUEST ); } await dbConfig(); - - let UserModel = getModelByRole(role); + const UserModel = getModelByRole(role); const user = await UserModel.findById(user_id); - if (!user) { - return Response.json({ error: "User not found" }, { status: 404 }); + return errorHandler("User not found", STATUS_CODES.NOT_FOUND); } const isPasswordValid = await bcrypt.compare( currentPassword, user.password ); - if (!isPasswordValid) { - return Response.json( - { error: "Current password is incorrect" }, - { status: 400 } + return errorHandler( + "Current password is incorrect", + STATUS_CODES.BAD_REQUEST ); } const hashedNewPassword = await hashPassword(newPassword); - const updatedUser = await UserModel.findByIdAndUpdate( user_id, { $set: { password: hashedNewPassword } }, @@ -57,24 +57,15 @@ export async function PUT(req: Request) { ); if (!updatedUser) { - return Response.json( - { error: "Error updating password" }, - { status: 500 } - ); + return errorHandler("Error updating password", STATUS_CODES.SERVER_ERROR); } - return Response.json( - { msg: "Password updated successfully" }, + return NextResponse.json( + { message: "Password updated successfully" }, { status: 200 } ); } catch (error) { - return Response.json({ error: "Error updating password" }, { status: 500 }); + console.error("Error updating password:", error); + return errorHandler("Error updating password", STATUS_CODES.SERVER_ERROR); } } - -// hashing the password -async function hashPassword(password: string) { - const saltRounds = parseInt(process.env.BCRYPT_SALT_ROUNDS || "10"); - const hashedPassword = await bcrypt.hash(password, saltRounds); - return hashedPassword; -} diff --git a/app/components/OtpSection/index.tsx b/app/components/OtpSection/index.tsx index 1d271fc6..6b144735 100644 --- a/app/components/OtpSection/index.tsx +++ b/app/components/OtpSection/index.tsx @@ -77,15 +77,15 @@ export default function OtpSection({ userData }: userDataType) { const handleSubmit = async () => { const otpString = otp.join(""); - const data = await verifyOtp( + const response = await verifyOtp( userData.usernameOrEmail, userData.role, userData.action, otpString ); - if (data.error) { - setShowError(data.error); + if (response.error) { + setShowError(response.error); resetOtpInputs(); } else { setShowError(""); diff --git a/app/components/ProfileSettings/index.tsx b/app/components/ProfileSettings/index.tsx index 3b512d18..1e504304 100644 --- a/app/components/ProfileSettings/index.tsx +++ b/app/components/ProfileSettings/index.tsx @@ -193,7 +193,7 @@ export default function ProfileSettings({ user }: ProfileSettingsProps) { toast.dismiss(); - if (response.msg) { + if (response.message) { toast.success("Personal information updated successfully"); } else { toast.error("Failed to update personal information"); @@ -239,7 +239,7 @@ export default function ProfileSettings({ user }: ProfileSettingsProps) { toast.dismiss(); - if (response.msg) { + if (response.message) { toast.success("Address information updated successfully"); } else { toast.error("Failed to update address information"); @@ -263,7 +263,7 @@ export default function ProfileSettings({ user }: ProfileSettingsProps) { toast.dismiss(); - if (response.msg) { + if (response.message) { toast.success("Password updated successfully"); setCurrentPassword(""); setNewPassword(""); diff --git a/app/lib/actions.ts b/app/lib/actions.ts index 50868d21..a470eb53 100644 --- a/app/lib/actions.ts +++ b/app/lib/actions.ts @@ -2,58 +2,36 @@ import { logout } from "@sessions/sessionUtils"; import { redirect } from "next/navigation"; -import getBaseUrl from "@utils/getBaseUrl"; +import fetchHandler from "@utils/fetchHandler"; -export async function loginAction(formData: FormData) { +export async function loginAction(formData: FormData): Promise { const usernameOrEmail = formData.get("usernameOrEmail"); const password = formData.get("password"); const role = formData.get("role"); - const serverUrl = getBaseUrl(); + const endpoint = "/api/auth/login"; - try { - const response = await fetch(`${serverUrl}/api/auth/login`, { - method: "POST", - body: JSON.stringify({ usernameOrEmail, password, role }), - }); - - const userData = await response.json(); - - if (!response.ok) { - return { msg: userData.error, unauthorized: true }; - } else return userData; - } catch (error) { - console.error("Login failed:", error); - } + return await fetchHandler(endpoint, { + method: "POST", + body: JSON.stringify({ usernameOrEmail, password, role }), + }); } -export async function signupAction(formData: FormData) { - const [firstname, lastname, username, email, password, role] = [ - formData.get("firstname"), - formData.get("lastname"), - formData.get("username"), - formData.get("email"), - formData.get("password"), - formData.get("role"), - ]; - - const user = { firstname, lastname, username, email, password, role }; - - try { - const serverUrl = getBaseUrl(); - const response = await fetch(`${serverUrl}/api/auth/signup`, { - method: "POST", - body: JSON.stringify(user), - }); - - const userData = await response.json(); - - if (!response.ok) { - return { msg: userData.error, failure: true }; - } else return userData; - } catch (error) { - console.error("Signup failed:", error); - } +export async function signupAction(formData: FormData): Promise { + const user = { + firstname: formData.get("firstname"), + lastname: formData.get("lastname"), + username: formData.get("username"), + email: formData.get("email"), + password: formData.get("password"), + role: formData.get("role"), + }; + + const endpoint = "/api/auth/signup"; + return await fetchHandler(endpoint, { + method: "POST", + body: JSON.stringify(user), + }); } export async function logoutAction() { diff --git a/app/lib/admin/addAdmin.tsx b/app/lib/admin/addAdmin.tsx index cbf74554..516960e2 100644 --- a/app/lib/admin/addAdmin.tsx +++ b/app/lib/admin/addAdmin.tsx @@ -1,21 +1,28 @@ "use server"; + +import { getSessionToken } from "../sessions/sessionUtils"; import fetchHandler from "@utils/fetchHandler"; -export default async function addAdmin(formData: FormData) { +export default async function addAdmin(formData: FormData): Promise { const endpoint = "/api/admin/add-admin"; + const session = getSessionToken(); try { const formDataObject = Object.fromEntries(formData.entries()); - const result = await fetchHandler(endpoint, { - method: "POST", - body: JSON.stringify(formDataObject), - cache: "no-cache", - }); + const result = await fetchHandler( + endpoint, + { + method: "POST", + body: JSON.stringify(formDataObject), + cache: "no-cache", + }, + session! + ); return result; } catch (error) { console.error("An error occurred while adding admin:", error); - return { error: "An unexpected error occurred" }; + throw error; } } diff --git a/app/lib/admin/getAdminData.tsx b/app/lib/admin/getAdminData.tsx index d27d8cb5..d2b4b238 100644 --- a/app/lib/admin/getAdminData.tsx +++ b/app/lib/admin/getAdminData.tsx @@ -1,14 +1,27 @@ +"use server"; + import fetchHandler from "@utils/fetchHandler"; +import { getSessionToken } from "../sessions/sessionUtils"; +import { Admin } from "@pft-types/index"; -export default async function getAdminData() { +export default async function getAdminData(): Promise { const endpoint = "/api/admin"; + const session = getSessionToken(); try { - const adminData = await fetchHandler(endpoint, { - cache: "no-cache", - }); + const response = await fetchHandler( + endpoint, + { + cache: "no-cache", + }, + session! + ); + + if (response.error) { + throw new Error(response.error.message); + } - return adminData; + return response.data!; } catch (error) { console.error("An error occurred while fetching admin data:", error); throw error; diff --git a/app/lib/admin/getDashboardData.tsx b/app/lib/admin/getDashboardData.tsx index 2cc806c1..08faff3c 100644 --- a/app/lib/admin/getDashboardData.tsx +++ b/app/lib/admin/getDashboardData.tsx @@ -1,33 +1,57 @@ +"use server"; + import fetchHandler from "@utils/fetchHandler"; +import { getSessionToken } from "../sessions/sessionUtils"; +import { PaginatedResponse, TilesDataType } from "@pft-types/admin"; -export async function getTilesData() { +export async function getTilesData(): Promise { const endpoint = "/api/admin/dashboard/tiles"; + const session = getSessionToken(); try { - const adminData = await fetchHandler(endpoint, { - next: { - revalidate: 5000, + const response = await fetchHandler( + endpoint, + { + next: { + revalidate: 5000, + }, }, - }); + session! + ); + + if (response.error) { + throw new Error(response.error.message); + } - return adminData; + return response.data!; } catch (error) { console.error("An error occurred while fetching admin data:", error); throw error; } } -export async function getRecentUsersData(page: number) { +export async function getRecentUsersData( + page: number +): Promise { const endpoint = `/api/admin/dashboard/recent-users?page=${page}&limit=10`; + const session = getSessionToken(); try { - const data = await fetchHandler(endpoint, { - next: { - revalidate: 5000, + const response = await fetchHandler( + endpoint, + { + next: { + revalidate: 5000, + }, }, - }); + session! + ); + + if (response.error) { + throw new Error(response.error.message); + } - return data; + return response.data!; } catch (error) { console.error("An error occurred while fetching admin data:", error); throw error; diff --git a/app/lib/admin/getHospitals.tsx b/app/lib/admin/getHospitals.tsx index bb590fe6..604ea3b6 100644 --- a/app/lib/admin/getHospitals.tsx +++ b/app/lib/admin/getHospitals.tsx @@ -1,17 +1,36 @@ +"use server"; + import fetchHandler from "@utils/fetchHandler"; +import { getSessionToken } from "../sessions/sessionUtils"; +import { + HospitalData, + HospitalUserData, + PaginationMetadata, +} from "@pft-types/admin"; export async function getHospitalsList( currentPage: number = 1, pageSize: number = 10 -) { +): Promise<{ + hospitals: [HospitalData]; + pagination: PaginationMetadata; +}> { const endpoint = `/api/admin/hospitals?page=${currentPage}&limit=${pageSize}`; + const session = getSessionToken(); try { - const data = await fetchHandler(endpoint); + const response = await fetchHandler<{ + hospitals: [HospitalData]; + pagination: PaginationMetadata; + }>(endpoint, {}, session!); + + if (response.error) { + throw new Error(response.error.message); + } return { - hospitals: data.hospitals, - pagination: data.pagination, + hospitals: response.data!.hospitals, + pagination: response.data!.pagination, }; } catch (error) { console.error("An error occurred while fetching hospitals list:", error); @@ -23,15 +42,26 @@ export async function getHospitalDetails( hospitalId: string, currentPage: number = 1, pageSize: number = 10 -) { +): Promise<{ + users: [HospitalUserData]; + pagination: PaginationMetadata; +}> { const endpoint = `/api/admin/hospitals/users?hospitalId=${hospitalId}&page=${currentPage}&limit=${pageSize}`; + const session = getSessionToken(); try { - const data = await fetchHandler(endpoint); + const response = await fetchHandler<{ + users: [HospitalUserData]; + pagination: PaginationMetadata; + }>(endpoint, {}, session!); + + if (response.error) { + throw new Error(response.error.message); + } return { - users: data.users, - pagination: data.pagination, + users: response.data!.users, + pagination: response.data!.pagination, }; } catch (error) { console.error("An error occurred while fetching hospital details:", error); diff --git a/app/lib/admin/getTransactions.tsx b/app/lib/admin/getTransactions.tsx index 365867ad..65f2ddb4 100644 --- a/app/lib/admin/getTransactions.tsx +++ b/app/lib/admin/getTransactions.tsx @@ -1,12 +1,25 @@ +"use server"; + import fetchHandler from "@utils/fetchHandler"; +import { getSessionToken } from "../sessions/sessionUtils"; +import { TransactionDetails } from "@pft-types/admin"; -export default async function getTransactions() { +export default async function getTransactions(): Promise<[TransactionDetails]> { const endpoint = "/api/admin/transactions"; + const session = getSessionToken(); try { - const transactionsData = await fetchHandler(endpoint); + const response = await fetchHandler<[TransactionDetails]>( + endpoint, + {}, + session! + ); + + if (response.error) { + throw new Error(response.error.message); + } - return transactionsData; + return response.data!; } catch (error) { console.error("An error occurred while fetching transactions data:", error); throw error; diff --git a/app/lib/auth/authenticateUser.ts b/app/lib/auth/authenticateUser.ts index c6a84788..27b04e30 100644 --- a/app/lib/auth/authenticateUser.ts +++ b/app/lib/auth/authenticateUser.ts @@ -2,10 +2,11 @@ import { AppError, STATUS_CODES } from "@utils/index"; import { decrypt } from "@sessions/sessionUtils"; import { JWTExpired, JWTInvalid } from "jose/errors"; -export async function authenticateUser( +export default async function authenticateUser( authHeader: string | null ): Promise<{ id: string; role: string }> { if (!authHeader || !authHeader.startsWith("Bearer ")) { + console.log("Unauthorized : auth header not present"); throw new AppError("Unauthorized", STATUS_CODES.UNAUTHORIZED); } @@ -19,12 +20,11 @@ export async function authenticateUser( }; } catch (error) { console.error("Error in authentication:", error); - if (error instanceof JWTExpired) { throw new AppError("Token expired", STATUS_CODES.UNAUTHORIZED); } else if (error instanceof JWTInvalid) { throw new AppError("Invalid token", STATUS_CODES.UNAUTHORIZED); } - throw new AppError("Internal dfdfgv Error", STATUS_CODES.SERVER_ERROR); + throw new AppError("Internal Server Error", STATUS_CODES.SERVER_ERROR); } } diff --git a/app/lib/auth/index.ts b/app/lib/auth/index.ts new file mode 100644 index 00000000..ef7c477a --- /dev/null +++ b/app/lib/auth/index.ts @@ -0,0 +1,3 @@ +import authenticateUser from "./authenticateUser"; + +export { authenticateUser }; diff --git a/app/lib/demo-user/handleDemoUserLogin.tsx b/app/lib/demo-user/handleDemoUserLogin.tsx index 72df41e2..c73753c8 100644 --- a/app/lib/demo-user/handleDemoUserLogin.tsx +++ b/app/lib/demo-user/handleDemoUserLogin.tsx @@ -1,44 +1,34 @@ import toast from "react-hot-toast"; -import getBaseUrl from "@utils/getBaseUrl"; +import fetchHandler from "@utils/fetchHandler"; const handleDemoUserLogin = async ( role: string, redirectDemoUser: (role: string) => void ) => { + const endpoint = "/api/demouser"; + try { toast.loading("Logging in...", { id: "demoLogin" }); - const serverUrl = getBaseUrl(); - - const response = await fetch(`${serverUrl}/api/demouser`, { + const response = await fetchHandler(endpoint, { method: "POST", - headers: { - "Content-Type": "application/json", - }, body: JSON.stringify({ role }), + cache: "no-cache", }); - const result = await response.json(); - - if (!response.ok) { - console.error("Error while demouser login:", result.error); - return { success: false, error: result.error }; + if (response.error) { + console.error("Error while demo user login:", response.error); + toast.error(`${response.error.message}`); + return; } - if (result.success) { - toast.success("Login successful, redirecting...", { id: "demoLogin" }); - redirectDemoUser(role); - } else { - throw new Error(result.error || "Login failed"); - } + toast.success("Login successful, redirecting...", { id: "demoLogin" }); + redirectDemoUser(role); } catch (error) { console.error("Demo login error:", error); - toast.error( - error instanceof Error - ? error.message - : "An unexpected error occurred. Please try again.", - { id: "demoLogin" } - ); + toast.error("An unexpected error occurred. Please try again.", { + id: "demoLogin", + }); } }; diff --git a/app/lib/demo-user/index.ts b/app/lib/demo-user/index.ts index 8a543881..9bb97226 100644 --- a/app/lib/demo-user/index.ts +++ b/app/lib/demo-user/index.ts @@ -1,3 +1,2 @@ import handleDemoUserLogin from "./handleDemoUserLogin"; - export { handleDemoUserLogin }; diff --git a/app/lib/doctor/getDoctorData.ts b/app/lib/doctor/getDoctorData.ts index a34ecc51..348d9107 100644 --- a/app/lib/doctor/getDoctorData.ts +++ b/app/lib/doctor/getDoctorData.ts @@ -1,28 +1,27 @@ "use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; +import { Doctor } from "@pft-types/index"; -export default async function getDoctorData() { +export default async function getDoctorData(): Promise { + const endpoint = "/api/doctor"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch(`${serverUrl}/api/doctor`, { - headers, - cache: "no-cache", - }); + const response = await fetchHandler>( + endpoint, + { + cache: "no-cache", + }, + session! + ); - if (!res.ok) { - console.error(`Error fetching doctor data: ${res.statusText}`); - throw new Error("fetching doctor data"); + if (response.error) { + throw new Error(response.error.message); } - const doctorData = await res.json(); - - return doctorData; + return response.data!; } catch (error) { console.error("An error occurred while fetching doctor data:", error); throw error; diff --git a/app/lib/doctor/index.ts b/app/lib/doctor/index.ts index 92287154..19f7c28b 100644 --- a/app/lib/doctor/index.ts +++ b/app/lib/doctor/index.ts @@ -1,3 +1,2 @@ import getDoctorData from "./getDoctorData"; - export { getDoctorData }; diff --git a/app/lib/emails/templates.tsx b/app/lib/emails/templates.tsx index e773cff7..c2f0f5bd 100644 --- a/app/lib/emails/templates.tsx +++ b/app/lib/emails/templates.tsx @@ -1,7 +1,8 @@ +import React from "react"; +import { Image } from "@nextui-org/react"; import { UserLog, bookingAppointment } from "@pft-types/index"; import { Html } from "@react-email/html"; import { getCurrentDateFormatted, getFormattedDate } from "@utils/getDate"; -import React from "react"; function Layout({ children }: { children: React.ReactNode }) { return ( @@ -35,8 +36,8 @@ function Layout({ children }: { children: React.ReactNode }) { alignItems: "center", }} > -
- Facebook - Instagram - Twitter - Youtube { + const endpoint = "/api/hospital"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch(`${serverUrl}/api/hospital`, { - headers, - cache: "no-cache", - }); + const response = await fetchHandler( + endpoint, + { + cache: "no-cache", + }, + session! + ); - if (!res.ok) { - console.error(`Error fetching hospital data: ${res.statusText}`); - throw new Error("fetching hospital data"); + if (response.error) { + throw new Error(response.error.message); } - const hospitalData = await res.json(); - - return hospitalData; + return response.data!; } catch (error) { console.error("An error occurred while fetching hospital data:", error); throw error; diff --git a/app/lib/index.ts b/app/lib/index.ts new file mode 100644 index 00000000..6d3d9330 --- /dev/null +++ b/app/lib/index.ts @@ -0,0 +1,7 @@ +import authenticateUser from "./auth/authenticateUser"; +import sendEmail from "./sendemail"; +import sendNotification from "./novu"; +import verifyOtp from "./verifyOtp"; + +export * from "./emails/templates"; +export { authenticateUser, sendEmail, sendNotification, verifyOtp }; diff --git a/app/lib/logs/index.tsx b/app/lib/logs/index.tsx index 9c21f8a5..6e947567 100644 --- a/app/lib/logs/index.tsx +++ b/app/lib/logs/index.tsx @@ -1,7 +1,6 @@ import dbConfig from "@utils/db"; -import sendEmail from "../sendemail"; import { render } from "@react-email/render"; -import { UserActivityTemplate } from "../emails/templates"; +import { sendEmail, UserActivityTemplate } from "../index"; import { UserLog } from "@models/index"; import { userAgent } from "next/server"; @@ -16,6 +15,8 @@ type userlogType = { async function logUserActivity(userlog: userlogType, req: Request) { await dbConfig(); + const ip_addr = req.headers.get("x-forwarded-for") ?? "127.0.0.1"; + try { const { os, browser, device } = userAgent(req); @@ -26,9 +27,7 @@ async function logUserActivity(userlog: userlogType, req: Request) { action: userlog.action, userType: userlog.role, device: `${os.name} ${os.version}, ${browser.name} ${browser.version}, ${device.type}`, - ip: (req.headers.get("x-forwarded-for") ?? "127.0.0.1") - .split(",")[0] - .trim(), + ip: ip_addr.split(",")[0].trim(), location: await fetchLocationByIP(), }; @@ -47,7 +46,7 @@ async function logUserActivity(userlog: userlogType, req: Request) { }, }); } catch (error: any) { - console.error(`While logging user activities got an error : ${error.msg}`); + console.error(`While logging user activities got an error`); } } diff --git a/app/lib/novu/index.tsx b/app/lib/novu/index.tsx index e82a0029..57acf9bf 100644 --- a/app/lib/novu/index.tsx +++ b/app/lib/novu/index.tsx @@ -2,7 +2,7 @@ import { Novu } from "@novu/node"; export default async function sendNotification( subscriberId: string, - msg: string, + message: string, type: string ) { try { @@ -15,7 +15,7 @@ export default async function sendNotification( subscriberId, }, payload: { - msg, + message, type, }, }); diff --git a/app/lib/patient/bookAppointment.tsx b/app/lib/patient/bookAppointment.tsx index f249fd60..289890d7 100644 --- a/app/lib/patient/bookAppointment.tsx +++ b/app/lib/patient/bookAppointment.tsx @@ -1,37 +1,32 @@ "use server"; + +import fetchHandler from "@utils/fetchHandler"; import { bookingAppointment } from "@pft-types/index"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; export default async function bookAppointment( bookAppointmentData: bookingAppointment, transaction_id: string | null, appointment_charge: string -) { +): Promise { + const endpoint = "/api/patient/appointment"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); + try { - const response = await fetch(`${serverUrl}/api/patient/appointment`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${session}`, + const response = await fetchHandler( + endpoint, + { + method: "POST", + body: JSON.stringify({ + ...bookAppointmentData, + transaction_id, + appointment_charge, + }), }, - body: JSON.stringify({ - ...bookAppointmentData, - transaction_id, - appointment_charge, - }), - }); - - if (!response.ok) { - console.error(`Error booking appointments: ${response.statusText}`); - const res = await response.json(); - return { error: res.error }; - } + session! + ); - const res = await response.json(); - return res; + return response; } catch (error) { console.error("Error booking appointment:", error); throw error; diff --git a/app/lib/patient/getPatientData.tsx b/app/lib/patient/getPatientData.tsx index b15b3b69..e5703d5c 100644 --- a/app/lib/patient/getPatientData.tsx +++ b/app/lib/patient/getPatientData.tsx @@ -1,28 +1,27 @@ "use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; +import { Patient } from "@pft-types/index"; -export default async function getPatientData() { +export default async function getresponse(): Promise { + const endpoint = "/api/patient"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch(`${serverUrl}/api/patient`, { - headers, - cache: "no-cache", - }); + const response = await fetchHandler( + endpoint, + { + cache: "no-cache", + }, + session! + ); - if (!res.ok) { - console.error(`Error fetching patient data: ${res.statusText}`); - throw new Error("fetching patient data"); + if (response.error) { + throw new Error(response.error.message); } - const patientData = await res.json(); - - return patientData; + return response.data!; } catch (error) { console.error("An error occurred while fetching patient data:", error); throw error; diff --git a/app/lib/patient/getPatientMedicalHistory.tsx b/app/lib/patient/getPatientMedicalHistory.tsx index d21fdc13..4200f376 100644 --- a/app/lib/patient/getPatientMedicalHistory.tsx +++ b/app/lib/patient/getPatientMedicalHistory.tsx @@ -1,28 +1,27 @@ "use server"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; +import { MedicalHistory } from "@pft-types/patient"; -export default async function getPatientMedicalHistory() { +export default async function getPatientMedicalHistory(): Promise< + [MedicalHistory] +> { + const endpoint = "/api/patient/medicalhistory"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const response = await fetch(`${serverUrl}/api/patient/medicalhistory`, { - headers, - }); + const response = await fetchHandler<[MedicalHistory]>( + endpoint, + {}, + session! + ); - if (!response.ok) { - throw new Error( - `Failed to fetch patient medical history: ${response.statusText}` - ); + if (response.error) { + throw new Error(response.error.message); } - const res = await response.json(); - return res; + return response.data!; } catch (error) { console.error("Error fetching patient medical history:", error); throw error; diff --git a/app/lib/patient/getPaymentsHistory.tsx b/app/lib/patient/getPaymentsHistory.tsx index 7e695307..95b1ce60 100644 --- a/app/lib/patient/getPaymentsHistory.tsx +++ b/app/lib/patient/getPaymentsHistory.tsx @@ -1,26 +1,21 @@ "use server"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; +import { Payment } from "@pft-types/patient"; -export default async function getPaymentsHistory() { +export default async function getPaymentsHistory(): Promise<[Payment]> { + const endpoint = "/api/patient/paymenthistory"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const response = await fetch(`${serverUrl}/api/patient/paymenthistory`, { - headers, - }); + const response = await fetchHandler<[Payment]>(endpoint, {}, session!); - if (!response.ok) { - throw new Error(`Failed to fetch payments: ${response.statusText}`); + if (response.error) { + throw new Error(response.error.message); } - const res = await response.json(); - return res; + return response.data!; } catch (error) { console.error("Error fetching payments:", error); throw error; diff --git a/app/lib/patient/getUpcomingAppointments.tsx b/app/lib/patient/getUpcomingAppointments.tsx index 52f3a13f..8046bd92 100644 --- a/app/lib/patient/getUpcomingAppointments.tsx +++ b/app/lib/patient/getUpcomingAppointments.tsx @@ -1,29 +1,25 @@ "use server"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; +import { bookedAppointments } from "@pft-types/patient"; -export default async function getUpcomingAppointments() { +export default async function getUpcomingAppointments(): Promise { + const endpoint = "/api/patient/appointment"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); try { - const res = await fetch(`${serverUrl}/api/patient/appointment`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${session}`, - }, - // next: { revalidate: 10 }, - }); + const response = await fetchHandler( + endpoint, + {}, + session! + ); + // next: { revalidate: 10 }, - if (!res.ok) { - throw new Error( - `Failed to fetch upcoming appointments: ${res.statusText}` - ); + if (response.error) { + throw new Error(response.error.message); } - - return res.json(); + return response.data!; } catch (error) { console.error("Error fetching upcoming appointments:", error); throw error; diff --git a/app/lib/patient/misc/getCities.tsx b/app/lib/patient/misc/getCities.tsx index f2f2f39b..2ea227a5 100644 --- a/app/lib/patient/misc/getCities.tsx +++ b/app/lib/patient/misc/getCities.tsx @@ -1,21 +1,20 @@ -"use server"; +import fetchHandler from "@utils/fetchHandler"; -import getBaseUrl from "@utils/getBaseUrl"; - -export default async function getCities(selectedState: string) { - const serverUrl = getBaseUrl(); +export default async function getCities( + selectedState: string +): Promise<[string]> { + const endpoint = `/api/city/?state=${selectedState}`; try { - const response = await fetch( - `${serverUrl}/api/city/?state=${selectedState}` - ); - if (!response.ok) { - throw new Error("Failed to fetch cities"); + const response = await fetchHandler<[string]>(endpoint); + + if (response.error) { + throw new Error(response.error.message); } - const data = await response.json(); - return data; + + return response.data!; } catch (error) { - console.error("Error fetching cities :", error); + console.error("Error fetching cities:", error); throw error; } } diff --git a/app/lib/patient/misc/getDiseases.tsx b/app/lib/patient/misc/getDiseases.tsx index 82cb4bdf..d0972d76 100644 --- a/app/lib/patient/misc/getDiseases.tsx +++ b/app/lib/patient/misc/getDiseases.tsx @@ -1,19 +1,18 @@ -"use server"; +import fetchHandler from "@utils/fetchHandler"; -import getBaseUrl from "@utils/getBaseUrl"; - -export default async function getDiseases() { - const serverUrl = getBaseUrl(); +export default async function getDiseases(): Promise<[string]> { + const endpoint = `/api/gethospitals/disease/`; try { - const response = await fetch(`${serverUrl}/api/gethospitals/disease/`); - if (!response.ok) { - throw new Error("Failed to fetch diseases"); + const response = await fetchHandler<[string]>(endpoint); + + if (response.error) { + throw new Error(response.error.message); } - const data = await response.json(); - return data; + + return response.data!; } catch (error) { - console.error("Error fetching diseases :", error); + console.error("Error fetching diseases:", error); throw error; } } diff --git a/app/lib/patient/misc/getHospitals.tsx b/app/lib/patient/misc/getHospitals.tsx index 1e1e04c9..ce475054 100644 --- a/app/lib/patient/misc/getHospitals.tsx +++ b/app/lib/patient/misc/getHospitals.tsx @@ -1,24 +1,22 @@ -"use server"; - -import getBaseUrl from "@utils/getBaseUrl"; +import { BookAppointmentHospital } from "@pft-types/patient"; +import fetchHandler from "@utils/fetchHandler"; export default async function getHospitals( selectedState: string, selectedCity: string -) { - const serverUrl = getBaseUrl(); +): Promise<[BookAppointmentHospital]> { + const endpoint = `/api/gethospitals/?state=${selectedState}&city=${selectedCity}`; try { - const response = await fetch( - `${serverUrl}/api/gethospitals/?state=${selectedState}&city=${selectedCity}` - ); - if (!response.ok) { - throw new Error("Failed to fetch hospitals"); + const response = await fetchHandler<[BookAppointmentHospital]>(endpoint); + + if (response.error) { + throw new Error(response.error.message); } - const data = await response.json(); - return data; + + return response.data!; } catch (error) { - console.error("Error fetching hospitals :", error); + console.error("Error fetching hospitals:", error); throw error; } } diff --git a/app/lib/patient/misc/getStates.tsx b/app/lib/patient/misc/getStates.tsx index 1e1f5980..e34e1670 100644 --- a/app/lib/patient/misc/getStates.tsx +++ b/app/lib/patient/misc/getStates.tsx @@ -1,19 +1,17 @@ -"use server"; +import fetchHandler from "@utils/fetchHandler"; -import getBaseUrl from "@utils/getBaseUrl"; - -export default async function getStates() { - const serverUrl = getBaseUrl(); +export default async function getStates(): Promise<[string]> { + const endpoint = "/api/states"; try { - const response = await fetch(`${serverUrl}/api/states`); - if (!response.ok) { - throw new Error("Failed to fetch states"); + const response = await fetchHandler<[string]>(endpoint); + + if (response.error) { + throw new Error(response.error.message); } - const data = await response.json(); - return data; + return response.data!; } catch (error) { - console.error("Error fetching states :", error); + console.error("Error fetching states:", error); throw error; } } diff --git a/app/lib/patient/pendingAppointmentsReq.tsx b/app/lib/patient/pendingAppointmentsReq.tsx index dabec138..7825e539 100644 --- a/app/lib/patient/pendingAppointmentsReq.tsx +++ b/app/lib/patient/pendingAppointmentsReq.tsx @@ -1,32 +1,30 @@ "use server"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; -export default async function pendingAppointmentsRequest(hospital_id: string) { +export default async function pendingAppointmentsRequest( + hospital_id: string +): Promise<{ hasPendingAppointment: boolean }> { + const endpoint = "/api/patient/appointment/pending"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch(`${serverUrl}/api/patient/appointment/pending`, { - method: "POST", - body: JSON.stringify({ hospital_id }), - headers, - }); + const response = await fetchHandler<{ hasPendingAppointment: boolean }>( + endpoint, + { + method: "POST", + body: JSON.stringify({ hospital_id }), + }, + session! + ); - if (!res.ok) { - throw new Error( - `fetching pending appointment request : ${res.statusText}` - ); - } - - const data = await res.json(); - - return data; + return response.data!; } catch (error) { - console.error("An error occurred while :", error); + console.error( + "An error occurred while fetching pending appointment requests:", + error + ); + throw error; } } diff --git a/app/lib/patient/saveAppointmentTransaction.tsx b/app/lib/patient/saveAppointmentTransaction.tsx index 360371c1..d5e74c4b 100644 --- a/app/lib/patient/saveAppointmentTransaction.tsx +++ b/app/lib/patient/saveAppointmentTransaction.tsx @@ -1,6 +1,7 @@ "use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; export default async function saveAppointmentTransaction( transaction_id: string | null, @@ -10,7 +11,7 @@ export default async function saveAppointmentTransaction( description: string, amount: string, status: string -) { +): Promise { const transactionData = { transaction_id, patient_id, @@ -21,20 +22,24 @@ export default async function saveAppointmentTransaction( status, }; + const endpoint = "/api/transactions"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - - const headers = { - Authorization: `Bearer ${session}`, - }; try { - await fetch(`${serverUrl}/api/transactions`, { - method: "POST", - body: JSON.stringify(transactionData), - headers, - }); + const response = await fetchHandler( + endpoint, + { + method: "POST", + body: JSON.stringify(transactionData), + }, + session! + ); + + if (response.error) { + throw new Error(response.error.message); + } } catch (error) { - console.error("Error recording appointment transaction :", error); + console.error("Error recording appointment transaction:", error); + throw error; } } diff --git a/app/lib/razorpay/createOrderId.ts b/app/lib/razorpay/createOrderId.ts deleted file mode 100644 index 4d6d4013..00000000 --- a/app/lib/razorpay/createOrderId.ts +++ /dev/null @@ -1,25 +0,0 @@ -// const createOrderId = async (amount: string) => { -// try { -// const response = await fetch("/api/payment/create-order", { -// method: "POST", -// headers: { -// "Content-Type": "application/json", -// }, -// body: JSON.stringify({ -// amount: parseFloat(amount) * 100, -// currency: "INR", -// }), -// }); - -// if (!response.ok) { -// throw new Error("Network response was not ok"); -// } - -// const data = await response.json(); -// return data.orderId; -// } catch (error) { -// console.error("There was a problem with your fetch operation:", error); -// } -// }; - -// export default createOrderId; diff --git a/app/lib/receptionist/approveAppointment.tsx b/app/lib/receptionist/approveAppointment.tsx index 2e3337f7..2bc89725 100644 --- a/app/lib/receptionist/approveAppointment.tsx +++ b/app/lib/receptionist/approveAppointment.tsx @@ -1,33 +1,27 @@ "use server"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; -export default async function approveAppointment(patientId: string) { +export default async function approveAppointment( + patientId: string +): Promise { + const endpoint = "/api/receptionist/appointments/approve"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const response = await fetch( - `${serverUrl}/api/receptionist/appointments/approve`, + const response = await fetchHandler( + endpoint, { method: "POST", - headers, body: JSON.stringify({ patient_id: patientId }), - } + }, + session! ); - if (!response.ok) { - throw new Error( - `Failed to approve appointment: ${response.status} - ${response.statusText}` - ); - } + if (response.error) throw new Error(response.error.message); - const res = await response.json(); - return res; + return response.data!; } catch (error) { console.error("Error approving appointment:", error); throw error; diff --git a/app/lib/receptionist/getPendingAppointments.tsx b/app/lib/receptionist/getPendingAppointments.tsx index 8a0bd296..12a03ba6 100644 --- a/app/lib/receptionist/getPendingAppointments.tsx +++ b/app/lib/receptionist/getPendingAppointments.tsx @@ -1,32 +1,23 @@ "use server"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -import getBaseUrl from "@utils/getBaseUrl"; +import { PendingPatients } from "@pft-types/receptionist"; -export default async function getPendingAppointments() { +export default async function getPendingAppointments(): Promise { + const endpoint = "/api/receptionist/appointments/pending"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch( - `${serverUrl}/api/receptionist/appointments/pending`, - { - headers, - } + const response = await fetchHandler( + endpoint, + {}, + session! ); - if (!res.ok) { - throw new Error( - `Failed to fetch pending appointments: ${res.status} - ${res.statusText}` - ); - } + if (response.error) throw new Error(response.error.message); - const receptionistData = await res.json(); - - return receptionistData; + return response.data!; } catch (error) { console.error("Error fetching pending appointments:", error); throw error; diff --git a/app/lib/receptionist/getReceptionistData.tsx b/app/lib/receptionist/getReceptionistData.tsx index 8f3c485d..12843ae9 100644 --- a/app/lib/receptionist/getReceptionistData.tsx +++ b/app/lib/receptionist/getReceptionistData.tsx @@ -1,30 +1,25 @@ "use server"; -import getBaseUrl from "@utils/getBaseUrl"; +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; +import { Receptionist } from "@pft-types/index"; -export default async function getReceptionistData() { +export default async function getReceptionistData(): Promise { + const endpoint = "/api/receptionist"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch(`${serverUrl}/api/receptionist`, { - headers, - cache: "no-cache", - }); + const response = await fetchHandler( + endpoint, + { + cache: "no-cache", + }, + session! + ); - if (!res.ok) { - throw new Error( - `Failed to fetch receptionist data: ${res.status} - ${res.statusText}` - ); - } + if (response.error) throw new Error(response.error.message); - const receptionistData = await res.json(); - - return receptionistData; + return response.data!; } catch (error) { console.error("Error fetching receptionist data:", error); throw error; diff --git a/app/lib/receptionist/scanQrCode.tsx b/app/lib/receptionist/scanQrCode.tsx index 272db391..24b80888 100644 --- a/app/lib/receptionist/scanQrCode.tsx +++ b/app/lib/receptionist/scanQrCode.tsx @@ -1,22 +1,27 @@ "use server"; -import getBaseUrl from "@utils/getBaseUrl"; +import fetchHandler from "@utils/fetchHandler"; +import { getSessionToken } from "../sessions/sessionUtils"; -export default async function scanQRCode(email: string) { - const serverUrl = getBaseUrl(); +export default async function scanQRCode( + email: string +): Promise<{ message: string }> { + const endpoint = "/api/receptionist/scan"; + const session = getSessionToken(); try { - const res = await fetch(`${serverUrl}/api/receptionist/scan`, { - method: "POST", - body: JSON.stringify({ email }), - headers: { - "Content-Type": "application/json", + const result = await fetchHandler<{ message: string }>( + endpoint, + { + method: "POST", + body: JSON.stringify({ email }), }, - }); + session! + ); - const msg = await res.json(); - return msg; + return result.data!; } catch (error) { console.error("Error fetching data:", error); + throw error; } } diff --git a/app/lib/update-profile/index.ts b/app/lib/update-profile/index.ts index 0c4d5a3d..9a8ecb4b 100644 --- a/app/lib/update-profile/index.ts +++ b/app/lib/update-profile/index.ts @@ -1,5 +1,3 @@ -"use server"; - import updateAddress from "./update_address"; import updatePersonal from "./update_personal_info"; import resetPassword from "./reset_password"; diff --git a/app/lib/update-profile/reset_password.tsx b/app/lib/update-profile/reset_password.tsx index c95fdce5..ff15dc94 100644 --- a/app/lib/update-profile/reset_password.tsx +++ b/app/lib/update-profile/reset_password.tsx @@ -1,31 +1,30 @@ -import getBaseUrl from "@utils/getBaseUrl"; +"use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; export default async function resetPassword( currentPassword: string, newPassword: string -) { +): Promise { + const endpoint = "/api/update-profile/reset-password"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const response = await fetch( - `${serverUrl}/api/update-profile/reset-password`, + const response = await fetchHandler( + endpoint, { method: "PUT", - headers, body: JSON.stringify({ currentPassword, newPassword }), - } + }, + session! ); - const result = await response.json(); + if (response.error) return { error: response.error.message }; - return result; + return response.data!; } catch (error) { - console.error("Error updating password :", error); + console.error("Error updating password:", error); + throw error; } } diff --git a/app/lib/update-profile/update_address.tsx b/app/lib/update-profile/update_address.tsx index 87d20c3e..3d1ee444 100644 --- a/app/lib/update-profile/update_address.tsx +++ b/app/lib/update-profile/update_address.tsx @@ -1,25 +1,27 @@ -import getBaseUrl from "@utils/getBaseUrl"; +"use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -export default async function updateAddress(filteredFields: any) { +export default async function updateAddress(filteredFields: any): Promise { + const endpoint = "/api/update-profile/address"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const response = await fetch(`${serverUrl}/api/update-profile/address`, { - method: "PUT", - headers, - body: JSON.stringify(filteredFields), - }); + const response = await fetchHandler( + endpoint, + { + method: "PUT", + body: JSON.stringify(filteredFields), + }, + session! + ); - const result = await response.json(); + if (response.error) return { error: response.error.message }; - return result; + return response.data!; } catch (error) { console.error("Error updating address information:", error); + throw error; } } diff --git a/app/lib/update-profile/update_personal_info.tsx b/app/lib/update-profile/update_personal_info.tsx index 2ef27e24..25b90180 100644 --- a/app/lib/update-profile/update_personal_info.tsx +++ b/app/lib/update-profile/update_personal_info.tsx @@ -1,25 +1,29 @@ -import getBaseUrl from "@utils/getBaseUrl"; +"use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -export default async function updatePersonal(filteredFields: any) { +export default async function updatePersonal( + filteredFields: any +): Promise { + const endpoint = "/api/update-profile/personal"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const response = await fetch(`${serverUrl}/api/update-profile/personal`, { - method: "PUT", - headers, - body: JSON.stringify(filteredFields), - }); + const response = await fetchHandler( + endpoint, + { + method: "PUT", + body: JSON.stringify(filteredFields), + }, + session! + ); - const result = await response.json(); + if (response.error) return { error: response.error.message }; - return result; + return response.data!; } catch (error) { console.error("Error updating personal information:", error); + throw error; } } diff --git a/app/lib/update-profile/update_profile_picture.tsx b/app/lib/update-profile/update_profile_picture.tsx index d4982b5c..4c4d1b68 100644 --- a/app/lib/update-profile/update_profile_picture.tsx +++ b/app/lib/update-profile/update_profile_picture.tsx @@ -1,25 +1,28 @@ -import getBaseUrl from "@utils/getBaseUrl"; +"use server"; + +import fetchHandler from "@utils/fetchHandler"; import { getSessionToken } from "../sessions/sessionUtils"; -async function updateProfilePicture(profile_url: string) { +async function updateProfilePicture(profile_url: string): Promise { + const endpoint = "/api/update-profile/profile"; const session = getSessionToken(); - const serverUrl = getBaseUrl(); - const headers = { - Authorization: `Bearer ${session}`, - }; try { - const res = await fetch(`${serverUrl}/api/update-profile/profile`, { - method: "PUT", - headers, - body: JSON.stringify(profile_url), - }); + const response = await fetchHandler( + endpoint, + { + method: "PUT", + body: JSON.stringify(profile_url), + }, + session! + ); - const isProfileUpdated = await res.json(); + if (response.error) return { error: response.error.message }; - return isProfileUpdated; + return response.data!; } catch (error) { console.error("Error updating profile picture:", error); + throw error; } } diff --git a/app/lib/verifyOtp.ts b/app/lib/verifyOtp.ts index 31327a61..9d0ab93c 100644 --- a/app/lib/verifyOtp.ts +++ b/app/lib/verifyOtp.ts @@ -1,19 +1,16 @@ -import getBaseUrl from "@utils/getBaseUrl"; +import fetchHandler from "@utils/fetchHandler"; export default async function verifyOtp( usernameOrEmail: string, role: string, action: string, otp: string -) { - const serverUrl = getBaseUrl(); +): Promise { + const endpoint = "/api/auth/verifyotp"; try { - const response = await fetch(`${serverUrl}/api/auth/verifyotp`, { + const response = await fetchHandler(endpoint, { method: "POST", - headers: { - "Content-Type": "application/json", - }, body: JSON.stringify({ otp, usernameOrEmail, @@ -21,9 +18,12 @@ export default async function verifyOtp( action, }), }); - const data = await response.json(); - return data; + + if (response.error) return { error: response.error.message }; + + return response.data!; } catch (error) { - console.error("Error:", error); + console.error("Error verifying OTP:", error); + throw error; } } diff --git a/app/utils/fetchHandler.ts b/app/utils/fetchHandler.ts index 763ab1e6..cc5e1634 100644 --- a/app/utils/fetchHandler.ts +++ b/app/utils/fetchHandler.ts @@ -1,6 +1,3 @@ -"use server"; - -import { getSessionToken } from "@lib/sessions/sessionUtils"; import getBaseUrl from "@utils/getBaseUrl"; type ApiRequestOptions = Omit & { @@ -8,47 +5,68 @@ type ApiRequestOptions = Omit & { revalidate?: number | false; }; -async function fetchHandler(endpoint: string, options: ApiRequestOptions = {}) { - const session = getSessionToken(); +type FetchResult = { + data?: T; + error?: { + title: string; + message: string; + stackTrace: string | null; + }; +}; + +export default async function fetchHandler( + endpoint: string, + options: ApiRequestOptions = {}, + session?: string +): Promise> { const serverUrl = getBaseUrl(); const headers = new Headers(options.headers); - headers.set("Authorization", `Bearer ${session}`); headers.set("Content-Type", "application/json"); + if (session) headers.set("Authorization", `Bearer ${session}`); - const { cache, revalidate, ...restOptions } = options; + try { + const { cache, revalidate, ...restOptions } = options; - let cacheOption: RequestCache | undefined; - if (cache) { - cacheOption = cache; - } else if (revalidate === false) { - cacheOption = "no-store"; - } else if (typeof revalidate === "number") { - cacheOption = "force-cache"; - } + let cacheOption: RequestCache | undefined; + if (cache) { + cacheOption = cache; + } else if (revalidate === false) { + cacheOption = "no-store"; + } else if (typeof revalidate === "number") { + cacheOption = "force-cache"; + } - const fetchOptions: RequestInit = { - ...restOptions, - headers, - }; + const fetchOptions: RequestInit = { + ...restOptions, + headers, + }; - if (cacheOption) { - fetchOptions.cache = cacheOption; - } + if (cacheOption) { + fetchOptions.cache = cacheOption; + } - if (typeof revalidate === "number") { - fetchOptions.next = { revalidate }; - } + if (typeof revalidate === "number") { + fetchOptions.next = { revalidate }; + } - const response = await fetch(`${serverUrl}${endpoint}`, fetchOptions); + const response = await fetch(`${serverUrl}${endpoint}`, fetchOptions); - const result = await response.json(); + const result = await response.json(); - if (!response.ok) { - throw new Error(result.error || "An error occurred"); - } + if (!response.ok) { + return { + error: { + title: result.title || "Error", + message: result.message || "An error occurred", + stackTrace: result.stackTrace || null, + }, + }; + } - return result; + return { data: result }; + } catch (error: any) { + console.error("Error in fetchHandler:", error); + throw error; + } } - -export default fetchHandler; diff --git a/types/admin.d.ts b/types/admin.d.ts index ea174d31..4ffd175b 100644 --- a/types/admin.d.ts +++ b/types/admin.d.ts @@ -79,3 +79,32 @@ export type RecentUserPaginatedResponse = { totalPages: number; totalItems: number; }; + +export interface HospitalData { + id: string; + name: string; + username: string; + profile: string; + contact: string; + city: string; + state: string; +} + +export interface HospitalUserData { + id: string; + name: string; + role: string; + username: string; + profile: string; + gender: string; + contact: string; + city: string; + state: string; +} + +export interface PaginationMetadata { + currentPage: number; + pageSize: number; + totalPages: number; + totalCount: number; +} diff --git a/types/index.ts b/types/index.ts index b8d627ae..1a2a451e 100644 --- a/types/index.ts +++ b/types/index.ts @@ -88,4 +88,4 @@ export type SecurityBody = { export * from "./admin"; export * from "./patient"; -// export * from "./receptionist"; +export * from "./receptionist"; diff --git a/types/patient.d.ts b/types/patient.d.ts index 16010fc4..6c4ec889 100644 --- a/types/patient.d.ts +++ b/types/patient.d.ts @@ -38,6 +38,22 @@ export type bookingAppointment = { note: string; }; +export type BookAppointmentHospital = { + hospital_id: string; + hospital_name: string; + appointment_charge: string; +}; + +export type BookAppointmentProps = { + patientId: string; + name: string; + email: string; +}; + +export type MedicalDetailsProps = { + medicalDetails: MedicalHistory[]; +}; + export interface PaymentHistory { hospital: { name: string; @@ -89,3 +105,19 @@ export type BookingAppointmentType = bookingAppointment & { transaction_id: string | null; appointment_charge: string; }; + +export type Payment = { + hospital: { + name: string; + profile: string; + }; + disease: string; + description: string; + date: string; + amount: number; + status: "Success" | "Failed"; +}; + +export type PaymentDetailsProps = { + paymentHistory: Payment[]; +}; diff --git a/types/receptionist.d.ts b/types/receptionist.d.ts index e69de29b..e9627c74 100644 --- a/types/receptionist.d.ts +++ b/types/receptionist.d.ts @@ -0,0 +1,4 @@ +export interface PendingPatients { + patientDetails: PatientDetail[]; + totalCount: number; +}