148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
"use client";
|
||
|
||
import type { DoctorListData } from "@/features/doctor/lib/data";
|
||
import AddedButton from "@/shared/ui/added-button";
|
||
import { Button } from "@/shared/ui/button";
|
||
import {
|
||
Dialog,
|
||
DialogContent,
|
||
DialogFooter,
|
||
DialogHeader,
|
||
DialogTitle,
|
||
} from "@/shared/ui/dialog";
|
||
import { DashboardLayout } from "@/widgets/dashboard-layout/ui/DashboardLayout";
|
||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||
import { AxiosError } from "axios";
|
||
import { Loader2 } from "lucide-react";
|
||
import { useState } from "react";
|
||
import { useNavigate } from "react-router-dom";
|
||
import { toast } from "sonner";
|
||
import { doctor_api } from "../lib/api";
|
||
import { columns } from "../lib/column";
|
||
import { DataTable } from "../lib/data-table";
|
||
|
||
const Doctor = () => {
|
||
const router = useNavigate();
|
||
const queryClinent = useQueryClient();
|
||
const { data, isLoading, isError, refetch } = useQuery({
|
||
queryKey: ["doctor_list"],
|
||
queryFn: () => doctor_api.list(),
|
||
select(data) {
|
||
return data.data.data;
|
||
},
|
||
});
|
||
|
||
const { mutate: deleted, isPending: deletedPending } = useMutation({
|
||
mutationFn: ({ id }: { id: number }) => doctor_api.delete({ id }),
|
||
onSuccess: () => {
|
||
router("/physician");
|
||
queryClinent.refetchQueries({ queryKey: ["doctor_list"] });
|
||
setSelectedDistrict(null);
|
||
setDeleteDialog(false);
|
||
},
|
||
onError: (error: AxiosError) => {
|
||
const data = error.response?.data as { message?: string };
|
||
const errorData = error.response?.data as {
|
||
messages?: {
|
||
token_class: string;
|
||
token_type: string;
|
||
message: string;
|
||
}[];
|
||
};
|
||
const errorName = error.response?.data as {
|
||
data?: {
|
||
name: string[];
|
||
};
|
||
};
|
||
|
||
const message =
|
||
Array.isArray(errorName.data?.name) && errorName.data.name.length
|
||
? errorName.data.name[0]
|
||
: data?.message ||
|
||
(Array.isArray(errorData?.messages) && errorData.messages.length
|
||
? errorData.messages[0].message
|
||
: undefined) ||
|
||
"Xatolik yuz berdi";
|
||
|
||
toast.error(message);
|
||
},
|
||
});
|
||
|
||
const [deleteDialog, setDeleteDialog] = useState<boolean>(false);
|
||
const [selectedDistrict, setSelectedDistrict] =
|
||
useState<DoctorListData | null>(null);
|
||
|
||
const columnsProps = columns({
|
||
router: router,
|
||
onDeleteClick: (district) => {
|
||
setSelectedDistrict(district);
|
||
setDeleteDialog(true);
|
||
},
|
||
});
|
||
|
||
return (
|
||
<DashboardLayout>
|
||
<div className="flex justify-between items-center">
|
||
<AddedButton onClick={() => router("/physician/added")} />
|
||
</div>
|
||
<div className="space-y-6">
|
||
<h1 className="text-3xl font-bold">Shifokorlar ro‘yxati</h1>
|
||
{isLoading && (
|
||
<div className="w-full flex justify-center py-10">
|
||
<div className="flex flex-col items-center gap-2">
|
||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-300 border-t-primary"></div>
|
||
<p className="text-muted-foreground">Yuklanmoqda...</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
{isError && (
|
||
<div className="w-full py-10 flex flex-col items-center gap-3">
|
||
<p className="text-red-500 font-medium">
|
||
Ma'lumot yuklashda xatolik yuz berdi.
|
||
</p>
|
||
<Button onClick={() => refetch()}>Qayta yuklash</Button>
|
||
</div>
|
||
)}
|
||
{!isLoading && !isError && (
|
||
<div className="overflow-x-auto">
|
||
{data && <DataTable columns={columnsProps} data={data} />}
|
||
</div>
|
||
)}
|
||
</div>
|
||
<Dialog open={deleteDialog} onOpenChange={setDeleteDialog}>
|
||
<DialogContent>
|
||
<DialogHeader>
|
||
<DialogTitle className="text-start">O‘chirish</DialogTitle>
|
||
</DialogHeader>
|
||
<p>
|
||
Siz haqiqatdan ham{" "}
|
||
<strong>
|
||
{selectedDistrict?.first_name} {selectedDistrict?.last_name}
|
||
</strong>{" "}
|
||
shifokorni o‘chirmoqchimisiz?
|
||
</p>
|
||
<DialogFooter className="flex flex-row justify-end">
|
||
<Button variant="secondary" onClick={() => setDeleteDialog(false)}>
|
||
Bekor qilish
|
||
</Button>
|
||
<Button
|
||
variant="destructive"
|
||
onClick={() =>
|
||
selectedDistrict && deleted({ id: selectedDistrict.id })
|
||
}
|
||
>
|
||
{deletedPending ? (
|
||
<Loader2 className="animate-spin" />
|
||
) : (
|
||
"O'chirish"
|
||
)}
|
||
</Button>
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
</DashboardLayout>
|
||
);
|
||
};
|
||
|
||
export default Doctor;
|