forked from Transparency/kgroad-frontend2
254 lines
7.2 KiB
TypeScript
254 lines
7.2 KiB
TypeScript
"use client";
|
||
|
||
import Image from "next/image";
|
||
import "./ProfileAvatar.scss";
|
||
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/components/Loader/Loader";
|
||
|
||
interface IProfileAvatarProps {
|
||
img: string;
|
||
}
|
||
|
||
const ProfileAvatar: React.FC<IProfileAvatarProps> = ({
|
||
img,
|
||
}: IProfileAvatarProps) => {
|
||
const [modal, setModal] = useState<boolean>(false);
|
||
const [display_image, setDisplayImage] = useState<File | string>(
|
||
img
|
||
);
|
||
const [isDeleting, setIsDeleting] = useState<boolean>(false);
|
||
const [message, setMessage] = useState<boolean>(false);
|
||
const def =
|
||
"https://api.kgroaduat.fishrungames.com/media/user_photo/default.webp";
|
||
|
||
const [success, setSuccess] = useState<string>("");
|
||
const [loader, setLoader] = useState<boolean>(false);
|
||
const [error, setError] = useState<string>("");
|
||
|
||
const session = useSession();
|
||
const router = useRouter();
|
||
|
||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (
|
||
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);
|
||
setDisplayImage(def);
|
||
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 (
|
||
<div className="profile-avatar">
|
||
<img
|
||
className="profile-avatar__image"
|
||
src={img}
|
||
alt="User Image"
|
||
/>
|
||
<button
|
||
onClick={() => setModal(true)}
|
||
className="profile-avatar__change-btn"
|
||
>
|
||
<Image src={pen} alt="Pen Icon" />
|
||
</button>
|
||
|
||
{modal && (
|
||
<div
|
||
onClick={() => setModal(false)}
|
||
className="profile-avatar__modal"
|
||
>
|
||
<div
|
||
onClick={(e) => e.stopPropagation()}
|
||
className="profile-avatar__wrapper"
|
||
>
|
||
<div className="profile-avatar__text">
|
||
<div>
|
||
<h4>Фото профиля</h4>
|
||
<button onClick={() => setModal(false)}>
|
||
<Image src={close} alt="Close Icon" />
|
||
</button>
|
||
</div>
|
||
<p>
|
||
По фото профиля другие люди смогут вас узнавать, а вам
|
||
будет проще определять, в какой аккаунт вы вошли.
|
||
</p>
|
||
</div>
|
||
|
||
<img
|
||
className="profile-avatar__user-img"
|
||
src={imageIsString}
|
||
alt="User image"
|
||
/>
|
||
<div className="profile-avatar__btns">
|
||
{img === def && display_image === def ? (
|
||
<>
|
||
<label
|
||
className="profile-avatar__blue-btn"
|
||
htmlFor="change-image"
|
||
>
|
||
Добавить фото профиля
|
||
</label>
|
||
<input
|
||
onChange={handleChange}
|
||
id="change-image"
|
||
type="file"
|
||
/>
|
||
</>
|
||
) : isDeleting ? (
|
||
<>
|
||
<button
|
||
onClick={() => setIsDeleting(false)}
|
||
className="profile-avatar__gray-btn"
|
||
>
|
||
Отмена
|
||
</button>
|
||
<button
|
||
onClick={returnDefaultImage}
|
||
disabled={loader}
|
||
className="profile-avatar__blue-btn"
|
||
>
|
||
{loader ? <Loader /> : "Удалить"}
|
||
</button>
|
||
</>
|
||
) : img === display_image || success !== "" ? (
|
||
<>
|
||
<button
|
||
onClick={() => setIsDeleting(true)}
|
||
className="profile-avatar__gray-btn"
|
||
>
|
||
Удалить
|
||
</button>
|
||
<label
|
||
className="profile-avatar__blue-btn"
|
||
htmlFor="change-image"
|
||
>
|
||
Сменить
|
||
</label>
|
||
<input
|
||
onChange={handleChange}
|
||
id="change-image"
|
||
type="file"
|
||
/>
|
||
</>
|
||
) : (
|
||
<>
|
||
<button
|
||
onClick={() => setDisplayImage(img)}
|
||
className="profile-avatar__gray-btn"
|
||
>
|
||
Назад
|
||
</button>
|
||
<button
|
||
disabled={loader}
|
||
onClick={changeImage}
|
||
className="profile-avatar__blue-btn"
|
||
>
|
||
{loader ? <Loader /> : "Сохранить"}
|
||
</button>
|
||
</>
|
||
)}
|
||
</div>
|
||
|
||
{message && (
|
||
<div className="profile-avatar__message">
|
||
<p>
|
||
{success} {error}
|
||
</p>
|
||
<button onClick={() => setMessage(false)}>
|
||
<Image src={close_white} alt="Close Icon White" />
|
||
</button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default ProfileAvatar;
|