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";
function Images({ data }) {
const images_clinic = data.images_clinic;
return (
<div
className="
@@ -15,12 +17,7 @@ function Images({ data }) {
<CustomLoading width={600} height={400}>
<Image
className="rounded-[8px] overflow-hidden"
src={
(data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[0]) ||
""
}
src={images_clinic[0].url || ""}
alt="img clinic"
height={432}
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 Image from "next/image";
import Img from "./Img";
function List({ data }) {
const images_clinic = data.images_clinic;
return (
<div className="hidden w-full md:grid grid-cols-2 gap-[16px] lg:gap-[24px]">
<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[1]) ||
""
}
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[2]) ||
""
}
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[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>
{images_clinic.map((img) => (
<div className="w-full">
<CustomLoading width="full" height={190}>
<Image
className="rounded-[8px] overflow-hidden"
src={img.url || ""}
alt="img clinic"
height={204}
width={288}
/>
</CustomLoading>
</div>
))}
<Img
url={
data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[1]
}
/>
<Img
url={
data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[2]
}
/>
<Img
url={
data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[3]
}
/>
<Img
url={
data?.images_clinic &&
!!data?.images_clinic.length &&
data?.images_clinic[4]
}
/>
</div>
);
}
+1
View File
@@ -12,6 +12,7 @@ const listTab = ["درباره کلینیک", "اطلاعات تماس", "پزش
function ClinicPage({ data, doctors }) {
const [value, setValue] = useState(0);
const handleChange = (event, newValue) => setValue(newValue);
console.log(data);
const Components = [
<About data={data} />,
+1
View File
@@ -11,6 +11,7 @@ import specialtiesData from "@/data/specialties.json";
function ClinicsPage({ clinics, matchedCity, matchedState }) {
const router = useRouter();
const [filteredClinics, setFilteredClinics] = useState(clinics);
console.log(clinics);
const [selected, setSelected] = useState({
province: matchedState?.name || "",
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useEffect, useState } from "react";
import HeadTab from "../content/HeadTab";
import { request } from "@/services/response";
import { setNewData } from "./function";
@@ -12,6 +12,7 @@ import Surgeries from "./surgeries";
import FamilyHistory from "./familyHistory";
import Relatives from "./relatives";
import { dieses } from "./information/dieses";
import Cookies from "js-cookie";
function DetailUser({
user,
@@ -22,6 +23,8 @@ function DetailUser({
setIsTurnsDetails,
}) {
const [tab, setTab] = useState(0);
const [information, setInformation] = useState();
const [prevInfo, setPrevInfo] = useState();
const initialData = {
name: dataUser?.name,
description: dataUser?.description,
@@ -41,6 +44,27 @@ function DetailUser({
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) {
initialData.other = [
{
@@ -86,9 +110,12 @@ function DetailUser({
user={user}
data={data}
setData={setData}
prevInfo={prevInfo}
userInfo={userInfo}
dataUser={dataUser}
information={information}
initialData={initialData}
setInformation={setInformation}
updateDataUser={updateDataUser}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
@@ -1,4 +1,6 @@
function Content({ isConfirmed, children, title }) {
function Content({ isConfirmed, children, title, error }) {
console.log(error);
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 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>
)}
</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>
);
}
@@ -4,7 +4,7 @@ import { Button, Popover } from "@mui/material";
import { DatePicker } from "jalaali-react-date-picker";
import { useState } from "react";
function DateBirthday({ data, changeData }) {
function DateBirthday({ data, changeData, error }) {
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => {
@@ -21,7 +21,10 @@ function DateBirthday({ data, changeData }) {
return (
<div className="w-full">
<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}
>
<p className="text-[#7E7E7E] text-[14px] font-normal cursor-pointer">
@@ -1,6 +1,7 @@
import Content from "./Content";
import DateBirthday from "./DateBirthday";
import Field from "./Field";
import AutoSelector from "./component/AutoSelector";
import Field from "./component/Field";
import {
gender,
blood_group,
@@ -8,14 +9,22 @@ import {
education,
job,
} 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) =>
data && list && list.length && list.find((g) => g.id === data[name]);
console.log(errors);
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}>
<Field
type="number"
@@ -27,18 +36,21 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
data={userInfo?.username}
/>
</Content>
<Content title="کد ملی" isConfirmed={false}>
<Content error={errors?.national_code} title="کد ملی" isConfirmed={false}>
<Field
isTransparent={true}
iconGray={true}
error={errors?.national_code}
type="number"
iconGray={true}
name="national_code"
isTransparent={true}
changeData={changeData}
data={data?.national_code}
name="national_code"
disable={prevInfo && prevInfo.national_code}
/>
</Content>
<Content title="نام و نام خانوادگی" isConfirmed={false}>
<Content error={errors?.name} title="نام" isConfirmed={false}>
<Field
error={errors?.name}
isTransparent={true}
iconGray={true}
changeData={changeData}
@@ -46,8 +58,19 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
name="name"
/>
</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
error={errors?.gender}
updateData={(name, data) =>
changeData(data === "زن" ? "female" : "male", "value", name)
}
@@ -57,15 +80,17 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={gender}
/>
</Content>
<Content title="تاریخ تولد">
<Content error={errors?.birthday} title="تاریخ تولد">
<DateBirthday
error={errors?.birthday}
data={data?.birthday}
isConfirmed={false}
changeData={changeData}
/>
</Content>
<Content title="نام پدر" isConfirmed={false}>
<Content error={errors?.fathers_name} title="نام پدر" isConfirmed={false}>
<Field
error={errors?.fathers_name}
isTransparent={true}
iconGray={true}
changeData={changeData}
@@ -87,18 +112,26 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={insurance}
/>
</Content>
<Content title="شماره بیمه" isConfirmed={false}>
<Content
error={errors?.insurance_id}
title="شماره بیمه"
isConfirmed={false}
>
<Field
error={errors?.insurance_id}
isTransparent={true}
iconGray={true}
type="number"
changeData={changeData}
data={data?.supplementary_insurance}
name="supplementary_insurance"
data={data?.insurance_id}
name="insurance_id"
// data={data?.supplementary_insurance}
// name="supplementary_insurance"
/>
</Content>
<Content title="گروه خونی">
<Content error={errors?.blood_type} title="گروه خونی">
<AutoSelector
error={errors?.blood_type}
updateData={(name, value) =>
changeData(
blood_group.find((g) => g.label === value).id,
@@ -112,8 +145,9 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={blood_group}
/>
</Content>
<Content title="وضعیت تاهل">
<Content error={errors?.marital_status} title="وضعیت تاهل">
<AutoSelector
error={errors?.marital_status}
updateData={(name, value) =>
changeData(value === "متاهل" ? "married" : "single", "value", name)
}
@@ -133,8 +167,9 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
name="home_phone"
/>
</Content>
<Content title="تحصیلات">
<Content error={errors?.education} title="تحصیلات">
<AutoSelector
error={errors?.education}
updateData={(name, value) =>
changeData(
education.find((g) => g.label === value).id,
@@ -148,8 +183,9 @@ function Form({ data, userInfo, insurance, changeData, prevData }) {
list={education}
/>
</Content>
<Content title="شغل">
<Content error={errors?.job} title="شغل">
<AutoSelector
error={errors?.job}
updateData={(name, value) =>
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,
name,
iconGray,
error,
isTransparent,
type,
props,
@@ -24,19 +25,22 @@ function Field({
disabled={disable}
type={type || "text"}
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]"
}`}
onChange={(e) => {
changeData(e.target.value, "value", name);
}}
sx={{
// border: "1px solid red !important",
"& .MuiFormLabel-root": {
top: "-4px !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7 !important",
border: error
? "1px solid red !important"
: "1px solid #D7D7D7 !important",
},
"& .MuiInputBase-root": {
padding: "0 !important",
@@ -10,13 +10,17 @@ function Information({
data,
setData,
userInfo,
prevInfo,
dataUser,
initialData,
information,
setInformation,
updateDataUser,
}) {
const [disable, setDisable] = useState(true);
const [loading, setLoading] = useState(false);
const [insurance, setInsurance] = useState();
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState();
useEffect(() => {
request.getInsuranceType().then((res) => {
@@ -28,43 +32,54 @@ function Information({
}, []);
const changeData = (value, type, name) => {
disable && setDisable(false);
setData({
...data,
setInformation({
...information,
[name]: value,
});
};
const validationInfo = () => {};
const sendReq = () => {
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"](
data,
dataUser ? dataUser.uuid : Cookies.get("uuid")
)
.then(() => {
if (!dataUser) {
updateDataUser();
}
setLoading(false);
})
.catch(() => {
setLoading(false);
});
if (!dataUser) {
updateDataUser();
}
setLoading(false);
})
.catch((err) => {
console.log(err);
console.log(err?.response?.data);
if (err?.response?.data) {
setErrors(err.response.data);
}
setLoading(false);
});
};
return (
<div className="opacity-page">
<Form
data={data}
errors={errors}
userInfo={userInfo}
prevInfo={prevInfo}
prevData={dataUser}
insurance={insurance}
changeData={changeData}
/>
<Button
disabled={disable}
variant="contained"
onClick={sendReq}
loading={loading}
-1
View File
@@ -1,4 +1,3 @@
import Cookies from "js-cookie";
import Image from "next/image";
function Head({ user }) {