Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,8 +1,3 @@
|
||||
node_modules/
|
||||
*/node_modules/
|
||||
*/build/
|
||||
|
||||
**/node_modules/
|
||||
**/build/
|
||||
.DS_Store
|
||||
.env
|
||||
File diff suppressed because one or more lines are too long
@ -60,7 +60,7 @@ const config = {
|
||||
? 'https://flatlogic.com/projects'
|
||||
: 'http://localhost:3000/projects',
|
||||
|
||||
gpt_key: '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',
|
||||
gpt_key: process.env.GPT_KEY || '',
|
||||
};
|
||||
|
||||
config.pexelsKey = process.env.PEXELS_KEY || '';
|
||||
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -93,14 +93,6 @@ const menuAside: MenuAsideItem[] = [
|
||||
icon: icon.mdiAccountCircle,
|
||||
},
|
||||
|
||||
{
|
||||
href: '/chat-gpt',
|
||||
label: 'Chat GPT',
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
icon: icon.mdiChat ?? icon.mdiTable,
|
||||
},
|
||||
|
||||
{
|
||||
href: '/home',
|
||||
label: 'Home page',
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
import { ReactElement, useState, useEffect } from 'react';
|
||||
import LayoutAuthenticated from '../layouts/Authenticated';
|
||||
import SectionMain from '../components/SectionMain';
|
||||
import SectionTitle from '../components/SectionTitle';
|
||||
import CardBox from '../components/CardBox';
|
||||
import { useAppDispatch, useAppSelector } from '../stores/hooks';
|
||||
import { askGpt } from '../stores/openAiSlice';
|
||||
import LoadingSpinner from '../components/LoadingSpinner';
|
||||
import BaseButton from '../components/BaseButton';
|
||||
|
||||
const ChatGptPage = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { gptResponse, isAskingQuestion, errorMessage } = useAppSelector(state => state.openAi);
|
||||
const [prompt, setPrompt] = useState('');
|
||||
const [messages, setMessages] = useState<{ sender: 'user' | 'assistant'; text: string }[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (gptResponse) {
|
||||
setMessages(prev => [...prev, { sender: 'assistant', text: gptResponse }]);
|
||||
}
|
||||
}, [gptResponse]);
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!prompt.trim()) return;
|
||||
setMessages(prev => [...prev, { sender: 'user', text: prompt }]);
|
||||
dispatch(askGpt(prompt));
|
||||
setPrompt('');
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionMain>
|
||||
<SectionTitle title="Chat GPT" />
|
||||
<CardBox>
|
||||
|
||||
{/* Input area */}
|
||||
<textarea
|
||||
className="w-full p-2 border rounded mb-2"
|
||||
rows={4}
|
||||
value={prompt}
|
||||
onChange={e => setPrompt(e.target.value)}
|
||||
placeholder="Type your question here..."
|
||||
/>
|
||||
<div className="mb-2">
|
||||
<BaseButton
|
||||
label="Send"
|
||||
color="success"
|
||||
className="w-full"
|
||||
onClick={handleSubmit}
|
||||
disabled={!prompt.trim() || isAskingQuestion}
|
||||
/>
|
||||
{isAskingQuestion && <LoadingSpinner className="ml-2 mt-2" />}
|
||||
</div>
|
||||
|
||||
{/* Errors */}
|
||||
{errorMessage && <div className="text-red-500 mb-2">{errorMessage}</div>}
|
||||
|
||||
{/* Chat history */}
|
||||
<div className="mt-4">
|
||||
{messages.map((msg, idx) => (
|
||||
<div key={idx} className={`mb-2 flex ${msg.sender === 'user' ? 'justify-end' : 'justify-start'}`}>
|
||||
<div className={`p-2 rounded max-w-xs break-words ${msg.sender === 'user' ? 'bg-green-200 text-green-800' : 'bg-gray-200 text-gray-800'}`}>
|
||||
{msg.text}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</CardBox>
|
||||
</SectionMain>
|
||||
);
|
||||
};
|
||||
|
||||
ChatGptPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
|
||||
};
|
||||
|
||||
export default ChatGptPage;
|
||||
Loading…
x
Reference in New Issue
Block a user