'use client' import {ChangeEvent, Dispatch, SetStateAction, useContext, useEffect, useRef, useState} from "react"; import {AlertContext} from "@/context/AlertContext"; import System from "@/lib/models/System"; import {SessionContext} from "@/context/SessionContext"; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import { faBook, faBookOpen, faCalendarAlt, faFileWord, faInfo, faPencilAlt, faX } from "@fortawesome/free-solid-svg-icons"; import {SelectBoxProps} from "@/shared/interface"; import {BookProps, bookTypes} from "@/lib/models/Book"; import InputField from "@/components/form/InputField"; import TextInput from "@/components/form/TextInput"; import SelectBox from "@/components/form/SelectBox"; import DatePicker from "@/components/form/DatePicker"; import NumberInput from "@/components/form/NumberInput"; import TexteAreaInput from "@/components/form/TexteAreaInput"; import CancelButton from "@/components/form/CancelButton"; import SubmitButtonWLoading from "@/components/form/SubmitButtonWLoading"; import GuideTour, {GuideStep} from "@/components/GuideTour"; import {UserProps} from "@/lib/models/User"; import {useTranslations} from "next-intl"; import {LangContext, LangContextProps} from "@/context/LangContext"; // TODO: Refactor to use window.electron.invoke() instead of OfflineDataService interface MinMax { min: number; max: number; } export default function AddNewBookForm({setCloseForm}: { setCloseForm: Dispatch> }) { const t = useTranslations(); const {lang} = useContext(LangContext); const {session, setSession} = useContext(SessionContext); const {errorMessage} = useContext(AlertContext); const modalRef: React.RefObject = useRef(null); const [title, setTitle] = useState(''); const [subtitle, setSubtitle] = useState(''); const [summary, setSummary] = useState(''); const [publicationDate, setPublicationDate] = useState(''); const [wordCount, setWordCount] = useState(0); const [selectedBookType, setSelectedBookType] = useState(''); const [isAddingBook, setIsAddingBook] = useState(false); const [bookTypeHint, setBookTypeHint] = useState(false); const token: string = session?.accessToken ?? ''; const bookTypesHint: GuideStep[] = [{ id: 0, x: 80, y: 50, title: t("addNewBookForm.bookTypeHint.title"), content: (

{t("addNewBookForm.bookTypeHint.nouvelle.title")}

{t("addNewBookForm.bookTypeHint.nouvelle.range")}

{t("addNewBookForm.bookTypeHint.nouvelle.description")}

{t("addNewBookForm.bookTypeHint.novelette.title")}

{t("addNewBookForm.bookTypeHint.novelette.range")}

{t("addNewBookForm.bookTypeHint.novelette.description")}

{t("addNewBookForm.bookTypeHint.novella.title")}

{t("addNewBookForm.bookTypeHint.novella.range")}

{t("addNewBookForm.bookTypeHint.novella.description")}

{t("addNewBookForm.bookTypeHint.chapbook.title")}

{t("addNewBookForm.bookTypeHint.chapbook.range")}

{t("addNewBookForm.bookTypeHint.chapbook.description")}

{t("addNewBookForm.bookTypeHint.roman.title")}

{t("addNewBookForm.bookTypeHint.roman.range")}

{t("addNewBookForm.bookTypeHint.roman.description")}

{t("addNewBookForm.bookTypeHint.tip")}

), }] useEffect((): () => void => { document.body.style.overflow = 'hidden'; return (): void => { document.body.style.overflow = 'auto'; }; }, []); async function handleAddBook(): Promise { if (!title) { errorMessage(t('addNewBookForm.error.titleMissing')); return; } else { if (title.length < 2) { errorMessage(t('addNewBookForm.error.titleTooShort')); return; } if (title.length > 50) { errorMessage(t('addNewBookForm.error.titleTooLong')); return; } } if (selectedBookType === '') { errorMessage(t('addNewBookForm.error.typeMissing')); return; } setIsAddingBook(true); try { const offlineDataService = getOfflineDataService(); const bookData = { title, subTitle: subtitle, type: selectedBookType, summary, serie: 0, publicationDate, desiredWordCount: wordCount }; const bookId: string = await offlineDataService.createBook( bookData, session.user?.id || '', async () => { // Only called if online const id = await System.authPostToServer('book/add', { title: title, subTitle: subtitle, type: selectedBookType, summary: summary, serie: 0, publicationDate: publicationDate, desiredWordCount: wordCount, }, token, lang); if (!id) { throw new Error(t('addNewBookForm.error.addingBook')); } return id; } ); const book: BookProps = { bookId: bookId, ...bookData }; setSession({ ...session, user: { ...session.user as UserProps, books: [...((session.user as UserProps)?.books ?? []), book] } }); setIsAddingBook(false); setCloseForm(false) } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t('addNewBookForm.error.addingBook')); } setIsAddingBook(false); } } function maxWordsCountHint(): MinMax { switch (selectedBookType) { case 'short': return { min: 1000, max: 7500, }; case 'chapbook': return { min: 1000, max: 10000, }; case 'novelette' : return { min: 7500, max: 17500, }; case 'long' : return { min: 17500, max: 40000, }; case 'novel' : return { min: 40000, max: 0, }; default : return { min: 0, max: 0 } } } return (

{t("addNewBookForm.title")}

): void => setSelectedBookType(e.target.value)} data={bookTypes.map((types: SelectBoxProps): SelectBoxProps => { return { value: types.value, label: t(types.label) } })} defaultValue={selectedBookType} placeholder={t("addNewBookForm.typePlaceholder")}/> } action={async (): Promise => setBookTypeHint(true)} actionIcon={faInfo}/> ): void => setTitle(e.target.value)} placeholder={t("addNewBookForm.bookTitlePlaceholder")}/> }/> { selectedBookType !== 'lyric' && ( ): void => setSubtitle(e.target.value)} placeholder={t("addNewBookForm.subtitlePlaceholder")}/> }/> ) } ): void => setPublicationDate(e.target.value)}/> }/> { selectedBookType !== 'lyric' && ( <> 0 ? maxWordsCountHint().max.toLocaleString('fr-FR') : '∞'} ${t("addNewBookForm.words")}`} input={ }/> ): void => setSummary(e.target.value)} placeholder={t("addNewBookForm.summaryPlaceholder")} /> } /> ) }
setCloseForm(false)}/>
{bookTypeHint && setBookTypeHint(false)} onComplete={async (): Promise => setBookTypeHint(false)}/>}
); }