Add profile page

This commit is contained in:
ariari04 2024-09-10 15:02:17 +06:00
parent a106044047
commit 95674a489c
7 changed files with 150 additions and 26 deletions

View File

@ -1,8 +1,6 @@
/* eslint-disable @next/next/no-img-element */ /* eslint-disable @next/next/no-img-element */
import { apiInstance } from "@/shared/config/apiConfig"; import { apiInstance } from "@/shared/config/apiConfig";
import { INews, INewsData, NewsDataResponse } from "@/shared/types/news-type"; import { INews, NewsDataResponse } from "@/shared/types/news-type";
import Image from "next/image";
import calendar from "./icons/calendar.svg";
import { Metadata } from "next"; import { Metadata } from "next";
import { Container, Title } from "@/shared/ui"; import { Container, Title } from "@/shared/ui";

View File

@ -0,0 +1,45 @@
import { AxiosError } from "axios";
import { apiInstance } from "@/shared/config/apiConfig";
import { getServerSession } from "next-auth";
import { authConfig } from "@/shared/config/authConfig";
import { Title } from "@/shared/ui";
import ProfileNav from "@/widgets/ProfileNav/ProfileNav";
const Profile = async ({
children,
}: Readonly<{
children: React.ReactNode;
}>) => {
const session = await getServerSession(authConfig);
const getProfile = async () => {
const Authorization = `Bearer ${session?.access_token}`;
const config = {
headers: {
Authorization,
},
};
try {
const response = await apiInstance.get<{
report_count: number;
}>("/users/profile/", config);
return response.data;
} catch (error: unknown) {
if (error instanceof AxiosError) console.log(error.message);
}
};
const data = await getProfile();
return (
<div className="flex flex-col">
<Title text="Личный кабинет" className="mb-[50px]" />
<ProfileNav report_count={data?.report_count as number} />
{children}
</div>
);
};
export default Profile;

View File

@ -0,0 +1,13 @@
"use client";
import { useRouter } from "@/shared/config/navigation";
import { useEffect } from "react";
const Profile = () => {
const router = useRouter();
useEffect(() => {
router.push("/profile/personal");
}, []);
return <></>;
};
export default Profile;

View File

@ -0,0 +1,29 @@
import { cn } from "@/lib/utils";
import { signOut } from "next-auth/react";
interface ILogoutButtonProps {
className?: string;
}
const LogoutButton: React.FC<ILogoutButtonProps> = ({
className,
}: ILogoutButtonProps) => {
return (
<button
type="button"
className={cn(
"p-[10px] border border-red-500 rounded-sm font-semibold leading-5 text-red-500",
className
)}
onClick={() =>
signOut({
callbackUrl: "/",
})
}
>
Выйти из аккаунта
</button>
);
};
export default LogoutButton;

View File

@ -1,6 +1,5 @@
import { usePathname } from "next/navigation";
import { useSession } from "next-auth/react"; import { useSession } from "next-auth/react";
import { Link } from "@/shared/config/navigation"; import { Link, usePathname } from "@/shared/config/navigation";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
interface INavAuthProps { interface INavAuthProps {
@ -8,29 +7,30 @@ interface INavAuthProps {
setOpenMenu: (open: boolean) => void; setOpenMenu: (open: boolean) => void;
} }
const NavAuth: React.FC<INavAuthProps> = ({ const NavAuth: React.FC<INavAuthProps> = ({ responsible, setOpenMenu }) => {
responsible,
setOpenMenu,
}: INavAuthProps) => {
const t = useTranslations("navigation"); const t = useTranslations("navigation");
const session = useSession(); const session = useSession();
const auth = session.status === "authenticated" ? true : false; const auth = session.status === "authenticated";
const pathname = usePathname(); const pathname = usePathname();
const isActiveProfile = pathname === "/profile"; const isActiveProfile = pathname === "/profile";
const isActiveSignIn = pathname === "/sign-in"; const isActiveSignIn = pathname === "/sign-in";
const linkStyles = (isActive: boolean) =>
`w-fit px-5 py-3 border-3 rounded-lg font-semibold transition-colors duration-300 ${
responsible
? isActive
? "bg-[#3695d8] text-white"
: "bg-white text-[#3695d8] border-[#3695d8]"
: "bg-[#3695d8] text-white border-[#3695d8]"
}`;
return ( return (
<> <>
{auth ? ( {auth ? (
<Link <Link
onClick={() => setOpenMenu(false)} onClick={() => setOpenMenu(false)}
href="/profile/personal" href="/profile/personal"
className={`${ className={linkStyles(isActiveProfile)}
responsible
? `w-fit px-5 py-3 border-3 rounded-lg font-semibold transition-colors duration-300 ${"bg-[#3695d8] text-white"}`
: "w-fit px-5 py-3 border-3 rounded-lg font-semibold transition-colors duration-300 bg-[#3695d8] text-white border-[#3695d8]"
}`}
> >
{t("profile")} {t("profile")}
</Link> </Link>
@ -38,15 +38,7 @@ const NavAuth: React.FC<INavAuthProps> = ({
<Link <Link
onClick={() => setOpenMenu(false)} onClick={() => setOpenMenu(false)}
href="/sign-in" href="/sign-in"
className={`${ className={linkStyles(isActiveSignIn)}
responsible
? `w-fit px-5 py-3 border-3 rounded-lg font-semibold transition-colors duration-300 ${
isActiveSignIn
? "bg-[#3695d8] text-white"
: "bg-white text-[#3695d8] border-[#3695d8]"
}`
: "w-fit px-5 py-3 border-3 rounded-lg font-semibold transition-colors duration-300 bg-[#3695d8] text-white"
}`}
> >
{t("login")} {t("login")}
</Link> </Link>

View File

@ -48,7 +48,7 @@ const Navbar = () => {
{LINKS().map((link) => ( {LINKS().map((link) => (
<Link <Link
className={`text-black opacity-0.5 size-4 font-normal min-w-[150px] flex justify-center${ className={`text-black opacity-0.5 size-4 font-normal min-w-[150px] flex justify-center${
pathname === link.pathname ? " opacity-1 font-extrabold" : "" pathname === link.pathname ? "opacity-1 font-bold" : ""
}`} }`}
key={link.id} key={link.id}
href={link.pathname} href={link.pathname}

View File

@ -0,0 +1,47 @@
"use client";
import LogoutButton from "@/features/LogoutButton";
import { Link, usePathname } from "@/shared/config/navigation";
interface IProfileNavProps {
report_count?: number;
}
const ProfileNav: React.FC<IProfileNavProps> = ({
report_count,
}: IProfileNavProps) => {
const pathname = usePathname();
return (
<nav className="mb-[55px] flex items-center justify-between">
<div className="flex items-center">
<Link
id={pathname === "/profile/personal" ? "profile-nav__link" : ""}
href="/profile/personal"
className="mr-[46px] text-[20px] font-semibold leading-6 text-gray-500"
>
Личные данные
</Link>
<Link
id={pathname === "/profile/my-reports" ? "profile-nav__link" : ""}
href="/profile/my-reports"
className="text-[20px] font-semibold leading-6 text-gray-500"
>
Мои обращения
</Link>
<span className="ml-4 py-[2px] px-[10px] rounded-md bg-white text-[14px] font-semibold leading-6 text-light-blue cursor-auto ">
{report_count}
</span>
</div>
{pathname === "/profile/personal" ? (
<LogoutButton />
) : (
<Link id="profile-nav__create-report" href="/create-report">
Написать обращение
</Link>
)}
</nav>
);
};
export default ProfileNav;