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:
@@ -4,17 +4,21 @@ import { Button } from "@mui/material";
|
|||||||
import CloseModalD from "@/components/icons/CloseModalD";
|
import CloseModalD from "@/components/icons/CloseModalD";
|
||||||
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
|
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
|
||||||
import ArrowLeftM from "@/components/icons/ArrowLeftM";
|
import ArrowLeftM from "@/components/icons/ArrowLeftM";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { request } from "@/services/response";
|
||||||
|
|
||||||
function Content({
|
function Content({
|
||||||
state,
|
state,
|
||||||
states,
|
states,
|
||||||
selected,
|
selected,
|
||||||
|
setDoctors,
|
||||||
updateData,
|
updateData,
|
||||||
handleClose,
|
handleClose,
|
||||||
filteredCities,
|
filteredCities,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
}) {
|
}) {
|
||||||
const citySelected = selected.city;
|
const citySelected = selected.city;
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
const listboxProps = {
|
const listboxProps = {
|
||||||
style: {
|
style: {
|
||||||
maxHeight: 200,
|
maxHeight: 200,
|
||||||
@@ -22,12 +26,7 @@ function Content({
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilter = () => {
|
const handleFilter = (city) => {
|
||||||
const city =
|
|
||||||
selected &&
|
|
||||||
citySelected &&
|
|
||||||
filteredCities.find((item) => item.name === citySelected);
|
|
||||||
|
|
||||||
const current = new URLSearchParams(window.location.search);
|
const current = new URLSearchParams(window.location.search);
|
||||||
current.set("province", city.id);
|
current.set("province", city.id);
|
||||||
const newUrl = `${window.location.pathname}?${current.toString()}`;
|
const newUrl = `${window.location.pathname}?${current.toString()}`;
|
||||||
@@ -37,6 +36,45 @@ function Content({
|
|||||||
handleClose();
|
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 =
|
const valState =
|
||||||
selected &&
|
selected &&
|
||||||
citySelected &&
|
citySelected &&
|
||||||
@@ -78,8 +116,9 @@ function Content({
|
|||||||
</div>
|
</div>
|
||||||
<div className="w-full flex justify-end">
|
<div className="w-full flex justify-end">
|
||||||
<Button
|
<Button
|
||||||
|
loading={loading}
|
||||||
className="!w-full md:!w-fit !flex !px-3 items-center justify-center gap-1 mr-auto"
|
className="!w-full md:!w-fit !flex !px-3 items-center justify-center gap-1 mr-auto"
|
||||||
onClick={handleFilter}
|
onClick={sendReq}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
disabled={!selected.city || !selected.province}
|
disabled={!selected.city || !selected.province}
|
||||||
|
|||||||
@@ -11,20 +11,20 @@ import citiesData from "@/data/city.json";
|
|||||||
import Content from "./Content";
|
import Content from "./Content";
|
||||||
|
|
||||||
function ModalSearchCity({
|
function ModalSearchCity({
|
||||||
|
open,
|
||||||
|
state,
|
||||||
|
setOpen,
|
||||||
children,
|
children,
|
||||||
selected,
|
selected,
|
||||||
|
setDoctors,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
state,
|
|
||||||
setSelected,
|
setSelected,
|
||||||
open,
|
|
||||||
setOpen,
|
|
||||||
}) {
|
}) {
|
||||||
const provinceSelected = selected.province;
|
const provinceSelected = selected.province;
|
||||||
|
|
||||||
const states = addLabelToList(statesData);
|
const states = addLabelToList(statesData);
|
||||||
const cities = addLabelToList(citiesData);
|
const cities = addLabelToList(citiesData);
|
||||||
const [filteredCities, setFilteredCities] = useState([]);
|
const [filteredCities, setFilteredCities] = useState([]);
|
||||||
state;
|
|
||||||
|
|
||||||
const handleClose = () => setOpen(false);
|
const handleClose = () => setOpen(false);
|
||||||
|
|
||||||
@@ -65,6 +65,7 @@ function ModalSearchCity({
|
|||||||
state={state}
|
state={state}
|
||||||
states={states}
|
states={states}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
|
setDoctors={setDoctors}
|
||||||
updateData={updateData}
|
updateData={updateData}
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
handleSearch={handleSearch}
|
handleSearch={handleSearch}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ async function Doctors({ searchParams }) {
|
|||||||
|
|
||||||
if (matchedCity) params.city = matchedCity?.id || null;
|
if (matchedCity) params.city = matchedCity?.id || null;
|
||||||
if (matchedState) params.state = matchedState?.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`, {
|
const response = await axios.get(`${API_URL}/api/v1/doctors`, {
|
||||||
params,
|
params,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
|
|||||||
const [doctors, setDoctors] = useState(list);
|
const [doctors, setDoctors] = useState(list);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [fields, setFields] = useState({
|
const [fields, setFields] = useState({
|
||||||
search: "",
|
search: params.search || "",
|
||||||
stars: "",
|
stars: "",
|
||||||
});
|
});
|
||||||
const [selected, setSelected] = useState({
|
const [selected, setSelected] = useState({
|
||||||
@@ -28,8 +28,6 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
|
|||||||
specialties.find((item) => item[key] === name);
|
specialties.find((item) => item[key] === name);
|
||||||
const isParent =
|
const isParent =
|
||||||
findItem("name", fieldName) && findItem("name", fieldName).parent;
|
findItem("name", fieldName) && findItem("name", fieldName).parent;
|
||||||
const dataParent =
|
|
||||||
findItem("name", fieldName) && isParent && findItem("id", isParent);
|
|
||||||
|
|
||||||
const defaultData = {
|
const defaultData = {
|
||||||
category: isParent ? findItem("id", isParent) : findItem("name", fieldName),
|
category: isParent ? findItem("id", isParent) : findItem("name", fieldName),
|
||||||
@@ -50,6 +48,7 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
|
|||||||
setOpen={setOpen}
|
setOpen={setOpen}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
state={matchedState}
|
state={matchedState}
|
||||||
|
setDoctors={setDoctors}
|
||||||
setSelected={setSelected}
|
setSelected={setSelected}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@@ -78,10 +77,13 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
|
|||||||
setConfirmedData={setConfirmedData}
|
setConfirmedData={setConfirmedData}
|
||||||
/>
|
/>
|
||||||
<SortList
|
<SortList
|
||||||
fields={fields}
|
|
||||||
setFields={setFields}
|
|
||||||
data={data}
|
data={data}
|
||||||
|
fields={fields}
|
||||||
setData={setData}
|
setData={setData}
|
||||||
|
setFields={setFields}
|
||||||
|
setDoctors={setDoctors}
|
||||||
|
matchedCity={matchedCity}
|
||||||
|
matchedState={matchedState}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import specialties from "@/data/specialties.json";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { request } from "@/services/response";
|
import { request } from "@/services/response";
|
||||||
|
import { degreeVal } from "@/helper";
|
||||||
|
|
||||||
function ButtonApply({
|
function ButtonApply({
|
||||||
data,
|
data,
|
||||||
@@ -36,21 +37,32 @@ function ButtonApply({
|
|||||||
const mappings = [
|
const mappings = [
|
||||||
{
|
{
|
||||||
key: "field",
|
key: "field",
|
||||||
getValue: () => {
|
getValue: (name) => {
|
||||||
if (data.category) {
|
if (data.category) {
|
||||||
const children = specialties.filter(
|
const children = specialties.filter(
|
||||||
(item) => item.parent === data.category.id
|
(item) => item.parent === data.category.id
|
||||||
);
|
);
|
||||||
return children.length > 0
|
return children.length > 0
|
||||||
? children.find((item) => item.name === data.specialties.name)
|
? children.find((item) => item.name === data.specialties.name)[
|
||||||
?.name
|
name || "id"
|
||||||
: data.category.name;
|
]
|
||||||
|
: data.category[name || "id"];
|
||||||
}
|
}
|
||||||
return null;
|
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 },
|
{ key: "turn", getValue: () => data.turn },
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -60,9 +72,20 @@ function ButtonApply({
|
|||||||
};
|
};
|
||||||
|
|
||||||
mappings.forEach(({ key, getValue }) => {
|
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);
|
current.set(key, value);
|
||||||
requestData[key] = value;
|
});
|
||||||
|
|
||||||
|
mappings.forEach(({ key, getValue }) => {
|
||||||
|
let value = getValue();
|
||||||
|
requestData[key === "field" ? "specialty" : key] = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
const queryString = current.toString();
|
const queryString = current.toString();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function SendReq({ fields, setDoctors, matchedCity, matchedState }) {
|
|||||||
let state = matchedState?.id || null;
|
let state = matchedState?.id || null;
|
||||||
if (province) {
|
if (province) {
|
||||||
const findCity = cities.find((item) => item.id === 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 (findCity) city = findCity.id;
|
||||||
if (findState) state = findState.id;
|
if (findState) state = findState.id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { MenuItem, Select, SvgIcon } from "@mui/material";
|
import { MenuItem, Select, SvgIcon } from "@mui/material";
|
||||||
import { useState } from "react";
|
|
||||||
import ArrowBottomD from "../../icons/ArrowBottomD";
|
import ArrowBottomD from "../../icons/ArrowBottomD";
|
||||||
import SortD from "../../icons/SortD";
|
import SortD from "../../icons/SortD";
|
||||||
import StarDI from "@/components/icons/StarDI";
|
import StarDI from "@/components/icons/StarDI";
|
||||||
|
import { request } from "@/services/response";
|
||||||
|
import { degreeVal } from "@/helper";
|
||||||
|
|
||||||
const listSort = [
|
const listSort = [
|
||||||
{ label: 3, id: 3 },
|
{ label: 3, id: 3 },
|
||||||
@@ -10,9 +11,34 @@ const listSort = [
|
|||||||
{ label: 5, id: 5 },
|
{ label: 5, id: 5 },
|
||||||
];
|
];
|
||||||
|
|
||||||
function SelectSort({ fields, setFields }) {
|
function SelectSort({
|
||||||
const handleChange = (event) =>
|
data,
|
||||||
setFields({ ...fields, stars: Number(event.target.value) });
|
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 (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@@ -4,13 +4,28 @@ import FilterModal from "../modal/FilterModal";
|
|||||||
import FilterBtn from "./FilterBtn";
|
import FilterBtn from "./FilterBtn";
|
||||||
import SelectSort from "./SelectSort";
|
import SelectSort from "./SelectSort";
|
||||||
|
|
||||||
function SortList({ fields, data, setFields, setData }) {
|
function SortList({
|
||||||
|
fields,
|
||||||
|
data,
|
||||||
|
setData,
|
||||||
|
setFields,
|
||||||
|
setDoctors,
|
||||||
|
matchedCity,
|
||||||
|
matchedState,
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-wrap items-center lg:!w-[25%] gap-[20px] gap-y-[12px] lg:gap-0">
|
<div className="flex flex-wrap items-center lg:!w-[25%] gap-[20px] gap-y-[12px] lg:gap-0">
|
||||||
<FilterModal data={data} setData={setData}>
|
<FilterModal data={data} setData={setData}>
|
||||||
<FilterBtn />
|
<FilterBtn />
|
||||||
</FilterModal>
|
</FilterModal>
|
||||||
<SelectSort fields={fields} setFields={setFields} />
|
<SelectSort
|
||||||
|
data={data}
|
||||||
|
fields={fields}
|
||||||
|
setFields={setFields}
|
||||||
|
setDoctors={setDoctors}
|
||||||
|
matchedCity={matchedCity}
|
||||||
|
matchedState={matchedState}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,46 @@
|
|||||||
import React from "react";
|
import { TextField } from "@mui/material";
|
||||||
import { TextField } from "@mui/material";
|
|
||||||
|
|
||||||
function FilterText({ data, setData }) {
|
function FilterText({ data, setData }) {
|
||||||
return (
|
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
|
<TextField
|
||||||
variant="standard"
|
variant="standard"
|
||||||
onChange={(e) => setData({ ...data, search: e.target.value })}
|
onChange={(e) => setData({ ...data, search: e.target.value })}
|
||||||
|
|||||||
@@ -4,16 +4,30 @@ import SearchD from "@/components/icons/SearchD";
|
|||||||
import { Search } from "@mui/icons-material";
|
import { Search } from "@mui/icons-material";
|
||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import specialties from "@/data/specialties.json";
|
||||||
|
import cities from "@/data/city.json";
|
||||||
|
|
||||||
function RedirectLink({ data }) {
|
function RedirectLink({ data }) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const handleRedirect = () => {
|
const handleRedirect = () => {
|
||||||
const queryParams = new URLSearchParams({
|
const filters = {};
|
||||||
province: data.province || "",
|
if (data.province) {
|
||||||
city: data.city || "",
|
const item = cities.find((item) => item.name === data.city);
|
||||||
search: data.search || "",
|
filters.province = item.id;
|
||||||
}).toString();
|
}
|
||||||
|
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}`);
|
router.push(`/doctors?${queryParams}`);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
function LgSearch() {
|
|
||||||
return <div>LgSearch</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LgSearch;
|
|
||||||
@@ -257,3 +257,9 @@ export const dateToTimestamp = (date) => {
|
|||||||
|
|
||||||
return inSeconde;
|
return inSeconde;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const degreeVal = [
|
||||||
|
{ name: "پزشک عمومی", val: "general" },
|
||||||
|
{ name: "پزشک متخصص", val: "specialist" },
|
||||||
|
{ name: "پزشک فوق تخصص", val: "subspecialistplus" },
|
||||||
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user