import React, {ChangeEvent, useContext, useEffect, useState} from "react"; import {SessionContext, SessionContextProps} from "@/context/SessionContext"; import {BookContext, BookContextProps} from "@/context/BookContext"; import {ChapterContext, ChapterContextProps} from "@/context/ChapterContext"; import {AlertContext, AlertContextProps} from "@/context/AlertContext"; import {AIInspire, InspirationAIIdea} from "@/lib/types/quillsense"; import {apiPost} from '@/lib/api/client'; import {htmlToText} from '@/lib/utils/html'; import InputField from "@/components/form/InputField"; import TextInput from "@/components/form/TextInput"; import {ArrowRight, Lightbulb, Link} from "lucide-react"; import {useTranslations} from '@/lib/i18n'; import {LangContext, LangContextProps} from "@/context/LangContext"; import {EditorContext, EditorContextProps} from "@/context/EditorContext"; import {AIUsageContext, AIUsageContextProps} from "@/context/AIUsageContext"; import EmptyState from "@/components/ui/EmptyState"; import PulseLoader from "@/components/ui/PulseLoader"; import LockCard from "@/components/ui/LockCard"; export default function InspireMe({hasKey}: { hasKey: boolean }): React.JSX.Element { const t = useTranslations(); const {session}: SessionContextProps = useContext(SessionContext); const {editor}: EditorContextProps = useContext(EditorContext); const {book}: BookContextProps = useContext(BookContext); const {chapter}: ChapterContextProps = useContext(ChapterContext); const {errorMessage}: AlertContextProps = useContext(AlertContext); const {lang}: LangContextProps = useContext(LangContext); const {setTotalCredits, setTotalPrice}: AIUsageContextProps = useContext(AIUsageContext); const [prompt, setPrompt] = useState(''); const [hideHelp, setHideHelp] = useState(true); const [loading, setLoading] = useState(false); const [inspirations, setInspirations] = useState([]); useEffect((): void => { if (prompt.trim().length > 0) { setHideHelp(true); } else { setHideHelp(false); } }, [prompt]); async function handleInspireMe(): Promise { if (prompt.trim() === '') { errorMessage(t("inspireMe.emptyPromptError")); return; } setLoading(true); setInspirations([]); try { let content: string = ''; if (editor) { try { content = editor.getHTML(); content = htmlToText(content); } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t('inspireMe.error.contentRetrievalUnknown')); } setLoading(false); return; } } if (!book?.bookId) { errorMessage(t('inspireMe.error.noBook')); setLoading(false); return; } if (chapter?.chapterOrder === undefined) { errorMessage(t('inspireMe.error.noChapter')); setLoading(false); return; } const inspire: AIInspire = await apiPost( `quillsense/inspire`, { prompt: prompt, bookId: book.bookId, chapterOrder: chapter.chapterOrder, currentContent: content, }, session.accessToken, lang ) if (inspire.useYourKey) { setTotalPrice((prevState: number): number => prevState + inspire.totalPrice) } else { setTotalCredits(inspire.totalPrice) } setInspirations(inspire.data.ideas); } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t('inspireMe.error.unknown')); } } finally { setLoading(false); } } if (!hasKey) { return ; } return (
): void => setPrompt(e.target.value)} placeholder={t("inspireMe.inputPlaceholder")} /> } icon={Lightbulb} fieldName={t("inspireMe.fieldName")} actionLabel={t("inspireMe.actionLabel")} actionIcon={Lightbulb} action={async (): Promise => handleInspireMe()} />
{loading && ( )} {!loading && inspirations.length > 0 && (

{t("inspireMe.resultHeading")}

{inspirations.map((idea: InspirationAIIdea, index: number): React.JSX.Element => (

{idea.idea}

{t("inspireMe.justificationHeading")}

{idea.reason}

{t("inspireMe.linkHeading")}
{idea.relatedTo}
))}
)} {!loading && inspirations.length === 0 && ( )}
); }