'use client'; import React, {useContext, useEffect, useState} from 'react'; import {BookContext} from "@/context/BookContext"; import {ChapterProps} from "@/lib/models/Chapter"; import {ChapterContext} from '@/context/ChapterContext'; import {EditorContext} from '@/context/EditorContext' import {Editor, useEditor} from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import Underline from "@tiptap/extension-underline"; import TextAlign from "@tiptap/extension-text-align"; import {AlertContext, AlertProvider} from "@/context/AlertContext"; import System from "@/lib/models/System"; import {SessionContext} from '@/context/SessionContext'; import {SessionProps} from "@/lib/models/Session"; import User, {UserProps} from "@/lib/models/User"; import {BookProps} from "@/lib/models/Book"; import {AppRouterInstance} from "next/dist/shared/lib/app-router-context.shared-runtime"; import {useRouter} from "next/navigation"; import ScribeTopBar from "@/components/ScribeTopBar"; import ScribeControllerBar from "@/components/ScribeControllerBar"; import ScribeLeftBar from "@/components/leftbar/ScribeLeftBar"; import ScribeEditor from "@/components/editor/ScribeEditor"; import ComposerRightBar from "@/components/rightbar/ComposerRightBar"; import ScribeFooterBar from "@/components/ScribeFooterBar"; import GuideTour, {GuideStep} from "@/components/GuideTour"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {faBookMedical, faFeather} from "@fortawesome/free-solid-svg-icons"; import TermsOfUse from "@/components/TermsOfUse"; import frMessages from '@/lib/locales/fr.json'; import enMessages from '@/lib/locales/en.json'; import Image from "next/image"; import {NextIntlClientProvider, useTranslations} from "next-intl"; import {LangContext} from "@/context/LangContext"; import {AIUsageContext} from "@/context/AIUsageContext"; const messagesMap = { fr: frMessages, en: enMessages }; function ScribeContent() { const t = useTranslations(); const {lang: locale} = useContext(LangContext); const {errorMessage, successMessage} = useContext(AlertContext); const editor: Editor | null = useEditor({ extensions: [ StarterKit, Underline, TextAlign.configure({ types: ['heading', 'paragraph'], }), ], injectCSS: false, immediatelyRender: false, }); const router: AppRouterInstance = useRouter(); const [session, setSession] = useState({user: null, accessToken: '', isConnected: false}); const [currentChapter, setCurrentChapter] = useState(undefined); const [currentBook, setCurrentBook] = useState(null); const [currentCredits, setCurrentCredits] = useState(160); const [amountSpent, setAmountSpent] = useState(session.user?.aiUsage || 0); const [isLoading, setIsLoading] = useState(true); const [sessionAttempts, setSessionAttempts] = useState(0) const [isTermsAccepted, setIsTermsAccepted] = useState(false); const [homeStepsGuide, setHomeStepsGuide] = useState(false); const homeSteps: GuideStep[] = [ { id: 0, x: 50, y: 50, title: t("homePage.guide.welcome", {name: session.user?.name || ''}), content: (

{t("homePage.guide.step0.description1")}


{t("homePage.guide.step0.description2")}

), }, { id: 1, position: 'right', targetSelector: `[data-guide="left-panel-container"]`, title: t("homePage.guide.step1.title"), content: (

: {t("homePage.guide.step1.addBook")}


: {t("homePage.guide.step1.generateStory")}

), }, { id: 2, title: t("homePage.guide.step2.title"), position: 'bottom', targetSelector: `[data-guide="search-bar"]`, content: (

{t("homePage.guide.step2.description")}

), }, { id: 3, title: t("homePage.guide.step3.title"), targetSelector: `[data-guide="user-dropdown"]`, position: 'auto', content: (

{t("homePage.guide.step3.description")}

), }, { id: 4, title: t("homePage.guide.step4.title"), content: (

{t("homePage.guide.step4.description1")}


{t("homePage.guide.step4.description2")}

), }, ]; useEffect((): void => { checkAuthentification().then() }, []); useEffect((): void => { if (session.isConnected) { setIsTermsAccepted(session.user?.termsAccepted ?? false); setHomeStepsGuide(User.guideTourDone(session.user?.guideTour ?? [], 'home-basic')); setIsLoading(false); } else { if (sessionAttempts > 2) { router.push('/'); } } setSessionAttempts(sessionAttempts + 1); }, [session]); useEffect((): void => { if (currentBook) { getLastChapter().then(); } }, [currentBook]); async function handleHomeTour(): Promise { try { const response: boolean = await System.authPostToServer('logs/tour', { plateforme: 'web', tour: 'home-basic' }, session.accessToken, locale ); if (response) { setSession(User.setNewGuideTour(session, 'home-basic')); setHomeStepsGuide(false); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("homePage.errors.termsError")); } } } async function checkAuthentification(): Promise { const token: string | null = System.getCookie('token'); if (token) { try { const user: UserProps = await System.authGetQueryToServer('user/infos', token, locale); if (!user) { errorMessage(t("homePage.errors.userNotFound")); } setSession({ isConnected: true, user: user, accessToken: token, }); setCurrentCredits(user.creditsBalance) setAmountSpent(user.aiUsage) } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("homePage.errors.authenticationError")); } window.location.href = 'https://eritors.com/login'; } } else { window.location.href = 'https://eritors.com/login'; } } async function handleTermsAcceptance(): Promise { try { const response: boolean = await System.authPostToServer(`user/terms/accept`, { version: '2025-07-1' }, session.accessToken, locale); if (response) { setIsTermsAccepted(true); setHomeStepsGuide(true); const newSession: SessionProps = { ...session, user: { ...session?.user as UserProps, termsAccepted: true } } setSession(newSession); } else { errorMessage(t("homePage.errors.termsAcceptError")); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("homePage.errors.termsAcceptError")); } } } async function getLastChapter(): Promise { if (session?.accessToken) { try { const response: ChapterProps | null = await System.authGetQueryToServer(`chapter/last-chapter`, session.accessToken, locale, {bookid: currentBook?.bookId}); if (response) { setCurrentChapter(response) } else { setCurrentChapter(undefined); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("homePage.errors.lastChapterError")); } } } } if (isLoading) { return (
ERitors Logo

{t("homePage.loading")}

) } return (
{ homeStepsGuide && setHomeStepsGuide(false)}/> } { !isTermsAccepted && }
); } export default function Scribe() { const [locale, setLocale] = useState<'fr' | 'en'>('fr'); useEffect((): void => { const lang: "fr" | "en" | null = System.getCookie('lang') as "fr" | "en" | null; if (lang) { setLocale(lang); } }, []); const messages = messagesMap[locale]; return ( ); }