handle save some data and send server correct & change component form & clean code & fix bugs

This commit is contained in:
Ehsan
2025-07-18 13:54:48 +03:30
parent 278602372d
commit 901bca6529
9 changed files with 235 additions and 108 deletions
+3 -8
View File
@@ -16,17 +16,12 @@ function SendAppo({ hour }) {
doctor_id: doctorId, doctor_id: doctorId,
slot: hour, slot: hour,
}) })
.then((res) => { .then(() => {
setLoading(false); setLoading(false);
}) })
.catch((err) => { .catch(() => {
console.log(err); //
}); });
// if (locateVisit) {
// setStep((prev) => prev + 1);
// } else {
// setIsError(true);
// }
}; };
return ( return (
+102
View File
@@ -0,0 +1,102 @@
import MenuItem from "@mui/material/MenuItem";
import ListSubheader from "@mui/material/ListSubheader";
import Select from "@mui/material/Select";
import { useState } from "react";
import { styleTextSelectRight } from "@/mui";
import IconMultipleSelect from "@/components/icons/IconMultipleSelect";
function groupSpecialtiesByParent(specialties) {
const groups = [];
const parents = specialties.filter((item) => item.parent === null);
parents.forEach((parent) => {
const children = specialties.filter((item) => item.parent === parent.id);
if (children.length > 0) {
groups.push({
parent,
children,
});
}
});
return groups;
}
export default function GroupedSelect({
list,
name,
updateData,
data,
nameKey = "name",
}) {
const groupedList = groupSpecialtiesByParent(list);
const handleChange = (event) => {
const value = event.target.value;
updateData && updateData(value, "value", name);
};
return (
<div className="w-full auto-complete-selector">
<Select
value={data}
onChange={handleChange}
IconComponent={IconMultipleSelect}
MenuProps={{
style: {
maxHeight: 300,
},
}}
className="!w-full"
sx={{
...styleTextSelectRight,
"& .MuiSelect-icon": {
left: "16px",
right: "auto",
},
"& .MuiInputBase-input": { padding: "12.5px 14px !important" },
"& .MuiInputBase-root": {
borderRadius: 2,
padding: "0 !important",
height: {
xs: "43px !important",
sm: "43px !important",
md: "46px !important",
lg: "48px !important",
},
},
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7",
},
"& .MuiInput-underline:hover:not(.Mui-disabled):before, .MuiOutlinedInput-notchedOutline":
{
borderColor: "#D7D7D7 !important",
},
"& .muirtl-1kiro5a-MuiInputBase-root-MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline":
{
border: "1px solid #5559CE !important",
},
}}
>
{groupedList.map((group) => [
<ListSubheader
key={group.parent.id}
sx={{
backgroundColor: "#35343D",
color: "#fff",
fontSize: "14px",
}}
>
{group.parent[nameKey]}
</ListSubheader>,
...group.children.map((child) => (
<MenuItem key={child.id} value={child.id}>
{child[nameKey]}
</MenuItem>
)),
])}
</Select>
</div>
);
}
+97
View File
@@ -0,0 +1,97 @@
import Selector from "./fields/Selector";
import EditField from "@/app/component/fields/EditField";
import GroupedSelect from "@/app/component/selectors/GroupedSelect";
import MultipleSelect from "@/app/component/selectors/MultipleSelect";
// Data
import specialties from "@/data/specialties.json";
import education from "@/data/education.json";
import ContentText from "@/app/component/ContentText";
const validate_medical_number = {
min: 1,
max: 9999999999,
};
function Fields({ services, data, updateNum, changeData }) {
return (
<>
<ContentText text="نام و نام خانوادگی">
<EditField
isTransparent={true}
iconGray={true}
changeData={changeData}
data={data?.name}
placeholder={data?.name.placeholder}
name="name"
/>
</ContentText>
<ContentText text="شماره نظام پزشکی">
<EditField
isTransparent={true}
iconGray={true}
changeData={updateNum}
data={data?.medical_system_number}
noDisable={true}
type="number"
placeholder={data?.medical_system_number.placeholder}
name="medical_system_number"
props={{
inputProps: validate_medical_number,
}}
/>
</ContentText>
<ContentText text="تخصص">
<GroupedSelect
updateData={changeData}
data={data?.expertise.value}
name="expertise"
list={specialties}
nameKey="name"
/>
</ContentText>
<ContentText text="مدرک">
<Selector
updateData={changeData}
label="انتخاب کنید..."
name="degree"
data={data?.degree.value}
list={education}
nameKey="label"
/>
</ContentText>
<ContentText text="مهارت ها">
<MultipleSelect
name="skills"
list={services}
updateData={changeData}
value={data?.skills.value}
/>
</ContentText>
<ContentText text="شماره موبایل">
<EditField
isTransparent={true}
iconGray={true}
changeData={changeData}
data={data?.phone}
type="number"
placeholder={data?.phone.placeholder}
name="phone"
/>
</ContentText>
<ContentText text="توضیحات">
<EditField
multiline={5}
placeholder="درباره سوابق خود توضیحاتی بنویسید..."
isTransparent={true}
iconGray={true}
changeData={changeData}
data={data?.description}
name="description"
/>
</ContentText>
</>
);
}
export default Fields;
@@ -1,11 +1,11 @@
import { FormControlLabel, Radio, RadioGroup } from "@mui/material"; import { FormControlLabel, Radio, RadioGroup } from "@mui/material";
function RadioGender({ changeData, name }) { function RadioGender({ changeData, name, data }) {
return ( return (
<RadioGroup <RadioGroup
dir="ltr" dir="ltr"
value={data}
className="!flex radio-mui !flex-row !gap-[36px] !items-center !justify-start" className="!flex radio-mui !flex-row !gap-[36px] !items-center !justify-start"
defaultValue="woman"
onChange={(e) => changeData(e.target.value, "value", name)} onChange={(e) => changeData(e.target.value, "value", name)}
sx={{ sx={{
"& .muirtl-j204z7-MuiFormControlLabel-root": { "& .muirtl-j204z7-MuiFormControlLabel-root": {
@@ -17,12 +17,14 @@ function RadioGender({ changeData, name }) {
label="مرد" label="مرد"
value="man" value="man"
control={<Radio />} control={<Radio />}
dir="rtl"
className="!text-[#A1A1A1]" className="!text-[#A1A1A1]"
/> />
<FormControlLabel <FormControlLabel
label="زن" label="زن"
value="woman" value="woman"
control={<Radio />} control={<Radio />}
dir="rtl"
className="!text-[#A1A1A1]" className="!text-[#A1A1A1]"
/> />
</RadioGroup> </RadioGroup>
@@ -2,9 +2,12 @@ import BottomSelect from "@/components/icons/BottomSelect";
import { Autocomplete, Button, TextField } from "@mui/material"; import { Autocomplete, Button, TextField } from "@mui/material";
import { styleTextSelectRight } from "@/mui"; import { styleTextSelectRight } from "@/mui";
function Selector({ updateData, nameKey, label, name, list }) { function Selector({ data, updateData, nameKey, label, name, list }) {
const selectedOption = list.find((item) => item.id === data) || null;
return ( return (
<Autocomplete <Autocomplete
value={selectedOption}
disablePortal disablePortal
options={list} options={list}
getOptionLabel={(option) => option[nameKey] || ""} getOptionLabel={(option) => option[nameKey] || ""}
@@ -17,7 +20,6 @@ function Selector({ updateData, nameKey, label, name, list }) {
}} }}
sx={{ sx={{
...styleTextSelectRight, ...styleTextSelectRight,
// Hide Icon Number
"& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button": "& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button":
{ {
display: "none", display: "none",
+19 -92
View File
@@ -2,17 +2,9 @@ import { useEffect, useState } from "react";
import FieldDate from "./fields/FieldDate"; import FieldDate from "./fields/FieldDate";
import RadioGender from "./fields/RadioGender"; import RadioGender from "./fields/RadioGender";
import SendReq from "./sendReq"; import SendReq from "./sendReq";
import Selector from "./fields/Selector";
// Components
import EditField from "@/app/component/fields/EditField";
import ContentText from "@/app/component/ContentText"; import ContentText from "@/app/component/ContentText";
// Data
import specialties from "@/data/specialties.json";
import education from "@/data/education.json";
import MultipleSelect from "@/app/component/selectors/MultipleSelect";
import { request } from "@/services/response"; import { request } from "@/services/response";
import Fields from "./Fields";
const validate_medical_number = { const validate_medical_number = {
min: 1, min: 1,
@@ -41,7 +33,6 @@ function Form({ image, data, setData, resetData }) {
const validateValue = parseValue > max ? data[name].value : value; const validateValue = parseValue > max ? data[name].value : value;
changeData(validateValue, type, name); changeData(validateValue, type, name);
}; };
const filteredSpe = specialties.filter((item) => item.parent);
useEffect(() => { useEffect(() => {
request request
@@ -49,94 +40,30 @@ function Form({ image, data, setData, resetData }) {
.then((res) => { .then((res) => {
setServices(res.data); setServices(res.data);
}) })
.catch((err) => { .catch(() => {
console.log(err); //
}); });
}, []); }, []);
console.log(services);
return ( return (
<> <>
<div className="mt-[24px] sm-modal scroll-mui md:mt-[26px] lg:mt-[28px] grid grid-cols-1 md:grid-cols-2 gap-x-[48px] gap-y-[24px]"> <div className="mt-[24px] sm-modal scroll-mui md:mt-[26px] lg:mt-[28px] grid grid-cols-1 md:grid-cols-2 gap-x-[48px] gap-y-[24px]">
<ContentText text="نام و نام خانوادگی"> <Fields
<EditField data={data}
isTransparent={true} services={services}
iconGray={true} changeData={changeData}
changeData={changeData} updateNum={updateNum}
data={data?.name} />
placeholder={data?.name.placeholder} <div className="flex flex-col gap-y-[24px]">
name="name" <FieldDate changeListData={changeData} data={data?.time_work} />
/> <ContentText text="جنسیت">
</ContentText> <RadioGender
<ContentText text="شماره نظام پزشکی"> changeData={changeData}
<EditField data={data?.gender.value}
isTransparent={true} name="gender"
iconGray={true} />
changeData={updateNum} </ContentText>
data={data?.medical_system_number} </div>
noDisable={true}
type="number"
placeholder={data?.medical_system_number.placeholder}
name="medical_system_number"
props={{
inputProps: validate_medical_number,
}}
/>
</ContentText>
<ContentText text="تخصص">
<Selector
updateData={changeData}
data={data?.expertise.value}
label="انتخاب کنید..."
name="expertise"
list={filteredSpe}
nameKey="name"
/>
</ContentText>
<ContentText text="مدرک">
<Selector
updateData={changeData}
label="انتخاب کنید..."
name="degree"
data={data?.degree.value}
list={education}
nameKey="label"
/>
</ContentText>
<ContentText text="مهارت ها">
<MultipleSelect
name="skills"
list={services}
updateData={changeData}
value={data?.skills.value}
/>
</ContentText>
<ContentText text="شماره موبایل">
<EditField
isTransparent={true}
iconGray={true}
changeData={changeData}
data={data?.phone}
type="number"
placeholder={data?.phone.placeholder}
name="phone"
/>
</ContentText>
<FieldDate changeListData={changeData} data={data?.time_work} />
<ContentText text="جنسیت">
<RadioGender changeData={changeData} name="gender" />
</ContentText>
<ContentText text="توضیحات">
<EditField
multiline={5}
placeholder="درباره سوابق خود توضیحاتی بنویسید..."
isTransparent={true}
iconGray={true}
changeData={changeData}
data={data?.description}
name="description"
/>
</ContentText>
</div> </div>
<SendReq img={image} data={data} resetData={resetData} /> <SendReq img={image} data={data} resetData={resetData} />
</> </>
@@ -12,7 +12,10 @@ export const transformData = (data) => {
activity_time: dateToTimestamp(data.time_work.value), activity_time: dateToTimestamp(data.time_work.value),
doctor_mobile_number: data.phone.value, doctor_mobile_number: data.phone.value,
degree: data.degree.value, degree: data.degree.value,
specialty: [Number(data.expertise.value)], specialty: [data.expertise.value],
info: data.description.value, info: data.description.value,
doctor_id: data.medical_system_number.value,
doctor_services: data.skills.value,
gender: data.gender.value,
}; };
}; };
@@ -27,6 +27,7 @@ function SendReq({ img, data, resetData }) {
}; };
const saveImg = () => { const saveImg = () => {
resetData();
setLoading(true); setLoading(true);
if (img) { if (img) {
request request
@@ -35,7 +36,7 @@ function SendReq({ img, data, resetData }) {
const imgId = res.fid[0].value; const imgId = res.fid[0].value;
saveData(imgId); saveData(imgId);
}) })
.catch((err) => { .catch(() => {
setLoading(false); setLoading(false);
}); });
} else { } else {
@@ -47,7 +48,6 @@ function SendReq({ img, data, resetData }) {
<div className="mt-[40px] w-full flex justify-end"> <div className="mt-[40px] w-full flex justify-end">
<Button <Button
className="!w-full md:!w-fit !shadow-none !rounded-[4px] !gap-[4px] !text-[#EFEFEF] !text-[14px] md:!text-[16px] !font-medium" className="!w-full md:!w-fit !shadow-none !rounded-[4px] !gap-[4px] !text-[#EFEFEF] !text-[14px] md:!text-[16px] !font-medium"
// onClick={() => setValue((prev) => prev + 1)}
disabled={!checkAllValues(data)} disabled={!checkAllValues(data)}
variant="contained" variant="contained"
onClick={saveImg} onClick={saveImg}
-1
View File
@@ -8,7 +8,6 @@ import UploadFile from "@/app/component/uploadFile";
function AddDoctorPage() { function AddDoctorPage() {
const [data, setData] = useState(defaultState); const [data, setData] = useState(defaultState);
const [image, setImage] = useState(""); const [image, setImage] = useState("");
console.log(data);
const resetData = () => { const resetData = () => {
setData(defaultState); setData(defaultState);