page add panel/doctor role agent && save data crop img && upload img && just roles agent can access panel && save data doctor && add field phone number && remove two tab
This commit is contained in:
@@ -1,15 +1,19 @@
|
|||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Cropper from "react-easy-crop";
|
import Cropper from "react-easy-crop";
|
||||||
import { cropImage } from "./cropImg";
|
import { cropImage, dataURLtoFile } from "./cropImg";
|
||||||
|
|
||||||
function Crop({ data, uploadImg, handleClose }) {
|
function Crop({ data, uploadImg, handleClose }) {
|
||||||
const [crop, setCrop] = useState({ x: 0, y: 0 });
|
const [crop, setCrop] = useState({ x: 0, y: 0 });
|
||||||
const [zoom, setZoom] = useState(1);
|
const [zoom, setZoom] = useState(1);
|
||||||
const [croppedAreaPixels, setCroppedAreaPixels] = useState(null);
|
const [croppedAreaPixels, setCroppedAreaPixels] = useState(null);
|
||||||
|
|
||||||
const onComplete = (imagePromisse) =>
|
const onComplete = async (imagePromise) => {
|
||||||
imagePromisse.then((image) => uploadImg(image));
|
const dataUrl = await imagePromise;
|
||||||
|
const file = dataURLtoFile(dataUrl, "cropped-image.jpg");
|
||||||
|
|
||||||
|
uploadImg({ blob: dataUrl, file });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-[16px]">
|
<div className="mt-[16px]">
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ async function getCroppedImg(imageSrc, pixelCrop) {
|
|||||||
ctx.drawImage(
|
ctx.drawImage(
|
||||||
image,
|
image,
|
||||||
safeArea / 2 - image.width * 0.5,
|
safeArea / 2 - image.width * 0.5,
|
||||||
safeArea / 2 - image.height * 0.5,
|
safeArea / 2 - image.height * 0.5
|
||||||
);
|
);
|
||||||
const data = ctx.getImageData(0, 0, safeArea, safeArea);
|
const data = ctx.getImageData(0, 0, safeArea, safeArea);
|
||||||
|
|
||||||
@@ -31,12 +31,26 @@ async function getCroppedImg(imageSrc, pixelCrop) {
|
|||||||
ctx.putImageData(
|
ctx.putImageData(
|
||||||
data,
|
data,
|
||||||
Math.round(0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x),
|
Math.round(0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x),
|
||||||
Math.round(0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y),
|
Math.round(0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y)
|
||||||
);
|
);
|
||||||
|
|
||||||
return canvas.toDataURL("image/jpeg");
|
return canvas.toDataURL("image/jpeg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const dataURLtoFile = (dataurl, filename) => {
|
||||||
|
const arr = dataurl.split(",");
|
||||||
|
const mime = arr[0].match(/:(.*?);/)[1];
|
||||||
|
const bstr = atob(arr[1]);
|
||||||
|
let n = bstr.length;
|
||||||
|
const u8arr = new Uint8Array(n);
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new File([u8arr], filename, { type: mime });
|
||||||
|
};
|
||||||
|
|
||||||
export const cropImage = async (image, croppedAreaPixels, onError) => {
|
export const cropImage = async (image, croppedAreaPixels, onError) => {
|
||||||
try {
|
try {
|
||||||
const croppedImage = await getCroppedImg(image, croppedAreaPixels);
|
const croppedImage = await getCroppedImg(image, croppedAreaPixels);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function UploadFile({ image, setImage }) {
|
|||||||
<Image
|
<Image
|
||||||
width={24}
|
width={24}
|
||||||
height={24}
|
height={24}
|
||||||
src={image}
|
src={image.blob}
|
||||||
alt="img-uploaded"
|
alt="img-uploaded"
|
||||||
className="w-[74px] h-[74px] rounded-full overflow-hidden object-cover"
|
className="w-[74px] h-[74px] rounded-full overflow-hidden object-cover"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { redirect } from "next/navigation";
|
|||||||
export default async function Dashboard({ searchParams }) {
|
export default async function Dashboard({ searchParams }) {
|
||||||
const { matchedCity } = getStateInfo();
|
const { matchedCity } = getStateInfo();
|
||||||
const user = await getUser();
|
const user = await getUser();
|
||||||
|
|
||||||
const ability = defineAbilitiesFor(user);
|
const ability = defineAbilitiesFor(user);
|
||||||
const cookieStore = cookies();
|
const cookieStore = cookies();
|
||||||
const token = cookieStore.get("access_token");
|
const token = cookieStore.get("access_token");
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
import Content from "@/components/panel/Content";
|
import Content from "@/components/panel/Content";
|
||||||
|
import { defineAbilitiesFor } from "@/lib/ability";
|
||||||
|
import { getUser } from "@/lib/auth";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
async function LayoutPanel({ children }) {
|
||||||
|
const user = await getUser();
|
||||||
|
const ability = defineAbilitiesFor(user);
|
||||||
|
|
||||||
|
if (!ability.can("access", "Panel")) {
|
||||||
|
return redirect("/");
|
||||||
|
}
|
||||||
|
|
||||||
function LayoutPanel({ children }) {
|
|
||||||
return <Content children={children} />;
|
return <Content children={children} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
import CalendarTick from "@/components/icons/CalendarTick";
|
|
||||||
import LocationAdd from "@/components/icons/LocationAdd";
|
|
||||||
import UserEdit from "@/components/icons/UserEdit";
|
|
||||||
|
|
||||||
function Step({ value }) {
|
|
||||||
const list = [
|
|
||||||
{ icon: <UserEdit active={value >= 0} />, name: "اطلاعات عمومی" },
|
|
||||||
{ icon: <LocationAdd active={value >= 1} />, name: "اطلاعات مطب" },
|
|
||||||
{ icon: <CalendarTick active={value >= 2} />, name: "روزهای کاری" },
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ul className="flex items-center justify-center">
|
|
||||||
{list.map((item, idx) => (
|
|
||||||
<li className="flex items-center justify-center" key={idx}>
|
|
||||||
<div className="flex flex-col items-center justify-center gap-2">
|
|
||||||
<div
|
|
||||||
className={`flex items-center bg-[#F6F6F6] justify-center p-[18px]
|
|
||||||
w-[32px] h-[32px] sm:w-[46px] sm:h-[46px] md:w-[60px] md:h-[60px] lg:w-[75px] lg:h-[75px] rounded-full
|
|
||||||
relative overflow-hidden before:delay-500 before:transition-all before:duration-500
|
|
||||||
before:absolute before:w-full before:h-full before:bg-[#5559CE] dark:bg-[#D7D8ED]
|
|
||||||
${
|
|
||||||
value >= idx
|
|
||||||
? "before:right-0 !bg-transparent delay-700"
|
|
||||||
: "before:-right-full"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="z-10 delay-500">{item.icon}</div>
|
|
||||||
</div>
|
|
||||||
<p
|
|
||||||
className={`text-[10px] sm:text-[12px] md:text-[14px] lg:text-[16px] text-nowrap delay-500
|
|
||||||
${
|
|
||||||
value >= idx
|
|
||||||
? "font-bold text-[#5559CE]"
|
|
||||||
: "font-normal text-[#616161] dark:text-[#a1a1a1]"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{item.name}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{list.length > idx + 1 && (
|
|
||||||
<span
|
|
||||||
className={`block rounded-[16px] transition-all duration-500 h-[2px]
|
|
||||||
bg-[#EFEFEF] dark:bg-[#EFEFEF] w-[35px] sm:w-[56px] md:w-[77px] lg:w-[100px]
|
|
||||||
relative overflow-hidden before:transition-all before:duration-500
|
|
||||||
before:absolute before:w-full before:h-full before:bg-[#5559CE] before:ease-linear
|
|
||||||
|
|
||||||
${value > idx ? "before:right-0" : "before:-right-full"}`}
|
|
||||||
></span>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Step;
|
|
||||||
@@ -1,72 +1,15 @@
|
|||||||
export const defaultState = {
|
export const defaultState = {
|
||||||
general: {
|
name: { value: "", placeholder: "", isEdit: true },
|
||||||
name: { value: "", placeholder: "", isEdit: true },
|
medical_system_number: {
|
||||||
medical_system_number: {
|
value: "",
|
||||||
value: "",
|
placeholder: 1741025645,
|
||||||
placeholder: 1741025645,
|
isEdit: true,
|
||||||
isEdit: true,
|
|
||||||
},
|
|
||||||
expertise: { value: "", placeholder: "دندان پزشکی", isEdit: true },
|
|
||||||
description: { value: "", isEdit: true },
|
|
||||||
skills: { value: "", isEdit: true },
|
|
||||||
time_work: { value: "", isEdit: true },
|
|
||||||
degree: { value: "", isEdit: true },
|
|
||||||
},
|
},
|
||||||
office: {
|
expertise: { value: "", placeholder: "دندان پزشکی", isEdit: true },
|
||||||
address: { value: "مپ", isEdit: true },
|
description: { value: "", isEdit: true },
|
||||||
phone: { value: "", placeholder: 1741025645, isEdit: true },
|
skills: { value: "", isEdit: true },
|
||||||
office_number1: { value: "", isEdit: true },
|
time_work: { value: "", isEdit: true },
|
||||||
state: { value: "", isEdit: true },
|
phone: { value: "", placeholder: "", isEdit: true },
|
||||||
city: { value: "", isEdit: true },
|
degree: { value: "", isEdit: true },
|
||||||
},
|
gender: { value: "woman", isEdit: true },
|
||||||
work_day: [
|
|
||||||
{
|
|
||||||
name: "شنبه",
|
|
||||||
number_turns: { value: 1, isEdit: true },
|
|
||||||
turn_time: "",
|
|
||||||
workplace: "",
|
|
||||||
morning_time: ["", ""],
|
|
||||||
evening_time: ["", ""],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "یکشنبه",
|
|
||||||
number_turns: { value: 1, isEdit: true },
|
|
||||||
turn_time: "",
|
|
||||||
workplace: "",
|
|
||||||
morning_time: ["", ""],
|
|
||||||
evening_time: ["", ""],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "دوشنبه",
|
|
||||||
number_turns: { value: 1, isEdit: true },
|
|
||||||
turn_time: "",
|
|
||||||
workplace: "",
|
|
||||||
morning_time: ["", ""],
|
|
||||||
evening_time: ["", ""],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "سه شنبه",
|
|
||||||
number_turns: { value: 1, isEdit: true },
|
|
||||||
turn_time: "",
|
|
||||||
workplace: "",
|
|
||||||
morning_time: ["", ""],
|
|
||||||
evening_time: ["", ""],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "چهار شنبه",
|
|
||||||
number_turns: { value: 1, isEdit: true },
|
|
||||||
turn_time: "",
|
|
||||||
workplace: "",
|
|
||||||
morning_time: ["", ""],
|
|
||||||
evening_time: ["", ""],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "پنج شنبه",
|
|
||||||
number_turns: { value: 1, isEdit: true },
|
|
||||||
turn_time: "",
|
|
||||||
workplace: "",
|
|
||||||
morning_time: ["", ""],
|
|
||||||
evening_time: ["", ""],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-4
@@ -1,11 +1,12 @@
|
|||||||
import { FormControlLabel, Radio, RadioGroup } from "@mui/material";
|
import { FormControlLabel, Radio, RadioGroup } from "@mui/material";
|
||||||
|
|
||||||
function RadioGender() {
|
function RadioGender({ changeData, name }) {
|
||||||
return (
|
return (
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
dir="ltr"
|
dir="ltr"
|
||||||
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="female"
|
defaultValue="woman"
|
||||||
|
onChange={(e) => changeData(e.target.value, "value", name)}
|
||||||
sx={{
|
sx={{
|
||||||
"& .muirtl-j204z7-MuiFormControlLabel-root": {
|
"& .muirtl-j204z7-MuiFormControlLabel-root": {
|
||||||
marginLeft: "0 !important",
|
marginLeft: "0 !important",
|
||||||
@@ -14,13 +15,13 @@ function RadioGender() {
|
|||||||
>
|
>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
label="مرد"
|
label="مرد"
|
||||||
value="male"
|
value="man"
|
||||||
control={<Radio />}
|
control={<Radio />}
|
||||||
className="!text-[#A1A1A1]"
|
className="!text-[#A1A1A1]"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
label="زن"
|
label="زن"
|
||||||
value="female"
|
value="woman"
|
||||||
control={<Radio />}
|
control={<Radio />}
|
||||||
className="!text-[#A1A1A1]"
|
className="!text-[#A1A1A1]"
|
||||||
/>
|
/>
|
||||||
+25
-16
@@ -1,7 +1,7 @@
|
|||||||
import FieldDate from "./FieldDate";
|
import FieldDate from "./fields/FieldDate";
|
||||||
import RadioGender from "./RadioGender";
|
import RadioGender from "./fields/RadioGender";
|
||||||
import SendReq from "./SendReq";
|
import SendReq from "./sendReq";
|
||||||
import Selector from "./Selector";
|
import Selector from "./fields/Selector";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import EditField from "@/app/component/EditField";
|
import EditField from "@/app/component/EditField";
|
||||||
@@ -16,19 +16,15 @@ const validate_medical_number = {
|
|||||||
max: 9999999999,
|
max: 9999999999,
|
||||||
};
|
};
|
||||||
|
|
||||||
function Form({ setValue, parent, data, setData }) {
|
function Form({ image, data, setData, resetData }) {
|
||||||
const changeData = (value, type, name) => {
|
const changeData = (value, type, name) => {
|
||||||
|
|
||||||
type !== "isEdit" &&
|
type !== "isEdit" &&
|
||||||
setData((prev) => {
|
setData((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[parent]: {
|
[name]: {
|
||||||
...prev[parent],
|
...prev[name],
|
||||||
[name]: {
|
[type]: value,
|
||||||
...prev[parent][name],
|
|
||||||
[type]: value,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -73,6 +69,7 @@ function Form({ setValue, parent, data, setData }) {
|
|||||||
<ContentText text="تخصص">
|
<ContentText text="تخصص">
|
||||||
<Selector
|
<Selector
|
||||||
updateData={changeData}
|
updateData={changeData}
|
||||||
|
data={data?.expertise.value}
|
||||||
label="انتخاب کنید..."
|
label="انتخاب کنید..."
|
||||||
name="expertise"
|
name="expertise"
|
||||||
list={filteredSpe}
|
list={filteredSpe}
|
||||||
@@ -82,9 +79,9 @@ function Form({ setValue, parent, data, setData }) {
|
|||||||
<ContentText text="مدرک">
|
<ContentText text="مدرک">
|
||||||
<Selector
|
<Selector
|
||||||
updateData={changeData}
|
updateData={changeData}
|
||||||
// type="number"
|
|
||||||
label="انتخاب کنید..."
|
label="انتخاب کنید..."
|
||||||
name="degree"
|
name="degree"
|
||||||
|
data={data?.degree.value}
|
||||||
list={education}
|
list={education}
|
||||||
nameKey="label"
|
nameKey="label"
|
||||||
/>
|
/>
|
||||||
@@ -111,12 +108,24 @@ function Form({ setValue, parent, data, setData }) {
|
|||||||
name="skills"
|
name="skills"
|
||||||
/>
|
/>
|
||||||
</ContentText>
|
</ContentText>
|
||||||
<ContentText text="جنسیت">
|
|
||||||
<RadioGender />
|
<ContentText text="شماره موبایل">
|
||||||
|
<EditField
|
||||||
|
isTransparent={true}
|
||||||
|
iconGray={true}
|
||||||
|
changeData={changeData}
|
||||||
|
data={data?.phone}
|
||||||
|
type="number"
|
||||||
|
placeholder={data?.phone.placeholder}
|
||||||
|
name="phone"
|
||||||
|
/>
|
||||||
</ContentText>
|
</ContentText>
|
||||||
<FieldDate changeListData={changeData} data={data?.time_work} />
|
<FieldDate changeListData={changeData} data={data?.time_work} />
|
||||||
|
<ContentText text="جنسیت">
|
||||||
|
<RadioGender changeData={changeData} name="gender" />
|
||||||
|
</ContentText>
|
||||||
</div>
|
</div>
|
||||||
<SendReq setValue={setValue} data={data} />
|
<SendReq img={image} data={data} resetData={resetData} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import moment from "jalali-moment";
|
||||||
|
|
||||||
|
export const dateToTimestamp = (date) => {
|
||||||
|
const gregorianMoment = moment(date, "jYYYY/jM/jD").locale("fa");
|
||||||
|
const unixTimestamp = gregorianMoment.valueOf();
|
||||||
|
return unixTimestamp / 1000;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const transformData = (data) => {
|
||||||
|
return {
|
||||||
|
name: data.name.value,
|
||||||
|
activity_time: dateToTimestamp(data.time_work.value),
|
||||||
|
doctor_mobile_number: data.phone.value,
|
||||||
|
degree: data.degree.value,
|
||||||
|
specialty: [Number(data.expertise.value)],
|
||||||
|
info: data.description.value,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import ArrowLeftPA from "@/components/icons/ArrowLeftPA";
|
||||||
|
import { checkAllValues } from "@/helper";
|
||||||
|
import { request } from "@/services/response";
|
||||||
|
import { Button } from "@mui/material";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { transformData } from "./function";
|
||||||
|
import { defaultState } from "../../defaultState";
|
||||||
|
|
||||||
|
function SendReq({ img, data, resetData }) {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const saveData = (img) => {
|
||||||
|
let transformed = transformData(data);
|
||||||
|
|
||||||
|
if (img) {
|
||||||
|
transformed.image = [img];
|
||||||
|
}
|
||||||
|
|
||||||
|
request
|
||||||
|
.postDoctor(transformed)
|
||||||
|
.then(() => {
|
||||||
|
resetData();
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveImg = () => {
|
||||||
|
setLoading(true);
|
||||||
|
if (img) {
|
||||||
|
request
|
||||||
|
.postImageUpload(img.file)
|
||||||
|
.then((res) => {
|
||||||
|
const imgId = res.fid[0].value;
|
||||||
|
saveData(imgId);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mt-[40px] w-full flex justify-end">
|
||||||
|
<Button
|
||||||
|
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)}
|
||||||
|
variant="contained"
|
||||||
|
onClick={saveImg}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
<p className={loading ? "opacity-0" : ""}>ثبت اطلاعات</p>
|
||||||
|
<div className={!checkAllValues(data) ? "opacity-40" : "opacity-100"}>
|
||||||
|
<ArrowLeftPA />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SendReq;
|
||||||
@@ -1,59 +1,29 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import Form from "./form";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
// Tabs
|
|
||||||
import WorkingDays from "./listMenu/workingDays";
|
|
||||||
import OfficeInformation from "./listMenu/officeInformation";
|
|
||||||
import GeneralInformation from "./listMenu/generalInformation";
|
|
||||||
import Step from "./Step";
|
|
||||||
import { defaultState } from "./defaultState";
|
import { defaultState } from "./defaultState";
|
||||||
|
import UploadFile from "@/app/component/uploadFile";
|
||||||
|
|
||||||
function AddDoctorPage() {
|
function AddDoctorPage() {
|
||||||
const [value, setValue] = useState(0);
|
|
||||||
const [data, setData] = useState(defaultState);
|
const [data, setData] = useState(defaultState);
|
||||||
|
const [image, setImage] = useState("");
|
||||||
|
console.log(data);
|
||||||
const resetData = () => {
|
const resetData = () => {
|
||||||
setData(defaultState);
|
setData(defaultState);
|
||||||
setValue(0);
|
setImage();
|
||||||
};
|
};
|
||||||
|
|
||||||
const components = [
|
|
||||||
<GeneralInformation
|
|
||||||
data={data}
|
|
||||||
parent="general"
|
|
||||||
setData={setData}
|
|
||||||
setValue={setValue}
|
|
||||||
/>,
|
|
||||||
<OfficeInformation
|
|
||||||
data={data}
|
|
||||||
parent="office"
|
|
||||||
setData={setData}
|
|
||||||
setValue={setValue}
|
|
||||||
/>,
|
|
||||||
<WorkingDays
|
|
||||||
data={data}
|
|
||||||
parent="work_day"
|
|
||||||
setData={setData}
|
|
||||||
resetData={resetData}
|
|
||||||
/>,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="opacity-page">
|
<div className="opacity-page bg-transparent dark:shadow-[0px_4px_25px_10px_#1F1D2B] md:dark:bg-[#222433] md:bg-[#FFF] opacity-page rounded-[8px] shadow-none md:shadow-[0px_1px_24.8px_0px_rgba(204,204,204,0.18)] pt-0 md:pt-[12px] lg:pt-[24px] px-0 md:px-[24px] p-[24px]">
|
||||||
<h1 className="text-[#525252] dark:text-[#D7D8ED] text-[20px] font-bold hidden md:flex">
|
<UploadFile image={image} setImage={setImage} />
|
||||||
پروفایل من
|
<Form
|
||||||
</h1>
|
data={data}
|
||||||
<div
|
image={image}
|
||||||
className="rounded-[8px] mt-0 md:mt-[24px] bg-transparent md:bg-[#FFF]
|
parent={parent}
|
||||||
md:dark:bg-[#222433] shadow-none md:shadow-[0px_1px_24.8px_0px_rgba(204,204,204,0.18)] dark:shadow-none pt-0
|
setData={setData}
|
||||||
md:pt-[30px] pb-0 md:pb-[12px] lg:pb-[24px] px-0 md:px-[14px] lg:px-[26px] xl:px-[56px]"
|
resetData={resetData}
|
||||||
>
|
/>
|
||||||
<Step value={value} />
|
|
||||||
<div className="mt-[24px] md:mt-[28px] lg:mt-[32px]">
|
|
||||||
{components[value]}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
import ArrowLeftPH from "@/components/icons/ArrowLeftPH";
|
|
||||||
import { Button } from "@mui/material";
|
|
||||||
|
|
||||||
function Menu({ value, open, setOpen, listTab, handleChange }) {
|
|
||||||
return (
|
|
||||||
<ul
|
|
||||||
className={`
|
|
||||||
flex bg-[#FAFAFA] flex-col justify-start items-start dark:bg-[#222433]
|
|
||||||
fixed h-screen w-full z-50 top-[60px] pt-[20px] transition-all duration-500
|
|
||||||
${open ? "right-0" : "-right-full"}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{listTab.map((item, idx) => (
|
|
||||||
<li key={idx} className="w-[calc(100%-32px)] mx-[16px]">
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
handleChange(_, idx);
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
className="!flex !p-2 !items-center !justify-between !w-full"
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
className={`
|
|
||||||
text-[16px] transition-all duration-500
|
|
||||||
${
|
|
||||||
value === idx
|
|
||||||
? "text-[#5559CE] font-bold"
|
|
||||||
: "text-[#7E7E7E] font-normal"
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{item}
|
|
||||||
</p>
|
|
||||||
<ArrowLeftPH active={value === idx} />
|
|
||||||
</Button>
|
|
||||||
{listTab.length > idx + 1 && (
|
|
||||||
<span className="my-[12px] block h-px w-full bg-[#EFEFEF] dark:bg-[#343645]"></span>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Menu;
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import Tabs from "@/app/component/Tabs";
|
|
||||||
|
|
||||||
function Tab({ value, listTab, handleChange }) {
|
|
||||||
return (
|
|
||||||
<Tabs
|
|
||||||
isSm={false}
|
|
||||||
style={{
|
|
||||||
".MuiTabs-indicator": {
|
|
||||||
height: "2px",
|
|
||||||
borderRadius: "16px",
|
|
||||||
background: "#5559CE",
|
|
||||||
},
|
|
||||||
"& .MuiTabs-flexContainer": {
|
|
||||||
borderBottom: "2px solid #EFEFEF",
|
|
||||||
},
|
|
||||||
"& .mui-11pdt05-MuiButtonBase-root-MuiTab-root.Mui-selected": {
|
|
||||||
color: "#5559CE !important",
|
|
||||||
},
|
|
||||||
"& .MuiButtonBase-root": {
|
|
||||||
fontWeight: "400 !important",
|
|
||||||
},
|
|
||||||
"& .MuiButtonBase-root.Mui-selected": {
|
|
||||||
color: "#5559CE !important",
|
|
||||||
fontWeight: "700 !important",
|
|
||||||
transition: "0.3s all !important",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
value={value}
|
|
||||||
listTab={listTab}
|
|
||||||
handleChange={handleChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Tab;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import UploadFile from "@/app/component/uploadFile";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
function Head() {
|
|
||||||
const [image, setImage] = useState("");
|
|
||||||
|
|
||||||
return <UploadFile image={image} setImage={setImage} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Head;
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import ArrowLeftPA from "@/components/icons/ArrowLeftPA";
|
|
||||||
import { checkAllValues } from "@/helper";
|
|
||||||
import { Button } from "@mui/material";
|
|
||||||
|
|
||||||
function SendReq({ setValue, data }) {
|
|
||||||
return (
|
|
||||||
<div className="mt-[40px] w-full flex justify-end">
|
|
||||||
<Button
|
|
||||||
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)}
|
|
||||||
variant="contained"
|
|
||||||
>
|
|
||||||
ثبت اطلاعات
|
|
||||||
<div className={!checkAllValues(data) ? "opacity-40" : "opacity-100"}>
|
|
||||||
<ArrowLeftPA />
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SendReq;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import Form from "./form";
|
|
||||||
import Head from "./Head";
|
|
||||||
|
|
||||||
function GeneralInformation({ setValue, parent, data, setData }) {
|
|
||||||
return (
|
|
||||||
<div className="opacity-page pb-[24px] px-0 md:px-[24px] lg:px-[56px]">
|
|
||||||
<Head />
|
|
||||||
<Form
|
|
||||||
parent={parent}
|
|
||||||
setData={setData}
|
|
||||||
setValue={setValue}
|
|
||||||
data={data.general}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GeneralInformation;
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import Menu from "./Menu";
|
|
||||||
import Tab from "./Tab";
|
|
||||||
|
|
||||||
function ListMenu({ value, open, setOpen, handleChange, listTab }) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="hidden md:flex">
|
|
||||||
<Tab value={value} listTab={listTab} handleChange={handleChange} />
|
|
||||||
</div>
|
|
||||||
<div className="flex md:hidden">
|
|
||||||
<Menu
|
|
||||||
open={open}
|
|
||||||
value={value}
|
|
||||||
listTab={listTab}
|
|
||||||
setOpen={setOpen}
|
|
||||||
handleChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ListMenu;
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { city, state } from "./listSelector";
|
|
||||||
import EditField from "@/app/component/EditField";
|
|
||||||
import ContentText from "@/app/component/ContentText";
|
|
||||||
import AddLocationP from "@/components/icons/AddLocationP";
|
|
||||||
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
|
|
||||||
import { useState } from "react";
|
|
||||||
import ModalMap from "./modal";
|
|
||||||
|
|
||||||
// Data
|
|
||||||
import statesData from "@/data/state.json";
|
|
||||||
import citiesData from "@/data/city.json";
|
|
||||||
import Selector from "./Selector";
|
|
||||||
|
|
||||||
const validate_phone_number = {
|
|
||||||
min: 1,
|
|
||||||
max: 9999999999,
|
|
||||||
};
|
|
||||||
|
|
||||||
function Form({ parent, data, setData }) {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
const handleClose = () => setOpen(false);
|
|
||||||
const handleOpen = () => setOpen(true);
|
|
||||||
|
|
||||||
const changeData = (value, type, name) =>
|
|
||||||
type !== "isEdit" &&
|
|
||||||
setData((prev) => {
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
[parent]: {
|
|
||||||
...prev[parent],
|
|
||||||
[name]: {
|
|
||||||
...prev[parent][name],
|
|
||||||
[type]: value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateNum = (value, type, name) => {
|
|
||||||
const parseValue = +value;
|
|
||||||
const { max } = validate_phone_number;
|
|
||||||
const validateValue = parseValue > max ? data[name].value : value;
|
|
||||||
changeData(validateValue, type, name);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="mt-[24px] grid grid-cols-1 md:grid-cols-2 gap-x-[48px] gap-y-[24px]">
|
|
||||||
<ContentText text="استان">
|
|
||||||
<Selector
|
|
||||||
updateData={changeData}
|
|
||||||
label="انتخاب کنید..."
|
|
||||||
name="state"
|
|
||||||
list={statesData}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="شهر">
|
|
||||||
<Selector
|
|
||||||
updateData={changeData}
|
|
||||||
label="انتخاب کنید..."
|
|
||||||
name="city"
|
|
||||||
list={citiesData}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="آدرس">
|
|
||||||
<div className="relative w-full">
|
|
||||||
<EditField
|
|
||||||
icon={<AddLocationP />}
|
|
||||||
isTransparent={true}
|
|
||||||
placeholder="از روی نقشه انتخاب کنید..."
|
|
||||||
iconGray={true}
|
|
||||||
changeData={changeData}
|
|
||||||
data={data?.address}
|
|
||||||
name="address"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className="absolute left-0 top-0 w-full h-full opacity-0 z-10 cursor-pointer"
|
|
||||||
onClick={handleOpen}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="شماره موبایل">
|
|
||||||
<EditField
|
|
||||||
isTransparent={true}
|
|
||||||
iconGray={true}
|
|
||||||
changeData={updateNum}
|
|
||||||
data={data?.phone}
|
|
||||||
noDisable={true}
|
|
||||||
type="number"
|
|
||||||
placeholder="شماره موبایل"
|
|
||||||
name="phone"
|
|
||||||
props={{
|
|
||||||
inputProps: validate_phone_number,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="شماره مطب">
|
|
||||||
<EditField
|
|
||||||
isTransparent={true}
|
|
||||||
iconGray={true}
|
|
||||||
changeData={updateNum}
|
|
||||||
data={data?.office_number1}
|
|
||||||
noDisable={true}
|
|
||||||
type="number"
|
|
||||||
placeholder="شماره مطب"
|
|
||||||
name="office_number1"
|
|
||||||
props={{
|
|
||||||
inputProps: validate_phone_number,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
{/* <ContentText text="شماره مطب">
|
|
||||||
<EditField
|
|
||||||
isTransparent={true}
|
|
||||||
iconGray={true}
|
|
||||||
changeData={updateNum}
|
|
||||||
data={data?.office_number2}
|
|
||||||
noDisable={true}
|
|
||||||
type="number"
|
|
||||||
placeholder="شماره مطب"
|
|
||||||
name="office_number2"
|
|
||||||
props={{
|
|
||||||
inputProps: validate_phone_number,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ContentText> */}
|
|
||||||
</div>
|
|
||||||
<ModalMap open={open} handleClose={handleClose} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
import BottomSelect from "@/components/icons/BottomSelect";
|
|
||||||
import { Autocomplete, Button, TextField } from "@mui/material";
|
|
||||||
import { styleTextSelectRight } from "@/mui";
|
|
||||||
|
|
||||||
function Selector({ updateData, label, name, list }) {
|
|
||||||
return (
|
|
||||||
<Autocomplete
|
|
||||||
disablePortal
|
|
||||||
options={list}
|
|
||||||
getOptionLabel={(option) => option.name || ""}
|
|
||||||
// isOptionEqualToValue={(option, value) => option.id === value.id}
|
|
||||||
className="!w-full !rounded-lg auto-complete-selector "
|
|
||||||
onChange={(e, newValue) => {
|
|
||||||
if (newValue) {
|
|
||||||
updateData && updateData(newValue.id, "value", name);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
...styleTextSelectRight,
|
|
||||||
// Hide Icon Number
|
|
||||||
"& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button":
|
|
||||||
{
|
|
||||||
display: "none",
|
|
||||||
},
|
|
||||||
"& input[type=number]": {
|
|
||||||
MozAppearance: "textfield",
|
|
||||||
},
|
|
||||||
"& .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",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
renderOption={(props, option) => (
|
|
||||||
<Button
|
|
||||||
fullWidth
|
|
||||||
{...props}
|
|
||||||
key={option.id || props.id}
|
|
||||||
className="!flex !justify-start !p-[8px] !text-start !text-[#A1A1A1] hover:dark:!bg-[#35343D] !bg-[#FFF] dark:!bg-[#1F1D2B]"
|
|
||||||
>
|
|
||||||
{option.name || option.label}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
{...params}
|
|
||||||
InputProps={{
|
|
||||||
...params.InputProps,
|
|
||||||
endAdornment: (
|
|
||||||
<div className="absolute left-4">
|
|
||||||
<BottomSelect />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
placeholder={label}
|
|
||||||
sx={{
|
|
||||||
borderRadius: "8px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Selector;
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import ArrowLeftPA from "@/components/icons/ArrowLeftPA";
|
|
||||||
import { Button } from "@mui/material";
|
|
||||||
import Form from "./Form";
|
|
||||||
import { checkAllValues } from "@/helper";
|
|
||||||
import ScrollToTop from "@/app/component/ScrollToTop";
|
|
||||||
|
|
||||||
function OfficeInformation({ setValue, parent, data, setData }) {
|
|
||||||
return (
|
|
||||||
<div className="opacity-page pb-[24px] px-0 md:px-[24px] lg:px-[56px]">
|
|
||||||
<ScrollToTop />
|
|
||||||
<Form parent={parent} setData={setData} data={data.office} />
|
|
||||||
<div className="mt-[40px] w-full flex justify-end">
|
|
||||||
<Button
|
|
||||||
className={`!w-full md:!w-fit !shadow-none !rounded-[4px] !gap-[4px] !text-[#EFEFEF] !text-[14px] md:!text-[16px] !font-medium
|
|
||||||
${!checkAllValues(data.office) && "opacity-60"}`}
|
|
||||||
disabled={!checkAllValues(data.office)}
|
|
||||||
onClick={() => setValue((prev) => prev + 1)}
|
|
||||||
variant="contained"
|
|
||||||
>
|
|
||||||
ثبت اطلاعات
|
|
||||||
<div
|
|
||||||
className={
|
|
||||||
!checkAllValues(data.office) ? "opacity-40" : "opacity-100"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ArrowLeftPA />
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default OfficeInformation;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
export const state = [
|
|
||||||
{ label: "استان 1", id: 10 },
|
|
||||||
{ label: "استان 2", id: 20 },
|
|
||||||
{ label: "استان 3", id: 30 },
|
|
||||||
{ label: "استان 4", id: 40 },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const city = [
|
|
||||||
{ label: "شهر 1", id: 10 },
|
|
||||||
{ label: "شهر 2", id: 20 },
|
|
||||||
{ label: "شهر 3", id: 30 },
|
|
||||||
{ label: "شهر 4", id: 40 },
|
|
||||||
];
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import { styleDefault } from "@/mui";
|
|
||||||
import { Modal } from "@mui/material";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
import MapPicker from "react-google-map-picker";
|
|
||||||
|
|
||||||
const DefaultLocation = {
|
|
||||||
lat: 9.912345921562734,
|
|
||||||
lng: 105.97776559918576,
|
|
||||||
};
|
|
||||||
const DefaultZoom = 10;
|
|
||||||
|
|
||||||
function ModalMap({ open, handleClose }) {
|
|
||||||
const [defaultLocation, setDefaultLocation] = useState(DefaultLocation);
|
|
||||||
|
|
||||||
const [location, setLocation] = useState(defaultLocation);
|
|
||||||
const [zoom, setZoom] = useState(DefaultZoom);
|
|
||||||
|
|
||||||
function handleChangeLocation(lat, lng) {
|
|
||||||
setLocation({ lat: lat, lng: lng });
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleChangeZoom(newZoom) {
|
|
||||||
setZoom(newZoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleResetLocation() {
|
|
||||||
setDefaultLocation({ ...DefaultLocation });
|
|
||||||
setZoom(DefaultZoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal open={open} onClose={handleClose} className="w-full">
|
|
||||||
<div
|
|
||||||
style={styleDefault}
|
|
||||||
className="!px-[16px] !overflow-auto md:!min-w-[580px] md:!px-[24px] lg:!px-[32px] !py-[24px] !bg-[#FFF] !rounded-[8px] !shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)]
|
|
||||||
!w-full md:!w-fit !h-full md:!h-fit !flex !flex-col !justify-between !max-h-screen md:!max-h-[calc(100%_-_32px)]"
|
|
||||||
>
|
|
||||||
<MapPicker
|
|
||||||
zoom={zoom}
|
|
||||||
mapTypeId="roadmap"
|
|
||||||
style={{ height: "500px" }}
|
|
||||||
onChangeZoom={handleChangeZoom}
|
|
||||||
defaultLocation={defaultLocation}
|
|
||||||
onChangeLocation={handleChangeLocation}
|
|
||||||
apiKey="AIzaSyD07E1VvpsN_0FvsmKAj4nK9GnLq-9jtj8"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ModalMap;
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import ModalAddTime from "./modal/ModalAddTime";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableContainer,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
} from "@mui/material";
|
|
||||||
import ContentModal from "./modal";
|
|
||||||
import EditOrangeAD from "@/components/icons/EditOrangeAD";
|
|
||||||
|
|
||||||
function List({ parent, data, setData, setIsDisable }) {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const handleOpen = () => setOpen(true);
|
|
||||||
const handleClose = () => setOpen(false);
|
|
||||||
|
|
||||||
const [dataChange, setDataChange] = useState({
|
|
||||||
is_morgen: false,
|
|
||||||
idx: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full flex justify-center table-profile-page">
|
|
||||||
<TableContainer
|
|
||||||
className="!mt-[40px] md:!mt-[36px] lg:!mt-[32px] !w-fit"
|
|
||||||
sx={{
|
|
||||||
"&.MuiTableContainer-root": {
|
|
||||||
boxShadow: "none !important",
|
|
||||||
border: "none !important",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Table>
|
|
||||||
<TableHead className="!py-2">
|
|
||||||
<TableRow className="!bg-[#EFEFEF] !py-2 dark:!bg-[#343645]">
|
|
||||||
<TableCell
|
|
||||||
className="!py-[10px] !text-[#616161] dark:!text-[#D7D8ED] !text-[14px] !font-normal"
|
|
||||||
align="left"
|
|
||||||
>
|
|
||||||
روز های هفته
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
className="!py-[10px] !text-[#616161] dark:!text-[#D7D8ED] !text-[14px] !font-normal"
|
|
||||||
align="left"
|
|
||||||
>
|
|
||||||
تایم صبح
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
className="!py-[10px] !text-[#616161] dark:!text-[#D7D8ED] !text-[14px] !font-normal"
|
|
||||||
align="left"
|
|
||||||
>
|
|
||||||
تایم عصر
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{data[parent].map((row, idx) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.name}
|
|
||||||
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
|
|
||||||
>
|
|
||||||
<TableCell
|
|
||||||
className="!border-[1px] !border-[#DBDBDB] dark:!text-[#A1A1A1]"
|
|
||||||
component="th"
|
|
||||||
scope="row"
|
|
||||||
>
|
|
||||||
{row.name}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
className="!border-[1px] !text-[#616161] dark:!text-[#D7D8ED] !text-center !text-[16px] !font-medium !border-[#DBDBDB]"
|
|
||||||
align="right"
|
|
||||||
>
|
|
||||||
{row.morning_time[0] || row.morning_time[1] ? (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
handleOpen();
|
|
||||||
setDataChange({
|
|
||||||
is_morgen: true,
|
|
||||||
idx,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
className="!gap-[6px] !min-w-[146px] !py-[4px] dark:!text-[#D7D8ED] !px-[8px] !text-[#616161] !text-[16px] !font-bold"
|
|
||||||
>
|
|
||||||
{row.morning_time[0] === "تعطیل"
|
|
||||||
? row.morning_time[0]
|
|
||||||
: `${row.morning_time[0]} - ${row.morning_time[1]}`}
|
|
||||||
<EditOrangeAD />
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<ModalAddTime
|
|
||||||
setDataChange={setDataChange}
|
|
||||||
handleOpen={handleOpen}
|
|
||||||
setData={setData}
|
|
||||||
isMorgen={true}
|
|
||||||
idx={idx}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
className="!border-[1px] !text-[#616161] dark:!text-[#D7D8ED] !text-center !text-[16px] !font-medium !border-[#DBDBDB]"
|
|
||||||
align="right"
|
|
||||||
>
|
|
||||||
{row.evening_time[0] || row.evening_time[1] ? (
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
handleOpen();
|
|
||||||
setDataChange({
|
|
||||||
is_morgen: false,
|
|
||||||
idx,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
className="!gap-[6px] !min-w-[146px] !py-[4px] dark:!text-[#D7D8ED] !px-[8px] !text-[#616161] !text-[16px] !font-bold"
|
|
||||||
>
|
|
||||||
{row.morning_time[0] === "تعطیل"
|
|
||||||
? row.morning_time[0]
|
|
||||||
: `${row.evening_time[0]} - ${row.evening_time[1]}`}
|
|
||||||
<EditOrangeAD />
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<ModalAddTime
|
|
||||||
setDataChange={setDataChange}
|
|
||||||
handleOpen={handleOpen}
|
|
||||||
setData={setData}
|
|
||||||
isMorgen={false}
|
|
||||||
idx={idx}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
<ContentModal
|
|
||||||
open={open}
|
|
||||||
data={data}
|
|
||||||
parent={parent}
|
|
||||||
setOpen={setOpen}
|
|
||||||
setData={setData}
|
|
||||||
dataChange={dataChange}
|
|
||||||
handleClose={handleClose}
|
|
||||||
setIsDisable={setIsDisable}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default List;
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import { Button } from "@mui/material";
|
|
||||||
import ArrowLeftWhiteD from "@/components/icons/ArrowLeftWhiteD";
|
|
||||||
import { request } from "@/services/response";
|
|
||||||
import { useState } from "react";
|
|
||||||
import moment from "jalali-moment";
|
|
||||||
import { defaultState } from "../../defaultState";
|
|
||||||
|
|
||||||
const dateToTimestamp = (date) => {
|
|
||||||
const gregorianMoment = moment(date, "jYYYY/jM/jD").locale("fa");
|
|
||||||
const unixTimestamp = gregorianMoment.valueOf();
|
|
||||||
return unixTimestamp / 1000;
|
|
||||||
};
|
|
||||||
|
|
||||||
const transformData = (data) => {
|
|
||||||
return {
|
|
||||||
name: data.general.name.value,
|
|
||||||
activity_time: dateToTimestamp(data.general.time_work.value),
|
|
||||||
doctor_mobile_number: data.office.phone.value,
|
|
||||||
state: [Number(data.office.state.value)],
|
|
||||||
city: [Number(data.office.city.value)],
|
|
||||||
degree: data.general.degree.value,
|
|
||||||
specialty: [Number(data.general.expertise.value)],
|
|
||||||
info: data.general.description.value,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function SendReq({ data, isDisable, resetData }) {
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
const saveData = () => {
|
|
||||||
setLoading(true);
|
|
||||||
|
|
||||||
const transformed = transformData(data);
|
|
||||||
|
|
||||||
request
|
|
||||||
.postDoctor(transformed)
|
|
||||||
.then(() => {
|
|
||||||
resetData();
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
className="!gap-[4px] !w-full md:!w-fit !mr-auto !text-nowrap !flex !flex-nowrap !py-[8px]
|
|
||||||
!rounded-[4px] !text-[#EFEFEF] !text-[14px] md:!text-[16px] !font-medium
|
|
||||||
!mt-[48px] md:!mt-[44px] lg:!mt-[40px] !px-[16px] sm:!px-[19px] md:!px-[22px] lg:!px-[24px]"
|
|
||||||
disabled={isDisable}
|
|
||||||
variant="contained"
|
|
||||||
onClick={saveData}
|
|
||||||
loading={loading}
|
|
||||||
>
|
|
||||||
<p className={loading ? "opacity-0" : ""}>ثبت اطلاعات</p>
|
|
||||||
<div className={isDisable ? "opacity-40" : "opacity-100"}>
|
|
||||||
<ArrowLeftWhiteD />
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SendReq;
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import List from "./List";
|
|
||||||
import { useState } from "react";
|
|
||||||
import ScrollToTop from "@/app/component/ScrollToTop";
|
|
||||||
import SendReq from "./SendReq";
|
|
||||||
|
|
||||||
function WorkingDays({ parent, data, setData, resetData }) {
|
|
||||||
const [isDisable, setIsDisable] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="opacity-page pb-[24px]">
|
|
||||||
<ScrollToTop />
|
|
||||||
<p className="text-[#525252] dark:text-[#D7D8ED] text-[14px] md:text-[16px] text-center md:text-start font-bold">
|
|
||||||
لیست روزهای کاری
|
|
||||||
</p>
|
|
||||||
<List
|
|
||||||
data={data}
|
|
||||||
parent={parent}
|
|
||||||
setData={setData}
|
|
||||||
setIsDisable={setIsDisable}
|
|
||||||
/>
|
|
||||||
<SendReq resetData={resetData} isDisable={isDisable} data={data} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WorkingDays;
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
import { Button } from "@mui/material";
|
|
||||||
import ContentText from "@/app/component/ContentText";
|
|
||||||
import TimePickerField from "@/app/component/TimePickerField";
|
|
||||||
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
|
|
||||||
import { turnTime, workplace } from "./listSelector";
|
|
||||||
import EditField from "@/app/component/EditField";
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
const validate_number_turns = {
|
|
||||||
min: 1,
|
|
||||||
max: 10,
|
|
||||||
};
|
|
||||||
|
|
||||||
function Form({
|
|
||||||
handleClose,
|
|
||||||
isVacation,
|
|
||||||
parent,
|
|
||||||
setData,
|
|
||||||
dataChange,
|
|
||||||
data,
|
|
||||||
value,
|
|
||||||
}) {
|
|
||||||
const [update, setUpdate] = useState(false);
|
|
||||||
const updateData = (value, type, name) =>
|
|
||||||
setData((prev) => {
|
|
||||||
const newData = prev;
|
|
||||||
newData[parent][dataChange.idx][name] = value;
|
|
||||||
return newData;
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateNum = (value, type, name) => {
|
|
||||||
const prevData = data;
|
|
||||||
const prevVal = data[parent][dataChange.idx][name].value;
|
|
||||||
const parseValue = +value;
|
|
||||||
const { max } = validate_number_turns;
|
|
||||||
const validateValue = parseValue > max ? prevVal : value;
|
|
||||||
data[parent][dataChange.idx][name].value = validateValue;
|
|
||||||
setUpdate(!update);
|
|
||||||
setData(prevData);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-[32px] md:gap-[36px] lg:gap-[40px] min-w-fit md:min-w-[420px]">
|
|
||||||
<div className="flex relative flex-col gap-[16px]">
|
|
||||||
<ContentText text="تعداد نوبت">
|
|
||||||
<EditField
|
|
||||||
isTransparent={true}
|
|
||||||
iconGray={true}
|
|
||||||
changeData={updateNum}
|
|
||||||
data={data[parent][dataChange.idx].number_turns}
|
|
||||||
noDisable={true}
|
|
||||||
type="number"
|
|
||||||
placeholder="انتخاب کنید..."
|
|
||||||
name="number_turns"
|
|
||||||
props={{
|
|
||||||
inputProps: validate_number_turns,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="زمان نوبت">
|
|
||||||
<AutoCompleteSelect
|
|
||||||
updateData={updateData}
|
|
||||||
label="زمان نوبت"
|
|
||||||
name="turn_time"
|
|
||||||
list={turnTime}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="محل کار">
|
|
||||||
<AutoCompleteSelect
|
|
||||||
updateData={updateData}
|
|
||||||
label="محل کار"
|
|
||||||
name="workplace"
|
|
||||||
list={workplace}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="زمان شروع">
|
|
||||||
<TimePickerField
|
|
||||||
dataChange={dataChange}
|
|
||||||
isDisable={isVacation}
|
|
||||||
disable={value === 1}
|
|
||||||
setData={setData}
|
|
||||||
timeStart={true}
|
|
||||||
data={data[parent]}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<ContentText text="زمان پایان">
|
|
||||||
<TimePickerField
|
|
||||||
dataChange={dataChange}
|
|
||||||
isDisable={isVacation}
|
|
||||||
disable={value === 1}
|
|
||||||
setData={setData}
|
|
||||||
timeStart={false}
|
|
||||||
data={data[parent]}
|
|
||||||
/>
|
|
||||||
</ContentText>
|
|
||||||
<div
|
|
||||||
className={`
|
|
||||||
absolute transition-all duration-500 right-0 top-0 w-full h-full bg-[rgba(255,255,255,.85)] dark:bg-[rgba(34,36,51,.85)]
|
|
||||||
${isVacation ? "max-w-full" : "max-w-0"}`}
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-wrap items-center justify-center gap-[16px]">
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
onClick={handleClose}
|
|
||||||
className="!text-[16px] !max-w-[calc(50%_-_8px)] dark:!bg-[#C7CEF4] dark:!text-[#5559CE] !font-medium !border-[#5559CE] !py-[5px] md:!py-[7px] lg:!py-[9px] !shadow-none !px-[46px]"
|
|
||||||
>
|
|
||||||
انصراف
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={handleClose}
|
|
||||||
className="!text-[16px] !max-w-[calc(50%_-_8px)] !font-medium !shadow-none !py-[5px] md:!py-[7px] lg:!py-[9px] !px-[46px]"
|
|
||||||
>
|
|
||||||
ذخیره
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Form;
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import AddTimeP from "@/components/icons/AddTimeP";
|
|
||||||
import { Button } from "@mui/material";
|
|
||||||
import React from "react";
|
|
||||||
|
|
||||||
function ModalAddTime({ handleOpen, isMorgen, idx, setDataChange }) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
variant="text"
|
|
||||||
onClick={() => {
|
|
||||||
handleOpen();
|
|
||||||
setDataChange({
|
|
||||||
is_morgen: isMorgen,
|
|
||||||
idx,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
className="!gap-[2px] md:!min-w-[146px] sm:!gap-[4px] md:!gap-[6px] lg:!gap-[8px] !p-1 !text-[#5559CE] !text-[14px] md:!text-[16px] !font-medium"
|
|
||||||
>
|
|
||||||
<AddTimeP />
|
|
||||||
انتخاب کنید
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ModalAddTime;
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import { FormControlLabel, Radio, RadioGroup } from "@mui/material";
|
|
||||||
|
|
||||||
function Radios({ value, handleChange }) {
|
|
||||||
return (
|
|
||||||
<RadioGroup
|
|
||||||
dir="ltr"
|
|
||||||
defaultValue={value}
|
|
||||||
onChange={handleChange}
|
|
||||||
className="!flex radio-mui !flex-row !mb-[24px] !my-[40px] !gap-[36px] !items-center !justify-end"
|
|
||||||
sx={{
|
|
||||||
"& .muirtl-j204z7-MuiFormControlLabel-root": {
|
|
||||||
marginLeft: "0 !important",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormControlLabel
|
|
||||||
className="!text-[#A1A1A1]"
|
|
||||||
value={0}
|
|
||||||
control={<Radio />}
|
|
||||||
label="روز کاری"
|
|
||||||
/>
|
|
||||||
<FormControlLabel
|
|
||||||
className="!text-[#A1A1A1]"
|
|
||||||
value={1}
|
|
||||||
control={<Radio />}
|
|
||||||
label="تعطیل"
|
|
||||||
/>
|
|
||||||
</RadioGroup>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Radios;
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
import CloseModalD from "@/components/icons/CloseModalD";
|
|
||||||
import { styleDefault } from "@/mui";
|
|
||||||
import { Box, Button, Modal } from "@mui/material";
|
|
||||||
import Radios from "./Radios";
|
|
||||||
import Form from "./Form";
|
|
||||||
import { useState } from "react";
|
|
||||||
import { checkTimes } from "@/helper";
|
|
||||||
|
|
||||||
function ContentModal({
|
|
||||||
open,
|
|
||||||
data,
|
|
||||||
setData,
|
|
||||||
parent,
|
|
||||||
dataChange,
|
|
||||||
handleClose,
|
|
||||||
setIsDisable,
|
|
||||||
}) {
|
|
||||||
const [value, setValue] = useState(0);
|
|
||||||
const [isVacation, setIsVacation] = useState(false);
|
|
||||||
|
|
||||||
const handleChange = (event) => {
|
|
||||||
const valueRadio = +event.target.value;
|
|
||||||
|
|
||||||
const newData = data[parent];
|
|
||||||
const { idx, is_morgen } = dataChange;
|
|
||||||
newData[idx][is_morgen ? "morning_time" : "evening_time"][0] = "تعطیل";
|
|
||||||
|
|
||||||
setIsVacation(valueRadio);
|
|
||||||
setValue(valueRadio);
|
|
||||||
const disable = checkTimes(newData).includes(false);
|
|
||||||
!disable && setIsDisable(disable);
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeModal = () => {
|
|
||||||
handleClose();
|
|
||||||
setValue(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal open={open} onClose={closeModal}>
|
|
||||||
<Box
|
|
||||||
sx={styleDefault}
|
|
||||||
className="!w-full !rounded-none md:!rounded-[8px] dark:!bg-[#222433] dark:!shadow-[0px_4px_25px_10px_#1F1D2B]
|
|
||||||
md:!w-fit !h-full md:!h-fit !py-[20px] !px-[16px] !pb-[56px]"
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<p className="text-[#525252] dark:text-[#D7D8ED] text-[16px] md:text-[18px] lg:text-[20px] font-bold">
|
|
||||||
اضافه کردن روز کاری
|
|
||||||
</p>
|
|
||||||
<Button variant="text" className="!p-1" onClick={closeModal}>
|
|
||||||
<CloseModalD />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div className="mx-0 md:mx-[52px]">
|
|
||||||
<Radios value={value} handleChange={handleChange} />
|
|
||||||
<Form
|
|
||||||
handleClose={closeModal}
|
|
||||||
dataChange={dataChange}
|
|
||||||
isVacation={value}
|
|
||||||
setData={setData}
|
|
||||||
parent={parent}
|
|
||||||
value={value}
|
|
||||||
data={data}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ContentModal;
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
const numberTurns = [
|
|
||||||
{ id: "1", label: 1 },
|
|
||||||
{ id: "2", label: 2 },
|
|
||||||
{ id: "3", label: 3 },
|
|
||||||
];
|
|
||||||
|
|
||||||
const turnTime = [
|
|
||||||
{ id: 1, label: "00:05" },
|
|
||||||
{ id: 2, label: "00:10" },
|
|
||||||
{ id: 3, label: "00:15" },
|
|
||||||
{ id: 4, label: "00:20" },
|
|
||||||
{ id: 5, label: "00:25" },
|
|
||||||
{ id: 6, label: "00:30" },
|
|
||||||
{ id: 7, label: "00:40" },
|
|
||||||
{ id: 8, label: "00:50" },
|
|
||||||
{ id: 9, label: "01:00" },
|
|
||||||
{ id: 10, label: "01:15" },
|
|
||||||
{ id: 11, label: "01:30" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const workplace = [
|
|
||||||
{ id: "1", label: "تهران" },
|
|
||||||
{ id: "2", label: "رشت" },
|
|
||||||
{ id: "3", label: "اصفهان" },
|
|
||||||
];
|
|
||||||
|
|
||||||
export { numberTurns, turnTime, workplace };
|
|
||||||
+7
-4
@@ -23,18 +23,21 @@ export const handleTwoLength = (value) =>
|
|||||||
|
|
||||||
export const checkAllValues = (data) => {
|
export const checkAllValues = (data) => {
|
||||||
for (let key in data) {
|
for (let key in data) {
|
||||||
if (typeof data[key] === "object" && data[key] !== null) {
|
const item = data[key];
|
||||||
if ("value" in data[key]) {
|
|
||||||
if (!data[key].value) {
|
if (typeof item === "object" && item !== null) {
|
||||||
|
if ("value" in item) {
|
||||||
|
if (!item.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!checkAllValues(data[key])) {
|
if (!checkAllValues(item)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ export function defineAbilitiesFor(user) {
|
|||||||
if (user) {
|
if (user) {
|
||||||
can("access", "Dashboard");
|
can("access", "Dashboard");
|
||||||
cannot("access", "Login");
|
cannot("access", "Login");
|
||||||
|
const parsedData = JSON.parse(user.value);
|
||||||
|
|
||||||
|
if (parsedData.roles.find((item) => item === "representation")) {
|
||||||
|
can("access", "Panel");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
can("access", "Login");
|
can("access", "Login");
|
||||||
cannot("access", "Dashboard");
|
cannot("access", "Dashboard");
|
||||||
|
|||||||
@@ -60,4 +60,12 @@ export const request = {
|
|||||||
),
|
),
|
||||||
postAppointment: (data) => api.post(`api/v1/appointment`, data),
|
postAppointment: (data) => api.post(`api/v1/appointment`, data),
|
||||||
postDoctor: (data) => api.post("api/v1/doctor", data),
|
postDoctor: (data) => api.post("api/v1/doctor", data),
|
||||||
|
postImageUpload: (data) =>
|
||||||
|
api.post("file/upload/clinic_pro/doctor/field_image", data, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/octet-stream",
|
||||||
|
"Content-Disposition": 'file; filename="filename.jpg"',
|
||||||
|
"X-CSRF-Token": "",
|
||||||
|
},
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user