Add components for Act management and integrate Electron setup
This commit is contained in:
131
components/quillsense/QuillSenseComponent.tsx
Normal file
131
components/quillsense/QuillSenseComponent.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import React, {useContext, useState} from 'react';
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {
|
||||
faBars,
|
||||
faComments,
|
||||
faExchangeAlt,
|
||||
faLanguage,
|
||||
faLightbulb,
|
||||
faSpellCheck,
|
||||
IconDefinition
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import QuillSense, {QSView,} from "@/lib/models/QuillSense";
|
||||
|
||||
import QuillList from "@/components/quillsense/modes/QuillList";
|
||||
import QuillConversation from "./modes/QuillConversation";
|
||||
import Dictionary from "@/components/quillsense/modes/Dictionary";
|
||||
import Synonyms from "@/components/quillsense/modes/Synonyms";
|
||||
import InspireMe from "@/components/quillsense/modes/InspireMe";
|
||||
import {SessionContext} from "@/context/SessionContext";
|
||||
import {useTranslations} from "next-intl";
|
||||
import Conjugator from "@/components/quillsense/modes/Conjugator";
|
||||
|
||||
interface QSOption {
|
||||
view: QSView;
|
||||
icon: IconDefinition;
|
||||
}
|
||||
|
||||
export default function QuillSenseComponent() {
|
||||
const [view, setView] = useState<QSView>('chat');
|
||||
const t = useTranslations();
|
||||
const [selectedConversation, setSelectedConversation] = useState<string>('');
|
||||
const {session} = useContext(SessionContext);
|
||||
|
||||
const isBringYourKeys: boolean = QuillSense.isBringYourKeys(session);
|
||||
const subLevel: number = QuillSense.getSubLevel(session)
|
||||
|
||||
const isGPTEnabled: boolean = QuillSense.isOpenAIEnabled(session);
|
||||
const isSubTierTwo: boolean = QuillSense.getSubLevel(session) >= 1;
|
||||
const hasAccess: boolean = isGPTEnabled || isSubTierTwo;
|
||||
|
||||
const qsOptions: QSOption[] = [
|
||||
{view: 'dictionary', icon: faSpellCheck},
|
||||
{view: 'conjugator', icon: faLanguage},
|
||||
{view: 'synonyms', icon: faExchangeAlt},
|
||||
{view: 'inspiration', icon: faLightbulb},
|
||||
{view: 'chat', icon: faComments},
|
||||
];
|
||||
|
||||
function handleSetView(view: QSView): void {
|
||||
setView(view);
|
||||
}
|
||||
|
||||
function handleSelectConversation(conversationId: string) {
|
||||
setSelectedConversation(conversationId);
|
||||
setView('chat');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full w-full bg-secondary/20 backdrop-blur-sm overflow-hidden">
|
||||
<div
|
||||
className="px-3 py-3 flex items-center justify-between border-b border-secondary/50 bg-secondary/30 shadow-sm">
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={() => handleSetView(view === 'chat' ? 'list' : 'chat')}
|
||||
className="group text-text-primary mr-3 hover:text-primary p-2 rounded-lg hover:bg-secondary/50 transition-all hover:scale-110"
|
||||
aria-label={t('quillSense.toggleList')}
|
||||
>
|
||||
<FontAwesomeIcon icon={faBars}
|
||||
className={'w-5 h-5 transition-transform group-hover:scale-110'}/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
{
|
||||
qsOptions.map((option: QSOption) => (
|
||||
<button
|
||||
key={option.view}
|
||||
disabled={!isBringYourKeys && subLevel < 2 && option.view !== 'chat'}
|
||||
onClick={(): void => handleSetView(option.view)}
|
||||
className={`group p-2.5 rounded-lg transition-all duration-200 ${
|
||||
view === option.view
|
||||
? 'bg-primary text-white shadow-md shadow-primary/30 scale-105'
|
||||
: !isBringYourKeys && subLevel < 2 && option.view !== 'chat'
|
||||
? 'text-muted/40 cursor-not-allowed'
|
||||
: 'text-text-primary hover:text-primary hover:bg-secondary/50 hover:scale-110'
|
||||
}`}
|
||||
aria-label={t(`quillSense.options.${option.view}`)}
|
||||
>
|
||||
<FontAwesomeIcon icon={option.icon}
|
||||
className={'w-4 h-4 transition-transform group-hover:scale-110'}/>
|
||||
</button>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
isBringYourKeys || subLevel >= 1 ? (
|
||||
<>
|
||||
{view === 'list' ? (
|
||||
<QuillList handleSelectConversation={handleSelectConversation}/>
|
||||
) : view === 'chat' ? (
|
||||
<QuillConversation
|
||||
disabled={!isBringYourKeys && subLevel < 2}
|
||||
selectedConversation={selectedConversation}
|
||||
setSelectConversation={setSelectedConversation}
|
||||
/>
|
||||
) : view === 'dictionary' ? (
|
||||
<Dictionary hasKey={hasAccess}/>
|
||||
) : view === 'synonyms' ? (
|
||||
<Synonyms hasKey={hasAccess}/>
|
||||
) : view === 'conjugator' ? (
|
||||
<Conjugator hasKey={hasAccess}/>
|
||||
) : view === 'inspiration' ? (
|
||||
<InspireMe hasKey={hasAccess}/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center h-full text-text-primary p-8">
|
||||
<div
|
||||
className="w-20 h-20 rounded-2xl bg-primary/10 flex items-center justify-center mb-6 shadow-md">
|
||||
<FontAwesomeIcon icon={faLightbulb} className="w-10 h-10 text-primary"/>
|
||||
</div>
|
||||
<p className="text-xl font-['ADLaM_Display'] text-center mb-3">{t('quillSense.needSubscription')}</p>
|
||||
<p className="text-lg text-muted text-center max-w-md leading-relaxed">{t('quillSense.subscriptionDescription')}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user