diff --git a/package.json b/package.json
index ef2d2bf..3a059b9 100644
--- a/package.json
+++ b/package.json
@@ -15,11 +15,14 @@
"axios": "^1.9.0",
"code-editor": "file:",
"framer-motion": "^12.12.2",
+ "groq-sdk": "^0.37.0",
"install": "^0.13.0",
"npm": "^11.4.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
- "react-icons": "^5.5.0"
+ "react-icons": "^5.5.0",
+ "react-markdown": "^10.1.0",
+ "react-syntax-highlighter": "^16.1.0"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
diff --git a/src/components/ChatBot/ChatBubble.jsx b/src/components/ChatBot/ChatBubble.jsx
new file mode 100644
index 0000000..4a5c17b
--- /dev/null
+++ b/src/components/ChatBot/ChatBubble.jsx
@@ -0,0 +1,40 @@
+// src/components/ChatBot/ChatBubble.jsx
+import React from "react";
+import ReactMarkdown from "react-markdown";
+import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
+import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism";
+
+export default function ChatBubble({ message }) {
+ return (
+
+
+ {children}
+
+ ) : (
+
+ {children}
+
+ );
+ },
+ }}
+ >
+ {message.content}
+
+
+ );
+}
diff --git a/src/components/ChatBot/ChatInput.jsx b/src/components/ChatBot/ChatInput.jsx
new file mode 100644
index 0000000..b788116
--- /dev/null
+++ b/src/components/ChatBot/ChatInput.jsx
@@ -0,0 +1,32 @@
+// src/components/ChatBot/ChatInput.jsx
+import React, { useState } from "react";
+
+export default function ChatInput({ onSend }) {
+ const [text, setText] = useState("");
+
+ const handleSend = () => {
+ if (text.trim()) {
+ onSend(text);
+ setText("");
+ }
+ };
+
+ const handleKeyDown = (e) => {
+ if (e.key === "Enter" && !e.shiftKey) {
+ e.preventDefault();
+ handleSend();
+ }
+ };
+
+ return (
+
+
+ );
+}
diff --git a/src/components/ChatBot/CodeMate.jsx b/src/components/ChatBot/CodeMate.jsx
new file mode 100644
index 0000000..7ccd1f0
--- /dev/null
+++ b/src/components/ChatBot/CodeMate.jsx
@@ -0,0 +1,124 @@
+import React, { useState } from "react";
+import ChatBubble from "./ChatBubble";
+import ChatInput from "./ChatInput";
+import { askCodeMate } from "./chatApi";
+import "./chatbot.css";
+
+const LANGUAGES = ["javascript", "python", "cpp", "java"]; // add more if needed
+
+export default function CodeMate() {
+ const [open, setOpen] = useState(false);
+ const [fullScreen, setFullScreen] = useState(false);
+ const [selectedLang, setSelectedLang] = useState("javascript");
+
+ const [messages, setMessages] = useState([
+ {
+ role: "system",
+ content: `
+You are CodeMate, an AI coding assistant inside an online compiler.
+
+Strict rules:
+1. Always provide **three approaches** for every logic question:
+ 1. Brute Force
+ 2. Better Approach
+ 3. Optimal Approach
+2. Always explain **time and space complexity** for each approach.
+3. Always write code in the **programming language selected by the user** (use the variable "selectedLang").
+4. Respond in simple, beginner-friendly language.
+5. Use Markdown formatting with numbered lists and code blocks.
+
+Example:
+1. Brute Force
+\`\`\`${selectedLang}
+// code here
+\`\`\`
+Time Complexity: O(...)
+Space Complexity: O(...)
+
+2. Better Approach
+\`\`\`${selectedLang}
+// code here
+\`\`\`
+Time Complexity: O(...)
+Space Complexity: O(...)
+
+3. Optimal Approach
+\`\`\`${selectedLang}
+// code here
+\`\`\`
+Time Complexity: O(...)
+Space Complexity: O(...)
+`
+ },
+ {
+ role: "assistant",
+ content: "Hi 👋 I'm CodeMate. Ask me about logic, optimization, or errors."
+ }
+ ]);
+
+ const sendMessage = async (text) => {
+ if (!text.trim()) return;
+
+ const userMsg = { role: "user", content: text };
+ const updated = [...messages, userMsg];
+ setMessages(updated);
+
+ try {
+ // Always pass the language to the prompt
+ const reply = await askCodeMate([
+ ...updated,
+ { role: "system", content: `Use ${selectedLang} for all code.` }
+ ]);
+
+ setMessages((prev) => [...prev, { role: "assistant", content: reply }]);
+ } catch (err) {
+ setMessages((prev) => [
+ ...prev,
+ { role: "assistant", content: "⚠️ Error connecting to Groq API." },
+ ]);
+ }
+ };
+
+ return (
+ <>
+
+
+ {open && (
+
+
+
CodeMate AI
+
+
+
+
+
+
+
+
+ {messages
+ .filter((m) => m.role !== "system")
+ .map((msg, i) => (
+
+ ))}
+
+
+
+
+ )}
+ >
+ );
+}
diff --git a/src/components/ChatBot/chatApi.js b/src/components/ChatBot/chatApi.js
new file mode 100644
index 0000000..d151bcd
--- /dev/null
+++ b/src/components/ChatBot/chatApi.js
@@ -0,0 +1,28 @@
+// src/components/ChatBot/chatApi.js
+import Groq from "groq-sdk";
+
+// Initialize Groq with your API key
+const groq = new Groq({
+ apiKey: import.meta.env.VITE_GROQ_API_KEY,
+ dangerouslyAllowBrowser: true, // required to call from frontend
+});
+
+// Set your model
+const MODEL_NAME = "llama-3.3-70b-versatile";
+
+// Function to send messages to Groq
+export async function askCodeMate(messages) {
+ try {
+ const chat = await groq.chat.completions.create({
+ model: MODEL_NAME,
+ messages: messages,
+ temperature: 0.3, // Adjust creativity
+ });
+
+ // Return the assistant's reply
+ return chat.choices[0].message.content;
+ } catch (err) {
+ console.error("Groq API Error:", err);
+ throw new Error("Error connecting to Groq API.");
+ }
+}
diff --git a/src/components/ChatBot/chatbot.css b/src/components/ChatBot/chatbot.css
new file mode 100644
index 0000000..2fc6d11
--- /dev/null
+++ b/src/components/ChatBot/chatbot.css
@@ -0,0 +1,246 @@
+/* --- 1. Variables for Easy Tweaking --- */
+:root {
+ --chat-primary: #3b82f6;
+ --chat-primary-gradient: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
+ --chat-bg: #09090b; /* Deep OLED Black */
+ --chat-surface: #18181b; /* Slightly lighter for inputs/headers */
+ --chat-border: #27272a;
+ --chat-text: #f4f4f5;
+ --chat-text-muted: #a1a1aa;
+ --chat-bubble-user: #2563eb;
+ --chat-bubble-bot: #27272a;
+ --shadow-sm: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
+ --shadow-glow: 0 0 15px rgba(59, 130, 246, 0.5);
+ --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+}
+
+/* --- 2. The Toggle Button --- */
+.chat-toggle {
+ position: fixed;
+ bottom: 25px;
+ right: 25px;
+ background: var(--chat-primary-gradient);
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ padding: 0;
+ width: 60px; /* Fixed width/height for perfect circle */
+ height: 60px;
+ border-radius: 50%;
+ font-size: 26px;
+ cursor: pointer;
+ z-index: 9999;
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5), var(--shadow-glow);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.chat-toggle:hover {
+ transform: scale(1.1) rotate(10deg);
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.6), 0 0 20px rgba(59, 130, 246, 0.7);
+}
+
+/* --- 3. The Main Container --- */
+.chat-container {
+ position: fixed;
+ bottom: 100px;
+ right: 25px;
+ width: 380px;
+ height: 600px; /* Fixed height for better consistency */
+ max-height: 80vh;
+ background-color: var(--chat-bg);
+ /* Glassmorphism effect */
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ color: var(--chat-text);
+ border: 1px solid var(--chat-border);
+ border-radius: 16px;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ z-index: 9999;
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ font-family: var(--font-family);
+}
+
+.chat-container.fullscreen {
+ bottom: 0;
+ right: 0;
+ width: 100vw;
+ height: 100vh;
+ max-height: 100vh;
+ border-radius: 0;
+ border: none;
+}
+
+/* --- 4. The Header --- */
+.chat-header {
+ background-color: rgba(24, 24, 27, 0.95); /* High opacity for readability */
+ padding: 16px 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-weight: 600;
+ font-size: 16px;
+ border-bottom: 1px solid var(--chat-border);
+ letter-spacing: 0.5px;
+}
+
+.chat-header-buttons {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.chat-header button {
+ background: transparent;
+ border: none;
+ color: var(--chat-text-muted);
+ font-size: 18px;
+ cursor: pointer;
+ transition: color 0.2s;
+ padding: 4px;
+ border-radius: 4px;
+}
+
+.chat-header button:hover {
+ color: white;
+ background-color: rgba(255,255,255, 0.1);
+}
+
+.language-select {
+ background-color: #000;
+ color: var(--chat-text);
+ border: 1px solid var(--chat-border);
+ border-radius: 6px;
+ padding: 4px 8px;
+ font-size: 12px;
+ cursor: pointer;
+ outline: none;
+ transition: border-color 0.2s;
+}
+
+.language-select:hover {
+ border-color: var(--chat-primary);
+}
+
+/* --- 5. The Body (Messages Area) --- */
+.chat-body {
+ flex-grow: 1;
+ overflow-y: auto;
+ padding: 20px;
+ background-image: radial-gradient(circle at 50% 50%, #1a1a20 1px, transparent 1px);
+ background-size: 20px 20px; /* Subtle dot pattern */
+ scrollbar-width: thin;
+ scrollbar-color: #3f3f46 transparent;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.chat-body::-webkit-scrollbar {
+ width: 6px;
+}
+
+.chat-body::-webkit-scrollbar-thumb {
+ background-color: #3f3f46;
+ border-radius: 3px;
+}
+
+/* --- 6. Chat Bubbles (The User/Assistant Styles) --- */
+/* Note: I added styling to make these actual bubbles, not just text alignment */
+
+.chat-bubble {
+ max-width: 85%;
+ padding: 12px 16px;
+ font-size: 14px;
+ line-height: 1.5;
+ position: relative;
+ word-wrap: break-word;
+}
+
+.chat-bubble.user {
+ align-self: flex-end;
+ background: var(--chat-primary-gradient);
+ color: white;
+ border-radius: 18px 18px 2px 18px; /* Top-Left, Top-Right, Btm-Right, Btm-Left */
+ box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
+ text-align: left; /* Text inside bubble should usually be left */
+ margin-left: auto; /* Pushes to right */
+}
+
+.chat-bubble.assistant {
+ align-self: flex-start;
+ background-color: var(--chat-bubble-bot);
+ color: var(--chat-text);
+ border: 1px solid var(--chat-border);
+ border-radius: 18px 18px 18px 2px;
+ text-align: left;
+ margin-right: auto; /* Pushes to left */
+}
+
+/* --- 7. Code Blocks inside Chat --- */
+.inline-code {
+ background-color: rgba(0, 0, 0, 0.3);
+ padding: 2px 6px;
+ border-radius: 4px;
+ font-family: 'Menlo', 'Consolas', monospace;
+ font-size: 0.9em;
+ color: #ff79c6; /* Dracula pink for code */
+ border: 1px solid rgba(255,255,255,0.05);
+}
+
+/* --- 8. Input Area --- */
+.chat-input {
+ display: flex;
+ padding: 16px;
+ background-color: var(--chat-surface);
+ border-top: 1px solid var(--chat-border);
+ gap: 10px;
+ align-items: flex-end; /* Aligns button to bottom of text area */
+}
+
+.chat-input textarea {
+ flex-grow: 1;
+ padding: 12px;
+ resize: none;
+ border: 1px solid var(--chat-border);
+ border-radius: 10px;
+ outline: none;
+ background-color: #09090b;
+ color: white;
+ font-family: var(--font-family);
+ font-size: 14px;
+ line-height: 1.4;
+ height: 44px; /* Default height */
+ min-height: 44px;
+ max-height: 120px;
+ transition: border-color 0.2s, box-shadow 0.2s;
+}
+
+.chat-input textarea:focus {
+ border-color: var(--chat-primary);
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
+}
+
+.chat-input button {
+ background: var(--chat-primary-gradient);
+ border: none;
+ width: 44px;
+ height: 44px;
+ border-radius: 10px;
+ color: white;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: transform 0.2s, box-shadow 0.2s;
+ box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
+}
+
+.chat-input button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 15px rgba(37, 99, 235, 0.4);
+}
\ No newline at end of file
diff --git a/src/pages/CompilerLandingPage.jsx b/src/pages/CompilerLandingPage.jsx
index 620e7bc..121b6d4 100644
--- a/src/pages/CompilerLandingPage.jsx
+++ b/src/pages/CompilerLandingPage.jsx
@@ -4,6 +4,11 @@ import TopBar from "../components/TopBar";
import FileBar from "../components/FileBar";
import { executeCode } from "../utils/api.js";
import Output from "../components/Output";
+import CodeMate from "../components/ChatBot/CodeMate";
+
+
+
+
import { CODE_SNIPPETS } from "../utils/constant";
import CodeEditorWindow from "../components/CodeEditorWindow";
@@ -291,6 +296,8 @@ const CodeEditor = () => {
showOutput={showOutput}
toggleTerminal={setShowOutput}
/>
+
+
);
};