184 lines
8.7 KiB
TypeScript
184 lines
8.7 KiB
TypeScript
import React, {useContext, useState} from "react";
|
|
import {ChapterProps, chapterVersions} from "@/lib/models/Chapter";
|
|
import {ChapterContext} from "@/context/ChapterContext";
|
|
import {BookContext} from "@/context/BookContext";
|
|
import System from "@/lib/models/System";
|
|
import UserMenu from "@/components/UserMenu";
|
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
|
import {faGear, faGlobe, faHome} from "@fortawesome/free-solid-svg-icons";
|
|
import {SelectBoxProps} from "@/shared/interface";
|
|
import {AlertContext} from "@/context/AlertContext";
|
|
import {SessionContext} from "@/context/SessionContext";
|
|
import Book, {BookListProps} from "@/lib/models/Book";
|
|
import Modal from "@/components/Modal";
|
|
import BookSetting from "@/components/book/settings/BookSetting";
|
|
import SelectBox from "@/components/form/SelectBox";
|
|
import {useTranslations} from "next-intl";
|
|
import {LangContext, LangContextProps} from "@/context/LangContext";
|
|
import CreditCounter from "@/components/CreditMeters";
|
|
import QuillSense from "@/lib/models/QuillSense";
|
|
|
|
export default function ScribeControllerBar() {
|
|
const {chapter, setChapter} = useContext(ChapterContext);
|
|
const {book, setBook} = useContext(BookContext);
|
|
const {errorMessage} = useContext(AlertContext)
|
|
const {session} = useContext(SessionContext);
|
|
const t = useTranslations();
|
|
const {lang, setLang} = useContext<LangContextProps>(LangContext)
|
|
|
|
const isGPTEnabled: boolean = QuillSense.isOpenAIEnabled(session);
|
|
const isGemini: boolean = QuillSense.isOpenAIEnabled(session);
|
|
const isAnthropic: boolean = QuillSense.isOpenAIEnabled(session);
|
|
const isSubTierTwo: boolean = QuillSense.getSubLevel(session) >= 2;
|
|
const hasAccess: boolean = (isGPTEnabled || isAnthropic || isGemini) || isSubTierTwo;
|
|
|
|
const [showSettingPanel, setShowSettingPanel] = useState<boolean>(false);
|
|
|
|
async function handleChapterVersionChanged(version: number) {
|
|
try {
|
|
const response: ChapterProps = await System.authGetQueryToServer<ChapterProps>(`chapter/whole`, session.accessToken, lang, {
|
|
bookid: book?.bookId,
|
|
id: chapter?.chapterId,
|
|
version: version,
|
|
});
|
|
if (!response) {
|
|
errorMessage(t("controllerBar.chapterNotFound"));
|
|
return;
|
|
}
|
|
setChapter(response);
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
errorMessage(e.message);
|
|
} else {
|
|
errorMessage(t("controllerBar.unknownChapterError"));
|
|
}
|
|
}
|
|
}
|
|
|
|
async function getBook(bookId: string): Promise<void> {
|
|
try {
|
|
const response: BookListProps = await System.authGetQueryToServer<BookListProps>(`book/basic-information`, session.accessToken, lang, {
|
|
id: bookId,
|
|
});
|
|
if (!response) {
|
|
errorMessage(t("controllerBar.bookNotFound"));
|
|
return;
|
|
}
|
|
setBook!!({
|
|
bookId: response.id,
|
|
type: response.type,
|
|
title: response.title,
|
|
subTitle: response.subTitle,
|
|
summary: response.summary,
|
|
publicationDate: response.desiredReleaseDate,
|
|
desiredWordCount: response.desiredWordCount,
|
|
totalWordCount: response.desiredWordCount,
|
|
});
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
errorMessage(e.message);
|
|
} else {
|
|
errorMessage(t("controllerBar.unknownBookError"));
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleLanguageChange(language: "fr" | "en"): void {
|
|
System.setCookie('lang', language, 365);
|
|
const newLang: "en" | "fr" | null = System.getCookie('lang') as "en" | "fr" | null;
|
|
if (newLang) {
|
|
setLang(language);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className="flex items-center justify-between px-6 py-3 bg-tertiary/90 backdrop-blur-sm border-b border-secondary/50 shadow-md">
|
|
<div className="flex items-center space-x-4">
|
|
<div className="flex items-center gap-2">
|
|
{book && (
|
|
<button onClick={(): void => setShowSettingPanel(true)}
|
|
className="group p-2 rounded-lg text-muted hover:text-text-primary hover:bg-secondary/50 transition-all hover:scale-110">
|
|
<FontAwesomeIcon icon={faGear}
|
|
className={'w-5 h-5 transition-transform group-hover:rotate-90'}/>
|
|
</button>
|
|
)}
|
|
{
|
|
book && (
|
|
<button onClick={(): void => {
|
|
setBook && setBook(null)
|
|
setChapter && setChapter(undefined)
|
|
}}
|
|
className="group p-2 rounded-lg text-muted hover:text-primary hover:bg-secondary/50 transition-all hover:scale-110">
|
|
<FontAwesomeIcon icon={faHome}
|
|
className={'w-5 h-5 transition-transform group-hover:scale-110'}/>
|
|
</button>
|
|
)
|
|
}
|
|
</div>
|
|
<div className="min-w-[200px]">
|
|
<SelectBox onChangeCallBack={(e) => getBook(e.target.value)}
|
|
data={Book.booksToSelectBox(session.user?.books ?? [])} defaultValue={book?.bookId}
|
|
placeholder={t("controllerBar.selectBook")}/>
|
|
</div>
|
|
{chapter && (
|
|
<div className="min-w-[180px]">
|
|
<SelectBox onChangeCallBack={(e) => handleChapterVersionChanged(parseInt(e.target.value))}
|
|
data={chapterVersions.filter((version: SelectBoxProps): boolean => {
|
|
return !(version.value === '1' && !hasAccess);
|
|
}).map((version: SelectBoxProps) => {
|
|
return {
|
|
value: version.value.toString(),
|
|
label: t(version.label)
|
|
}
|
|
})} defaultValue={chapter?.chapterContent.version.toString()}/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="flex items-center space-x-4">
|
|
{
|
|
hasAccess &&
|
|
<CreditCounter isCredit={isSubTierTwo}/>
|
|
}
|
|
<div
|
|
className="flex items-center bg-secondary/50 rounded-xl overflow-hidden border border-secondary shadow-sm">
|
|
<div className="flex items-center px-3 py-2 bg-dark-background/50 border-r border-secondary">
|
|
<FontAwesomeIcon icon={faGlobe} className="w-4 h-4 text-primary"/>
|
|
</div>
|
|
<button
|
|
onClick={() => handleLanguageChange('fr')}
|
|
className={`px-4 py-2 text-sm font-semibold transition-all ${
|
|
lang === 'fr'
|
|
? 'bg-primary text-text-primary shadow-md'
|
|
: 'bg-transparent text-text-secondary hover:bg-secondary/50 hover:text-text-primary'
|
|
}`}
|
|
>
|
|
FR
|
|
</button>
|
|
<button
|
|
onClick={() => handleLanguageChange('en')}
|
|
className={`px-4 py-2 text-sm font-semibold transition-all ${
|
|
lang === 'en'
|
|
? 'bg-primary text-text-primary shadow-md'
|
|
: 'bg-transparent text-text-secondary hover:bg-secondary/50 hover:text-text-primary'
|
|
}`}
|
|
>
|
|
EN
|
|
</button>
|
|
</div>
|
|
<UserMenu/>
|
|
</div>
|
|
{
|
|
showSettingPanel &&
|
|
<Modal title={t("controllerBar.bookSettings")}
|
|
size={'large'}
|
|
onClose={() => setShowSettingPanel(false)}
|
|
onConfirm={() => {
|
|
}}
|
|
children={<BookSetting/>}
|
|
enableFooter={false}
|
|
/>
|
|
}
|
|
</div>
|
|
)
|
|
} |