send filter degree, gender and speciality with en name, handle set url in doctors page with searchbar home for key field or search, set value of province in url with id, change filter stars with ASC and DESC, bg-color of field in spcialties

This commit is contained in:
Ehsan
2025-09-09 19:48:45 +03:30
parent 8bbe2e03bb
commit d04aa8568d
12 changed files with 203 additions and 43 deletions
+46 -7
View File
@@ -4,17 +4,21 @@ import { Button } from "@mui/material";
import CloseModalD from "@/components/icons/CloseModalD";
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
import ArrowLeftM from "@/components/icons/ArrowLeftM";
import { useState } from "react";
import { request } from "@/services/response";
function Content({
state,
states,
selected,
setDoctors,
updateData,
handleClose,
filteredCities,
handleSearch,
}) {
const citySelected = selected.city;
const [loading, setLoading] = useState(false);
const listboxProps = {
style: {
maxHeight: 200,
@@ -22,12 +26,7 @@ function Content({
},
};
const handleFilter = () => {
const city =
selected &&
citySelected &&
filteredCities.find((item) => item.name === citySelected);
const handleFilter = (city) => {
const current = new URLSearchParams(window.location.search);
current.set("province", city.id);
const newUrl = `${window.location.pathname}?${current.toString()}`;
@@ -37,6 +36,45 @@ function Content({
handleClose();
};
const sendReq = () => {
setLoading(true);
const itemCity =
selected &&
citySelected &&
filteredCities.find((item) => item.name === citySelected);
const params = new URLSearchParams(window.location.search);
const specialty = params.get("specialty");
const gender = params.get("gender");
const degree = params.get("degree");
const active = params.get("turn");
const city =
states.find((item) => item.name === selected.province)?.id || null;
const state =
filteredCities.find((item) => item.name === selected.city)?.id || null;
const requestData = {
specialty: specialty === "null" ? null : specialty,
gender,
degree,
active,
city,
state,
};
request
.getDoctors(requestData)
.then((res) => {
if (res && res.data) setDoctors(res.data);
})
.catch(() => {})
.finally(() => {
setLoading(false);
handleFilter(itemCity);
});
};
const valState =
selected &&
citySelected &&
@@ -78,8 +116,9 @@ function Content({
</div>
<div className="w-full flex justify-end">
<Button
loading={loading}
className="!w-full md:!w-fit !flex !px-3 items-center justify-center gap-1 mr-auto"
onClick={handleFilter}
onClick={sendReq}
variant="contained"
color="primary"
disabled={!selected.city || !selected.province}
+5 -4
View File
@@ -11,20 +11,20 @@ import citiesData from "@/data/city.json";
import Content from "./Content";
function ModalSearchCity({
open,
state,
setOpen,
children,
selected,
setDoctors,
handleSearch,
state,
setSelected,
open,
setOpen,
}) {
const provinceSelected = selected.province;
const states = addLabelToList(statesData);
const cities = addLabelToList(citiesData);
const [filteredCities, setFilteredCities] = useState([]);
state;
const handleClose = () => setOpen(false);
@@ -65,6 +65,7 @@ function ModalSearchCity({
state={state}
states={states}
selected={selected}
setDoctors={setDoctors}
updateData={updateData}
handleClose={handleClose}
handleSearch={handleSearch}
+1
View File
@@ -13,6 +13,7 @@ async function Doctors({ searchParams }) {
if (matchedCity) params.city = matchedCity?.id || null;
if (matchedState) params.state = matchedState?.id || null;
if (searchParams.search) params.name = searchParams.search;
const response = await axios.get(`${API_URL}/api/v1/doctors`, {
params,
+7 -5
View File
@@ -16,7 +16,7 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
const [doctors, setDoctors] = useState(list);
const [open, setOpen] = useState(false);
const [fields, setFields] = useState({
search: "",
search: params.search || "",
stars: "",
});
const [selected, setSelected] = useState({
@@ -28,8 +28,6 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
specialties.find((item) => item[key] === name);
const isParent =
findItem("name", fieldName) && findItem("name", fieldName).parent;
const dataParent =
findItem("name", fieldName) && isParent && findItem("id", isParent);
const defaultData = {
category: isParent ? findItem("id", isParent) : findItem("name", fieldName),
@@ -50,6 +48,7 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
setOpen={setOpen}
selected={selected}
state={matchedState}
setDoctors={setDoctors}
setSelected={setSelected}
>
<Button
@@ -78,10 +77,13 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
setConfirmedData={setConfirmedData}
/>
<SortList
fields={fields}
setFields={setFields}
data={data}
fields={fields}
setData={setData}
setFields={setFields}
setDoctors={setDoctors}
matchedCity={matchedCity}
matchedState={matchedState}
/>
</div>
</div>
+31 -8
View File
@@ -3,6 +3,7 @@ import specialties from "@/data/specialties.json";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { request } from "@/services/response";
import { degreeVal } from "@/helper";
function ButtonApply({
data,
@@ -36,21 +37,32 @@ function ButtonApply({
const mappings = [
{
key: "field",
getValue: () => {
getValue: (name) => {
if (data.category) {
const children = specialties.filter(
(item) => item.parent === data.category.id
);
return children.length > 0
? children.find((item) => item.name === data.specialties.name)
?.name
: data.category.name;
? children.find((item) => item.name === data.specialties.name)[
name || "id"
]
: data.category[name || "id"];
}
return null;
},
},
{ key: "gender", getValue: () => data.gender || null },
{ key: "degree", getValue: () => data.degree || null },
{
key: "gender",
getValue: () => (data.gender === "زن" ? "woman" : "man" || null),
},
{
key: "degree",
getValue: (name) => {
const item = degreeVal.find((item) => item.name === data.degree);
return (item && item[name || "val"]) || null;
},
},
{ key: "turn", getValue: () => data.turn },
];
@@ -60,9 +72,20 @@ function ButtonApply({
};
mappings.forEach(({ key, getValue }) => {
const value = getValue();
let value;
if (key === "field") {
value = getValue("name");
} else if (key === "gender") {
value = data.gender;
} else if ("degree") {
value = getValue("name");
}
current.set(key, value);
requestData[key] = value;
});
mappings.forEach(({ key, getValue }) => {
let value = getValue();
requestData[key === "field" ? "specialty" : key] = value;
});
const queryString = current.toString();
+1 -1
View File
@@ -25,7 +25,7 @@ function SendReq({ fields, setDoctors, matchedCity, matchedState }) {
let state = matchedState?.id || null;
if (province) {
const findCity = cities.find((item) => item.id === province);
const findState = states.find((item) => item.id === findCity.province_id);
const findState = states.find((item) => item.id === findCity?.province_id);
if (findCity) city = findCity.id;
if (findState) state = findState.id;
}
+30 -4
View File
@@ -1,8 +1,9 @@
import { MenuItem, Select, SvgIcon } from "@mui/material";
import { useState } from "react";
import ArrowBottomD from "../../icons/ArrowBottomD";
import SortD from "../../icons/SortD";
import StarDI from "@/components/icons/StarDI";
import { request } from "@/services/response";
import { degreeVal } from "@/helper";
const listSort = [
{ label: 3, id: 3 },
@@ -10,9 +11,34 @@ const listSort = [
{ label: 5, id: 5 },
];
function SelectSort({ fields, setFields }) {
const handleChange = (event) =>
setFields({ ...fields, stars: Number(event.target.value) });
function SelectSort({
data,
fields,
setFields,
setDoctors,
matchedCity,
matchedState,
}) {
const handleChange = (event) => {
const valSort = Number(event.target.value);
setFields({ ...fields, stars: valSort });
const params = { sort: valSort === 3 ? "ASC" : "DESC", active: data.turn };
if (data.specialties) params.specialty = data.specialties.id;
else if (data.category) params.specialty = data.category.id;
if (data.gender !== "هر دو")
params.gender = data.gender === "مرد" ? "man" : "woman";
if (data.degree && data.degree !== "همه موارد")
params.degree = degreeVal.find((item) => item.name === data.degree)?.val;
if (matchedCity) params.city = matchedCity.id;
if (matchedState) params.state = matchedState.id;
request
.getDoctors(params)
.then((res) => {
if (res && res.data) setDoctors(res.data);
})
.catch(() => {});
};
return (
<Select
+17 -2
View File
@@ -4,13 +4,28 @@ import FilterModal from "../modal/FilterModal";
import FilterBtn from "./FilterBtn";
import SelectSort from "./SelectSort";
function SortList({ fields, data, setFields, setData }) {
function SortList({
fields,
data,
setData,
setFields,
setDoctors,
matchedCity,
matchedState,
}) {
return (
<div className="flex flex-wrap items-center lg:!w-[25%] gap-[20px] gap-y-[12px] lg:gap-0">
<FilterModal data={data} setData={setData}>
<FilterBtn />
</FilterModal>
<SelectSort fields={fields} setFields={setFields} />
<SelectSort
data={data}
fields={fields}
setFields={setFields}
setDoctors={setDoctors}
matchedCity={matchedCity}
matchedState={matchedState}
/>
</div>
);
}
+40 -2
View File
@@ -1,8 +1,46 @@
import React from "react";
import { TextField } from "@mui/material";
import { TextField } from "@mui/material";
function FilterText({ data, setData }) {
return (
// <Autocomplete
// freeSolo
// options={specialtiesData}
// getOptionLabel={(option) => option.name}
// // inputValue={inputValue}
// className="!w-full"
// onInputChange={(event, newInputValue) => {
// // setInputValue && setInputValue(newInputValue);
// // handleSearch(newInputValue);
// }}
// onChange={(event, newValue) => {
// setSelectedOption(newValue);
// handleSearch(newValue ? newValue.name : "");
// }}
// renderInput={(params) => (
// <TextField
// {...params}
// variant="standard"
// placeholder={placeholder}
// dir="rtl"
// InputProps={{
// ...params.InputProps,
// disableUnderline: true,
// style: { height: "100%" },
// }}
// sx={{
// background: "transparent !important",
// "& .MuiInputBase-input": {
// background: "#FAFAFA",
// color: "#6C757D",
// padding: "0 16px",
// fontSize: "14px",
// fontFamily: "inherit",
// },
// }}
// className="!shadow-none !w-full !px-5 !h-full !text-[14px] md:!text-[16px] !min-w-[50%] !rounded-0 !font-normal"
// />
// )}
// />
<TextField
variant="standard"
onChange={(e) => setData({ ...data, search: e.target.value })}
+19 -5
View File
@@ -4,16 +4,30 @@ import SearchD from "@/components/icons/SearchD";
import { Search } from "@mui/icons-material";
import { Button } from "@mui/material";
import { useRouter } from "next/navigation";
import specialties from "@/data/specialties.json";
import cities from "@/data/city.json";
function RedirectLink({ data }) {
const router = useRouter();
const handleRedirect = () => {
const queryParams = new URLSearchParams({
province: data.province || "",
city: data.city || "",
search: data.search || "",
}).toString();
const filters = {};
if (data.province) {
const item = cities.find((item) => item.name === data.city);
filters.province = item.id;
}
if (data.search) {
const specialtyItem = specialties.find((item) =>
item.name.includes(data.search)
);
if (specialtyItem) {
filters.field = specialtyItem.name;
} else {
filters.search = data.search;
}
}
const queryParams = new URLSearchParams(filters).toString();
router.push(`/doctors?${queryParams}`);
};
-5
View File
@@ -1,5 +0,0 @@
function LgSearch() {
return <div>LgSearch</div>;
}
export default LgSearch;
+6
View File
@@ -257,3 +257,9 @@ export const dateToTimestamp = (date) => {
return inSeconde;
};
export const degreeVal = [
{ name: "پزشک عمومی", val: "general" },
{ name: "پزشک متخصص", val: "specialist" },
{ name: "پزشک فوق تخصص", val: "subspecialistplus" },
];