validation & change deisng sidebar dashboard & add menu to profile & handle menu item in profile & add api

This commit is contained in:
Ehsan
2025-06-03 00:50:10 +03:30
parent 0217e5e67e
commit dafeebc54f
18 changed files with 142 additions and 95 deletions
+80
View File
@@ -0,0 +1,80 @@
import { useState } from "react";
import ProfilePA from "@/components/icons/ProfilePA";
import LogoutP from "@/components/icons/LogoutP";
import SettingPA from "@/components/icons/SettingPA";
import CardDA from "@/components/icons/CardDA";
import { Button, Popover } from "@mui/material";
import Link from "next/link";
import ModalLogout from "./ModalLogout";
function DetailProfile({ anchorEl, setAnchorEl }) {
const [modal, setModal] = useState(false);
const handleClose = () => setAnchorEl(null);
const closeModal = () => setModal(false);
const openModal = () => setModal(true);
const open = Boolean(anchorEl);
const id = open ? "simple-popover" : undefined;
return (
<>
<ModalLogout open={modal} handleClose={closeModal} />
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
>
<div className="flex pt-[11px] pb-[14px] flex-col items-start gap-[8px] min-w-[185px]">
<Link href="/dashboard" className="w-full">
<Button
fullWidth
variant="text"
className="!text-[#7E7E7E] !text-[14px] !font-medium !flex !justify-start !p-[8px] !gap-[5px]"
>
<ProfilePA />
پروفایل من
</Button>
</Link>
<Button
fullWidth
variant="text"
className="!text-[#7E7E7E] !text-[14px] !font-medium !flex !justify-start !p-[8px] !gap-[5px]"
>
<CardDA />
پرداخت ها
</Button>
<Button
fullWidth
variant="text"
className="!text-[#7E7E7E] !text-[14px] !font-medium !flex !justify-start !p-[8px] !gap-[5px]"
>
<SettingPA />
تنظیمات
</Button>
<Button
fullWidth
color="error"
variant="contained"
onClick={openModal}
sx={{
"&.MuiButtonBase-root": {
paddingTop: "8px !important",
paddingBottom: "8px !important",
},
}}
className="!flex !w-[calc(100%-16px)] !mx-auto !text-[#FAFAFA] !text-[14px] !font-medium !items-center !justify-center !gap-[5px]"
>
<LogoutP />
خروج
</Button>
</div>
</Popover>
</>
);
}
export default DetailProfile;
+11 -8
View File
@@ -2,7 +2,7 @@ import Content from "@/components/dashboard/Content";
import { defineAbilitiesFor } from "@/lib/ability";
import { getUser } from "@/lib/auth";
import { getStateInfo } from "@/lib/getStateInfo";
import { cookies } from "next/headers";
import { cookies, headers } from "next/headers";
import { redirect } from "next/navigation";
export default async function Dashboard() {
@@ -12,15 +12,18 @@ export default async function Dashboard() {
const cookieStore = cookies();
const token = cookieStore.get("access_token");
// const response = await axios.get(
// "https://back-dev.clinic-pro.ir/api/v1/user-profile/e4fd81b4-31bc-4f9a-b300-da23026f9d79"
// );
// console.log(response);
if (!ability.can("access", "Dashboard")) {
return redirect("/");
}
return <Content matchedCity={matchedCity} logged={token} />;
const userAgent = headers().get("user-agent") || "";
const isMobile = /Mobi|Android/i.test(userAgent);
return (
<Content
matchedCity={matchedCity}
logged={token}
initialTurnsDetails={isMobile}
/>
);
}
+2 -2
View File
@@ -6,9 +6,9 @@ import userData from "@/data/userData.json";
import DashboardPage from "@/components/dashboard";
import UserAccountPage from "./userAccount";
function Content({ matchedCity, logged }) {
function Content({ matchedCity, logged, initialIsOpenSide }) {
const [value, setValue] = useState(0);
const [isOpenSide, setIsOpenSide] = useState(false);
const [isOpenSide, setIsOpenSide] = useState(initialIsOpenSide);
const [isTurnsDetails, setIsTurnsDetails] = useState(false);
return (
@@ -5,18 +5,16 @@ function HeadTab({
tab,
user,
listTab,
components,
includeData,
handleChange,
isTurnsDetails,
setIsTurnsDetails,
components,
}) {
return (
<div className="opacity-page">
{isTurnsDetails ? (
<IsTurnsDetails
user={user}
setIsTurnsDetails={setIsTurnsDetails}
/>
<IsTurnsDetails user={user} setIsTurnsDetails={setIsTurnsDetails} />
) : (
<>
<div className="!w-full">
@@ -24,6 +24,7 @@ const listTab = [
function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
const [tab, setTab] = useState(0);
const [data, setData] = useState(profileData[0]);
const [includeData, setIncludeData] = useState(false);
const handleChange = (_, newValue) => setTab(newValue);
const changeData = (action, name, id, payload) => {
@@ -72,6 +73,7 @@ function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
user={user}
listTab={listTab}
components={components}
includeData={includeData}
handleChange={handleChange}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
@@ -10,6 +10,7 @@ import Transactions from "./sidebars/transactions";
import Turns from "./sidebars/turns";
import DownloadD from "@/components/icons/DownloadD";
import ArrowRightD from "@/components/icons/ArrowRightD";
import { useState } from "react";
const listTab = [
"حساب کاربری",
+1
View File
@@ -18,6 +18,7 @@ const listIcons = [
{ name: "تلگرام", icon: <TelegramBlueD /> },
{ name: "لینکدین", icon: <LinkedingBlueD /> },
{ name: "کپی لینک", icon: <CopyBlueD /> },
{ name: "دانلود", icon: <CopyBlueD /> },
];
function Share() {
+1
View File
@@ -2,6 +2,7 @@ import AppointmentList from "./appointmentList";
import DetailDoctor from "./detailDoctor";
import Share from "./detailDoctor/Share";
import CustomLoading from "@/app/component/loading/Custom";
import Poster from "./poster";
function DoctorPage({ doctor }) {
return (
+1 -1
View File
@@ -8,7 +8,7 @@ function Address({ data }) {
<p className="text-[#E7EEF6] text-[20px] font-semibold">آدرس:</p>
</div>
<p className="text-[#E7EEF6] text-[16px] !font-normal mt-[16px]">
{data.location}
{data?.location}
</p>
</div>
);
+1 -1
View File
@@ -3,7 +3,7 @@ import Image from "next/image";
function ImageProfile({ data }) {
return (
<div className="bg-stroke-circle ml-[10px] mt-[57px] p-[9px] rounded-full overflow-hidden">
<Image src={data.img} width={173} height={173} alt="profile-user" />
<Image src={data?.img} width={173} height={173} alt="profile-user" />
</div>
);
}
+2 -2
View File
@@ -8,10 +8,10 @@ function Telefon({ data }) {
<p className="text-[#E7EEF6] text-[20px] font-semibold">تلفن:</p>
</div>
<p className="text-[#E7EEF6] text-[16px] font-normal mt-[16px]">
{data.phone}
{data?.phone}
</p>
<p className="text-[#E7EEF6] text-[16px] font-normal mt-[12px]">
{data.phone} - {data.phone}
{data?.phone} - {data?.phone}
</p>
</div>
);
+2 -2
View File
@@ -15,10 +15,10 @@ function Poster({ data }) {
<p className="text-[#E7EEF6] text-[16px] font-bold">nobat724.com</p>
</div>
<p className="mt-[40px] text-[#E7EEF6] text-[20px] font-bold">
{data.name}
{data?.name}
</p>
<p className="text-[24px] mt-[20px] text-[#E7EEF6] font-bold">
تخصص: {data.expertise}
تخصص: {data?.expertise}
</p>
<Services data={data} />
<Address data={data} />
+2 -10
View File
@@ -7,8 +7,8 @@ import Row from "./list/Row";
import Col from "./list/col";
import ButtonMenu from "./list/col/ButtonMenu";
import BgGray from "./list/col/BgGray";
import UserLogin from "@/components/icons/UserLogin";
import { useState } from "react";
import ProfileUser from "./profile";
function Content({ matchedCity, name, logged }) {
const [isActive, setIsActive] = useState(false);
@@ -34,15 +34,7 @@ function Content({ matchedCity, name, logged }) {
</div>
<Row name={name} />
{logged ? (
<Link href="/dashboard">
<Button
className={`!flex !p-2 !rounded-full transition-all duration-500 !bg-[#EFEFEF]`}
variant="text"
color="primary"
>
<UserLogin />
</Button>
</Link>
<ProfileUser />
) : (
<Link href="/login">
<Button variant="outlined" color="primary">
+28
View File
@@ -0,0 +1,28 @@
import DetailProfile from "@/app/component/DetailProfile";
import UserLogin from "@/components/icons/UserLogin";
import { removeToken } from "@/utils";
import { Button } from "@mui/material";
import { useState } from "react";
function ProfileUser() {
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => setAnchorEl(event.currentTarget);
const handleClose = () => setAnchorEl(null);
return (
<>
<Button
variant="text"
color="primary"
onClick={handleClick}
className={`!flex !p-2 !rounded-full transition-all duration-500 !bg-[#EFEFEF]`}
>
<UserLogin />
</Button>
<DetailProfile anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
</>
);
}
export default ProfileUser;
+1 -1
View File
@@ -9,7 +9,7 @@ import NotificationD from "@/components/icons/NotificationD";
import { Button } from "@mui/material";
import ArrowLeftSideBar from "@/components/icons/ArrowLeftSideBar";
import { useState } from "react";
import ModalLogout from "./ModalLogout";
import ModalLogout from "../../../app/component/ModalLogout";
function List({
value,
+3 -62
View File
@@ -1,20 +1,13 @@
import { useState } from "react";
import { Button, Popover } from "@mui/material";
import { Button } from "@mui/material";
import ArrowBottomHD from "@/components/icons/ArrowBottomHD";
import ProfilePA from "@/components/icons/ProfilePA";
import LogoutP from "@/components/icons/LogoutP";
import SettingPA from "@/components/icons/SettingPA";
import CardDA from "@/components/icons/CardDA";
import Image from "next/image";
import DetailProfile from "@/app/component/DetailProfile";
function MenuProfile({ data }) {
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => setAnchorEl(event.currentTarget);
const handleClose = () => setAnchorEl(null);
const open = Boolean(anchorEl);
const id = open ? "simple-popover" : undefined;
return (
<>
@@ -49,59 +42,7 @@ function MenuProfile({ data }) {
<ArrowBottomHD />
</div>
</Button>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
>
<div className="flex pt-[11px] pb-[14px] flex-col items-start gap-[8px] min-w-[185px]">
<Button
fullWidth
variant="text"
className="!text-[#7E7E7E] !text-[14px] !font-medium !flex !justify-start !p-[8px] !gap-[5px]"
>
<ProfilePA />
پروفایل من
</Button>
<Button
fullWidth
variant="text"
className="!text-[#7E7E7E] !text-[14px] !font-medium !flex !justify-start !p-[8px] !gap-[5px]"
>
<CardDA />
پرداخت ها
</Button>
<Button
fullWidth
variant="text"
className="!text-[#7E7E7E] !text-[14px] !font-medium !flex !justify-start !p-[8px] !gap-[5px]"
>
<SettingPA />
تنظیمات
</Button>
<Button
fullWidth
color="error"
variant="contained"
onClick={handleClose}
sx={{
"&.MuiButtonBase-root": {
paddingTop: "8px !important",
paddingBottom: "8px !important",
},
}}
className="!flex !w-[calc(100%-16px)] !mx-auto !text-[#FAFAFA] !text-[14px] !font-medium !items-center !justify-center !gap-[5px]"
>
<LogoutP />
خروج
</Button>
</div>
</Popover>
<DetailProfile anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
</>
);
}
+1 -1
View File
@@ -3,7 +3,7 @@ import HeadMd from "./HeadMd";
import HeadSm from "./HeadSm";
import { Button } from "@mui/material";
import LogoutOrangeP from "@/components/icons/LogoutOrangeP";
import ModalLogout from "@/components/layout/sidebar/ModalLogout";
import ModalLogout from "@/app/component/ModalLogout";
import { useState } from "react";
function Sidebar({ active, setActive, open, setOpen }) {