dashboard design and functionality and data and page doctor and clinic change data

This commit is contained in:
Ehsan
2025-06-04 03:58:38 +03:30
parent dafeebc54f
commit 0a8874c4ab
18 changed files with 419 additions and 102 deletions
+3 -1
View File
@@ -6,10 +6,11 @@ import userData from "@/data/userData.json";
import DashboardPage from "@/components/dashboard";
import UserAccountPage from "./userAccount";
function Content({ matchedCity, logged, initialIsOpenSide }) {
function Content({ matchedCity, logged, initialIsOpenSide, dataUser }) {
const [value, setValue] = useState(0);
const [isOpenSide, setIsOpenSide] = useState(initialIsOpenSide);
const [isTurnsDetails, setIsTurnsDetails] = useState(false);
console.log(dataUser);
return (
<DashboardPage
@@ -25,6 +26,7 @@ function Content({ matchedCity, logged, initialIsOpenSide }) {
>
<UserAccountPage
value={value}
dataUser={dataUser}
setValue={setValue}
user={userData.data}
isOpenSide={isOpenSide}
@@ -21,7 +21,7 @@ const listTab = [
"بستگان",
];
function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
function DetailUser({ user, isTurnsDetails, setIsTurnsDetails, dataUser }) {
const [tab, setTab] = useState(0);
const [data, setData] = useState(profileData[0]);
const [includeData, setIncludeData] = useState(false);
@@ -56,6 +56,7 @@ function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
const components = [
<Information
user={user}
dataUser={dataUser}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
/>,
@@ -1,6 +1,5 @@
import Content from "./Content";
import EditField from "@/app/component/EditField";
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
import DateBirthday from "./DateBirthday";
import {
insurance,
@@ -10,8 +9,11 @@ import {
education,
job,
} from "./listSelector";
import AutoSelector from "@/app/component/element/AutoSelector";
function Form({ data, changeData, selected, updateSelect }) {
const findVal = (list, name) => list.find((g) => g.id === selected[name]);
function Form({ data, changeData, updateSelect }) {
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-[24px]">
<Content title="شماره موبایل" isConfirmed={true}>
@@ -44,8 +46,11 @@ function Form({ data, changeData, updateSelect }) {
/>
</Content>
<Content title="جنسیت">
<AutoCompleteSelect
updateData={updateSelect}
<AutoSelector
updateData={(name, data) =>
updateSelect(name, data === "زن" ? "female" : "male")
}
value={findVal(gender, "gender")}
label="جنسیت"
name="gender"
list={gender}
@@ -68,8 +73,9 @@ function Form({ data, changeData, updateSelect }) {
/>
</Content>
<Content title="نوع بیمه">
<AutoCompleteSelect
<AutoSelector
updateData={updateSelect}
value={findVal(insurance, "insurance")}
label="نوع بیمه"
name="insurance"
list={insurance}
@@ -86,16 +92,22 @@ function Form({ data, changeData, updateSelect }) {
/>
</Content>
<Content title="گروه خونی">
<AutoCompleteSelect
updateData={updateSelect}
<AutoSelector
updateData={(name, value) =>
updateSelect(name, blood_group.find((g) => g.label === value).id)
}
value={findVal(blood_group, "blood_group")}
label="گروه خونی"
name="blood_group"
list={blood_group}
/>
</Content>
<Content title="وضعیت تاهل">
<AutoCompleteSelect
updateData={updateSelect}
<AutoSelector
updateData={(name, value) =>
updateSelect(name, marital_status.find((g) => g.label === value).id)
}
value={findVal(marital_status, "marital_status")}
label="وضعیت تاهل"
name="marital_status"
list={marital_status}
@@ -112,16 +124,22 @@ function Form({ data, changeData, updateSelect }) {
/>
</Content>
<Content title="تحصیلات">
<AutoCompleteSelect
updateData={updateSelect}
<AutoSelector
updateData={(name, value) =>
updateSelect(name, education.find((g) => g.label === value).id)
}
value={findVal(education, "education")}
label="تحصیلات"
name="education"
list={education}
/>
</Content>
<Content title="شغل">
<AutoCompleteSelect
updateData={updateSelect}
<AutoSelector
updateData={(name, value) =>
updateSelect(name, job.find((g) => g.label === value).id)
}
value={findVal(job, "job")}
label="شغل"
name="job"
list={job}
@@ -3,27 +3,29 @@ import Form from "./Form";
import { Button } from "@mui/material";
import ArrowLeftWhiteD from "@/components/icons/ArrowLeftWhiteD";
function Information({ user }) {
function Information({ user, dataUser }) {
const [disable, setDisable] = useState(true);
const [data, setData] = useState({
phone: { value: user.phone, isEdit: true },
national_code: { value: user.national_code, isEdit: true },
name: { value: user.name, isEdit: true },
date_of_birth: { value: user.date_of_birth, isEdit: true },
father_name: { value: user.father_name, isEdit: true },
insurance_number: { value: user.insurance_number, isEdit: true },
home_phone: { value: user.home_phone, isEdit: true },
phone: { value: dataUser.work_phone, isEdit: true },
national_code: { value: dataUser.national_code, isEdit: true },
name: { value: dataUser.name, isEdit: true },
date_of_birth: { value: dataUser.birthday, isEdit: true },
father_name: { value: dataUser.fathers_name, isEdit: true },
insurance_number: { value: dataUser.supplementary_insurance, isEdit: true },
home_phone: { value: dataUser.home_phone, isEdit: true },
work_phone: { value: user.work_phone, isEdit: true },
});
const [selected, setSelected] = useState({
gender: "",
blood_group: "",
insurance: "",
marital_status: "",
education: "",
job: "",
gender: dataUser.gender,
blood_group: dataUser.blood_type,
insurance: dataUser.supplementary_insurance,
marital_status: dataUser.marital_status,
education: dataUser.education,
job: dataUser.job,
});
const changeData = (value, type, name) =>
const changeData = (value, type, name) => {
disable && setDisable(false);
setData({
...data,
[name]: {
@@ -31,17 +33,28 @@ function Information({ user }) {
[type]: value,
},
});
};
const updateSelect = (event, name) =>
const updateSelect = (name, event) => {
disable && setDisable(false);
setSelected({ ...selected, [name]: event });
};
return (
<div className="opacity-page">
<Form data={data} changeData={changeData} updateSelect={updateSelect} />
<Form
data={data}
changeData={changeData}
selected={selected}
updateSelect={updateSelect}
/>
<Button
className="!gap-[4px] !mr-auto !text-nowrap !flex !flex-nowrap !py-[8px]
!bg-[#5559CE] !rounded-[4px] !text-[#EFEFEF] !text-[14px] md:!text-[16px] !font-medium
!mt-[32px] sm:!mt-[38px] md:!mt-[43px] lg:!mt-[48px] !px-[16px] sm:!px-[19px] md:!px-[22px] lg:!px-[24px]"
disabled={disable}
variant="contained"
className={`!gap-[4px] !mr-auto !text-nowrap !flex !flex-nowrap !py-[8px]
!rounded-[4px] !text-[#EFEFEF] !text-[14px] md:!text-[16px] !font-medium
!mt-[32px] sm:!mt-[38px] md:!mt-[43px] lg:!mt-[48px] !px-[16px] sm:!px-[19px] md:!px-[22px] lg:!px-[24px]
${disable ? "" : "!bg-[#5559CE]"}`}
>
ثبت اطلاعات
<ArrowLeftWhiteD />
@@ -1,30 +1,35 @@
export const gender = [
{ label: "مرد", id: 10 },
{ label: "زن", id: 20 },
{ label: "مرد", id: "male" },
{ label: "زن", id: "female" },
];
export const blood_group = [
{ label: "A+", id: 10 },
{ label: "B+", id: 20 },
{ label: "AB", id: 30 },
{ label: "O+", id: 40 },
{ label: "A+", id: "a_positive" },
{ label: "A-", id: "a_negative" },
{ label: "B+", id: "b_positive" },
{ label: "B-", id: "b_negative" },
{ label: "O+", id: "o_positive" },
{ label: "O-", id: "o_negative" },
{ label: "AB+", id: "ab_positive" },
{ label: "AB-", id: "ab_negative" },
];
export const marital_status = [
{ label: "متاهل", id: 10 },
{ label: "مجرد", id: 20 },
{ label: "متاهل", id: "married" },
{ label: "مجرد", id: "single" },
];
export const education = [
{ label: "دیپلم", id: 10 },
{ label: "فوق دیپلم", id: 20 },
{ label: "لیسانس", id: 30 },
{ label: "کارشناسی ارشد", id: 40 },
{ label: "دیپلم", id: "diploma" },
{ label: "دیپلم تحصیلات تکمیلی", id: "postgraduate_diploma" },
{ label: "لیسانس", id: "bachelor_s_degree" },
{ label: "کارشناسی ارشد", id: "master_s_degree" },
{ label: "دکترا", id: "doctorate" },
];
export const job = [
{ label: "آزاد", id: 10 },
{ label: "دولتی", id: 20 },
{ label: "آزاد", id: "azad" },
{ label: "دولتی", id: "dolati" },
];
export const insurance = [
@@ -29,10 +29,12 @@ function UserAccountPage({
setValue,
isOpenSide,
setIsOpenSide,
dataUser,
}) {
const sidebars = [
<DetailUser
user={user}
dataUser={dataUser}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
/>,
+83
View File
@@ -0,0 +1,83 @@
import { useRef } from "react";
// Icons
import CopyBlueD from "@/components/icons/CopyBlueD";
import DownloadBlue from "@/components/icons/DownloadBlue";
import WhatsappBlueD from "@/components/icons/WhatsappBlueD";
import TelegramBlueD from "@/components/icons/TelegramBlueD";
import LinkedingBlueD from "@/components/icons/LinkedingBlueD";
// Packages
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import { Button } from "@mui/material";
function List({ hiddenRef }) {
const handleDownloadPDF = async () => {
const element = hiddenRef.current;
if (!element) return;
const canvas = await html2canvas(element, {
backgroundColor: "#ffffff",
useCORS: true,
scale: 2,
});
const imgData = canvas.toDataURL("image/png");
const imgWidth = 210;
const imgProps = canvas;
const pxPerMm = imgProps.width / imgWidth;
const imgHeight = canvas.height / pxPerMm;
const pdf = new jsPDF({
orientation: "portrait",
unit: "mm",
format: [imgWidth, imgHeight],
});
pdf.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight);
pdf.save("poster.pdf");
};
const listIcons = [
{ name: "واتساپ", icon: <WhatsappBlueD /> },
{ name: "تلگرام", icon: <TelegramBlueD /> },
{ name: "لینکدین", icon: <LinkedingBlueD /> },
{ name: "کپی لینک", icon: <CopyBlueD /> },
{ name: "دانلود", icon: <DownloadBlue /> },
];
return (
<>
<ul className="flex items-center mx-[60px] sm:mx-[86px] md:mx-[112px] lg:mx-[140px] justify-center mt-[8px] md:mt-[12px] lg:mt-[16px] gap-[24px] sm:gap-[26px] md:gap-[29px] lg:gap-[32px]">
{listIcons.map((item, idx) => (
<li
key={idx}
className="flex flex-col justify-center items-center w-fit gap-[2px]"
>
<Button
className="
!p-[0px] !bg-[#EAECFA] !rounded-full !min-w-0 grid place-items-center
!w-[24px] sm:!w-[28px] md:!w-[32px] lg:!w-[36px]
!h-[24px] sm:!h-[28px] md:!h-[32px] lg:!h-[36px]
"
onClick={handleDownloadPDF}
variant="text"
>
<div
className="grid place-items-center w-full-icon
!w-[16px] md:!w-[17px] lg:!w-[18px]
!h-[16px] md:!h-[17px] lg:!h-[18px]"
>
{item.icon}
</div>
</Button>
</li>
))}
</ul>
</>
);
}
export default List;
+13 -41
View File
@@ -1,27 +1,18 @@
"use client";
import { useState } from "react";
import { useRef, useState } from "react";
import { styleDefault } from "@/mui";
import ShareDI from "@/components/icons/ShareDI";
import { Box, Button, Modal } from "@mui/material";
// Icons
import CopyBlueD from "@/components/icons/CopyBlueD";
import CloseModalD from "@/components/icons/CloseModalD";
import WhatsappBlueD from "@/components/icons/WhatsappBlueD";
import TelegramBlueD from "@/components/icons/TelegramBlueD";
import LinkedingBlueD from "@/components/icons/LinkedingBlueD";
import List from "./List";
import Poster from "../poster";
const listIcons = [
{ name: "واتساپ", icon: <WhatsappBlueD /> },
{ name: "تلگرام", icon: <TelegramBlueD /> },
{ name: "لینکدین", icon: <LinkedingBlueD /> },
{ name: "کپی لینک", icon: <CopyBlueD /> },
{ name: "دانلود", icon: <CopyBlueD /> },
];
function Share() {
function Share({ data }) {
const hiddenRef = useRef();
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
@@ -37,12 +28,17 @@ function Share() {
<ShareDI />
<p className="hidden lg:flex">اشتراک گذاری</p>
</Button>
<div className="fixed top-0 left-0 opacity-0 pointer-events-none -z-10">
<div ref={hiddenRef}>
<Poster data={data} />
</div>
</div>
<Modal open={open} onClose={handleClose}>
<Box
sx={styleDefault}
className="!pt-[12px] md:!pt-[14px] lg:!py-[16px]
className="!pt-[12px] md:!pt-[14px] lg:!py-[16px] !overflow-hidden
!px-[12px] sm:!px-[16px] md:!px-[20px] lg:!px-[24px]
!pb-[12px] sm:!pb-[16px] lg:!pb-[20px] !rounded-[8px] overflow-hidden"
!pb-[12px] sm:!pb-[16px] lg:!pb-[20px] !rounded-[8px]"
>
<div className="flex items-center justify-between w-full">
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium">
@@ -60,31 +56,7 @@ function Share() {
<p className="text-[#525252] text-[11px] md:text-[12px] lg:text-[14px] font-normal">
شما می توانید این پزشک را با دیگران به اشتراک بگذارید:
</p>
<ul className="flex items-center mx-[60px] sm:mx-[86px] md:mx-[112px] lg:mx-[140px] justify-center mt-[8px] md:mt-[12px] lg:mt-[16px] gap-[24px] sm:gap-[26px] md:gap-[29px] lg:gap-[32px]">
{listIcons.map((item, idx) => (
<li
key={idx}
className="flex flex-col justify-center items-center w-fit gap-[2px]"
>
<Button
className="
!p-[0px] !bg-[#EAECFA] !rounded-full !min-w-0 grid place-items-center
!w-[24px] sm:!w-[28px] md:!w-[32px] lg:!w-[36px]
!h-[24px] sm:!h-[28px] md:!h-[32px] lg:!h-[36px]
"
variant="text"
>
<div
className="grid place-items-center w-full-icon
!w-[16px] md:!w-[17px] lg:!w-[18px]
!h-[16px] md:!h-[17px] lg:!h-[18px]"
>
{item.icon}
</div>
</Button>
</li>
))}
</ul>
<List data={data} hiddenRef={hiddenRef} />
</Box>
</Modal>
</div>
+1 -1
View File
@@ -9,7 +9,7 @@ function DetailDoctor({ doctor }) {
return (
<div className="w-full lg:w-[59%]">
<div className="hidden lg:flex">
<Share />
<Share data={doctor} />
</div>
<Title doctor={doctor} />
<Link />
+35
View File
@@ -0,0 +1,35 @@
function DownloadBlue() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M16.4405 8.89999C20.0405 9.20999 21.5105 11.06 21.5105 15.11V15.24C21.5105 19.71 19.7205 21.5 15.2505 21.5H8.74047C4.27047 21.5 2.48047 19.71 2.48047 15.24V15.11C2.48047 11.09 3.93047 9.23999 7.47047 8.90999"
stroke="#5559CE"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M12 2V14.88"
stroke="#5559CE"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M15.3484 12.65L11.9984 16L8.64844 12.65"
stroke="#5559CE"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export default DownloadBlue;
@@ -32,6 +32,13 @@ function SendReq({
secure: true,
sameSite: "strict",
});
Cookies.set("uuid", uuid, {
expires: refreshTokenExpires,
path: "/",
secure: true,
sameSite: "strict",
});
};
const handleReq = async () => {