diff --git a/app/api/config.ts b/app/api/config.ts index 4457a65..046a0e0 100644 --- a/app/api/config.ts +++ b/app/api/config.ts @@ -24,6 +24,7 @@ export const ENDPOINTS = { change: `${API_PREFIX}/profile/preference/login/change`, // ?login= }, status: `${API_PREFIX}/profile/preference/status/edit`, + avatar: `${API_PREFIX}/profile/preference/avatar/edit`, privacy: { stats: `${API_PREFIX}/profile/preference/privacy/stats/edit`, counts: `${API_PREFIX}/profile/preference/privacy/counts/edit`, diff --git a/app/components/Profile/Profile.EditModal.tsx b/app/components/Profile/Profile.EditModal.tsx index 59d1781..bb0d7fc 100644 --- a/app/components/Profile/Profile.EditModal.tsx +++ b/app/components/Profile/Profile.EditModal.tsx @@ -1,14 +1,17 @@ "use client"; -import { Modal } from "flowbite-react"; +import { FileInput, Label, Modal } from "flowbite-react"; import { Spinner } from "../Spinner/Spinner"; import useSWR from "swr"; import { ENDPOINTS } from "#/api/config"; import { useEffect, useState } from "react"; -import { unixToDate } from "#/api/utils"; +import { b64toBlob, unixToDate } from "#/api/utils"; import { ProfileEditPrivacyModal } from "./Profile.EditPrivacyModal"; import { ProfileEditStatusModal } from "./Profile.EditStatusModal"; import { ProfileEditSocialModal } from "./Profile.EditSocialModal"; +import { CropModal } from "../CropModal/CropModal"; +import { useSWRConfig } from "swr"; +import { useUserStore } from "#/store/auth"; const fetcher = async (url: string) => { const res = await fetch(url); @@ -33,6 +36,9 @@ export const ProfileEditModal = (props: { const [privacyModalOpen, setPrivacyModalOpen] = useState(false); const [statusModalOpen, setStatusModalOpen] = useState(false); const [socialModalOpen, setSocialModalOpen] = useState(false); + const [avatarModalOpen, setAvatarModalOpen] = useState(false); + const [avatarUri, setAvatarUri] = useState(null); + const [tempAvatarUri, setTempAvatarUri] = useState(null); const [privacyModalSetting, setPrivacyModalSetting] = useState("none"); const [privacySettings, setPrivacySettings] = useState({ privacy_stats: 9, @@ -46,6 +52,8 @@ export const ProfileEditModal = (props: { }); const [status, setStatus] = useState(""); const [login, setLogin] = useState(""); + const { mutate } = useSWRConfig(); + const userStore = useUserStore(); const privacy_stat_act_social_text = { 0: "Все пользователи", @@ -71,6 +79,19 @@ export const ProfileEditModal = (props: { `${ENDPOINTS.user.settings.login.info}?token=${props.token}` ); + const handleFileRead = (e, fileReader) => { + const content = fileReader.result; + setTempAvatarUri(content); + }; + + const handleFilePreview = (file) => { + const fileReader = new FileReader(); + fileReader.onloadend = (e) => { + handleFileRead(e, fileReader); + }; + fileReader.readAsDataURL(file); + }; + useEffect(() => { if (prefData) { setPrivacySettings({ @@ -93,6 +114,33 @@ export const ProfileEditModal = (props: { } }, [loginData]); + useEffect(() => { + if (avatarUri) { + let block = avatarUri.split(";"); + let contentType = block[0].split(":")[1]; + let realData = block[1].split(",")[1]; + const blob = b64toBlob(realData, contentType); + + const formData = new FormData(); + formData.append("image", blob, "cropped.jpg"); + formData.append("name", "image"); + const uploadRes = fetch( + `${ENDPOINTS.user.settings.avatar}?token=${props.token}`, + { + method: "POST", + body: formData, + } + ).then((res) => { + if (res.ok) { + mutate( + `${ENDPOINTS.user.profile}/${props.profile_id}?token=${props.token}` + ); + userStore.checkAuth(); + } + }); + } + }, [avatarUri]); + return ( <> -

Изменить фото профиля

-

- {prefData.is_change_avatar_banned - ? `Заблокировано до ${unixToDate( - prefData.ban_change_avatar_expires, - "full" - )}` - : "Загрузить с устройства"} -

+