feat: add login editing

This commit is contained in:
Kentai Radiquum 2024-09-21 00:33:26 +05:00
parent 725b8a2c10
commit b3f432b36a
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
3 changed files with 171 additions and 5 deletions

View file

@ -0,0 +1,154 @@
"use client";
import { Button, Modal, Textarea } from "flowbite-react";
import { ENDPOINTS } from "#/api/config";
import { useEffect, useState } from "react";
import { useSWRConfig } from "swr";
import { Spinner } from "../Spinner/Spinner";
import { unixToDate } from "#/api/utils";
import { useUserStore } from "#/store/auth";
export const ProfileEditLoginModal = (props: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
token: string;
setLogin: (status: string) => void;
profile_id: number;
}) => {
const [loading, setLoading] = useState(false);
const [sending, setSending] = useState(false);
const [_login, _setLogin] = useState("");
const [_loginData, _setLoginData] = useState({
code: 0,
avatar: "",
login: "",
is_change_available: false,
last_change_at: 0,
next_change_available_at: 0,
});
const [_loginLength, _setLoginLength] = useState(0);
const { mutate } = useSWRConfig();
const userStore = useUserStore();
useEffect(() => {
setLoading(true);
fetch(`${ENDPOINTS.user.settings.login.info}?token=${props.token}`)
.then((res) => {
if (res.ok) {
return res.json();
}
})
.then((data) => {
_setLoginData(data);
_setLogin(data.login);
_setLoginLength(data.login.length);
setLoading(false);
});
}, [props.isOpen]);
function handleInput(e: any) {
_setLogin(e.target.value);
_setLoginLength(e.target.value.length);
}
function _setLoginSetting() {
setSending(true);
if (!_login || _login == "") {
alert("Никнейм не может быть пустым");
return;
}
fetch(
`${ENDPOINTS.user.settings.login.change}?login=${encodeURIComponent(
_login
)}&token=${props.token}`
)
.then((res) => {
if (res.ok) {
return res.json();
} else {
new Error("failed to send data");
}
})
.then((data) => {
if (data.code == 3) {
alert("Данный никнейм уже существует, попробуйте другой");
setSending(false);
return;
}
mutate(
`${ENDPOINTS.user.profile}/${props.profile_id}?token=${props.token}`
);
userStore.checkAuth();
props.setLogin(_login);
setSending(false);
props.setIsOpen(false);
})
.catch((err) => {
console.log(err);
setSending(false);
});
}
return (
<Modal
dismissible
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
size={"4xl"}
>
<Modal.Header>Изменить никнейм</Modal.Header>
<Modal.Body>
{loading ? (
<div className="flex items-center justify-center py-8">
<Spinner />
</div>
) : (
<>
{!_loginData.is_change_available ? (
<>
<p>Вы недавно изменили никнейм</p>
<p>
следующее изменение будет доступно:{" "}
<span className="font-bold">
{unixToDate(_loginData.next_change_available_at, "full")}
</span>
</p>
</>
) : (
<>
<Textarea
disabled={sending}
rows={1}
id="login"
className="w-full"
name="login"
onChange={(e) => handleInput(e)}
value={_login}
maxLength={20}
/>
<p className="text-sm text-right text-gray-500 dark:text-gray-300">
{_loginLength}/20
</p>
</>
)}
</>
)}
</Modal.Body>
<Modal.Footer>
{_loginData.is_change_available && (
<Button
color="blue"
onClick={() => _setLoginSetting()}
disabled={sending || loading}
>
Сохранить
</Button>
)}
<Button color="red" onClick={() => props.setIsOpen(false)}>
Отмена
</Button>
</Modal.Footer>
</Modal>
);
};

View file

@ -12,6 +12,7 @@ import { ProfileEditSocialModal } from "./Profile.EditSocialModal";
import { CropModal } from "../CropModal/CropModal";
import { useSWRConfig } from "swr";
import { useUserStore } from "#/store/auth";
import { ProfileEditLoginModal } from "./Profile.EditLoginModal";
const fetcher = async (url: string) => {
const res = await fetch(url);
@ -37,6 +38,7 @@ export const ProfileEditModal = (props: {
const [statusModalOpen, setStatusModalOpen] = useState(false);
const [socialModalOpen, setSocialModalOpen] = useState(false);
const [avatarModalOpen, setAvatarModalOpen] = useState(false);
const [loginModalOpen, setLoginModalOpen] = useState(false);
const [avatarUri, setAvatarUri] = useState(null);
const [tempAvatarUri, setTempAvatarUri] = useState(null);
const [privacyModalSetting, setPrivacyModalSetting] = useState("none");
@ -160,9 +162,6 @@ export const ProfileEditModal = (props: {
<span className="w-8 h-8 iconify mdi--user"></span>
<p className="text-xl font-bold">Профиль</p>
</div>
<p className="mx-1 text-base text-gray-500">
Некоторые изменения будут видны после перезагрузки страницы
</p>
</div>
<button
className="p-2 text-left rounded-md hover:bg-gray-100"
@ -205,6 +204,9 @@ export const ProfileEditModal = (props: {
<button
className="p-2 text-left rounded-md hover:bg-gray-100"
disabled={prefData.is_change_login_banned}
onClick={() => {
setLoginModalOpen(true);
}}
>
<p className="text-lg">Изменить никнейм</p>
<p className="text-base text-gray-500">
@ -366,7 +368,6 @@ export const ProfileEditModal = (props: {
src={tempAvatarUri}
setSrc={setAvatarUri}
setTempSrc={setTempAvatarUri}
// setImageData={setImageData}
aspectRatio={1 / 1}
guides={true}
quality={100}
@ -376,6 +377,13 @@ export const ProfileEditModal = (props: {
width={600}
height={600}
/>
<ProfileEditLoginModal
isOpen={loginModalOpen}
setIsOpen={setLoginModalOpen}
token={props.token}
setLogin={setLogin}
profile_id={props.profile_id}
/>
</>
);
};

View file

@ -1,4 +1,8 @@
# 3.2.0
# 3.2.1
## Добавлено
- Редактирование профиля
## Изменено