Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Authentication and API Handling Features with New Implementations #3

Merged
merged 41 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
52e82fa
chore: 🔧 Extend CI/CD pipeline for 'fix-' branches
ad956 Sep 23, 2024
80c3a27
chore(admin): 🛠️ implement errorHandler for consistent error response…
ad956 Sep 23, 2024
d82e050
chore(patient): ⚡ optimize error handling using errorHandler and Next…
ad956 Sep 23, 2024
fb94826
chore(receptionist): 🧹 clean up error management with errorHandler an…
ad956 Sep 23, 2024
cb943a4
chore(hospital): 🔄 refactor error handling to use errorHandler and Ne…
ad956 Sep 23, 2024
839bb64
chore(updateprofile): ✨ enhance error responses with errorHandler and…
ad956 Sep 23, 2024
27111a3
chore(auth): 🔒 secure error handling with errorHandler and NextRespon…
ad956 Sep 23, 2024
e2c96db
chore(doctor): 📝 standardize error handling using errorHandler and ut…
ad956 Sep 23, 2024
bc5fd01
chore(transactions): 🔍 review error management with errorHandler and …
ad956 Sep 23, 2024
711542a
chore(demosuer): 🎉 improve error handling with errorHandler and switc…
ad956 Sep 23, 2024
83dbd2c
chore: 🚀 Refactor error handling to use errorHandler
ad956 Sep 23, 2024
425b04f
feat(auth): replace getBaseUrl and auth headers with fetchHandler 🛠️
ad956 Sep 23, 2024
b81c039
feat(demo): update to use fetchHandler, removing getBaseUrl 🌟
ad956 Sep 23, 2024
e06014f
feat(doctor): refactor to use fetchHandler instead of getBaseUrl 🔍
ad956 Sep 23, 2024
b430f72
feat(hospital): migrate to fetchHandler, eliminating getBaseUrl 🏥
ad956 Sep 23, 2024
330c066
refactor(patient): switch to fetchHandler, removing base URL logic 🔄
ad956 Sep 23, 2024
0be267a
refactor(receptionist): utilize fetchHandler, removing getBaseUrl 🔄
ad956 Sep 23, 2024
eeb279a
chore(update-profile): refactor to use fetchHandler, eliminating base…
ad956 Sep 23, 2024
0afb25c
refactor: replace 'msg' with 'message' in various components 🔄
ad956 Sep 23, 2024
b606552
chore: restructure exports 📦
ad956 Sep 23, 2024
3008bcf
refactor: replace fetch implementation in verifyOtp with fetchHandler 🔄
ad956 Sep 23, 2024
cbb5f0e
refactor: replace 'msg' with 'message' in various components 🔄
ad956 Sep 23, 2024
19af0c2
remove createOrderId
ad956 Sep 23, 2024
efc7129
feat(session-expired): add suspense fallback for session expired page ⚠️
ad956 Sep 25, 2024
3a72f12
chore: refactor types and API methods 🚀
ad956 Sep 25, 2024
bb6edb5
chore: refactor API method 🚀
ad956 Sep 25, 2024
f43f0b4
feat(types): add new types for better type safety 🛠️
ad956 Sep 25, 2024
4df5484
feat(utils): create custom fetch handler with enhanced options ⚙️
ad956 Sep 25, 2024
14e8228
fix(api): resolve dynamic server usage error by moving headers, searc…
ad956 Sep 25, 2024
ddef955
feat(admin): implement API call for fetching admin data with enhanced…
ad956 Sep 25, 2024
fec7256
feat(doctor): add API method for retrieving doctor data with improved…
ad956 Sep 25, 2024
a6e7b06
feat(patient): implement patient data fetching API with better type h…
ad956 Sep 25, 2024
fba8ac1
feat(receptionist): integrate receptionist API with secure session to…
ad956 Sep 25, 2024
32869ba
feat(hospital): create hospital data fetching API with enhanced type …
ad956 Sep 25, 2024
9ab8cfd
feat(auth): enhance user authentication with detailed error handling 🔐
ad956 Sep 25, 2024
c97ed5b
feat(demo-login): implement demo user login with fetchHandler and toa…
ad956 Sep 25, 2024
432d2f0
refactor: replace img tag with Next.js Image component for optimized …
ad956 Sep 25, 2024
038598d
refactor: console log the logging error
ad956 Sep 25, 2024
69dbeda
feat(update-profile): enhance profile management with fetchHandler in…
ad956 Sep 25, 2024
15d1607
feat(auth): implement login and signup actions with fetchHandler inte…
ad956 Sep 25, 2024
d8d8287
refactor(verifyOtp): Integrated fetchHandler with TypeScript types 🔒
ad956 Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/test-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions app/(pages)/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -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.");
}
}

Expand Down
11 changes: 6 additions & 5 deletions app/(pages)/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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.");
}
}

Expand Down
5 changes: 4 additions & 1 deletion app/(pages)/admin/add-admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
11 changes: 7 additions & 4 deletions app/(pages)/admin/components/LoginForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.");
}
}

Expand Down
26 changes: 4 additions & 22 deletions app/(pages)/admin/hospitals/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<UserData[]>([]);
const [users, setUsers] = useState<HospitalUserData[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedRole, setSelectedRole] = useState<string>("All");

const [currentUser, setCurrentUser] = useState<UserData | null>(null);
const [currentUser, setCurrentUser] = useState<HospitalUserData | null>(null);
const [pagination, setPagination] = useState<PaginationMetadata>({
currentPage: 1,
pageSize: 10,
Expand Down
18 changes: 1 addition & 17 deletions app/(pages)/admin/hospitals/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<HospitalData[]>([]);
Expand Down
3 changes: 1 addition & 2 deletions app/(pages)/admin/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -13,7 +12,7 @@ export default async function AdminLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const admin: Admin = await getAdminData();
const admin = await getAdminData();

return (
<main className="h-screen flex flex-row">
Expand Down
3 changes: 1 addition & 2 deletions app/(pages)/admin/transactions/page.tsx
Original file line number Diff line number Diff line change
@@ -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 <Transactions transactions={transactions} />;
}
3 changes: 1 addition & 2 deletions app/(pages)/doctor/layout.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -14,7 +13,7 @@ export default async function DoctorLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const doctor: Doctor = await getDoctorData();
const doctor = await getDoctorData();

return (
<main className="h-screen flex">
Expand Down
3 changes: 1 addition & 2 deletions app/(pages)/hospital/layout.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -14,7 +13,7 @@ export default async function HospitalLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const hospital: Hospital = await getHospitalData();
const hospital = await getHospitalData();

return (
<main className="h-screen flex">
Expand Down
3 changes: 1 addition & 2 deletions app/(pages)/patient/appointments/page.tsx
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
38 changes: 14 additions & 24 deletions app/(pages)/patient/components/BookAppointment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -51,11 +43,12 @@ export default function BookAppointment({
const [selectedState, setSelectedState] = useState("");
const [cities, setCities] = useState<string[]>([]);
const [selectedCity, setSelectedCity] = useState("");
const [selectedHospital, setSelectedHospital] = useState<Hospital>({
hospital_id: "",
hospital_name: "",
appointment_charge: "",
});
const [selectedHospital, setSelectedHospital] =
useState<BookAppointmentHospital>({
hospital_id: "",
hospital_name: "",
appointment_charge: "",
});
const [selectedDisease, setSelectedDisease] = useState("");
const [loadingStates, setLoadingStates] = useState(false);
const [loadingCities, setLoadingCities] = useState(false);
Expand All @@ -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<BookAppointmentHospital[]>([]);
const [diseases, setDiseases] = useState<string[]>([]);
const [additionalNote, setAdditionalNote] = useState("");
const [noteError, setNoteError] = useState("");
Expand Down Expand Up @@ -171,9 +162,8 @@ export default function BookAppointment({
function handleHospitalChange(e: ChangeEvent<HTMLSelectElement>): 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({
Expand Down Expand Up @@ -255,7 +245,7 @@ export default function BookAppointment({
return;
}
clearSelected();
toast.success(response.msg);
toast.success(response.message);
}

function clearSelected() {
Expand Down
6 changes: 1 addition & 5 deletions app/(pages)/patient/components/MedicalDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { MedicalHistory } from "@pft-types/index";
import { MedicalDetailsProps } from "@pft-types/index";
import {
Chip,
Spinner,
Expand All @@ -14,10 +14,6 @@ import {
} from "@nextui-org/react";
import { getFormattedDate } from "@utils/getDate";

type MedicalDetailsProps = {
medicalDetails: MedicalHistory[];
};

export default function MedicalDetails({
medicalDetails,
}: MedicalDetailsProps) {
Expand Down
19 changes: 1 addition & 18 deletions app/(pages)/patient/components/PaymentDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 1 addition & 2 deletions app/(pages)/patient/layout.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -15,7 +14,7 @@ export default async function PatientLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
const patient: Patient = await getPatientData();
const patient = await getPatientData();

return (
<main className="h-screen flex">
Expand Down
6 changes: 2 additions & 4 deletions app/(pages)/patient/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<section className="bg-[#f3f6fd] p-2 overflow-y-auto">
Expand Down
Loading