Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/components/Message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useState } from "react";

interface CodeBlockProps {
code: string;
}

const CodeBlock: React.FC<CodeBlockProps> = ({ code }) => {
const [copyStatus, setCopyStatus] = useState<"idle" | "copied">("idle");

const handleCopyClick = () => {
navigator.clipboard.writeText(code).then(() => {
setCopyStatus("copied");

setTimeout(() => {
setCopyStatus("idle");
}, 2000);
});
};
return (
<div className="relative my-4">
<pre className="whitespace-pre-wrap rounded bg-gray-800 p-2 font-mono text-sm text-white">
{code}
</pre>
<button
className="absolute top-1 right-1 rounded bg-white py-1 px-2 text-xs text-gray-600 shadow"
onClick={handleCopyClick}
>
{copyStatus === "idle" ? "Copy" : "Copied"}
</button>
</div>
);
};

interface MessageProps {
role: "user" | "system" | "assistant";
content: string;
}

const Message: React.FC<MessageProps> = ({ role, content }) => {
const parts = content.split(/(```[\s\S]+?```)/g);

return (
<div
className={`flex ${role === "user" ? "justify-end" : "justify-start"}`}
>
<div
className={`m-2 rounded-lg px-4 py-2 ${
role === "user"
? "ml-10 rounded-br-none bg-blue-500 text-white"
: "mr-10 rounded-bl-none bg-gray-200 text-black"
}`}
>
{parts.map((part, index) => {
if (part.startsWith("```")) {
const codeContent = part.slice(3, part.length - 3);
return <CodeBlock key={index} code={codeContent} />;
} else {
return <span key={index}>{part}</span>;
}
})}
</div>
</div>
);
};

export default Message;
41 changes: 41 additions & 0 deletions src/components/MessageInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useState } from "react";

interface MessageInputProps {
onSend: (message: string) => void;
}

const MessageInput: React.FC<MessageInputProps> = ({ onSend }) => {
const [input, setInput] = useState("");

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (input.trim() !== "") {
onSend(input);
setInput("");
}
};

return (
<form
onSubmit={handleSubmit}
className="mt-3 flex w-full items-center gap-3 rounded-lg "
>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
className="w-full rounded-lg border px-4 py-2 focus:border-blue-300 focus:outline-none focus:ring"
placeholder="Type your message..."
maxLength={2000}
/>
<button
type="submit"
className="rounded-lg bg-blue-500 px-4 py-2 text-white"
>
Send
</button>
</form>
);
};

export default MessageInput;
15 changes: 15 additions & 0 deletions src/components/TypingIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react";

const TypingIndicator = () => {
return (
<div className="m-2 mr-10 w-20 rounded-lg rounded-bl-none bg-gray-200 px-4 py-2 text-black">
<div className="typing-indicator ">
<div className="typing-indicator-dot"></div>
<div className="typing-indicator-dot"></div>
<div className="typing-indicator-dot"></div>
</div>
</div>
);
};

export default TypingIndicator;
1 change: 0 additions & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const MyApp: AppType<{ session: Session | null }> = ({
}) => {
return (
<SessionProvider session={session}>
<HeaderAdvanced />
<Component {...pageProps} />
</SessionProvider>
);
Expand Down
70 changes: 33 additions & 37 deletions src/pages/api/chatgpt.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { Configuration, OpenAIApi } from "openai";
import {topics} from '../../constants/topic';

const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

const constructPrompt = (topic: string, prompt='', language = 'javascript', level = 'junior', position = 'full-stack engineer') => {
switch(topic) {
case topics.EXPLAIN_CODE:
return `Explain this block of code: ${prompt}`;
case topics.FIX_CODE:
return `Is there anything wrong this block of code: ${prompt}`;
case topics.WRITE_CODE:
return `Write Some Code that does the following: ${prompt}`;
case topics.INTERVIEW_QUESTION:
return `Give me a list of interview questions for a ${level} ${position} developer.`
case topics.CODING_QUESTION:
return `Give me a list of ${level} coding questions in ${language}`
case topics.CODING_QUESTION_ANSWER:
return `Give me the answers to the following questions: ${prompt}`
default:
return prompt;
export default async function chatGpt(
req: NextApiRequest,
res: NextApiResponse
) {
const messages = req.body;

if (!messages || !Array.isArray(messages)) {
res.status(400).json({ error: "Invalid request: messages should be an array" });
return;
}

const openaiMessages = messages.map((message) => ({
role: message.role,
content: message.content,
}));

try {
const completion = await openai.createChatCompletion({
messages: openaiMessages,
temperature: 0.7,
max_tokens: 1500,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
model: "gpt-3.5-turbo",
});

const response = completion?.data?.choices[0]?.message?.content;
res.status(200).json({ role: "assistant", content: response });
} catch (error) {
console.error(error);
res.status(500).json({ error: "An error occurred while processing the request" });
}
}
export default async function chatGpt(req, res) {
const { prompt, language, level, position, topic } = req.body;
const content = constructPrompt(topic, prompt, language, level, position);
const completion = await openai.createChatCompletion({
messages: [
{
role: "user",
content: content + '\n\n###\n\n',
}
],
temperature: 0.7,
max_tokens: 256,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
model: "gpt-3.5-turbo",
});
const response = completion?.data?.choices[0]?.message?.content;
res.status(200).json({ result: response });
}
Loading