update dashboard data and design and change req from ssr to csr & change design and data doctor and clinic item

This commit is contained in:
Ehsan
2025-06-17 00:26:16 +03:30
parent 528006e7ff
commit debd6b0eb5
13 changed files with 306 additions and 116 deletions
@@ -4,6 +4,8 @@ import Image from "next/image";
import CustomLoading from "@/app/component/loading/Custom"; import CustomLoading from "@/app/component/loading/Custom";
function Images({ data }) { function Images({ data }) {
const images_clinic = data.images_clinic;
return ( return (
<div <div
className=" className="
@@ -15,12 +17,7 @@ function Images({ data }) {
<CustomLoading width={600} height={400}> <CustomLoading width={600} height={400}>
<Image <Image
className="rounded-[8px] overflow-hidden" className="rounded-[8px] overflow-hidden"
src={ src={images_clinic[0].url || ""}
(data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[0]) ||
""
}
alt="img clinic" alt="img clinic"
height={432} height={432}
width={600} width={600}
@@ -0,0 +1,21 @@
import CustomLoading from "@/app/component/loading/Custom";
import Image from "next/image";
import React from "react";
function Img({ url }) {
return (
<div className="w-full">
<CustomLoading width="full" height={190}>
<Image
className="rounded-[8px] overflow-hidden"
src={url || ""}
alt="img clinic"
height={204}
width={288}
/>
</CustomLoading>
</div>
);
}
export default Img;
@@ -1,73 +1,53 @@
import CustomLoading from "@/app/component/loading/Custom"; import CustomLoading from "@/app/component/loading/Custom";
import Image from "next/image"; import Image from "next/image";
import Img from "./Img";
function List({ data }) { function List({ data }) {
const images_clinic = data.images_clinic;
return ( return (
<div className="hidden w-full md:grid grid-cols-2 gap-[16px] lg:gap-[24px]"> <div className="hidden w-full md:grid grid-cols-2 gap-[16px] lg:gap-[24px]">
<div className="w-full"> {images_clinic.map((img) => (
<CustomLoading width="full" height={190}> <div className="w-full">
<Image <CustomLoading width="full" height={190}>
className="rounded-[8px] overflow-hidden" <Image
src={ className="rounded-[8px] overflow-hidden"
(data?.images_clinic && src={img.url || ""}
!!data?.images_clinic.length && alt="img clinic"
data?.images_clinic[1]) || height={204}
"" width={288}
} />
alt="img clinic" </CustomLoading>
height={204} </div>
width={288} ))}
/> <Img
</CustomLoading> url={
</div> data?.images_clinic &&
<div className="w-full"> !!data?.images_clinic.length &&
<CustomLoading width="full" height={190}> data?.images_clinic[1]
<Image }
className="rounded-[8px] overflow-hidden" />
src={ <Img
(data?.images_clinic && url={
!!data?.images_clinic.length && data?.images_clinic &&
data?.images_clinic[2]) || !!data?.images_clinic.length &&
"" data?.images_clinic[2]
} }
alt="img clinic" />
height={204} <Img
width={288} url={
/> data?.images_clinic &&
</CustomLoading> !!data?.images_clinic.length &&
</div> data?.images_clinic[3]
<div className="w-full"> }
<CustomLoading width="full" height={190}> />
<Image <Img
className="rounded-[8px] overflow-hidden" url={
src={ data?.images_clinic &&
(data?.images_clinic && !!data?.images_clinic.length &&
!!data?.images_clinic.length && data?.images_clinic[4]
data?.images_clinic[3]) || }
"" />
}
alt="img clinic"
height={204}
width={288}
/>
</CustomLoading>
</div>
<div className="w-full">
<CustomLoading width="full" height={190}>
<Image
className="rounded-[8px] overflow-hidden"
src={
(data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[4]) ||
""
}
alt="img clinic"
height={204}
width={288}
/>
</CustomLoading>
</div>
</div> </div>
); );
} }
+1
View File
@@ -12,6 +12,7 @@ const listTab = ["درباره کلینیک", "اطلاعات تماس", "پزش
function ClinicPage({ data, doctors }) { function ClinicPage({ data, doctors }) {
const [value, setValue] = useState(0); const [value, setValue] = useState(0);
const handleChange = (event, newValue) => setValue(newValue); const handleChange = (event, newValue) => setValue(newValue);
console.log(data);
const Components = [ const Components = [
<About data={data} />, <About data={data} />,
+1
View File
@@ -11,6 +11,7 @@ import specialtiesData from "@/data/specialties.json";
function ClinicsPage({ clinics, matchedCity, matchedState }) { function ClinicsPage({ clinics, matchedCity, matchedState }) {
const router = useRouter(); const router = useRouter();
const [filteredClinics, setFilteredClinics] = useState(clinics); const [filteredClinics, setFilteredClinics] = useState(clinics);
console.log(clinics);
const [selected, setSelected] = useState({ const [selected, setSelected] = useState({
province: matchedState?.name || "", province: matchedState?.name || "",
@@ -1,4 +1,4 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import HeadTab from "../content/HeadTab"; import HeadTab from "../content/HeadTab";
import { request } from "@/services/response"; import { request } from "@/services/response";
import { setNewData } from "./function"; import { setNewData } from "./function";
@@ -12,6 +12,7 @@ import Surgeries from "./surgeries";
import FamilyHistory from "./familyHistory"; import FamilyHistory from "./familyHistory";
import Relatives from "./relatives"; import Relatives from "./relatives";
import { dieses } from "./information/dieses"; import { dieses } from "./information/dieses";
import Cookies from "js-cookie";
function DetailUser({ function DetailUser({
user, user,
@@ -22,6 +23,8 @@ function DetailUser({
setIsTurnsDetails, setIsTurnsDetails,
}) { }) {
const [tab, setTab] = useState(0); const [tab, setTab] = useState(0);
const [information, setInformation] = useState();
const [prevInfo, setPrevInfo] = useState();
const initialData = { const initialData = {
name: dataUser?.name, name: dataUser?.name,
description: dataUser?.description, description: dataUser?.description,
@@ -41,6 +44,27 @@ function DetailUser({
national_code: dataUser?.national_code, national_code: dataUser?.national_code,
}; };
useEffect(() => {
const user = Cookies.get("userInfo");
const parsedUserInfo = user && JSON.parse(user);
console.log(parsedUserInfo);
if (parsedUserInfo) {
request
.getUserProfile(parsedUserInfo.uuid)
.then((res) => {
setInformation(res);
setPrevInfo(res);
})
.catch((err) => {
console.log(err);
});
} else {
// handle Error
}
}, []);
console.log(information);
if (!dataUser) { if (!dataUser) {
initialData.other = [ initialData.other = [
{ {
@@ -86,9 +110,12 @@ function DetailUser({
user={user} user={user}
data={data} data={data}
setData={setData} setData={setData}
prevInfo={prevInfo}
userInfo={userInfo} userInfo={userInfo}
dataUser={dataUser} dataUser={dataUser}
information={information}
initialData={initialData} initialData={initialData}
setInformation={setInformation}
updateDataUser={updateDataUser} updateDataUser={updateDataUser}
isTurnsDetails={isTurnsDetails} isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails} setIsTurnsDetails={setIsTurnsDetails}
@@ -1,4 +1,6 @@
function Content({ isConfirmed, children, title }) { function Content({ isConfirmed, children, title, error }) {
console.log(error);
return ( return (
<div className="flex w-full flex-col items-start justify-start gap-[8px] sm:gap-[3px] md:gap-[7px] lg:gap-[9px]"> <div className="flex w-full flex-col items-start justify-start gap-[8px] sm:gap-[3px] md:gap-[7px] lg:gap-[9px]">
<div className="flex min-h-[32px] items-center justify-start gap-[8px] md:gap-[6px] lg:gap-[4px]"> <div className="flex min-h-[32px] items-center justify-start gap-[8px] md:gap-[6px] lg:gap-[4px]">
@@ -12,7 +14,10 @@ function Content({ isConfirmed, children, title }) {
</p> </p>
)} )}
</div> </div>
{children} <div className="flex flex-col w-full items-start justify-start gap-1">
{children}
<p className="text-red-600 text-[12px]">{error || ""}</p>
</div>
</div> </div>
); );
} }
@@ -4,7 +4,7 @@ import { Button, Popover } from "@mui/material";
import { DatePicker } from "jalaali-react-date-picker"; import { DatePicker } from "jalaali-react-date-picker";
import { useState } from "react"; import { useState } from "react";
function DateBirthday({ data, changeData }) { function DateBirthday({ data, changeData, error }) {
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => { const handleClick = (event) => {
@@ -21,7 +21,10 @@ function DateBirthday({ data, changeData }) {
return ( return (
<div className="w-full"> <div className="w-full">
<div <div
className="relative w-full border cursor-pointer py-[15px] px-[16px] border-solid border-[#D7D7D7] rounded-[8px] h-[48px]" className={`relative w-full border cursor-pointer py-[15px] px-[16px] border-solid
rounded-[8px] h-[48px]
${error ? "border-[#ff0000]" : "border-[#D7D7D7]"}
`}
onClick={handleClick} onClick={handleClick}
> >
<p className="text-[#7E7E7E] text-[14px] font-normal cursor-pointer"> <p className="text-[#7E7E7E] text-[14px] font-normal cursor-pointer">
@@ -1,6 +1,7 @@
import Content from "./Content"; import Content from "./Content";
import DateBirthday from "./DateBirthday"; import DateBirthday from "./DateBirthday";
import Field from "./Field"; import AutoSelector from "./component/AutoSelector";
import Field from "./component/Field";
import { import {
gender, gender,
blood_group, blood_group,
@@ -8,14 +9,22 @@ import {
education, education,
job, job,
} from "./listSelector"; } from "./listSelector";
import AutoSelector from "@/app/component/element/AutoSelector";
function Form({ data, userInfo, insurance, changeData, prevData }) { function Form({
data,
userInfo,
insurance,
errors,
prevInfo,
changeData,
prevData,
}) {
const findVal = (list, name) => const findVal = (list, name) =>
data && list && list.length && list.find((g) => g.id === data[name]); data && list && list.length && list.find((g) => g.id === data[name]);
console.log(errors);
return ( return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-[24px]"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-x-[24px] gap-y-[10px]">
<Content title="شماره موبایل" isConfirmed={true}> <Content title="شماره موبایل" isConfirmed={true}>
<Field <Field
type="number" type="number"
@@ -27,18 +36,21 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
data={userInfo?.username} data={userInfo?.username}
/> />
</Content> </Content>
<Content title="کد ملی" isConfirmed={false}> <Content error={errors?.national_code} title="کد ملی" isConfirmed={false}>
<Field <Field
isTransparent={true} error={errors?.national_code}
iconGray={true}
type="number" type="number"
iconGray={true}
name="national_code"
isTransparent={true}
changeData={changeData} changeData={changeData}
data={data?.national_code} data={data?.national_code}
name="national_code" disable={prevInfo && prevInfo.national_code}
/> />
</Content> </Content>
<Content title="نام و نام خانوادگی" isConfirmed={false}> <Content error={errors?.name} title="نام" isConfirmed={false}>
<Field <Field
error={errors?.name}
isTransparent={true} isTransparent={true}
iconGray={true} iconGray={true}
changeData={changeData} changeData={changeData}
@@ -46,8 +58,19 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
name="name" name="name"
/> />
</Content> </Content>
<Content title="جنسیت"> <Content error={errors?.family} title="نام خانوادگی" isConfirmed={false}>
<Field
error={errors?.family}
isTransparent={true}
iconGray={true}
changeData={changeData}
data={data?.family}
name="family"
/>
</Content>
<Content error={errors?.gender} title="جنسیت">
<AutoSelector <AutoSelector
error={errors?.gender}
updateData={(name, data) => updateData={(name, data) =>
changeData(data === "زن" ? "female" : "male", "value", name) changeData(data === "زن" ? "female" : "male", "value", name)
} }
@@ -57,15 +80,17 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={gender} list={gender}
/> />
</Content> </Content>
<Content title="تاریخ تولد"> <Content error={errors?.birthday} title="تاریخ تولد">
<DateBirthday <DateBirthday
error={errors?.birthday}
data={data?.birthday} data={data?.birthday}
isConfirmed={false} isConfirmed={false}
changeData={changeData} changeData={changeData}
/> />
</Content> </Content>
<Content title="نام پدر" isConfirmed={false}> <Content error={errors?.fathers_name} title="نام پدر" isConfirmed={false}>
<Field <Field
error={errors?.fathers_name}
isTransparent={true} isTransparent={true}
iconGray={true} iconGray={true}
changeData={changeData} changeData={changeData}
@@ -87,18 +112,26 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={insurance} list={insurance}
/> />
</Content> </Content>
<Content title="شماره بیمه" isConfirmed={false}> <Content
error={errors?.insurance_id}
title="شماره بیمه"
isConfirmed={false}
>
<Field <Field
error={errors?.insurance_id}
isTransparent={true} isTransparent={true}
iconGray={true} iconGray={true}
type="number" type="number"
changeData={changeData} changeData={changeData}
data={data?.supplementary_insurance} data={data?.insurance_id}
name="supplementary_insurance" name="insurance_id"
// data={data?.supplementary_insurance}
// name="supplementary_insurance"
/> />
</Content> </Content>
<Content title="گروه خونی"> <Content error={errors?.blood_type} title="گروه خونی">
<AutoSelector <AutoSelector
error={errors?.blood_type}
updateData={(name, value) => updateData={(name, value) =>
changeData( changeData(
blood_group.find((g) => g.label === value).id, blood_group.find((g) => g.label === value).id,
@@ -112,8 +145,9 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={blood_group} list={blood_group}
/> />
</Content> </Content>
<Content title="وضعیت تاهل"> <Content error={errors?.marital_status} title="وضعیت تاهل">
<AutoSelector <AutoSelector
error={errors?.marital_status}
updateData={(name, value) => updateData={(name, value) =>
changeData(value === "متاهل" ? "married" : "single", "value", name) changeData(value === "متاهل" ? "married" : "single", "value", name)
} }
@@ -133,8 +167,9 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
name="home_phone" name="home_phone"
/> />
</Content> </Content>
<Content title="تحصیلات"> <Content error={errors?.education} title="تحصیلات">
<AutoSelector <AutoSelector
error={errors?.education}
updateData={(name, value) => updateData={(name, value) =>
changeData( changeData(
education.find((g) => g.label === value).id, education.find((g) => g.label === value).id,
@@ -148,8 +183,9 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={education} list={education}
/> />
</Content> </Content>
<Content title="شغل"> <Content error={errors?.job} title="شغل">
<AutoSelector <AutoSelector
error={errors?.job}
updateData={(name, value) => updateData={(name, value) =>
changeData(value === "آزاد" ? "azad" : "dolati", "value", name) changeData(value === "آزاد" ? "azad" : "dolati", "value", name)
} }
@@ -0,0 +1,101 @@
import BottomSelect from "@/components/icons/BottomSelect";
import { Autocomplete, Button, TextField } from "@mui/material";
import { styleTextSelectRight } from "@/mui";
function AutoSelector({
list,
value,
isError,
updateData,
label,
error,
disabled = false,
listboxProps,
name,
}) {
return (
<Autocomplete
disablePortal
options={list}
disabled={disabled}
value={value || ""}
ListboxProps={listboxProps}
getOptionLabel={(option) => {
if (typeof option === "string") return option;
return option?.name || option?.label || "";
}}
className="!w-full !rounded-lg auto-complete-selector"
onChange={(e, newValue) => {
updateData(name, newValue?.label || newValue || "");
}}
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: error
? "1px solid red !important"
: "1px solid #D7D7D7 !important",
},
"& .MuiInput-underline:hover:not(.Mui-disabled):before, .MuiOutlinedInput-notchedOutline":
{
borderColor: error ? "red !important" : "#D7D7D7 !important",
},
"& .muirtl-1kiro5a-MuiInputBase-root-MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline":
{
border: "1px solid #5559CE !important",
},
"& .MuiOutlinedInput-notchedOutline": {
border: isError ? "1px solid red !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 AutoSelector;
@@ -10,6 +10,7 @@ function Field({
data, data,
name, name,
iconGray, iconGray,
error,
isTransparent, isTransparent,
type, type,
props, props,
@@ -24,19 +25,22 @@ function Field({
disabled={disable} disabled={disable}
type={type || "text"} type={type || "text"}
placeholder={placeholder || ""} placeholder={placeholder || ""}
className={`!w-full res-field-account dark:!bg-transparent ${ className={`!w-full res-field-account dark:!bg-transparent ${
isTransparent ? "!bg-transparent lg:!bg-[#FFF]" : "!bg-[#FFF]" isTransparent ? "!bg-transparent lg:!bg-[#FFF]" : "!bg-[#FFF]"
}`} }`}
onChange={(e) => { onChange={(e) => {
changeData(e.target.value, "value", name); changeData(e.target.value, "value", name);
}} }}
sx={{ sx={{
// border: "1px solid red !important",
"& .MuiFormLabel-root": { "& .MuiFormLabel-root": {
top: "-4px !important", top: "-4px !important",
}, },
"& .MuiInputBase-input": { padding: "12.5px 14px" }, "& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiOutlinedInput-notchedOutline": { "& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7 !important", border: error
? "1px solid red !important"
: "1px solid #D7D7D7 !important",
}, },
"& .MuiInputBase-root": { "& .MuiInputBase-root": {
padding: "0 !important", padding: "0 !important",
@@ -10,13 +10,17 @@ function Information({
data, data,
setData, setData,
userInfo, userInfo,
prevInfo,
dataUser, dataUser,
initialData, initialData,
information,
setInformation,
updateDataUser, updateDataUser,
}) { }) {
const [disable, setDisable] = useState(true); const [disable, setDisable] = useState(true);
const [loading, setLoading] = useState(false);
const [insurance, setInsurance] = useState(); const [insurance, setInsurance] = useState();
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState();
useEffect(() => { useEffect(() => {
request.getInsuranceType().then((res) => { request.getInsuranceType().then((res) => {
@@ -28,43 +32,54 @@ function Information({
}, []); }, []);
const changeData = (value, type, name) => { const changeData = (value, type, name) => {
disable && setDisable(false); setInformation({
setData({ ...information,
...data,
[name]: value, [name]: value,
}); });
}; };
const validationInfo = () => {};
const sendReq = () => { const sendReq = () => {
setLoading(true); setLoading(true);
console.log(data); console.log(prevInfo);
console.log(prevInfo ? true : false);
if (!validationInfo())
request[prevInfo ? "patchUserProfile" : "postUserProfile"](
data,
prevInfo ? prevInfo.uuid : Cookies.get("uuid")
)
.then((res) => {
console.log(res);
request[dataUser ? "patchUserProfile" : "postUserProfile"]( if (!dataUser) {
data, updateDataUser();
dataUser ? dataUser.uuid : Cookies.get("uuid") }
) setLoading(false);
.then(() => { })
if (!dataUser) { .catch((err) => {
updateDataUser(); console.log(err);
} console.log(err?.response?.data);
setLoading(false); if (err?.response?.data) {
}) setErrors(err.response.data);
.catch(() => { }
setLoading(false);
}); setLoading(false);
});
}; };
return ( return (
<div className="opacity-page"> <div className="opacity-page">
<Form <Form
data={data} data={data}
errors={errors}
userInfo={userInfo} userInfo={userInfo}
prevInfo={prevInfo}
prevData={dataUser} prevData={dataUser}
insurance={insurance} insurance={insurance}
changeData={changeData} changeData={changeData}
/> />
<Button <Button
disabled={disable}
variant="contained" variant="contained"
onClick={sendReq} onClick={sendReq}
loading={loading} loading={loading}
-1
View File
@@ -1,4 +1,3 @@
import Cookies from "js-cookie";
import Image from "next/image"; import Image from "next/image";
function Head({ user }) { function Head({ user }) {