From 81aafdda7ca9e875e05c4d36753fdf6f56174dcb Mon Sep 17 00:00:00 2001 From: ariari04 Date: Wed, 11 Sep 2024 20:24:35 +0600 Subject: [PATCH] Add profile avatar --- src/app/[locale]/profile/personal/page.tsx | 41 +++ src/features/ProfileAvatar/ProfileAvatar.tsx | 244 ++++++++++++++++++ .../ProfileAvatar/icons/close-white.svg | 14 + src/features/ProfileAvatar/icons/close.svg | 14 + src/features/ProfileAvatar/icons/pen.svg | 8 + src/shared/types/profile-type.ts | 10 + 6 files changed, 331 insertions(+) create mode 100644 src/app/[locale]/profile/personal/page.tsx create mode 100644 src/features/ProfileAvatar/ProfileAvatar.tsx create mode 100644 src/features/ProfileAvatar/icons/close-white.svg create mode 100644 src/features/ProfileAvatar/icons/close.svg create mode 100644 src/features/ProfileAvatar/icons/pen.svg create mode 100644 src/shared/types/profile-type.ts diff --git a/src/app/[locale]/profile/personal/page.tsx b/src/app/[locale]/profile/personal/page.tsx new file mode 100644 index 0000000..f92910e --- /dev/null +++ b/src/app/[locale]/profile/personal/page.tsx @@ -0,0 +1,41 @@ +"use server"; + +import ProfileAvatar from "@/features/ProfileAvatar/ProfileAvatar"; +import { apiInstance } from "@/shared/config/apiConfig"; +import { authConfig } from "@/shared/config/authConfig"; +import { IProfile } from "@/shared/types/profile-type"; +import { AxiosError } from "axios"; +import { getServerSession } from "next-auth"; +import React from "react"; + +const Personal = async () => { + const session = await getServerSession(authConfig); + const getProfile = async () => { + const Authorization = `Bearer ${session?.access_token}`; + const config = { + headers: { + Authorization, + }, + }; + try { + const response = await apiInstance.get( + "/users/profile/", + config + ); + + return response.data; + } catch (error: unknown) { + if (error instanceof AxiosError) console.log(error.message); + } + }; + + const data = await getProfile(); + + return ( +
+ +
+ ); +}; + +export default Personal; diff --git a/src/features/ProfileAvatar/ProfileAvatar.tsx b/src/features/ProfileAvatar/ProfileAvatar.tsx new file mode 100644 index 0000000..b17b5d3 --- /dev/null +++ b/src/features/ProfileAvatar/ProfileAvatar.tsx @@ -0,0 +1,244 @@ +"use client"; + +import Image from "next/image"; +import pen from "./icons/pen.svg"; +import close from "./icons/close.svg"; +import close_white from "./icons/close-white.svg"; +import { authInstanse } from "@/shared/config/apiConfig"; +import { useRouter } from "next/navigation"; +import { useSession } from "next-auth/react"; +import { useState } from "react"; +import { AxiosError } from "axios"; +import Loader from "@/shared/ui/Loader/Loader"; + +interface IProfileAvatarProps { + img: string; +} + +const ProfileAvatar: React.FC = ({ + img, +}: IProfileAvatarProps) => { + const [modal, setModal] = useState(false); + const [display_image, setDisplayImage] = useState(img); + const [isDeleting, setIsDeleting] = useState(false); + const [message, setMessage] = useState(false); + + const [success, setSuccess] = useState(""); + const [loader, setLoader] = useState(false); + const [error, setError] = useState(""); + + const session = useSession(); + const router = useRouter(); + const def = "lflvl"; + const handleChange: React.ChangeEventHandler = (e) => { + if (e.target.files) { + setDisplayImage(e.target.files[0]); + } + }; + + const changeImage = async () => { + const formData = new FormData(); + + if (session.status === "unauthenticated") return; + + if (typeof display_image === typeof "string" || display_image === img) + return; + + formData.append("image", display_image); + + try { + setLoader(true); + const res = await authInstanse( + session.data?.access_token as string + ).patch("/users/update_image/", formData); + + setError(""); + setSuccess("Фото профиля обновлено"); + setMessage(true); + router.refresh(); + + setTimeout(() => { + setMessage(false); + }, 3000); + } catch (error: unknown) { + if (error instanceof AxiosError) { + setSuccess(""); + setError(error.message); + setMessage(true); + setTimeout(() => { + setMessage(false); + }, 3000); + } + } finally { + setLoader(false); + } + }; + + const returnDefaultImage = async () => { + if (session.status === "unauthenticated") return; + + try { + setLoader(true); + const res = await authInstanse( + session.data?.access_token as string + ).patch("/users/delete_image/", {}); + + setError(""); + setSuccess("Фото профиля удалено"); + setMessage(true); + router.refresh(); + + setTimeout(() => { + setMessage(false); + }, 3000); + } catch (error: unknown) { + if (error instanceof AxiosError) { + setSuccess(""); + setError(error.message); + setMessage(true); + setTimeout(() => { + setMessage(false); + }, 3000); + } + } finally { + setLoader(false); + } + }; + + const imageIsString = + typeof display_image === "string" + ? display_image + : typeof display_image === "undefined" + ? "" + : URL.createObjectURL(display_image as File); + return ( +
+ User Image + + + {modal && ( +
setModal(false)} + className="w-full h-full fixed top-0 left-0 flex items-center justify-center bg-black" + > +
e.stopPropagation()} + className="relative max-w-[400px] p-6 flex flex-col items-center bg-white rounded-sm shadow-sm" + > +
+
+

+ Фото профиля +

+ +
+

+ По фото профиля другие люди смогут вас узнавать, а вам будет + проще определять, в какой аккаунт вы вошли. +

+
+ + User image +
+ {img === def && display_image === def ? ( + <> + + + + ) : isDeleting ? ( + <> + + + + ) : img === display_image || success !== "" ? ( + <> + + + + + ) : ( + <> + + + + )} +
+ + {message && ( +
+

+ {success} {error} +

+ +
+ )} +
+
+ )} +
+ ); +}; + +export default ProfileAvatar; diff --git a/src/features/ProfileAvatar/icons/close-white.svg b/src/features/ProfileAvatar/icons/close-white.svg new file mode 100644 index 0000000..ab4a752 --- /dev/null +++ b/src/features/ProfileAvatar/icons/close-white.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/features/ProfileAvatar/icons/close.svg b/src/features/ProfileAvatar/icons/close.svg new file mode 100644 index 0000000..04f3f88 --- /dev/null +++ b/src/features/ProfileAvatar/icons/close.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/features/ProfileAvatar/icons/pen.svg b/src/features/ProfileAvatar/icons/pen.svg new file mode 100644 index 0000000..202f2c8 --- /dev/null +++ b/src/features/ProfileAvatar/icons/pen.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/src/shared/types/profile-type.ts b/src/shared/types/profile-type.ts new file mode 100644 index 0000000..319fdbc --- /dev/null +++ b/src/shared/types/profile-type.ts @@ -0,0 +1,10 @@ +export interface IProfile { + id: number; + email: string; + first_name: string; + last_name: string; + image: string; + role: number; + govern_status: null; + report_count: number; +}