# فیکس کندی و باگ‌های فیلتر صفحه پزشکان

## پروژه

`nobat724_front`

## زمینه

صفحه `/doctors` بعد از `npm run build && npm run start` (production mode) سه مشکل دارد:
۱. سرعت کلی سایت کند می‌شود
۲. مودال انتخاب شهر/استان بعد از کلیک «تایید و ادامه» دیر بسته می‌شود و فیلتر با تاخیر اعمال می‌شود
۳. دسته‌بندی (category/specialty) در مودال فیلتر درست کار نمی‌کند

## فایل‌های مرتبط

| فایل | نقش |
|------|-----|
| `nobat724_front/app/component/modalSearchCity/Content.js` | مودال انتخاب شهر/استان — دکمه «تایید و ادامه» |
| `nobat724_front/app/component/modalSearchCity/index.js` | wrapper مودال شهر |
| `nobat724_front/components/doctors/modal/ButtonApply.js` | دکمه «اعمال تغییرات» در مودال فیلتر |
| `nobat724_front/components/doctors/modal/Content.js` | محتوای مودال فیلتر (category/specialty) |
| `nobat724_front/components/doctors/modal/form/index.js` | فرم فیلتر — CateSelector برای category و specialty |
| `nobat724_front/components/doctors/head/index.js` | `sendReq` — تابع اصلی fetch |
| `nobat724_front/helper/index.js` (خط ۴۲۰) | `QueryForDoctorsReq` — تبدیل filter به params |
| `nobat724_front/helper/index.js` (خط ۲۱۵) | `filterList` — تولید parentList و childrenList |

## وضعیت فعلی

### باگ ۱ — مودال شهر/استان دیر بسته می‌شود

`Content.js` خط ۲۴: `getStateInfoClient()` در هر render صدا زده می‌شود:

```js
// app/component/modalSearchCity/Content.js
const { matchedState } = getStateInfoClient();
```

و دکمه «تایید و ادامه» منتظر `sendReq()` می‌ماند قبل از بستن:

```js
const handleClick = () => {
  setLoading(true);
  sendReq().finally(() => {
    setLoading(false);
    handleClose(); // ← مودال فقط بعد از پایان fetch بسته می‌شود
  });
};
```

`sendReq` در `head/index.js` یک HTTP request کامل است — تا پایان fetch مودال باز می‌ماند.

همچنین دو `disabled` prop روی دکمه تایید وجود دارد (یکی `loading` و یکی `!filter?.city || !filter?.state`) که در JSX اشتباه است — دومی override می‌کند.

### باگ ۲ — دسته‌بندی کار نمی‌کند

در `modal/Content.js`:

```js
function Content({ filter, setFilter, updateData, setDataInURL }) {
  const changeSpecialty = (name, value) => {
    const newFilter = { ...filter, [name]: value };

    if (name === "category") {
      const childrenList = specialties.filter((item) => item.parent);
      const filteredChildrenList = childrenList.filter(
        (item) => item.parent === value.id  // ← value می‌تواند null باشد (وقتی clear می‌شود)
      );
      const firstChildren = filteredChildrenList[0];
      newFilter.specialty = firstChildren || "";
    }

    setFilter(newFilter);
    setDataInURL(newFilter);
    return newFilter;
  };
```

وقتی `value` (category) null است (کاربر انتخاب را پاک می‌کند)، `value.id` crash می‌کند.

و `filterList` در `helper/index.js`:

```js
export const filterList = (data) => {
  const parentList = specialties.filter((item) => !item.parent);
  const childrenList = specialties.filter((item) => item.parent);

  const filteredChildrenList =
    data && data.category
      ? childrenList.filter((item) => item.parent === data.category.id)
      : [];
  // ← item.parent (string از JSON) vs data.category.id (ممکن است number باشد)
```

`specialties.json` فیلد `parent` را به‌صورت string ذخیره می‌کند (مثلاً `"1"`) اما `category.id` ممکن است number باشد — type mismatch.

### باگ ۳ — کندی کلی

احتمال اصلی: `getStateInfoClient()` و `cities.filter()` و `states.find()` در هر render اجرا می‌شوند بدون memoization. همچنین `sendReq` در `ButtonApply` و `Content` هر دو منتظر کامل شدن fetch قبل از بستن مودال هستند.

## وظایف

### ۱. فیکس بستن سریع مودال شهر/استان

در `app/component/modalSearchCity/Content.js` مودال را فوری ببند و fetch در پس‌زمینه ادامه یابد:

```js
const handleClick = () => {
  handleClose(); // فوری ببند
  sendReq();     // fetch در background
};
```

همچنین دو `disabled` را روی دکمه یکی کن:

```jsx
<Button
  disabled={!filter?.city || !filter?.state}
  onClick={handleClick}
  variant="contained"
>
```

### ۲. فیکس بستن سریع مودال فیلتر

در `components/doctors/modal/ButtonApply.js` همین الگو را اعمال کن:

```js
const handleClick = () => {
  setOpen(false); // فوری ببند
  sendReq();      // fetch در background
};
```

state `loading` را می‌توانی حذف کنی چون دیگر منتظر fetch نمی‌ماند.

### ۳. فیکس crash دسته‌بندی هنگام clear

در `components/doctors/modal/Content.js` خط مربوط به `value.id`:

```js
const changeSpecialty = (name, value) => {
  const newFilter = { ...filter, [name]: value };

  if (name === "category") {
    if (value) {
      const filteredChildrenList = specialties
        .filter((item) => item.parent)
        .filter((item) => String(item.parent) === String(value.id)); // ← String() برای type safety
      newFilter.specialty = filteredChildrenList[0] || null;
    } else {
      newFilter.specialty = null; // clear category → clear specialty هم
    }
  }

  setFilter(newFilter);
  setDataInURL(newFilter);
  return newFilter;
};
```

### ۴. فیکس type mismatch در filterList

در `helper/index.js` خط ۲۱۹:

```js
const filteredChildrenList =
  data && data.category
    ? childrenList.filter(
        (item) => String(item.parent) === String(data.category.id)
      )
    : [];
```

### ۵. بررسی کندی کلی

- در `app/component/modalSearchCity/index.js`، `useEffect` وابسته به `stateSelected` هر بار کل `cities` را filter می‌کند — با `useMemo` بهینه کن:

```js
const filteredCities = useMemo(() => {
  if (!stateSelected) return [];
  const selectedState = states.find((s) => s.name === stateSelected);
  if (!selectedState) return [];
  return cities.filter((c) => c.province_id === selectedState.id);
}, [stateSelected]);
// حذف useState و useEffect مربوطه
```

- `getStateInfoClient()` در `Content.js` را به بیرون از component ببر یا با `useMemo` cache کن.

## نکات مهم

- `specialties.json` فیلد `parent` را string ذخیره می‌کند (`"1"` نه `1`) — همیشه `String()` برای مقایسه استفاده کن
- مودال‌ها باید فوری بسته شوند (UX) و fetch در background ادامه یابد — کاربر نباید منتظر پاسخ API بماند
- `sendReq` در `head/index.js` یک Promise برمی‌گرداند — می‌توان بدون `await` صدا زد
- `disabled` دو بار روی یک `<Button>` در JSX: دومی اول override می‌کند — فقط یکی نگه‌دار
- بعد از تغییر، با `npm run build && npm run start` تست کن (نه dev mode)
