validation & change deisng sidebar dashboard & add menu to profile & handle menu item in profile & add api
This commit is contained in:
@@ -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
@@ -2,7 +2,7 @@ import Content from "@/components/dashboard/Content";
|
|||||||
import { defineAbilitiesFor } from "@/lib/ability";
|
import { defineAbilitiesFor } from "@/lib/ability";
|
||||||
import { getUser } from "@/lib/auth";
|
import { getUser } from "@/lib/auth";
|
||||||
import { getStateInfo } from "@/lib/getStateInfo";
|
import { getStateInfo } from "@/lib/getStateInfo";
|
||||||
import { cookies } from "next/headers";
|
import { cookies, headers } from "next/headers";
|
||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
export default async function Dashboard() {
|
export default async function Dashboard() {
|
||||||
@@ -12,15 +12,18 @@ export default async function Dashboard() {
|
|||||||
const cookieStore = cookies();
|
const cookieStore = cookies();
|
||||||
const token = cookieStore.get("access_token");
|
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")) {
|
if (!ability.can("access", "Dashboard")) {
|
||||||
return redirect("/");
|
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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import userData from "@/data/userData.json";
|
|||||||
import DashboardPage from "@/components/dashboard";
|
import DashboardPage from "@/components/dashboard";
|
||||||
import UserAccountPage from "./userAccount";
|
import UserAccountPage from "./userAccount";
|
||||||
|
|
||||||
function Content({ matchedCity, logged }) {
|
function Content({ matchedCity, logged, initialIsOpenSide }) {
|
||||||
const [value, setValue] = useState(0);
|
const [value, setValue] = useState(0);
|
||||||
const [isOpenSide, setIsOpenSide] = useState(false);
|
const [isOpenSide, setIsOpenSide] = useState(initialIsOpenSide);
|
||||||
const [isTurnsDetails, setIsTurnsDetails] = useState(false);
|
const [isTurnsDetails, setIsTurnsDetails] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,18 +5,16 @@ function HeadTab({
|
|||||||
tab,
|
tab,
|
||||||
user,
|
user,
|
||||||
listTab,
|
listTab,
|
||||||
|
components,
|
||||||
|
includeData,
|
||||||
handleChange,
|
handleChange,
|
||||||
isTurnsDetails,
|
isTurnsDetails,
|
||||||
setIsTurnsDetails,
|
setIsTurnsDetails,
|
||||||
components,
|
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="opacity-page">
|
<div className="opacity-page">
|
||||||
{isTurnsDetails ? (
|
{isTurnsDetails ? (
|
||||||
<IsTurnsDetails
|
<IsTurnsDetails user={user} setIsTurnsDetails={setIsTurnsDetails} />
|
||||||
user={user}
|
|
||||||
setIsTurnsDetails={setIsTurnsDetails}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="!w-full">
|
<div className="!w-full">
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const listTab = [
|
|||||||
function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
|
function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
|
||||||
const [tab, setTab] = useState(0);
|
const [tab, setTab] = useState(0);
|
||||||
const [data, setData] = useState(profileData[0]);
|
const [data, setData] = useState(profileData[0]);
|
||||||
|
const [includeData, setIncludeData] = useState(false);
|
||||||
|
|
||||||
const handleChange = (_, newValue) => setTab(newValue);
|
const handleChange = (_, newValue) => setTab(newValue);
|
||||||
const changeData = (action, name, id, payload) => {
|
const changeData = (action, name, id, payload) => {
|
||||||
@@ -72,6 +73,7 @@ function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
|
|||||||
user={user}
|
user={user}
|
||||||
listTab={listTab}
|
listTab={listTab}
|
||||||
components={components}
|
components={components}
|
||||||
|
includeData={includeData}
|
||||||
handleChange={handleChange}
|
handleChange={handleChange}
|
||||||
isTurnsDetails={isTurnsDetails}
|
isTurnsDetails={isTurnsDetails}
|
||||||
setIsTurnsDetails={setIsTurnsDetails}
|
setIsTurnsDetails={setIsTurnsDetails}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Transactions from "./sidebars/transactions";
|
|||||||
import Turns from "./sidebars/turns";
|
import Turns from "./sidebars/turns";
|
||||||
import DownloadD from "@/components/icons/DownloadD";
|
import DownloadD from "@/components/icons/DownloadD";
|
||||||
import ArrowRightD from "@/components/icons/ArrowRightD";
|
import ArrowRightD from "@/components/icons/ArrowRightD";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
const listTab = [
|
const listTab = [
|
||||||
"حساب کاربری",
|
"حساب کاربری",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const listIcons = [
|
|||||||
{ name: "تلگرام", icon: <TelegramBlueD /> },
|
{ name: "تلگرام", icon: <TelegramBlueD /> },
|
||||||
{ name: "لینکدین", icon: <LinkedingBlueD /> },
|
{ name: "لینکدین", icon: <LinkedingBlueD /> },
|
||||||
{ name: "کپی لینک", icon: <CopyBlueD /> },
|
{ name: "کپی لینک", icon: <CopyBlueD /> },
|
||||||
|
{ name: "دانلود", icon: <CopyBlueD /> },
|
||||||
];
|
];
|
||||||
|
|
||||||
function Share() {
|
function Share() {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import AppointmentList from "./appointmentList";
|
|||||||
import DetailDoctor from "./detailDoctor";
|
import DetailDoctor from "./detailDoctor";
|
||||||
import Share from "./detailDoctor/Share";
|
import Share from "./detailDoctor/Share";
|
||||||
import CustomLoading from "@/app/component/loading/Custom";
|
import CustomLoading from "@/app/component/loading/Custom";
|
||||||
|
import Poster from "./poster";
|
||||||
|
|
||||||
function DoctorPage({ doctor }) {
|
function DoctorPage({ doctor }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function Address({ data }) {
|
|||||||
<p className="text-[#E7EEF6] text-[20px] font-semibold">آدرس:</p>
|
<p className="text-[#E7EEF6] text-[20px] font-semibold">آدرس:</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[#E7EEF6] text-[16px] !font-normal mt-[16px]">
|
<p className="text-[#E7EEF6] text-[16px] !font-normal mt-[16px]">
|
||||||
{data.location}
|
{data?.location}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Image from "next/image";
|
|||||||
function ImageProfile({ data }) {
|
function ImageProfile({ data }) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-stroke-circle ml-[10px] mt-[57px] p-[9px] rounded-full overflow-hidden">
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ function Telefon({ data }) {
|
|||||||
<p className="text-[#E7EEF6] text-[20px] font-semibold">تلفن:</p>
|
<p className="text-[#E7EEF6] text-[20px] font-semibold">تلفن:</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[#E7EEF6] text-[16px] font-normal mt-[16px]">
|
<p className="text-[#E7EEF6] text-[16px] font-normal mt-[16px]">
|
||||||
{data.phone}
|
{data?.phone}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[#E7EEF6] text-[16px] font-normal mt-[12px]">
|
<p className="text-[#E7EEF6] text-[16px] font-normal mt-[12px]">
|
||||||
{data.phone} - {data.phone}
|
{data?.phone} - {data?.phone}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ function Poster({ data }) {
|
|||||||
<p className="text-[#E7EEF6] text-[16px] font-bold">nobat724.com</p>
|
<p className="text-[#E7EEF6] text-[16px] font-bold">nobat724.com</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-[40px] text-[#E7EEF6] text-[20px] font-bold">
|
<p className="mt-[40px] text-[#E7EEF6] text-[20px] font-bold">
|
||||||
{data.name}
|
{data?.name}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-[24px] mt-[20px] text-[#E7EEF6] font-bold">
|
<p className="text-[24px] mt-[20px] text-[#E7EEF6] font-bold">
|
||||||
تخصص: {data.expertise}
|
تخصص: {data?.expertise}
|
||||||
</p>
|
</p>
|
||||||
<Services data={data} />
|
<Services data={data} />
|
||||||
<Address data={data} />
|
<Address data={data} />
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import Row from "./list/Row";
|
|||||||
import Col from "./list/col";
|
import Col from "./list/col";
|
||||||
import ButtonMenu from "./list/col/ButtonMenu";
|
import ButtonMenu from "./list/col/ButtonMenu";
|
||||||
import BgGray from "./list/col/BgGray";
|
import BgGray from "./list/col/BgGray";
|
||||||
import UserLogin from "@/components/icons/UserLogin";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import ProfileUser from "./profile";
|
||||||
|
|
||||||
function Content({ matchedCity, name, logged }) {
|
function Content({ matchedCity, name, logged }) {
|
||||||
const [isActive, setIsActive] = useState(false);
|
const [isActive, setIsActive] = useState(false);
|
||||||
@@ -34,15 +34,7 @@ function Content({ matchedCity, name, logged }) {
|
|||||||
</div>
|
</div>
|
||||||
<Row name={name} />
|
<Row name={name} />
|
||||||
{logged ? (
|
{logged ? (
|
||||||
<Link href="/dashboard">
|
<ProfileUser />
|
||||||
<Button
|
|
||||||
className={`!flex !p-2 !rounded-full transition-all duration-500 !bg-[#EFEFEF]`}
|
|
||||||
variant="text"
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
<UserLogin />
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
) : (
|
) : (
|
||||||
<Link href="/login">
|
<Link href="/login">
|
||||||
<Button variant="outlined" color="primary">
|
<Button variant="outlined" color="primary">
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -9,7 +9,7 @@ import NotificationD from "@/components/icons/NotificationD";
|
|||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import ArrowLeftSideBar from "@/components/icons/ArrowLeftSideBar";
|
import ArrowLeftSideBar from "@/components/icons/ArrowLeftSideBar";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import ModalLogout from "./ModalLogout";
|
import ModalLogout from "../../../app/component/ModalLogout";
|
||||||
|
|
||||||
function List({
|
function List({
|
||||||
value,
|
value,
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Button, Popover } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import ArrowBottomHD from "@/components/icons/ArrowBottomHD";
|
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 Image from "next/image";
|
||||||
|
import DetailProfile from "@/app/component/DetailProfile";
|
||||||
|
|
||||||
function MenuProfile({ data }) {
|
function MenuProfile({ data }) {
|
||||||
const [anchorEl, setAnchorEl] = useState(null);
|
const [anchorEl, setAnchorEl] = useState(null);
|
||||||
|
|
||||||
const handleClick = (event) => setAnchorEl(event.currentTarget);
|
const handleClick = (event) => setAnchorEl(event.currentTarget);
|
||||||
const handleClose = () => setAnchorEl(null);
|
|
||||||
|
|
||||||
const open = Boolean(anchorEl);
|
|
||||||
const id = open ? "simple-popover" : undefined;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -49,59 +42,7 @@ function MenuProfile({ data }) {
|
|||||||
<ArrowBottomHD />
|
<ArrowBottomHD />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
<Popover
|
<DetailProfile anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
|
||||||
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>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import HeadMd from "./HeadMd";
|
|||||||
import HeadSm from "./HeadSm";
|
import HeadSm from "./HeadSm";
|
||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import LogoutOrangeP from "@/components/icons/LogoutOrangeP";
|
import LogoutOrangeP from "@/components/icons/LogoutOrangeP";
|
||||||
import ModalLogout from "@/components/layout/sidebar/ModalLogout";
|
import ModalLogout from "@/app/component/ModalLogout";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
function Sidebar({ active, setActive, open, setOpen }) {
|
function Sidebar({ active, setActive, open, setOpen }) {
|
||||||
|
|||||||
Reference in New Issue
Block a user