162 lines
7.8 KiB
JavaScript
162 lines
7.8 KiB
JavaScript
import { useState } from 'react';
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { useForm } from 'react-hook-form';
|
|
import api from '../api/axios'; // Import Axios instance ที่มี JWT Interceptor
|
|
import { FaPlus, FaTrash } from 'react-icons/fa';
|
|
|
|
// ฟังก์ชันสำหรับเรียก API (Read)
|
|
const fetchDoctors = async () => {
|
|
const { data } = await api.get('/doctors');
|
|
return data;
|
|
};
|
|
|
|
// ฟังก์ชันสำหรับเพิ่มแพทย์ใหม่ (Create)
|
|
const addDoctor = async (newDoctor) => {
|
|
const { data } = await api.post('/doctors', newDoctor);
|
|
return data;
|
|
};
|
|
|
|
// ฟังก์ชันสำหรับลบแพทย์ (Delete)
|
|
const deleteDoctor = async (id) => {
|
|
await api.delete(`/doctors/${id}`);
|
|
};
|
|
|
|
export default function DoctorsPage() {
|
|
const queryClient = useQueryClient();
|
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
|
|
// 1. ดึงข้อมูลแพทย์จาก API (Read)
|
|
const { data: doctors, isLoading, isError, error } = useQuery({
|
|
queryKey: ['doctors'],
|
|
queryFn: fetchDoctors,
|
|
});
|
|
|
|
// 2. จัดการฟอร์มสำหรับเพิ่มแพทย์ (Create)
|
|
const { register, handleSubmit, reset, formState: { errors } } = useForm();
|
|
|
|
// 3. จัดการการเพิ่มข้อมูล (Mutation)
|
|
const addDoctorMutation = useMutation({
|
|
mutationFn: addDoctor,
|
|
onSuccess: () => {
|
|
// เมื่อเพิ่มสำเร็จ ให้ Invalidate cache เพื่อให้ React Query ดึงข้อมูลใหม่
|
|
queryClient.invalidateQueries(['doctors']);
|
|
reset();
|
|
setIsModalOpen(false);
|
|
},
|
|
});
|
|
|
|
// 4. จัดการการลบข้อมูล (Mutation)
|
|
const deleteDoctorMutation = useMutation({
|
|
mutationFn: deleteDoctor,
|
|
onSuccess: () => {
|
|
// เมื่อลบสำเร็จ ให้ Invalidate cache เพื่อให้ React Query ดึงข้อมูลใหม่
|
|
queryClient.invalidateQueries(['doctors']);
|
|
},
|
|
});
|
|
|
|
const onSubmit = (data) => {
|
|
addDoctorMutation.mutate(data);
|
|
};
|
|
|
|
const handleDelete = (id) => {
|
|
if (window.confirm('คุณต้องการลบแพทย์คนนี้หรือไม่?')) {
|
|
deleteDoctorMutation.mutate(id);
|
|
}
|
|
};
|
|
|
|
if (isLoading) return <div>กำลังโหลดข้อมูล...</div>;
|
|
if (isError) return <div>เกิดข้อผิดพลาด: {error.message}</div>;
|
|
|
|
return (
|
|
<div className="container mx-auto p-4">
|
|
<h1 className="text-3xl font-bold mb-6">จัดการข้อมูลแพทย์</h1>
|
|
|
|
{/* ปุ่มสำหรับเปิด Modal เพิ่มแพทย์ */}
|
|
<div className="flex justify-end mb-4">
|
|
<button
|
|
className="btn btn-primary"
|
|
onClick={() => setIsModalOpen(true)}
|
|
>
|
|
<FaPlus className="mr-2" /> เพิ่มแพทย์ใหม่
|
|
</button>
|
|
</div>
|
|
|
|
{/* ตารางแสดงข้อมูลแพทย์ */}
|
|
<div className="overflow-x-auto shadow-xl rounded-lg">
|
|
<table className="table w-full">
|
|
<thead>
|
|
<tr className="bg-gray-100">
|
|
<th>ชื่อ</th>
|
|
<th>อีเมล</th>
|
|
<th>CRM</th>
|
|
<th>สาขา</th>
|
|
<th>เบอร์โทรศัพท์</th>
|
|
<th>การดำเนินการ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{doctors.map((doctor) => (
|
|
<tr key={doctor.id}>
|
|
<td>{doctor.name}</td>
|
|
<td>{doctor.email}</td>
|
|
<td>{doctor.crm}</td>
|
|
<td>{doctor.specialty}</td>
|
|
<td>{doctor.telephone}</td>
|
|
<td>
|
|
<button
|
|
className="btn btn-error btn-sm"
|
|
onClick={() => handleDelete(doctor.id)}
|
|
disabled={deleteDoctorMutation.isLoading}
|
|
>
|
|
{deleteDoctorMutation.isLoading ? 'กำลังลบ...' : <FaTrash />}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{/* Modal สำหรับเพิ่มแพทย์ */}
|
|
{isModalOpen && (
|
|
<div className="modal modal-open">
|
|
<div className="modal-box">
|
|
<h3 className="font-bold text-lg mb-4">เพิ่มแพทย์ใหม่</h3>
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<div className="form-control">
|
|
<label className="label">ชื่อ</label>
|
|
<input type="text" placeholder="ชื่อ" className="input input-bordered" {...register("name", { required: true })} />
|
|
</div>
|
|
<div className="form-control mt-2">
|
|
<label className="label">อีเมล</label>
|
|
<input type="email" placeholder="อีเมล" className="input input-bordered" {...register("email", { required: true })} />
|
|
</div>
|
|
<div className="form-control mt-2">
|
|
<label className="label">CRM</label>
|
|
<input type="text" placeholder="CRM" className="input input-bordered" {...register("crm", { required: true })} />
|
|
</div>
|
|
<div className="form-control mt-2">
|
|
<label className="label">สาขา</label>
|
|
<input type="text" placeholder="สาขา" className="input input-bordered" {...register("specialty", { required: true })} />
|
|
</div>
|
|
<div className="form-control mt-2">
|
|
<label className="label">เบอร์โทรศัพท์</label>
|
|
<input type="text" placeholder="เบอร์โทรศัพท์" className="input input-bordered" {...register("telephone", { required: true })} />
|
|
</div>
|
|
{/* ... เพิ่ม input สำหรับข้อมูลอื่น ๆ ... */}
|
|
|
|
<div className="modal-action mt-4">
|
|
<button type="submit" className="btn btn-primary" disabled={addDoctorMutation.isLoading}>
|
|
{addDoctorMutation.isLoading ? 'กำลังบันทึก...' : 'บันทึก'}
|
|
</button>
|
|
<button type="button" className="btn" onClick={() => setIsModalOpen(false)}>
|
|
ยกเลิก
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
} |