feat: add toast for creating/updating collection

This commit is contained in:
Kentai Radiquum 2025-03-21 00:51:23 +05:00
parent 4c6fb75785
commit b7661f47ef
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
4 changed files with 93 additions and 37 deletions

View file

@ -113,6 +113,7 @@ export const App = (props) => {
/>
)}
<ToastContainer
className={"mx-2 mb-20 sm:mb-0"}
position="bottom-center"
autoClose={5000}
hideProgressBar={false}

View file

@ -31,16 +31,16 @@ export async function tryCatch<T, E = Error>(
export async function tryCatchAPI<T, E = Error>(
promise: Promise<any>
): Promise<Result<any, E>> {
): Promise<Result<any, any>> {
try {
const res: Awaited<Response> = await promise;
if (!res.ok) {
return {
data: null,
error: JSON.stringify({
error: {
message: res.statusText,
code: res.status,
}) as E,
},
};
}
@ -53,7 +53,7 @@ export async function tryCatchAPI<T, E = Error>(
error: {
message: "Not Found",
code: 404,
} as E,
},
};
}
@ -64,13 +64,13 @@ export async function tryCatchAPI<T, E = Error>(
error: {
message: "API Returned an Error",
code: data.code || 500,
} as E,
},
};
}
return { data, error: null };
} catch (error) {
return { data: null, error: error as E };
return { data: null, error: error};
}
}

View file

@ -15,8 +15,8 @@ export async function generateMetadata(
if (error) {
return {
title: "Ошибка",
description: "Ошибка",
title: "Приватная коллекция",
description: "Приватная коллекция",
};
}

View file

@ -13,18 +13,27 @@ import {
FileInput,
Label,
Modal,
useThemeMode,
} from "flowbite-react";
import { ReleaseLink } from "#/components/ReleaseLink/ReleaseLink";
import { CropModal } from "#/components/CropModal/CropModal";
import { b64toBlob } from "#/api/utils";
import { b64toBlob, tryCatchAPI } from "#/api/utils";
import { useSWRfetcher } from "#/api/utils";
import { Spinner } from "#/components/Spinner/Spinner";
import { toast } from "react-toastify";
export const CreateCollectionPage = () => {
const userStore = useUserStore();
const searchParams = useSearchParams();
const router = useRouter();
const theme = useThemeMode();
useEffect(() => {
if (userStore.state === "finished" && !userStore.token) {
router.push("/login?redirect=/collections/create");
}
}, [userStore]);
const [edit, setEdit] = useState(false);
@ -138,12 +147,25 @@ export const CreateCollectionPage = () => {
e.preventDefault();
async function _createCollection() {
setIsSending(true);
const tid = toast.loading(
mode === "edit" ? "Редактируем коллекцию..." : "Создаём коллекцию...",
{
position: "bottom-center",
hideProgressBar: true,
closeOnClick: false,
pauseOnHover: false,
draggable: false,
theme: theme.mode == "light" ? "light" : "dark",
}
);
const url =
mode === "edit" ?
`${ENDPOINTS.collection.edit}/${collection_id}?token=${userStore.token}`
: `${ENDPOINTS.collection.create}?token=${userStore.token}`;
const res = await fetch(url, {
const { data, error } = await tryCatchAPI(
fetch(url, {
method: "POST",
body: JSON.stringify({
...collectionInfo,
@ -151,12 +173,24 @@ export const CreateCollectionPage = () => {
private: isPrivate,
releases: addedReleasesIds,
}),
})
);
if (error) {
let message = error.message;
if (error.code == 5) {
message =
"Вы превысили допустимый еженедельный лимит создания коллекций";
}
toast.update(tid, {
render: message,
type: "error",
autoClose: 2500,
isLoading: false,
closeOnClick: true,
draggable: true,
});
const data = await res.json();
if (data.code == 5) {
alert("Вы превысили допустимый еженедельный лимит создания коллекций!");
setIsSending(false);
return;
}
@ -169,33 +203,54 @@ export const CreateCollectionPage = () => {
const formData = new FormData();
formData.append("image", blob, "cropped.jpg");
formData.append("name", "image");
const uploadRes = await fetch(
await fetch(
`${ENDPOINTS.collection.editImage}/${data.collection.id}?token=${userStore.token}`,
{
method: "POST",
body: formData,
}
);
const uploadData = await uploadRes.json();
}
toast.update(tid, {
render: mode === "edit" ? `Коллекция ${collectionInfo.title} обновлена` : `Коллекция ${collectionInfo.title} создана`,
type: "success",
autoClose: 2500,
isLoading: false,
closeOnClick: true,
draggable: true,
});
router.push(`/collection/${data.collection.id}`);
setIsSending(false);
}
if (
collectionInfo.title.length >= 10 &&
addedReleasesIds.length >= 1 &&
userStore.token
) {
// setIsSending(true);
_createCollection();
} else if (collectionInfo.title.length < 10) {
alert("Необходимо ввести название коллекции не менее 10 символов");
} else if (!userStore.token) {
alert("Для создания коллекции необходимо войти в аккаунт");
} else if (addedReleasesIds.length < 1) {
alert("Необходимо добавить хотя бы один релиз в коллекцию");
if (collectionInfo.title.length < 10) {
toast.error("Необходимо ввести название коллекции не менее 10 символов", {
position: "bottom-center",
hideProgressBar: true,
type: "error",
autoClose: 2500,
isLoading: false,
closeOnClick: true,
draggable: true,
});
return;
}
if (addedReleasesIds.length < 1) {
toast.error("Необходимо добавить хотя бы один релиз в коллекцию", {
position: "bottom-center",
hideProgressBar: true,
type: "error",
autoClose: 2500,
isLoading: false,
closeOnClick: true,
draggable: true,
});
return;
}
_createCollection();
}
function _deleteRelease(release: any) {