import { useEffect, useRef, useState } from "react" import { API_URL } from "../../config" import { isLiteralUnion } from "../../utils/types" const addErrors = ["Не удалось опубликовать объявление", 'Неверный ответ от сервера', 'Неизвестная ошибка'] as const type AddError = typeof addErrors[number] const isAddError = (obj: unknown): obj is AddError => isLiteralUnion(obj, addErrors) const buttonStates = ["Опубликовать", "Загрузка...", "Опубликовано", "Отменено"] as const type ButtonState = typeof buttonStates[number] | AddError type AddResponse = { Answer: boolean } const isAddResponse = (obj: unknown): obj is AddResponse => typeof obj === 'object' && obj !== null && typeof Reflect.get(obj, 'Answer') === 'boolean' const useAddAnnouncement = () => { const [status, setStatus] = useState("Опубликовать") const timerIdRef = useRef() const abortControllerRef = useRef() const doAdd = async (formData: FormData) => { if (status === "Загрузка...") { abortControllerRef.current?.abort() setStatus("Отменено") timerIdRef.current = setTimeout(() => setStatus("Опубликовать"), 3000) return } setStatus("Загрузка...") const abortController = new AbortController() abortControllerRef.current = abortController try { const res = await fetch(API_URL + "/announcement", { method: 'PUT', body: formData, signal: abortController.signal }) const data: unknown = await res.json() if (!isAddResponse(data)) throw new Error('Неверный ответ от сервера') if (!data.Answer) { throw new Error("Не удалось опубликовать объявление") } setStatus("Опубликовано") } catch (err) { setStatus(isAddError(err) ? err : "Неизвестная ошибка") timerIdRef.current = setTimeout(() => setStatus("Опубликовать"), 10000) } } useEffect(() => { const abortController = abortControllerRef.current return () => { clearTimeout(timerIdRef.current) abortController?.abort() } }) return { doAdd, status } } export default useAddAnnouncement