Skip to content

Commit

Permalink
Appointment detail flicker problem resolved (#9987)
Browse files Browse the repository at this point in the history
  • Loading branch information
NikhilA8606 authored Jan 15, 2025
1 parent e38417d commit 2fc9e33
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 89 deletions.
106 changes: 106 additions & 0 deletions src/pages/Patient/components/AppointmentDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Dispatch, SetStateAction } from "react";
import { useTranslation } from "react-i18next";

import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";

import { usePatientContext } from "@/hooks/usePatientUser";

import mutate from "@/Utils/request/mutate";
import { formatName, formatPatientAge } from "@/Utils/utils";
import { formatAppointmentSlotTime } from "@/pages/Appointments/utils";
import PublicAppointmentApi from "@/types/scheduling/PublicAppointmentApi";
import { Appointment } from "@/types/scheduling/schedule";

function AppointmentDialog(props: {
appointment: Appointment | undefined;
open: boolean;
onOpenChange: (open: boolean) => void;
setAppointmentDialogOpen: Dispatch<SetStateAction<boolean>>;
}) {
const { t } = useTranslation();
const queryClient = useQueryClient();
const patient = usePatientContext();
const tokenData = patient?.tokenData;
const { mutate: cancelAppointment, isPending } = useMutation({
mutationFn: mutate(PublicAppointmentApi.cancelAppointment, {
headers: {
Authorization: `Bearer ${tokenData?.token}`,
},
}),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["appointment", tokenData?.phoneNumber],
});
props.setAppointmentDialogOpen(false);
},
});
const { appointment, open, onOpenChange } = props;

if (!appointment) return <></>;

return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="p-0">
<DialogHeader className="p-3">
<DialogDescription className="mb-4">
{t("appointment_details")}
</DialogDescription>
<div className="flex flex-row justify-between">
<div className="space-y-1">
<Label className="text-xs">{t("practitioner")}</Label>
<p className="text-base font-semibold">
{formatName(appointment.user)}
</p>
<p className="text-sm font-semibold text-gray-600">
{formatAppointmentSlotTime(appointment)}
</p>
</div>
<div className="space-y-1">
<Label className="text-xs">{t("patient_name")}</Label>
<p className="font-semibold text-base">
{appointment.patient.name}
</p>
<p className="text-sm text-gray-600 font-medium">
{formatPatientAge(appointment.patient as any, true)},{" "}
{t(`GENDER__${appointment.patient.gender}`)}
</p>
</div>
</div>
</DialogHeader>
<DialogFooter className="flex flex-row sm:justify-between items-center bg-blue-200 m-0 w-full p-3 rounded-b-lg">
<span className="text-sm font-semibold text-blue-700">
{t(appointment.status)}
</span>
<span className="flex flex-row gap-2">
<Button
variant="destructive"
disabled={isPending}
onClick={() => {
cancelAppointment({
appointment: appointment.id,
patient: appointment.patient.id,
});
}}
>
<span>{t("Cancel")}</span>
</Button>
<Button variant="secondary">
<span>{t("reschedule")}</span>
</Button>
</span>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

export default AppointmentDialog;
94 changes: 5 additions & 89 deletions src/pages/Patient/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
import dayjs from "dayjs";
import { Link, navigate } from "raviger";
import { useState } from "react";
Expand All @@ -7,30 +7,21 @@ import { useTranslation } from "react-i18next";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

import Loading from "@/components/Common/Loading";

import { usePatientContext } from "@/hooks/usePatientUser";

import mutate from "@/Utils/request/mutate";
import query from "@/Utils/request/query";
import { formatName, formatPatientAge } from "@/Utils/utils";
import { formatAppointmentSlotTime } from "@/pages/Appointments/utils";
import { formatName } from "@/Utils/utils";
import PublicAppointmentApi from "@/types/scheduling/PublicAppointmentApi";
import { Appointment } from "@/types/scheduling/schedule";

import AppointmentDialog from "./components/AppointmentDialog";

function PatientIndex() {
const { t } = useTranslation();
const queryClient = useQueryClient();

const [selectedAppointment, setSelectedAppointment] = useState<
Appointment | undefined
Expand All @@ -55,19 +46,6 @@ function PatientIndex() {
enabled: !!tokenData?.token,
});

const { mutate: cancelAppointment, isPending } = useMutation({
mutationFn: mutate(PublicAppointmentApi.cancelAppointment, {
headers: {
Authorization: `Bearer ${tokenData?.token}`,
},
}),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["appointment", tokenData?.phoneNumber],
});
},
});

const getStatusChip = (status: string) => {
return (
<Badge
Expand Down Expand Up @@ -104,69 +82,6 @@ function PatientIndex() {
dayjs().isBefore(dayjs(appointment.token_slot.start_datetime)),
);

function AppointmentDialog(props: {
appointment: Appointment | undefined;
open: boolean;
onOpenChange: (open: boolean) => void;
}) {
const { appointment, open, onOpenChange } = props;
if (!appointment) return <></>;
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="p-0">
<DialogHeader className="p-3">
<DialogDescription className="mb-4">
{t("appointment_details")}
</DialogDescription>
<div className="flex flex-row justify-between">
<div className="space-y-1">
<Label className="text-xs">{t("practitioner")}</Label>
<p className="text-base font-semibold">
{formatName(appointment.user)}
</p>
<p className="text-sm font-semibold text-gray-600">
{formatAppointmentSlotTime(appointment)}
</p>
</div>
<div className="space-y-1">
<Label className="text-xs">{t("patient_name")}</Label>
<p className="font-semibold text-base">
{appointment.patient.name}
</p>
<p className="text-sm text-gray-600 font-medium">
{formatPatientAge(appointment.patient as any, true)},{" "}
{t(`GENDER__${appointment.patient.gender}`)}
</p>
</div>
</div>
</DialogHeader>
<DialogFooter className="flex flex-row sm:justify-between items-center bg-blue-200 m-0 w-full p-3 rounded-b-lg">
<span className="text-sm font-semibold text-blue-700">
{t(appointment.status)}
</span>
<span className="flex flex-row gap-2">
<Button
variant="destructive"
disabled={isPending}
onClick={() =>
cancelAppointment({
appointment: appointment.id,
patient: appointment.patient.id,
})
}
>
<span>{t("cancel")}</span>
</Button>
<Button variant="secondary">
<span>{t("reschedule")}</span>
</Button>
</span>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

const getAppointmentCard = (appointment: Appointment) => {
const appointmentTime = dayjs(appointment.token_slot.start_datetime);
const appointmentDate = appointmentTime.format("DD MMMM YYYY");
Expand Down Expand Up @@ -247,6 +162,7 @@ function PatientIndex() {
return (
<>
<AppointmentDialog
setAppointmentDialogOpen={setAppointmentDialogOpen}
appointment={selectedAppointment}
open={appointmentDialogOpen}
onOpenChange={(open) => {
Expand Down

0 comments on commit 2fc9e33

Please sign in to comment.