diff --git a/app/clinic/[slug]/page.js b/app/clinic/[slug]/page.js index b7c485a..b434599 100644 --- a/app/clinic/[slug]/page.js +++ b/app/clinic/[slug]/page.js @@ -2,15 +2,16 @@ import ClinicPage from "@/components/clinic"; import Layout from "@/components/layout/StLayout"; import { fetchReq } from "@/lib/req"; -async function Clinic({ params: { slug } }) { +async function Clinic({ params: { slug },searchParams }) { const API_URL = process.env.NEXT_PUBLIC_API_URL; - + const page = Number(searchParams?.page) || 1; const reqClinics = await fetchReq( `${API_URL}/api/v1/clinic/${slug}` ); const limit=50 + const reqDoctors = await fetchReq( - `${API_URL}/api/v1/clinic/doctor-list/${slug}?page=1&limit=${limit}` + `${API_URL}/api/v1/clinic/doctor-list/${slug}?page=${page}&limit=${limit}` ); diff --git a/components/clinic/components/doctors/List.js b/components/clinic/components/doctors/List.js index 660a137..82f54a0 100644 --- a/components/clinic/components/doctors/List.js +++ b/components/clinic/components/doctors/List.js @@ -20,34 +20,50 @@ function List({ const router = useRouter(); const changePage = async (_, num) => { setLoading(true); + + window.scrollTo({ top: 0, behavior: "smooth" }); + const searchParams = new URLSearchParams(window.location.search); searchParams.set("page", num); router.push(`/clinic/${slug}?${searchParams.toString()}`); setPage(num); - - let params = { - ...QueryForDoctorsClinicReq(filter), - current: num, - limit, - }; try { - const doctors = await getClinicDoctors(slug, params); - setDoctors(doctors.data); - setTotalPage(doctors?.page?.total_pages || 1); + let params = { + ...QueryForDoctorsClinicReq(filter), + page: num, + limit, + }; + + const res = await getClinicDoctors(slug, params); + console.log("📦 پاسخ API:", res); + + // اگر سرور داده را در data برمی‌گرداند + if (res?.data) { + setDoctors([...res.data]); + setTotalPage(res?.page?.total_pages || 1); + } + // اگر فقط آرایه برمی‌گرداند + else if (Array.isArray(res)) { + setDoctors([...res]); + setTotalPage(1); + } + setPage(num); + } catch (error) { + console.error("❌ خطا در دریافت داده:", error); } finally { setLoading(false); } }; - const doctorList = Array.isArray(doctors?.data) ? doctors.data : doctors; + const doctorList = Array.isArray(doctors) + ? doctors + : Array.isArray(doctors?.data) + ? doctors.data + : []; return ( <> - {loading ? ( -
-
-
- ) : doctorList?.length === 0 ? ( + { doctorList?.length === 0 ? (
دکتری مطابق فیلتر شما یافت نشد
@@ -55,7 +71,12 @@ function List({ <>
diff --git a/components/clinic/components/doctors/head/index.js b/components/clinic/components/doctors/head/index.js index 8b91230..6f43c37 100644 --- a/components/clinic/components/doctors/head/index.js +++ b/components/clinic/components/doctors/head/index.js @@ -57,9 +57,10 @@ function Head({ setDoctors, slug, filter, setFilter,setPage,setTotalPage }) { let params = QueryForDoctorsClinicReq(data); - if ( - data?.name === data.specialty?.name || - data?.name === data.category?.name + if ( + data?.specialty && + (data?.name === data.specialty?.name || + data?.name === data.category?.name) ) { delete params.name; } @@ -71,7 +72,7 @@ function Head({ setDoctors, slug, filter, setFilter,setPage,setTotalPage }) { const doctors = await getClinicDoctors(slug, params); // تنظیم داده‌ها در state - setDoctors(doctors); + setDoctors(doctors.data); // ✅ حالا که جواب API اومده، مقدار صفحات مشخصه if (doctors?.page) { diff --git a/components/clinic/components/doctors/head/search/AutoComplete.js b/components/clinic/components/doctors/head/search/AutoComplete.js index 83c5eac..d21d5df 100644 --- a/components/clinic/components/doctors/head/search/AutoComplete.js +++ b/components/clinic/components/doctors/head/search/AutoComplete.js @@ -2,71 +2,61 @@ import { Autocomplete, TextField } from "@mui/material"; import { useRef, useState, useEffect } from "react"; function AutoComplete({ - data, - noneBg, + data = [], // همیشه آرایه ایمن + noneBg = false, clearText, - inputValue, - placeholder, + inputValue = "", + placeholder = "", handleSearch, - setInputValue, - setSelectedOption, - debounce = 500, + debounce = 400, }) { const typingTimeoutRef = useRef(null); - const [localInput, setLocalInput] = useState(inputValue || ""); + const [localInput, setLocalInput] = useState(inputValue); + // sync بین inputValue بیرونی و مقدار محلی useEffect(() => { - setLocalInput(inputValue || ""); + if (inputValue !== localInput) setLocalInput(inputValue || ""); }, [inputValue]); + // پاک‌سازی تایمر هنگام خروج useEffect(() => { return () => { if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current); }; }, []); - const onInputChange = (_, newInputValue) => { - setLocalInput(newInputValue); - - if (setInputValue) setInputValue(newInputValue); - + // تایپ در input + const onInputChange = (_, newValue) => { + setLocalInput(newValue); if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current); typingTimeoutRef.current = setTimeout(() => { - handleSearch(newInputValue); + handleSearch(newValue); }, debounce); }; + // انتخاب از بین گزینه‌ها const onChange = (_, newValue) => { - if (typingTimeoutRef.current) { - clearTimeout(typingTimeoutRef.current); - typingTimeoutRef.current = null; - } - - const val = newValue - ? typeof newValue === "string" - ? newValue - : newValue.name - : ""; + if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current); + const val = typeof newValue === "string" ? newValue : newValue?.name || ""; setLocalInput(val); - setSelectedOption && setSelectedOption(newValue); handleSearch(val); - if (setInputValue) setInputValue(val); }; return ( - typeof option === "string" ? option : option.name - } disableClearable + options={Array.isArray(data) ? data : []} + getOptionLabel={(option) => + typeof option === "string" ? option : option.name || "" + } inputValue={localInput} - className="!w-full" onInputChange={onInputChange} onChange={onChange} + noOptionsText="پزشکی یافت نشد" + className="!w-full" renderOption={(props, option) => ( -
  • +
  • {option.name}
  • )} diff --git a/components/clinic/components/doctors/head/search/SearchField.js b/components/clinic/components/doctors/head/search/SearchField.js index 65a90bd..9229da1 100644 --- a/components/clinic/components/doctors/head/search/SearchField.js +++ b/components/clinic/components/doctors/head/search/SearchField.js @@ -1,79 +1,59 @@ +"use client"; + import { clearFilterParams } from "@/helper"; import { useRouter } from "next/navigation"; -import specialties from "@/data/specialties.json"; +import { useRef } from "react"; import AutoComplete from "./AutoComplete"; -function SearchField({ filter, setFilter, setDataInURL }) { +function SearchField({ filter, setFilter, setDataInURL, sendReq }) { const router = useRouter(); + const typingTimeoutRef = useRef(null); + // ✅ پاک کردن فیلد سرچ const clearText = () => { - clearFilterParams(router, ["name", "category", "specialty"]); - const newFilter = { - ...filter, - ...{ - name: "", - category: undefined, - specialty: undefined, - }, - }; + clearFilterParams(router, ["name"]); + const newFilter = { ...filter, name: "" }; setFilter(newFilter); + setDataInURL(newFilter); + sendReq(newFilter); // جستجو مجدد بدون نام پزشک }; - const handleSearch = (e) => { - const findName = specialties.find((item) => item.name === e); + // ✅ فقط جستجوی پزشک بر اساس name + const handleSearch = (value) => { + const newFilter = { ...filter, name: value }; const searchParams = new URLSearchParams(window.location.search); - let dataUrl = {}; - - if (findName) { - let newFilter = { ...filter }; - if (findName.parent) { - const itemParent = specialties.find( - (item) => item.id === findName.parent - ); - dataUrl.specialty = findName.name; - newFilter.category = itemParent; - newFilter.specialty = findName; - } else { - dataUrl.specialty = findName.name; - newFilter.category = findName; - newFilter.specialty = ""; - } + // اگر کاربر پاک کرد + if (!value.trim()) { searchParams.delete("name"); - Object.entries(dataUrl).forEach(([key, value]) => { - if (value) { - searchParams.set(key, value); - } - }); router.push(`?${searchParams.toString()}`); - newFilter.name = e; - setFilter(newFilter); - } else { - let newFilter = filter; - - if ( - filter.name === filter.specialty?.name || - filter.name === filter.category?.name - ) { - searchParams.delete("specialty"); - newFilter.specialty = ""; - newFilter.category = ""; - router.push(`?${searchParams.toString()}`); - } - newFilter.name = e; setFilter(newFilter); setDataInURL(newFilter); + sendReq(newFilter); + return; } + + // مقدار name در URL قرار می‌گیرد + searchParams.set("name", value); + router.push(`?${searchParams.toString()}`); + setFilter(newFilter); + setDataInURL(newFilter); + + // جلوگیری از درخواست زیاد + if (typingTimeoutRef.current) clearTimeout(typingTimeoutRef.current); + typingTimeoutRef.current = setTimeout(() => { + sendReq(newFilter); // ارسال درخواست به بک‌اند + }, 400); }; return (
    ); diff --git a/components/clinic/components/doctors/head/search/SendReq.js b/components/clinic/components/doctors/head/search/SendReq.js index b2245a0..17bb9e3 100644 --- a/components/clinic/components/doctors/head/search/SendReq.js +++ b/components/clinic/components/doctors/head/search/SendReq.js @@ -5,39 +5,28 @@ import specialties from "@/data/specialties.json"; function SendReq({ filter, setFilter, setDataInURL, sendReq }) { const [loading, setLoading] = useState(false); - // const checkName = () => { - // let newFilter = filter; - // const specialtyItem = - // filter.name && - // specialties.find((item) => item.name.includes(filter.name)); - - // if (specialtyItem) { - // if (specialtyItem.parent) { - // newFilter.specialty = specialtyItem; - // newFilter.category = specialties.find( - // (item) => item.id === specialtyItem.parent - // ); - // } else { - // newFilter.specialty = specialtyItem; - // } - // } - - // return newFilter; - // }; - const filterData = () => { + if (!filter?.name?.trim()) { + // اگر کاربر چیزی ننوشته، فقط کل لیست رو بگیر + setDataInURL(filter); + sendReq(filter); + return; + } + setLoading(true); - - // setLoading(true); - // // const newFilter = checkName(); - // // setFilter(filter); - // // setDataInURL(filter); - sendReq(filter).finally(() => { - setLoading(false); - }); + // ✅ 1. مقدار در URL ست بشه + if (setDataInURL) { + setDataInURL(filter); + } + + // ✅ 2. درخواست به بک‌اند بره + sendReq(filter) + .catch((err) => console.error("❌ خطا در جستجو:", err)) + .finally(() => { + setLoading(false); // ✅ 3. بعد از پاسخ، loading خاموش + }); }; - return (