From 26255b64fcfad69e54c72dea56fe7705b4cb3091 Mon Sep 17 00:00:00 2001 From: PawelC4 Date: Sun, 9 Nov 2025 01:28:33 -0500 Subject: [PATCH 1/4] pushing css for pages and small features --- app/Dashboard/page.tsx | 113 ++++++++++++++++++------ app/cards/page.tsx | 190 +++++++++++++++++++++++++++++----------- app/exportType/types.ts | 1 + app/page.tsx | 33 ++----- 4 files changed, 234 insertions(+), 103 deletions(-) diff --git a/app/Dashboard/page.tsx b/app/Dashboard/page.tsx index 86da3e8..bb47069 100644 --- a/app/Dashboard/page.tsx +++ b/app/Dashboard/page.tsx @@ -1,38 +1,74 @@ "use client"; import React, { useState } from "react"; -import { useRouter } from "next/navigation"; -import Link from 'next/link'; +// import { useRouter } from "next/navigation"; // Removed Next.js import +// import Link from 'next/link'; // Removed Next.js import -function Dashboard() { // 2. Changed from 'export default function' - const router = useRouter(); +export default function Dashboard() { + // const router = useRouter(); // Removed Next.js hook const [query, setQuery] = useState(""); const [sideBarOpen, setSidebarOpen] = useState(true); + // 1. Add state to track sort order + const [sortOrder, setSortOrder] = useState("newest"); // 'newest' or 'oldest' const projects = [ { name: "Alpha Project", createdAt: "2025-01-01" }, { name: "Beta Board", createdAt: "2025-02-15" }, { name: "Gamma Tasl", createdAt: "2025-03-10" }, ]; - const filtered = projects.filter((p) => + + // 2. Update sorting logic to use the sortOrder state + const sortedProjects = [...projects].sort((a, b) => { + // Get numeric timestamps to avoid TypeScript error + const dateA = new Date(a.createdAt).getTime(); + const dateB = new Date(b.createdAt).getTime(); + + if (sortOrder === "newest") { + return dateB - dateA; // Newest first + } else { + return dateA - dateB; // Oldest first + } + }); + + // 3. Filter the *sorted* array based on the query + const filtered = sortedProjects.filter((p) => p.name.toLowerCase().includes(query.toLowerCase()) ); + // Helper function to handle navigation for the "Create" button + const handleCreateClick = () => { + // Use standard window navigation instead of Next.js router + // Also corrected typo from "dashbaord" to "dashboard" + window.location.href = "/dashboard/create"; + }; + + // 4. Function to toggle the sort order + const toggleSortOrder = () => { + setSortOrder(currentOrder => (currentOrder === "newest" ? "oldest" : "newest")); + }; + return ( -
+
-
+
setQuery(e.target.value)} placeholder="Search projects, boards or tasks..." - className="w-full max-w-md px-4 py-2 rounded-md border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-blue-500" + className="w-full max-w-md px-4 py-2 rounded-md border text-black focus:outline-none focus:ring-2 focus:ring-blue-500" + style={{ backgroundColor: '#F7F7F7', borderColor: '#D1D1D1' }} // Search bar "off-white" />
@@ -90,25 +130,40 @@ function Dashboard() { // 2. Changed from 'export default function'
-

- Project Names -

+
+

+ Project Names +

+ +
    {filtered.map((project, index) => (
  • {project.name} - + Created: {project.createdAt}
  • ))} {filtered.length === 0 && ( -
  • No results found
  • +
  • No results found
  • )}
diff --git a/app/cards/page.tsx b/app/cards/page.tsx index 37faf57..322b377 100644 --- a/app/cards/page.tsx +++ b/app/cards/page.tsx @@ -1,9 +1,10 @@ "use client"; -import React, { useState, useEffect } from "react"; -import { motion, useMotionValue, useTransform, useAnimation } from "framer-motion"; -import { useRouter } from "next/navigation"; +import React, { useState } from "react"; +import { motion, useMotionValue, useTransform } from "framer-motion"; +// Removed local fallback JSX declaration — use the official React type definitions instead: +// install @types/react and @types/react-dom so JSX.IntrinsicElements is provided by those packages. // 1. Updated ColorWay interface interface ColorWay { card: string; @@ -28,31 +29,126 @@ interface CardData { tracks: string[]; } -const SwipeCards: React.FC<{ initialCards: CardData[] }> = ({ initialCards }) => { - const [cards, setCards] = useState(initialCards); - const router = useRouter(); +const cardData: CardData[] = [ + { - // Update cards state when initialCards prop changes - useEffect(() => { - setCards(initialCards); - }, [initialCards]); + id: 1, - const removeCard = () => { + title: " WEBSITE", + + summary: + + "FFind out what makes GoonMAXXER unique.With this innovative website you will be able to explore various features and functionalities that set GoonMAXXER apart from the rest.", + + tracks: ["Gemini", "Auth0", "VibeCODING", "SmellyMaxxing", "shitposting"], + + }, + + { + + id: 2, + + title: "Intro to React", + + summary: + + "Learn the fundamentals of React, including components, state, and props.", + + tracks: ["React", "JS", "Frontend"], + + }, + + { + + id: 3, + + title: "State Management", + + summary: + + "Explore complex state solutions with Zustand, Redux, and Context API.", + + tracks: ["React", "Zustand", "State"], + + }, + + { + + id: 4, + + title: "Next.js 14", + + summary: "Master the app router, server actions, and data fetching.", + + tracks: ["Next.js", "React", "Fullstack"], + + }, + + { + + id: 5, + + title: "UI/UX Principles", + + summary: + + "A complete guide to user-centric design, prototyping, and testing.", + + tracks: ["Design", "UI", "UX"], + + }, + + { + + id: 6, + + title: "Node.js Essentials", + + summary: + + "Build scalable, high-performance backend applications with Node.js.", + + tracks: ["Node", "Backend", "JS"], + + }, + + { + + id: 7, + + title: "TypeScript", + + summary: + + "Add static typing to your JavaScript projects for robust, large-scale apps.", + + tracks: ["TypeScript", "JS", "DevOps"], + + }, + + { + + id: 8, + + title: "Framer Motion", + + summary: "Create production-ready animations for your React applications.", + + tracks: ["React", "Animation", "Framer"], + + }, + +].reverse(); + +const SwipeCards: React.FC = () => { + const [cards, setCards] = useState(cardData); + + const onSwipe = () => { setCards((prev) => prev.slice(0, prev.length - 1)); }; - const handleAccept = (cardData: CardData) => { - removeCard(); - // Redirect to chatbot with card data - router.push(`/chatbot?title=${encodeURIComponent(cardData.title)}&summary=${encodeURIComponent(cardData.summary)}`); - }; - - const handleReject = () => { - removeCard(); - }; - const handleReset = () => { - setCards([]); // Reset to initial cards + setCards(cardData); }; return ( @@ -60,8 +156,8 @@ const SwipeCards: React.FC<{ initialCards: CardData[] }> = ({ initialCards }) => className="grid h-screen w-full place-items-center bg-orange-100" // -gradient-to-tr from-orange-200 to-orange-100 style={{ - backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' - viewBox='0 0 32 32' width='32' height='32' fill='none' + backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' + viewBox='0 0 32 32' width='32' height='32' fill='none' stroke-width='2' stroke='%23d4d4d4'%3e%3cpath d='M0 .5H31.5V32'/%3e%3c/svg%3e")`, }} > @@ -74,8 +170,7 @@ const SwipeCards: React.FC<{ initialCards: CardData[] }> = ({ initialCards }) => cardData={card} colorWay={colorWay} isFront={index === cards.length - 1} - onAccept={handleAccept} - onReject={handleReject} + onSwipe={onSwipe} /> ); }) @@ -104,11 +199,10 @@ interface CardProps { cardData: CardData; colorWay: ColorWay; isFront: boolean; - onAccept: (cardData: CardData) => void; - onReject: () => void; + onSwipe: () => void; } -const Card: React.FC = ({ cardData, colorWay, isFront, onAccept, onReject }) => { +const Card: React.FC = ({ cardData, colorWay, isFront, onSwipe }) => { const { title, summary, tracks } = cardData; const x = useMotionValue(0); @@ -118,30 +212,20 @@ const Card: React.FC = ({ cardData, colorWay, isFront, onAccept, onRe [-250, -100, 0, 100, 250], [0, 1, 1, 1, 0], ); - const controls = useAnimation(); const acceptOpacity = useTransform(x, [50, 150], [0, 1]); const rejectOpacity = useTransform(x, [-150, -50], [1, 0]); const badgeRotate = useTransform(x, [-150, 150], [-15, 15]); - const handleDragEnd = async (event: MouseEvent | TouchEvent | PointerEvent, info: { offset: { x: number } }) => { - if (info.offset.x > 100) { - // Card accepted - await controls.start({ x: 1000, opacity: 0, transition: { duration: 0.1 } }); // Animate off-screen quickly - onAccept(cardData); // Then call onAccept which removes the card and redirects - } else if (info.offset.x < -100) { - // Card rejected - await controls.start({ x: -1000, opacity: 0, transition: { duration: 0.1 } }); // Animate off-screen quickly - onReject(); // Then call onReject which removes the card - } else { - // Card not swiped far enough, snap back to center - controls.start({ x: 0, rotate: 0, opacity: 1, transition: { type: "spring", stiffness: 300, damping: 30 } }); + const handleDragEnd = (event: MouseEvent | TouchEvent | PointerEvent, info: { offset: { x: number } }) => { + if (Math.abs(info.offset.x) > 100) { + onSwipe(); } }; return ( = ({ cardData, colorWay, isFront, onAccept, onRe zIndex: isFront ? 2 : 1, pointerEvents: isFront ? "auto" : "none", }} - animate={controls} + animate={{ + scale: isFront ? 1 : 0.95, + y: isFront ? 0 : -40, + }} transition={{ type: "spring", stiffness: 300, damping: 30 }} drag={isFront ? "x" : false} dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }} @@ -175,20 +262,24 @@ const Card: React.FC = ({ cardData, colorWay, isFront, onAccept, onRe
{/* 3. Applied the specific titleColor here */}

{title}

{/* This summary

will inherit colorWay.text from the parent */} -

{summary}

+

{summary}

- {tracks.slice(0, 2).map((track, index) => ( + {/* This

will also inherit colorWay.text */} +

+ Tracks +

+ {tracks.map((track) => ( = ({ cardData, colorWay, isFront, onAccept, onRe }} > {track} - {index === 0 && tracks.length > 1 && ", "} ))}
@@ -207,4 +297,4 @@ const Card: React.FC = ({ cardData, colorWay, isFront, onAccept, onRe }; -export default SwipeCards; +export default SwipeCards; \ No newline at end of file diff --git a/app/exportType/types.ts b/app/exportType/types.ts index 9b2afbb..7281483 100644 --- a/app/exportType/types.ts +++ b/app/exportType/types.ts @@ -14,6 +14,7 @@ export interface GenerateConfig { temperature: number; topP: number; responseMimeType: string; + maxOutputTokens?: number; } export interface ChatSetting { diff --git a/app/page.tsx b/app/page.tsx index c297bb6..4342fc9 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,4 +1,5 @@ import Image from "next/image"; +import Link from "next/link"; export default function Home() { return ( @@ -8,19 +9,19 @@ export default function Home() { >
Next.js logo
@@ -39,29 +40,13 @@ export default function Home() { className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400" > Got a hackathon coming up? Tell us your track, your team’s skills, what you’re passionate about, and more — and we’ll provide you with the perfect project idea!{" "} - {/* -                Templates -              {" "} -              or the{" "} -               -                Learning -              {" "} */} - {/* center. */}

- {/* Get Started */}
From ed00148f588250b2ce027b578eeb94ce157178f9 Mon Sep 17 00:00:00 2001 From: Rainyy21 Date: Sun, 9 Nov 2025 01:31:32 -0500 Subject: [PATCH 2/4] 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" } From 3e3bff62fdf73a8581fc0e80ac2713d3047de5fd Mon Sep 17 00:00:00 2001 From: Rainyy21 Date: Sun, 9 Nov 2025 03:03:37 -0500 Subject: [PATCH 3/4] fix the ai and it should be working --- app/Dashboard/page.tsx | 11 +- app/api/chat/route.ts | 13 +- app/chatbot/page.tsx | 153 ++++-------- app/components/Cards.tsx | 172 ++++---------- app/formfile/generate-idea.ts | 3 +- app/formfile/page.tsx | 174 ++++---------- app/globals.css | 37 +-- app/page.tsx | 281 ----------------------- app/utils/component/ui/MessageWindow.tsx | 19 +- app/utils/geminiHelper.ts | 28 +-- 10 files changed, 160 insertions(+), 731 deletions(-) diff --git a/app/Dashboard/page.tsx b/app/Dashboard/page.tsx index 342cbc3..4a5ef08 100644 --- a/app/Dashboard/page.tsx +++ b/app/Dashboard/page.tsx @@ -1,8 +1,7 @@ "use client"; import React, { useState } from "react"; -// import { useRouter } from "next/navigation"; // Removed Next.js import -// import Link from 'next/link'; // Removed Next.js import +import Link from 'next/link'; export default function Dashboard() { // const router = useRouter(); // Removed Next.js hook @@ -79,23 +78,23 @@ export default function Dashboard() { className={`flex flex-col p-4 gap-3 text-zinc-700 dark:text-zinc-300 transition-opacity duration-200 ${sideBarOpen ? "opacity-100" : "opacity-0" }`} > - Home - +

Settings

- Logout - + diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 83d96ae..0056d7f 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -8,22 +8,19 @@ export async function POST(request: Request) { const { userMessage, history, settings } = await request.json() as { userMessage: string; history: ChatHistory; - settings: ChatSetting; + settings?: ChatSetting; // settings is optional from the request }; - const aiResponse = await chatToGemini(userMessage, history, settings); - return NextResponse.json({ response: aiResponse }); + // Call the Gemini helper function + const geminiResponse = await chatToGemini(userMessage, history, settings || {}); + + return NextResponse.json({ response: geminiResponse }); } catch (error) { console.error(error); return NextResponse.json( -<<<<<<< HEAD {error: "Error with the model response " + String(error)}, {status : 500} -======= - { error: "Error with the model response " }, - { status: 500 } ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a ); } } diff --git a/app/chatbot/page.tsx b/app/chatbot/page.tsx index 4be1b08..7cd0e95 100644 --- a/app/chatbot/page.tsx +++ b/app/chatbot/page.tsx @@ -1,90 +1,74 @@ "use client"; -import { useState, useEffect, useRef, useCallback } from "react"; +import { useState, useEffect, useRef, useCallback, Suspense } from "react"; 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() { + return ( + Loading chat...
}> + + + ); +} + +function ChatbotContent() { const [history, setHistory] = useState([]) const [loading, setLoading] = useState(false); - const historyRef = useRef([]); // Create a ref for history const [settings] = useState({ -<<<<<<< HEAD - temperature:1, - model:"gemini-2.5-pro", - 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" - -======= 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" ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a }); const router = useRouter(); const searchParams = useSearchParams(); const initialMessageSent = useRef(false); - useEffect(() => { - historyRef.current = history; // Keep the ref updated with the latest history - }, [history]); - const handleSend = useCallback(async (message: string) => { const newUserMessage: Message = { role: "user", parts: [{ text: message }], }; - setHistory(prevHistory => { - const currentHistory = [...prevHistory, newUserMessage]; + const currentHistory = [...history, newUserMessage]; + setHistory(currentHistory); + setLoading(true); - const sendApiRequest = async () => { -<<<<<<< HEAD - setLoading(true); - try{ -======= - try { ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a - const response = await fetch("/api/chat", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - userMessage: message, - history: historyRef.current, // Use the ref for history - settings: settings, - }), - }); + try { + const response = await fetch("/api/chat", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + userMessage: message, + history: currentHistory, + settings: settings, + }), + }); - const data = await response.json(); + const data = await response.json(); - if (data.error) { - console.error("AI Error:", data.error); - setLoading(false); - return; - } - - const aiMessage: Message = { - role: "model" as MessageRole, - parts: [{ text: data.response }], - }; - - setHistory(prevHistory => [...prevHistory, aiMessage]); - - } - catch (error) { - console.error("Request Failed:", error); - } + if (data.error) { + console.error("AI Error:", data.error); setLoading(false); - }; - sendApiRequest(); + return; + } - return currentHistory; - }); - }, [settings]); // Now handleSend only depends on settings + const aiMessage: Message = { + role: "model" as MessageRole, + parts: [{ text: data.response }], + }; + + setHistory((prevHistory) => [...prevHistory, aiMessage]); + } catch (error) { + console.error("Request Failed:", error); + } + setLoading(false); + }, [history, settings]); // Dependencies for useCallback useEffect(() => { if (!initialMessageSent.current) { @@ -93,61 +77,16 @@ export default function Home() { if (title && summary) { const message = `Explain the project titled '${title}' with the summary '${summary}' in detail, and suggest suitable roles for a team working on it.`; - - const newUserMessage: Message = { - role: "user", - parts: [{ text: message }], - }; - - setTimeout(() => { - setHistory((prevHistory) => [...prevHistory, newUserMessage]); // Add user message to history - }, 0); - - const sendInitialApiRequest = async () => { - setLoading(true); - try { - const response = await fetch("/api/chat", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - userMessage: message, - history: [...historyRef.current, newUserMessage], // Use ref for history - settings: settings, - }), - }); - - const data = await response.json(); - - if (data.error) { - console.error("AI Error:", data.error); - setLoading(false); - return; - } - - const aiMessage: Message = { - role: "model" as MessageRole, - parts: [{ text: data.response }], - }; - - setHistory((prevHistory) => [...prevHistory, aiMessage]); - } catch (error) { - console.error("Request Failed:", error); - } - setLoading(false); - }; - - sendInitialApiRequest(); + // eslint-disable-next-line react-hooks/set-state-in-effect + handleSend(message); initialMessageSent.current = true; } } - }, [searchParams, settings]); // Dependencies for this useEffect + }, [searchParams, settings, handleSend]); // Dependencies for this useEffect return (
-<<<<<<< HEAD {}} /> -======= - - { }} /> ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a
); } \ No newline at end of file diff --git a/app/components/Cards.tsx b/app/components/Cards.tsx index 322b377..12476c9 100644 --- a/app/components/Cards.tsx +++ b/app/components/Cards.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { motion, useMotionValue, useTransform } from "framer-motion"; +import { useRouter } from "next/navigation"; // Removed local fallback JSX declaration — use the official React type definitions instead: // install @types/react and @types/react-dom so JSX.IntrinsicElements is provided by those packages. @@ -29,126 +30,49 @@ interface CardData { tracks: string[]; } -const cardData: CardData[] = [ - { - id: 1, - title: " WEBSITE", +interface SwipeCardsProps { + initialCards: CardData[]; +} - summary: - - "FFind out what makes GoonMAXXER unique.With this innovative website you will be able to explore various features and functionalities that set GoonMAXXER apart from the rest.", - - tracks: ["Gemini", "Auth0", "VibeCODING", "SmellyMaxxing", "shitposting"], - - }, - - { - - id: 2, - - title: "Intro to React", - - summary: - - "Learn the fundamentals of React, including components, state, and props.", - - tracks: ["React", "JS", "Frontend"], - - }, - - { - - id: 3, - - title: "State Management", - - summary: - - "Explore complex state solutions with Zustand, Redux, and Context API.", - - tracks: ["React", "Zustand", "State"], - - }, - - { - - id: 4, - - title: "Next.js 14", - - summary: "Master the app router, server actions, and data fetching.", - - tracks: ["Next.js", "React", "Fullstack"], - - }, - - { - - id: 5, - - title: "UI/UX Principles", - - summary: - - "A complete guide to user-centric design, prototyping, and testing.", - - tracks: ["Design", "UI", "UX"], - - }, - - { - - id: 6, - - title: "Node.js Essentials", - - summary: - - "Build scalable, high-performance backend applications with Node.js.", - - tracks: ["Node", "Backend", "JS"], - - }, - - { - - id: 7, - - title: "TypeScript", - - summary: - - "Add static typing to your JavaScript projects for robust, large-scale apps.", - - tracks: ["TypeScript", "JS", "DevOps"], - - }, - - { - - id: 8, - - title: "Framer Motion", - - summary: "Create production-ready animations for your React applications.", - - tracks: ["React", "Animation", "Framer"], - - }, - -].reverse(); - -const SwipeCards: React.FC = () => { - const [cards, setCards] = useState(cardData); +const SwipeCards: React.FC = ({ initialCards }) => { + const [cards, setCards] = useState(initialCards); + const router = useRouter(); const onSwipe = () => { setCards((prev) => prev.slice(0, prev.length - 1)); }; + const handleRightSwipe = async (card: CardData) => { + try { + const response = await fetch("/api/chat", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + userMessage: `Explain the project: ${card.title}. Summary: ${card.summary}. Tracks: ${card.tracks.join(", ")}`, + history: [], // Provide an empty array for history + }), + }); + + if (!response.ok) { + const errorBody = await response.text(); // Read the response body + throw new Error(`HTTP error! status: ${response.status}, body: ${errorBody}`); + } + + // Assuming the chat API handles the message and we can then navigate + router.push(`/chatbot?title=${encodeURIComponent(card.title)}&summary=${encodeURIComponent(card.summary)}`); + } catch (error) { + console.error("Error sending project to chatbot:", error); + // Optionally, handle error state or show a message to the user + } + onSwipe(); // Remove the card after swiping right + }; + const handleReset = () => { - setCards(cardData); + setCards(initialCards); }; return ( @@ -171,6 +95,7 @@ const SwipeCards: React.FC = () => { colorWay={colorWay} isFront={index === cards.length - 1} onSwipe={onSwipe} + onRightSwipe={handleRightSwipe} /> ); }) @@ -199,10 +124,11 @@ interface CardProps { cardData: CardData; colorWay: ColorWay; isFront: boolean; - onSwipe: () => void; + onSwipe: () => void; // For left swipe (reject) + onRightSwipe: (card: CardData) => void; // For right swipe (accept) } -const Card: React.FC = ({ cardData, colorWay, isFront, onSwipe }) => { +const Card: React.FC = ({ cardData, colorWay, isFront, onSwipe, onRightSwipe }) => { const { title, summary, tracks } = cardData; const x = useMotionValue(0); @@ -218,14 +144,18 @@ const Card: React.FC = ({ cardData, colorWay, isFront, onSwipe }) => const badgeRotate = useTransform(x, [-150, 150], [-15, 15]); const handleDragEnd = (event: MouseEvent | TouchEvent | PointerEvent, info: { offset: { x: number } }) => { - if (Math.abs(info.offset.x) > 100) { + if (info.offset.x > 100) { + // Swiped right + onRightSwipe(cardData); + } else if (info.offset.x < -100) { + // Swiped left onSwipe(); } }; return ( = ({ cardData, colorWay, isFront, onSwipe }) => className="absolute left-10 top-10 z-10 rounded-2xl border-8 border-green-500 px-10 py-4" style={{ opacity: acceptOpacity, rotate: badgeRotate }} > -

Accept

+

Accept

-

Reject

+

Reject

{/* Card Content */}
{/* 3. Applied the specific titleColor here */}

{title}

{/* This summary

will inherit colorWay.text from the parent */} -

{summary}

+

{summary}

{/* This

will also inherit colorWay.text */} -

+

Tracks

{tracks.map((track) => ( { }; }; -<<<<<<< HEAD +export default function Home() { + const [ideaResponse, setIdeaResponse] = useState(""); const [generatedCards, setGeneratedCards] = useState([]); // New state for parsed cards + const [initialState] = useState(getInitialState); + const [showForm, setShowForm] = useState(initialState.showForm); + const initialIdeaGenerationAttempted = useRef(false); const [settings] = useState({ temperature: 1, model: "gemini-2.5-flash-lite", 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. -======= -// FIX 1 (Memoization): Moved settings OUTSIDE the component. -// This makes it a true constant. -const AI_SETTINGS: ChatSetting = { - temperature: 1, - model: "gemini-2.5-pro", - sysTemInstructions: `You are an elite hackathon idea generator. Your task is to generate five different creative, feasible, and relevant project idea. ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a The output MUST be in Markdown format and strictly follow this structure: ### Project Idea Title -<<<<<<< HEAD **Track** [print out the track you used] **Concept:** [A concise, single paragraph description of the product and its primary function.]`, }); - const parseAiResponse = (markdownString: string): CardData[] => { - console.log("Raw AI Response:", markdownString); - const ideas: CardData[] = []; - const ideaBlocks = markdownString.split("### ").filter(block => block.trim() !== ""); - - ideaBlocks.forEach((block, index) => { - // Match title: anything from the start of the block until the first newline or the start of "**Track**" - const titleMatch = block.match(/^(.*?)(?=\n\*\*Track\*\*|$)/s); - // Match track: "**Track**" followed by optional whitespace and then capture everything until the next "**Concept**" or end of block/line - const trackMatch = block.match(/\*\*Track\*\*\s*:\s*(.*?)(?=\n\*\*Concept\*\*|$)/s); // Added ':' and made whitespace more flexible - // Match concept: "**Concept:**" followed by optional whitespace and then capture everything until the end of the block - const conceptMatch = block.match(/\*\*Concept:\*\*\s*(.*)/s); - - const title = titleMatch ? titleMatch[1].trim() : `Idea ${index + 1}`; - const summary = conceptMatch ? conceptMatch[1].trim() : "No concept provided."; - const tracksRaw = trackMatch ? trackMatch[1].trim() : ""; - console.log("tracksRaw:", tracksRaw); // Added console.log for debugging - const tracks = tracksRaw.split(',').map(track => track.trim()).filter(track => track !== ''); - - ideas.push({ - id: index + 1, - title, - tracks, - summary, - }); - }); - console.log("Parsed Cards:", ideas); - return ideas; - }; -======= -**Relevance to Theme:** [Explain briefly] -**Core Technology:** [List 3-5 primary technologies] -**Team Fit:** [How the team's skills apply] -**Concept:** [A concise, single paragraph description of the product and its primary function.] -**Bonus Feature:** [A single, ambitious feature to impress judges.]`, -}; ->>>>>>> 44b5a4dc49ea757e9790ba8309edc6b37d764105 - -// ------------------------------------------------ - -export default function Home() { - - const [initialState] = useState(getInitialState); - const [showForm, setShowForm] = useState(initialState.showForm); - const [formData, setFormData] = useState(initialState.data); - const [ideaResponse, setIdeaResponse] = useState(""); - - // The 'settings' state [useState] is now removed from here. - - const handleFormSubmitFromFormPage = (submittedData: FormData) => { - setFormData(submittedData); - setShowForm(false); - generateIdeas(submittedData); - }; - - // Wrapped generateIdeas in useCallback const generateIdeas = useCallback(async (dataToProcess: FormData) => { - // 1. Data Cleaning + const parseAiResponse = (markdownString: string): CardData[] => { + console.log("Raw AI Response:", markdownString); + const ideas: CardData[] = []; + const ideaBlocks = markdownString.split("### ").filter(block => block.trim() !== ""); + + ideaBlocks.forEach((block, index) => { + const titleMatch = block.match(/^(.*?)(?=\n\*\*Track\*\*|$)/s); + const trackMatch = block.match(/\*\*Track\*\*\s*:\s*(.*?)(?=\n\*\*Concept\*\*|$)/s); + const conceptMatch = block.match(/\*\*Concept:\*\*\s*(.*)/s); + + const title = titleMatch ? titleMatch[1].trim() : `Idea ${index + 1}`; + const summary = conceptMatch ? conceptMatch[1].trim() : "No concept provided."; + const tracksRaw = trackMatch ? trackMatch[1].trim() : ""; + const tracks = tracksRaw.split(',').map(track => track.trim()).filter(track => track !== ''); + + ideas.push({ + id: index + 1, + title, + tracks, + summary, + }); + }); + console.log("Parsed Cards:", ideas); + return ideas; + }; + const submissionData: FormData = { ...dataToProcess, tracksStack: dataToProcess.tracksStack.filter(tracks => tracks.trim() !== ''), @@ -132,7 +98,6 @@ export default function Home() { .filter(student => student.studentName.trim() !== '' || student.skills.length > 0), }; - // 2. Prompt Construction const prompt = ` Hackathon: ${submissionData.Hackathon} Main Theme: ${submissionData.mainTheme} @@ -143,11 +108,9 @@ export default function Home() { Using the SYSTEM INSTRUCTIONS, generate 5 project ideas based on the data above.`; - // 3. API Call try { setIdeaResponse("Generating ideas... Please wait."); -<<<<<<< HEAD - setGeneratedCards([]); // Clear previous cards + setGeneratedCards([]); const response = await fetch("/api/generate-idea", { method: "POST", headers: { @@ -161,24 +124,10 @@ export default function Home() { const data = await response.json(); -======= - - const response = await fetch("/api/generate-idea", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - prompt: prompt, - settings: AI_SETTINGS, // Use the constant - }), - }); - - const data = await response.json(); ->>>>>>> 44b5a4dc49ea757e9790ba8309edc6b37d764105 if (data.error || !response.ok) { console.error("AI Error:", data.error); setIdeaResponse(`Error: Failed to generate idea. ${data.error || response.statusText}`); return; -<<<<<<< HEAD } setIdeaResponse(data.response); @@ -195,42 +144,21 @@ export default function Home() { } setIdeaResponse(`A network error occurred. Please try again. Details: ${errorMessage}`); } - }, [setIdeaResponse, setGeneratedCards, settings, parseAiResponse]); + }, [settings]); useEffect(() => { - if (typeof window !== 'undefined') { - const storedFormData = localStorage.getItem('formData'); - if (storedFormData) { - const parsedData: FormData = JSON.parse(storedFormData); - setTimeout(() => setShowForm(false), 0); - generateIdeas(parsedData); - localStorage.removeItem('formData'); -======= ->>>>>>> 44b5a4dc49ea757e9790ba8309edc6b37d764105 - } - setIdeaResponse(data.response); - - // FIX 2 (Unexpected any): Changed 'any' to 'unknown' and added a type check. - } catch (error: unknown) { - console.error("Request Failed:", error); - let errorMessage = "A network error occurred. Please try again."; - if (error instanceof Error) { - errorMessage += ` Details: ${error.message}`; - } - setIdeaResponse(errorMessage); - } - // FIX 3 (Linter): Disable the faulty memoization rule. - // The empty array is correct because setIdeaResponse is a stable state setter. - // eslint-disable-next-line react-hooks/preserve-manual-memoization - }, []); - - // Replaced useEffect - useEffect(() => { - if (initialState.runEffect) { + if (initialState.runEffect && !initialIdeaGenerationAttempted.current) { + // eslint-disable-next-line react-hooks/set-state-in-effect generateIdeas(initialState.data); + initialIdeaGenerationAttempted.current = true; } }, [initialState, generateIdeas]); + const handleFormSubmitFromFormPage = (submittedData: FormData) => { + setShowForm(false); + generateIdeas(submittedData); + }; + // --- JSX Rendering --- return (
@@ -239,7 +167,6 @@ export default function Home() { ) : ( <> -<<<<<<< HEAD {generatedCards.length > 0 ? ( ) : ( @@ -257,19 +184,6 @@ export default function Home() {
)} -======= -

- Generated Project Idea 💡 -

-
-

Generated Ideas:

-
') }} - /> - {ideaResponse === "" &&

Submit the form to generate project ideas.

} -
->>>>>>> 44b5a4dc49ea757e9790ba8309edc6b37d764105
); ->>>>>>> 44b5a4dc49ea757e9790ba8309edc6b37d764105 } - - -// {/* */} - - -// "use client"; - -// import React, { use, useState } from "react"; -// import { useRouter } from "next/navigation"; - -// export default function Dashboard() { -//   const router = useRouter();   -//   const[query, setQuery] = useState(""); -//   // const [projects, setProjects] = useState( [ -//   //     { id: 1, name: "Alpha Project", createdAt: new Date("2025-01-01")}, -//   //     { id: 2, name: "Beta Board", createdAt: new Date("2025-02-15")}, -//   //     { id: 3, name: "Gamma Task", createdAt: new Date("2025-03-10")} -//   // ]); -//   // const [newProjectName, setNewProjectName] = useState(""); -//   // const filtered = projects.filter( (p) => p.name.toLowerCase().includes(query.toLowerCase()) ); -//   // const handleCreate = () => { -//   //   if(!newProjectName.trim()) return; -//   //   const newProject = { -//   //     id: projects.length+1, name: newProjectName, createdAt: new Date(), -//   //   }; -//   // }; -//   const projects = [ -//     {name: "Alpha Project", createdAt: "2025-01-01"}, -//     {name: "Beta Board", createdAt: "2025-02-15"}, -//     {name: "Gamma Tasl", createdAt: "2025-03-10"}, -//   ] -//   const filtered = projects.filter( -//     (p) => p.name.toLowerCase().includes(query.toLowerCase()) -//   ); - -//  return ( -//    
-//      
-//        
-//          
-//            {/* */} -//             setQuery(e.target.value)} -//              placeholder="Search projects, boards or tasks..." -//              className="w-full max-w-md px-4 py-2 rounded-md border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-blue-500" -//            /> -//          
- -//          
-//            {/* setNewProjectName(e.target.value)} -//               placeholder="New Project Name" -//               className="px-3 py-2 rounded-md border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900  text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-blue-500" -//             /> */} -//              -//          
-//        
-//      
- -//      
-//        

-//          Project Names -//        

- -//        
-//          
    -//            {filtered.map((project, index) => ( -//              
  • -//                {project.name} -//                  -//                   {/* {project.createdAt.toLocaleDateString()} */} -//                   Created: {project.createdAt} -//                  -//              
  • -//            ))} - -//            {filtered.length === 0 && ( -//              
  • No results found
  • -//            )} -//          
-//        
-//      
-//    
-//  ); -// } \ No newline at end of file diff --git a/app/utils/component/ui/MessageWindow.tsx b/app/utils/component/ui/MessageWindow.tsx index b0083d3..c618df9 100644 --- a/app/utils/component/ui/MessageWindow.tsx +++ b/app/utils/component/ui/MessageWindow.tsx @@ -3,22 +3,13 @@ import { useRef, useEffect } from "react"; import { ChatHistory } from "@/app/exportType/types"; import { User, Bot } from "lucide-react" -<<<<<<< HEAD interface MessageWindowProps{ history :ChatHistory; isLoading: boolean; } export default function MessageWindow({history, isLoading}:MessageWindowProps){ - const messageEndRef = useRef(null); -======= -interface MessageWindowProps { - history: ChatHistory -} - -export default function MessageWindow({ history }: MessageWindowProps) { const messageEndRef = useRef(null); ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a useEffect(() => { messageEndRef.current?.scrollIntoView({ behavior: "smooth" }); @@ -59,7 +50,6 @@ export default function MessageWindow({ history }: MessageWindowProps) {
)} -<<<<<<< HEAD ); })} @@ -79,14 +69,7 @@ export default function MessageWindow({ history }: MessageWindowProps) { )} {/* Invisible element to help scroll to bottom */}
-======= - ); - })} - - {/* Invisible element to help scroll to bottom */} -
-
->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a
+ ); } \ No newline at end of file diff --git a/app/utils/geminiHelper.ts b/app/utils/geminiHelper.ts index 741f563..e5a11a5 100644 --- a/app/utils/geminiHelper.ts +++ b/app/utils/geminiHelper.ts @@ -10,7 +10,6 @@ if (!apiKey) { const genAI = new GoogleGenerativeAI(apiKey); export async function chatToGemini( -<<<<<<< HEAD userMessage:string , history:ChatHistory, settings:ChatSetting @@ -26,23 +25,6 @@ export async function chatToGemini( responseMimeType: "text/plain", maxOutputTokens: 1900, // Increased to allow for longer responses } -======= - userMessage: string, - history: ChatHistory, - settings: ChatSetting -): 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", - }); ->>>>>>> ce9e6f34ed31b7bff736cc9ba9a1b8dcdec85f3a - - const generationConfig: GenerateConfig = { - temperature: settings.temperature || 1, - topP: 0.9, - responseMimeType: "text/plain", - maxOutputTokens: 1900, // Increased to allow for longer responses - } const chatSession = model.startChat({ generationConfig, @@ -53,8 +35,12 @@ export async function chatToGemini( const result = await chatSession.sendMessage(userMessage); return result.response.text(); } - catch (error) { - console.error(error) - throw error + catch (error: unknown) { + if (error instanceof Error) { + console.error("Error in chatToGemini:", error.name, error.message, error); + } else { + console.error("Unknown error in chatToGemini:", error); + } + throw error; } } \ No newline at end of file From 45f06bfe8e4cb0ed37f21323d05c62d6780c548b Mon Sep 17 00:00:00 2001 From: Rainyy21 Date: Sun, 9 Nov 2025 03:20:24 -0500 Subject: [PATCH 4/4] change model --- app/chatbot/page.tsx | 2 +- app/components/Cards.tsx | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/chatbot/page.tsx b/app/chatbot/page.tsx index 7cd0e95..36191b5 100644 --- a/app/chatbot/page.tsx +++ b/app/chatbot/page.tsx @@ -19,7 +19,7 @@ function ChatbotContent() { const [loading, setLoading] = useState(false); const [settings] = useState({ temperature: 1, - model: "gemini-2.5-pro", + model: "gemini-2.5-flash", 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" }); diff --git a/app/components/Cards.tsx b/app/components/Cards.tsx index 12476c9..a4012f5 100644 --- a/app/components/Cards.tsx +++ b/app/components/Cards.tsx @@ -173,6 +173,9 @@ const Card: React.FC = ({ cardData, colorWay, isFront, onSwipe, onRig drag={isFront ? "x" : false} dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }} onDragEnd={handleDragEnd} + initial={{ x: 500, opacity: 0 }} // Start off-screen to the right and invisible + animate={{ x: 0, opacity: 1 }} // Animate to its natural position and fully visible + transition={{ type: "spring", stiffness: 100, damping: 20 }} // Smooth spring animation > {/* Accept/Reject Badges */}