Add components for Act management and integrate Electron setup
This commit is contained in:
421
components/book/settings/guide-line/GuideLineSetting.tsx
Normal file
421
components/book/settings/guide-line/GuideLineSetting.tsx
Normal file
@@ -0,0 +1,421 @@
|
||||
'use client'
|
||||
import React, {ChangeEvent, forwardRef, useContext, useEffect, useImperativeHandle, useState} from 'react';
|
||||
import System from '@/lib/models/System';
|
||||
import {AlertContext} from "@/context/AlertContext";
|
||||
import {BookContext} from '@/context/BookContext';
|
||||
import {SessionContext} from "@/context/SessionContext";
|
||||
import {GuideLine, GuideLineAI} from "@/lib/models/Book";
|
||||
import TexteAreaInput from "@/components/form/TexteAreaInput";
|
||||
import InputField from "@/components/form/InputField";
|
||||
import TextInput from "@/components/form/TextInput";
|
||||
import SelectBox from "@/components/form/SelectBox";
|
||||
import {
|
||||
advancedDialogueTypes,
|
||||
advancedNarrativePersons,
|
||||
beginnerDialogueTypes,
|
||||
beginnerNarrativePersons,
|
||||
intermediateDialogueTypes,
|
||||
intermediateNarrativePersons,
|
||||
langues,
|
||||
verbalTime
|
||||
} from "@/lib/models/Story";
|
||||
import {useTranslations} from "next-intl";
|
||||
import {LangContext} from "@/context/LangContext";
|
||||
|
||||
function GuideLineSetting(props: any, ref: any) {
|
||||
const t = useTranslations();
|
||||
const {lang} = useContext(LangContext);
|
||||
const {book} = useContext(BookContext);
|
||||
const {session} = useContext(SessionContext);
|
||||
const userToken: string = session?.accessToken ? session?.accessToken : '';
|
||||
const {errorMessage, successMessage} = useContext(AlertContext);
|
||||
const bookId = book?.bookId as string;
|
||||
const [activeTab, setActiveTab] = useState('personal');
|
||||
const authorLevel: string = session.user?.writingLevel?.toString() ?? '1';
|
||||
|
||||
const [tone, setTone] = useState<string>('');
|
||||
const [atmosphere, setAtmosphere] = useState<string>('');
|
||||
const [writingStyle, setWritingStyle] = useState<string>('');
|
||||
const [themes, setThemes] = useState<string>('');
|
||||
const [symbolism, setSymbolism] = useState<string>('');
|
||||
const [motifs, setMotifs] = useState<string>('');
|
||||
const [narrativeVoice, setNarrativeVoice] = useState<string>('');
|
||||
const [pacing, setPacing] = useState<string>('');
|
||||
const [intendedAudience, setIntendedAudience] = useState<string>('');
|
||||
const [keyMessages, setKeyMessages] = useState<string>('');
|
||||
|
||||
const [plotSummary, setPlotSummary] = useState<string>('');
|
||||
const [narrativeType, setNarrativeType] = useState<string>('');
|
||||
const [verbTense, setVerbTense] = useState<string>('');
|
||||
const [dialogueType, setDialogueType] = useState<string>('');
|
||||
const [toneAtmosphere, setToneAtmosphere] = useState<string>('');
|
||||
const [language, setLanguage] = useState<string>('');
|
||||
|
||||
useEffect((): void => {
|
||||
if (activeTab === 'personal') {
|
||||
getGuideLine().then();
|
||||
} else {
|
||||
getAIGuideLine().then();
|
||||
}
|
||||
}, [activeTab]);
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
{
|
||||
if (activeTab === 'personal') {
|
||||
return {
|
||||
handleSave: savePersonal
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
handleSave: saveQuillSense
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function getAIGuideLine(): Promise<void> {
|
||||
try {
|
||||
const response: GuideLineAI = await System.authGetQueryToServer<GuideLineAI>(`book/ai/guideline`, userToken, lang, {id: bookId});
|
||||
if (response) {
|
||||
setPlotSummary(response.globalResume);
|
||||
setVerbTense(response.verbeTense?.toString() || '');
|
||||
setNarrativeType(response.narrativeType?.toString() || '');
|
||||
setDialogueType(response.dialogueType?.toString() || '');
|
||||
setToneAtmosphere(response.atmosphere);
|
||||
setLanguage(response.langue?.toString() || '');
|
||||
setThemes(response.themes);
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
errorMessage(e.message);
|
||||
} else {
|
||||
errorMessage(t("guideLineSetting.errorUnknown"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getGuideLine(): Promise<void> {
|
||||
try {
|
||||
const response: GuideLine =
|
||||
await System.authGetQueryToServer<GuideLine>(
|
||||
`book/guide-line`,
|
||||
userToken,
|
||||
lang,
|
||||
{id: bookId},
|
||||
);
|
||||
if (response) {
|
||||
setTone(response.tone);
|
||||
setAtmosphere(response.atmosphere);
|
||||
setWritingStyle(response.writingStyle);
|
||||
setThemes(response.themes);
|
||||
setSymbolism(response.symbolism);
|
||||
setMotifs(response.motifs);
|
||||
setNarrativeVoice(response.narrativeVoice);
|
||||
setPacing(response.pacing);
|
||||
setIntendedAudience(response.intendedAudience);
|
||||
setKeyMessages(response.keyMessages);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
errorMessage(error.message);
|
||||
} else {
|
||||
errorMessage(t("guideLineSetting.errorUnknown"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function savePersonal(): Promise<void> {
|
||||
try {
|
||||
const response: boolean =
|
||||
await System.authPostToServer<boolean>(
|
||||
'book/guide-line',
|
||||
{
|
||||
bookId: bookId,
|
||||
tone: tone,
|
||||
atmosphere: atmosphere,
|
||||
writingStyle: writingStyle,
|
||||
themes: themes,
|
||||
symbolism: symbolism,
|
||||
motifs: motifs,
|
||||
narrativeVoice: narrativeVoice,
|
||||
pacing: pacing,
|
||||
intendedAudience: intendedAudience,
|
||||
keyMessages: keyMessages,
|
||||
},
|
||||
userToken,
|
||||
lang,
|
||||
);
|
||||
if (!response) {
|
||||
errorMessage(t("guideLineSetting.saveError"));
|
||||
return;
|
||||
}
|
||||
successMessage(t("guideLineSetting.saveSuccess"));
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
errorMessage(error.message);
|
||||
} else {
|
||||
errorMessage(t("guideLineSetting.errorUnknown"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function saveQuillSense(): Promise<void> {
|
||||
try {
|
||||
const response: boolean = await System.authPostToServer<boolean>(
|
||||
'quillsense/book/guide-line',
|
||||
{
|
||||
bookId: bookId,
|
||||
plotSummary: plotSummary,
|
||||
verbTense: verbTense,
|
||||
narrativeType: narrativeType,
|
||||
dialogueType: dialogueType,
|
||||
toneAtmosphere: toneAtmosphere,
|
||||
language: language,
|
||||
themes: themes,
|
||||
},
|
||||
userToken,
|
||||
lang,
|
||||
);
|
||||
if (response) {
|
||||
successMessage(t("guideLineSetting.saveSuccess"));
|
||||
} else {
|
||||
errorMessage(t("guideLineSetting.saveError"));
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
errorMessage(e.message);
|
||||
} else {
|
||||
errorMessage(t("guideLineSetting.errorUnknown"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex gap-2 border-b border-secondary/50 mb-6">
|
||||
<button
|
||||
className={`px-5 py-2.5 font-medium rounded-t-xl transition-all duration-200 ${
|
||||
activeTab === 'personal'
|
||||
? 'border-b-2 border-primary text-primary bg-primary/10 shadow-md'
|
||||
: 'text-text-secondary hover:text-text-primary hover:bg-secondary/30'
|
||||
}`}
|
||||
onClick={(): void => setActiveTab('personal')}
|
||||
>
|
||||
{t("guideLineSetting.personal")}
|
||||
</button>
|
||||
<button
|
||||
className={`px-5 py-2.5 font-medium rounded-t-xl transition-all duration-200 ${
|
||||
activeTab === 'quillsense'
|
||||
? 'border-b-2 border-primary text-primary bg-primary/10 shadow-md'
|
||||
: 'text-text-secondary hover:text-text-primary hover:bg-secondary/30'
|
||||
}`}
|
||||
onClick={() => setActiveTab('quillsense')}
|
||||
>
|
||||
{t("guideLineSetting.quillsense")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{activeTab === 'personal' && (
|
||||
<div className="space-y-4">
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.tone")} input={
|
||||
<TexteAreaInput
|
||||
value={tone}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>) => setTone(e.target.value)}
|
||||
placeholder={t("guideLineSetting.tonePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.atmosphere")} input={
|
||||
<TexteAreaInput
|
||||
value={atmosphere}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>) => setAtmosphere(e.target.value)}
|
||||
placeholder={t("guideLineSetting.atmospherePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.writingStyle")} input={
|
||||
<TexteAreaInput
|
||||
value={writingStyle}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setWritingStyle(e.target.value)}
|
||||
placeholder={t("guideLineSetting.writingStylePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.themes")} input={
|
||||
<TexteAreaInput
|
||||
value={themes}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setThemes(e.target.value)}
|
||||
placeholder={t("guideLineSetting.themesPlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.symbolism")} input={
|
||||
<TexteAreaInput
|
||||
value={symbolism}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setSymbolism(e.target.value)}
|
||||
placeholder={t("guideLineSetting.symbolismPlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.motifs")} input={
|
||||
<TexteAreaInput
|
||||
value={motifs}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setMotifs(e.target.value)}
|
||||
placeholder={t("guideLineSetting.motifsPlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.narrativeVoice")} input={
|
||||
<TexteAreaInput
|
||||
value={narrativeVoice}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setNarrativeVoice(e.target.value)}
|
||||
placeholder={t("guideLineSetting.narrativeVoicePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.pacing")} input={
|
||||
<TexteAreaInput
|
||||
value={pacing}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setPacing(e.target.value)}
|
||||
placeholder={t("guideLineSetting.pacingPlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.intendedAudience")} input={
|
||||
<TexteAreaInput
|
||||
value={intendedAudience}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setIntendedAudience(e.target.value)}
|
||||
placeholder={t("guideLineSetting.intendedAudiencePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.keyMessages")} input={
|
||||
<TexteAreaInput
|
||||
value={keyMessages}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setKeyMessages(e.target.value)}
|
||||
placeholder={t("guideLineSetting.keyMessagesPlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === 'quillsense' && (
|
||||
<div className="space-y-4">
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.plotSummary")} input={
|
||||
<TexteAreaInput
|
||||
value={plotSummary}
|
||||
setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setPlotSummary(e.target.value)}
|
||||
placeholder={t("guideLineSetting.plotSummaryPlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.toneAtmosphere")} input={
|
||||
<TextInput
|
||||
value={toneAtmosphere}
|
||||
setValue={(e: ChangeEvent<HTMLInputElement>): void => setToneAtmosphere(e.target.value)}
|
||||
placeholder={t("guideLineSetting.toneAtmospherePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.themes")} input={
|
||||
<TextInput
|
||||
value={themes}
|
||||
setValue={(e: ChangeEvent<HTMLInputElement>) => setThemes(e.target.value)}
|
||||
placeholder={t("guideLineSetting.themesPlaceholderQuill")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.verbTense")} input={
|
||||
<SelectBox
|
||||
defaultValue={verbTense}
|
||||
onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>): void => setVerbTense(event.target.value)}
|
||||
data={verbalTime}
|
||||
placeholder={t("guideLineSetting.verbTensePlaceholder")}
|
||||
/>
|
||||
}/>
|
||||
</div>
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.narrativeType")} input={
|
||||
<SelectBox defaultValue={narrativeType} data={
|
||||
authorLevel === '1'
|
||||
? beginnerNarrativePersons
|
||||
: authorLevel === '2'
|
||||
? intermediateNarrativePersons
|
||||
: advancedNarrativePersons
|
||||
} onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>): void => {
|
||||
setNarrativeType(event.target.value)
|
||||
}} placeholder={t("guideLineSetting.narrativeTypePlaceholder")}/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.dialogueType")} input={
|
||||
<SelectBox defaultValue={dialogueType} data={authorLevel === '1'
|
||||
? beginnerDialogueTypes
|
||||
: authorLevel === '2'
|
||||
? intermediateDialogueTypes
|
||||
: advancedDialogueTypes}
|
||||
onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>) => {
|
||||
setDialogueType(event.target.value)
|
||||
}} placeholder={t("guideLineSetting.dialogueTypePlaceholder")}/>
|
||||
}/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
|
||||
<InputField fieldName={t("guideLineSetting.language")} input={
|
||||
<SelectBox defaultValue={language} data={langues}
|
||||
onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>) => {
|
||||
setLanguage(event.target.value)
|
||||
}} placeholder={t("guideLineSetting.languagePlaceholder")}/>
|
||||
}/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default forwardRef(GuideLineSetting);
|
||||
Reference in New Issue
Block a user