diff --git a/app/component/ItemDoctor.js b/app/component/ItemDoctor.js index c9df883..7d9e92f 100644 --- a/app/component/ItemDoctor.js +++ b/app/component/ItemDoctor.js @@ -10,6 +10,9 @@ import Link from "next/link"; import CustomLoading from "./loading/Custom"; import TextLoading from "./loading/Text"; import CircularLoading from "./loading/Circular"; +import moment from "moment-jalaali"; + +moment.loadPersian({ dialect: "persian-modern" }); function ItemDoctor({ doctor }) { return ( @@ -78,7 +81,7 @@ function ItemDoctor({ doctor }) { }`} > {Number(doctor?.active) - ? `اولین نوبت آزاد: ${Number(doctor?.active)}` + ? `اولین نوبت آزاد: ${moment(doctor?.free_turn * 1000)?.format("dddd jD jMMMM")}` : "نوبت ندارد"}

diff --git a/app/component/modalSearchCity/Content.js b/app/component/modalSearchCity/Content.js index b92a954..99e4dc2 100644 --- a/app/component/modalSearchCity/Content.js +++ b/app/component/modalSearchCity/Content.js @@ -21,8 +21,6 @@ function Content({ const handleClick = () => { setLoading(true); sendReq().finally(() => { - console.log("asd"); - setLoading(false); handleClose(); }); diff --git a/app/doctors/page.js b/app/doctors/page.js index 9eb3f2b..30872fa 100644 --- a/app/doctors/page.js +++ b/app/doctors/page.js @@ -1,39 +1,24 @@ import DoctorsPage from "@/components/doctors"; import Layout from "@/components/layout/StLayout"; +import { buildDoctorParams } from "@/helper"; import { getStateInfo } from "@/lib/getStateInfo"; import axios from "axios"; -// Data -import states from "@/data/state.json"; -import cities from "@/data/city.json"; - async function Doctors({ searchParams }) { const { matchedCity, matchedState } = getStateInfo(); const API_URL = process.env.NEXT_PUBLIC_API_URL; let doctors = null; try { - const params = {}; - const state = searchParams.state; - const city = searchParams.city; - console.log(state); - console.log(city); - - if (matchedCity) - params.city = city - ? cities.find((item) => item.name === city)?.id - : matchedCity?.id || null; - if (matchedState) - params.state = state - ? states.find((item) => item.name === state)?.id - : matchedState?.id || null; - if (searchParams.search) params.name = searchParams.search; + const params = buildDoctorParams(searchParams); const response = await axios.get(`${API_URL}/api/v1/doctors`, { params, }); doctors = response.data.data; - } catch (error) {} + } catch (error) { + console.error("Error fetching doctors:", error); + } return ( diff --git a/components/doctors/content/index.js b/components/doctors/content/index.js deleted file mode 100644 index b969e4b..0000000 --- a/components/doctors/content/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' - -function Content() { - return ( -
Content
- ) -} - -export default Content \ No newline at end of file diff --git a/components/doctors/head/FilterLocate.js b/components/doctors/head/FilterLocate.js new file mode 100644 index 0000000..d1b2c89 --- /dev/null +++ b/components/doctors/head/FilterLocate.js @@ -0,0 +1,34 @@ +import LocationD from "../../icons/LocationD"; +import { Button } from "@mui/material"; +import ModalSearchCity from "@/app/component/modalSearchCity"; +import { useState } from "react"; + +function FilterLocate({ filter, sendReq, setFilter, setDataInURL }) { + const [open, setOpen] = useState(false); + + return ( + + + + ); +} + +export default FilterLocate; diff --git a/components/doctors/head/index.js b/components/doctors/head/index.js index ff70419..ff8702a 100644 --- a/components/doctors/head/index.js +++ b/components/doctors/head/index.js @@ -2,38 +2,26 @@ import { useState } from "react"; import SearchBar from "../search"; import SortList from "../sortlist"; -import { Button } from "@mui/material"; -import { useParams, useRouter, useSearchParams } from "next/navigation"; -import LocationD from "../../icons/LocationD"; +import { useRouter, useSearchParams } from "next/navigation"; import specialties from "@/data/specialties.json"; -import ModalSearchCity from "@/app/component/modalSearchCity"; // Data import states from "@/data/state.json"; import cities from "@/data/city.json"; import { QueryForDoctorsFilter, QueryForDoctorsReq } from "@/helper"; import { request } from "@/services/response"; +import FilterLocate from "./FilterLocate"; function Head({ matchedCity, matchedState, setDoctors }) { - const params = useParams(); const searchParams = useSearchParams(); const router = useRouter(); const fieldName = searchParams.get("specialty"); - const [open, setOpen] = useState(false); const findItem = (key, name) => specialties.find((item) => item[key] === name); const isParent = findItem("name", fieldName) && findItem("name", fieldName).parent; - const defaultData = { - category: isParent ? findItem("id", isParent) : findItem("name", fieldName), - specialties: isParent && findItem("name", fieldName), - turn: params && params.hasOwnProperty("turn") ? JSON.parse(params.turn) : 1, - gender: params.gender || "هر دو", - degree: params.degree || "همه موارد", - }; - const selectedState = searchParams.get("state") || matchedState?.name; const selectedCity = searchParams.get("city") || @@ -51,7 +39,6 @@ function Head({ matchedCity, matchedState, setDoctors }) { name: searchParams.get("name") || "", }; - const [data, setData] = useState(defaultData); const [filter, setFilter] = useState(defaultFilter); const setDataInURL = (newFilter) => { @@ -83,27 +70,12 @@ function Head({ matchedCity, matchedState, setDoctors }) { return (
- - - + />
diff --git a/components/doctors/modal/DeleteAllButton.js b/components/doctors/modal/DeleteAllButton.js new file mode 100644 index 0000000..25cfffb --- /dev/null +++ b/components/doctors/modal/DeleteAllButton.js @@ -0,0 +1,58 @@ +import CloseOrangeModal from "@/components/icons/CloseOrangeModal"; +import { Button, CircularProgress } from "@mui/material"; +import { useRouter } from "next/navigation"; +import { clearFilterParams } from "@/helper"; +import { useState } from "react"; + +function DeleteAllButton({ filter, sendReq, setFilter, handleClose }) { + const [loading, setLoading] = useState(false); + const router = useRouter(); + + const resetFilter = () => { + setLoading(true); + clearFilterParams(router, [ + "category", + "specialty", + "active", + "gender", + "degree", + ]); + + const newFilter = { + ...filter, + ...{ + category: undefined, + specialty: undefined, + active: 0, + gender: "هر دو", + degree: "همه موارد", + }, + }; + sendReq(newFilter).finally(() => { + setLoading(false); + handleClose(); + setFilter(newFilter); + }); + }; + + return ( +
+

فیلترها

+ +
+ ); +} + +export default DeleteAllButton; diff --git a/components/doctors/modal/FilterModal.js b/components/doctors/modal/FilterModal.js index eaa56d6..49f4e2a 100644 --- a/components/doctors/modal/FilterModal.js +++ b/components/doctors/modal/FilterModal.js @@ -1,13 +1,11 @@ "use client"; -import CloseOrangeModal from "@/components/icons/CloseOrangeModal"; import { styleDefault } from "@/mui"; -import { Button, Modal } from "@mui/material"; +import { Modal } from "@mui/material"; import { useState } from "react"; import Content from "./Content"; -import { useRouter } from "next/navigation"; -import { clearFilterParams } from "@/helper"; import ButtonApply from "./ButtonApply"; +import DeleteAllButton from "./DeleteAllButton"; function FilterModal({ filter, @@ -17,7 +15,6 @@ function FilterModal({ updateData, setDataInURL, }) { - const router = useRouter(); const [open, setOpen] = useState(false); const handleOpen = () => setOpen(true); @@ -25,30 +22,6 @@ function FilterModal({ setOpen(false); }; - const resetFilter = () => { - clearFilterParams(router, [ - "category", - "specialty", - "active", - "gender", - "degree", - ]); - - const newFilter = { - category: undefined, - specialty: undefined, - active: 0, - gender: "هر دو", - degree: "همه موارد", - }; - setFilter({ - ...filter, - ...newFilter, - }); - - handleClose(); - }; - return ( <> {/* Button Modal */} @@ -62,19 +35,12 @@ function FilterModal({ !w-full md:!w-fit !h-full md:!h-fit !flex !flex-col !justify-between !max-h-screen md:!max-h-[calc(100%_-_32px)]" >
-
-

فیلترها

- -
+ - + diff --git a/components/home/FrequentSearches.js b/components/home/FrequentSearches.js index a0ad3f6..c81f6ef 100644 --- a/components/home/FrequentSearches.js +++ b/components/home/FrequentSearches.js @@ -17,7 +17,7 @@ function FrequentSearches() { href={{ pathname: "/doctors", query: { - field: item.id, + specialty: item.name, }, }} > diff --git a/helper/index.js b/helper/index.js index 850fb08..f225fbc 100644 --- a/helper/index.js +++ b/helper/index.js @@ -1,8 +1,12 @@ import { toast } from "react-toastify"; -import specialties from "@/data/specialties.json"; import Cookies from "js-cookie"; import moment from "moment-jalaali"; +// Data +import specialties from "@/data/specialties.json"; +import states from "@/data/state.json"; +import cities from "@/data/city.json"; + export const numberToArStyle = (num) => num?.toLocaleString("ar-AE") || ""; export const isActiveURL = (link, name) => link === name; @@ -329,9 +333,25 @@ export const QueryForDoctorsReq = (newFilter) => { if (newFilter.state?.id) params.state = newFilter.state.id; if (newFilter.degree && newFilter.degree !== "همه موارد") - params.degree = newFilter.degree; + switch (newFilter.degree) { + case "کارشناس": + params.degree = "expert"; + break; + case "پزشک عمومی": + params.degree = "general"; + break; + case "پزشک متخصص": + params.degree = "specialist"; + break; + case "پزشک فوق تخصص": + params.degree = "subspecialistplus"; + break; + default: + break; + } + if (newFilter.gender && newFilter.gender !== "هر دو") - params.gender = newFilter.gender; + params.gender = newFilter.gender === "مرد" ? "man" : "woman"; if (newFilter.name) params.name = newFilter.name; @@ -342,3 +362,76 @@ export const QueryForDoctorsReq = (newFilter) => { return params; }; + +export const buildDoctorParams = (searchParams) => { + const params = {}; + + // 🔹 active + if (searchParams.active && Number(searchParams.active) === 1) { + params.active = 1; + } + + // 🔹 specialty (find by name in specialties.json) + if (searchParams.specialty) { + const spec = specialties.find((s) => s.name === searchParams.specialty); + if (spec) { + params.specialty = spec.id; + } + } + + // 🔹 city (find by name in city.json) + if (searchParams.city) { + const cityObj = cities.find((c) => c.name === searchParams.city); + if (cityObj) { + params.city = cityObj.id; + } + } + + // 🔹 state (find by name in state.json) + if (searchParams.state) { + const stateObj = states.find((s) => s.name === searchParams.state); + if (stateObj) { + params.state = stateObj.id; + } + } + + // 🔹 degree → convert fa → en + if (searchParams.degree) { + switch (searchParams.degree) { + case "کارشناس": + params.degree = "expert"; + break; + case "پزشک عمومی": + params.degree = "general"; + break; + case "پزشک متخصص": + params.degree = "specialist"; + break; + case "پزشک فوق تخصص": + params.degree = "subspecialistplus"; + break; + default: + break; + } + } + + // 🔹 gender + if (searchParams.gender) { + if (searchParams.gender === "مرد") params.gender = "man"; + if (searchParams.gender === "زن") params.gender = "woman"; + } + + // 🔹 name + if (searchParams.name) { + params.name = searchParams.name; + } + + // 🔹 sort (3 = ASC, 4|5 = DESC) + if (searchParams.sort) { + const sortNum = Number(searchParams.sort); + if (sortNum === 3) params.sort = "ASC"; + else if ([4, 5].includes(sortNum)) params.sort = "DESC"; + } + + return params; +};