From ed00148f588250b2ce027b578eeb94ce157178f9 Mon Sep 17 00:00:00 2001 From: Rainyy21 Date: Sun, 9 Nov 2025 01:31:32 -0500 Subject: [PATCH] added a exit button on the chat bot and make sure it still working --- app/api/chat/route.ts | 2 +- app/chatbot/page.tsx | 20 +++++++++++++++++--- app/exportType/types.ts | 2 +- app/formfile/page.tsx | 2 +- app/page.tsx | 8 +++++--- app/utils/component/ui/MessageWindow.tsx | 21 ++++++++++++++++++--- app/utils/geminiHelper.ts | 2 +- package-lock.json | 12 ++++++++++++ 8 files changed, 56 insertions(+), 13 deletions(-) diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index eeb8b31..80e8c46 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -17,7 +17,7 @@ export async function POST(request: Request) { catch(error){ console.error(error); return NextResponse.json( - {error: "Error with the model response "}, + {error: "Error with the model response " + String(error)}, {status : 500} ); } diff --git a/app/chatbot/page.tsx b/app/chatbot/page.tsx index 363f852..6c5624c 100644 --- a/app/chatbot/page.tsx +++ b/app/chatbot/page.tsx @@ -1,20 +1,22 @@ "use client"; import { useState, useEffect, useRef, useCallback } from "react"; -import { useSearchParams } from "next/navigation"; +import { useSearchParams, useRouter } from "next/navigation"; import ChatInput from "../utils/component/ui/ChatInput"; import MessageWindow from "../utils/component/ui/MessageWindow"; import { ChatHistory, ChatSetting, Message , MessageRole } from "@/app/exportType/types"; export default function Home(){ const [history, setHistory] = useState([]) + const [loading, setLoading] = useState(false); const historyRef = useRef([]); // Create a ref for history const [settings] = useState({ temperature:1, model:"gemini-2.5-pro", - sysTemInstructions:"you are a ai helper. Your goal is to expand the project idea and interact with the user on any problem or question they have with the project. You are not allow to code the project for them and stray away from your job" + systemInstruction:"you are a ai helper. Your goal is to expand the project idea and interact with the user on any problem or question they have with the project. You are not allow to code the project for them and stray away from your job" }); + const router = useRouter(); const searchParams = useSearchParams(); const initialMessageSent = useRef(false); @@ -32,6 +34,7 @@ export default function Home(){ const currentHistory = [...prevHistory, newUserMessage]; const sendApiRequest = async () => { + setLoading(true); try{ const response = await fetch("/api/chat", { method: "POST", @@ -49,6 +52,7 @@ export default function Home(){ if (data.error) { console.error("AI Error:", data.error); + setLoading(false); return; } @@ -63,6 +67,7 @@ export default function Home(){ catch (error) { console.error("Request Failed:", error); } + setLoading(false); }; sendApiRequest(); @@ -88,6 +93,7 @@ export default function Home(){ }, 0); const sendInitialApiRequest = async () => { + setLoading(true); try { const response = await fetch("/api/chat", { method: "POST", @@ -105,6 +111,7 @@ export default function Home(){ if (data.error) { console.error("AI Error:", data.error); + setLoading(false); return; } @@ -117,6 +124,7 @@ export default function Home(){ } catch (error) { console.error("Request Failed:", error); } + setLoading(false); }; sendInitialApiRequest(); @@ -128,7 +136,13 @@ export default function Home(){ return (
- + + {}} />
); diff --git a/app/exportType/types.ts b/app/exportType/types.ts index eca26ad..b840e20 100644 --- a/app/exportType/types.ts +++ b/app/exportType/types.ts @@ -19,7 +19,7 @@ export interface GenerateConfig{ export interface ChatSetting{ temperature :number; model: string; - sysTemInstructions: string; + systemInstruction: string; } export interface CardData { diff --git a/app/formfile/page.tsx b/app/formfile/page.tsx index ccf46ef..dbfd792 100644 --- a/app/formfile/page.tsx +++ b/app/formfile/page.tsx @@ -34,7 +34,7 @@ export default function Home() { const [settings] = useState({ temperature: 1, model: "gemini-2.5-flash-lite", - sysTemInstructions: `You are an elite hackathon idea generator. Your task is to choose at lease two track and generate five different creative, feasible, and relevant project idea. + systemInstruction: `You are an elite hackathon idea generator. Your task is to choose at lease two track and generate five different creative, feasible, and relevant project idea. The output MUST be in Markdown format and strictly follow this structure: ### Project Idea Title **Track** [print out the track you used] diff --git a/app/page.tsx b/app/page.tsx index f85cd0b..de9c3ba 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -5,11 +5,13 @@ import { useRouter } from 'next/navigation'; import Image from 'next/image'; import ProtectedNavButton from "../components/ProtectedNavButton"; import Link from 'next/link'; +import { style } from 'framer-motion/client'; + export default function Page() {   return (     
-      
+      
                  -           +                       Sign in            -           +                       Log out                    
diff --git a/app/utils/component/ui/MessageWindow.tsx b/app/utils/component/ui/MessageWindow.tsx index 6413cb3..d59e721 100644 --- a/app/utils/component/ui/MessageWindow.tsx +++ b/app/utils/component/ui/MessageWindow.tsx @@ -4,11 +4,12 @@ import { ChatHistory } from "@/app/exportType/types"; import {User, Bot} from "lucide-react" interface MessageWindowProps{ - history :ChatHistory + history :ChatHistory; + isLoading: boolean; } -export default function MessageWindow({history}:MessageWindowProps){ - const messageEndRef = useRef(null); +export default function MessageWindow({history, isLoading}:MessageWindowProps){ + const messageEndRef = useRef(null); useEffect(() =>{ messageEndRef.current?.scrollIntoView({behavior:"smooth"}); @@ -52,6 +53,20 @@ export default function MessageWindow({history}:MessageWindowProps){ ); })} + {isLoading && ( +
+
+
+ +
+
+
+
+ Loading... +
+
+
+ )} {/* Invisible element to help scroll to bottom */}
diff --git a/app/utils/geminiHelper.ts b/app/utils/geminiHelper.ts index 4fa619c..3a78f30 100644 --- a/app/utils/geminiHelper.ts +++ b/app/utils/geminiHelper.ts @@ -16,7 +16,7 @@ export async function chatToGemini( ):Promise{ const model = genAI.getGenerativeModel({ model:settings.model || "gemini-2.5-flash", - systemInstruction: settings.sysTemInstructions || "you are going to create a project idea, explain it in summery first before going to detail", + systemInstruction: settings.systemInstruction || "you are going to create a project idea, explain it in summery first before going to detail", }); const generationConfig:GenerateConfig = { diff --git a/package-lock.json b/package-lock.json index fa00b6d..299dff3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1470,6 +1471,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "dev": true, + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -1526,6 +1528,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz", "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", @@ -2023,6 +2026,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2341,6 +2345,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -2870,6 +2875,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3047,6 +3053,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -5123,6 +5130,7 @@ "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -5131,6 +5139,7 @@ "version": "19.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -5776,6 +5785,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "peer": true, "engines": { "node": ">=12" }, @@ -5927,6 +5937,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6187,6 +6198,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "dev": true, + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" }