From 534d2e121b495e95ba6b63a49542bce6f5a6820a Mon Sep 17 00:00:00 2001 From: Aneesh Date: Fri, 14 Nov 2025 21:39:27 +0530 Subject: [PATCH] WIP: chat layout changes --- app/api/chat/route.ts | 12 + app/chat/page.tsx | 7 + app/globals.css | 88 +- components.json | 5 +- components/chat/ChatHeader.tsx | 18 + components/chat/ChatInput.tsx | 33 + components/chat/ChatLayout.tsx | 31 + components/chat/ChatMessages.tsx | 33 + components/chat/MessageBubble.tsx | 46 + lib/utils.ts | 6 +- package-lock.json | 124 +- package.json | 4 +- pnpm-lock.yaml | 6061 +++++++++++++++++++++++++++++ types/ai-react.d.ts | 16 + types/ai-sdk-react.d.ts | 6 + 15 files changed, 6438 insertions(+), 52 deletions(-) create mode 100644 app/api/chat/route.ts create mode 100644 app/chat/page.tsx create mode 100644 components/chat/ChatHeader.tsx create mode 100644 components/chat/ChatInput.tsx create mode 100644 components/chat/ChatLayout.tsx create mode 100644 components/chat/ChatMessages.tsx create mode 100644 components/chat/MessageBubble.tsx create mode 100644 pnpm-lock.yaml create mode 100644 types/ai-react.d.ts create mode 100644 types/ai-sdk-react.d.ts diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts new file mode 100644 index 0000000..f703b54 --- /dev/null +++ b/app/api/chat/route.ts @@ -0,0 +1,12 @@ +import { streamText } from "ai"; + +export async function POST(req: Request) { + const { messages } = await req.json(); + + const response = await streamText({ + model: "gpt-4o-mini", + messages, + }); + + return response.toTextStreamResponse(); +} diff --git a/app/chat/page.tsx b/app/chat/page.tsx new file mode 100644 index 0000000..7abfc8e --- /dev/null +++ b/app/chat/page.tsx @@ -0,0 +1,7 @@ +"use client"; + +import ChatLayout from "@/components/chat/ChatLayout"; + +export default function ChatPage() { + return ; +} diff --git a/app/globals.css b/app/globals.css index f9f0f3e..2979d0b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -5,71 +5,71 @@ :root { --radius: 0.625rem; - --background: oklch(1 0 0); - --foreground: oklch(0.141 0.005 285.823); --card: oklch(1 0 0); - --card-foreground: oklch(0.141 0.005 285.823); + --card-foreground: oklch(0.13 0.028 261.692); --popover: oklch(1 0 0); - --popover-foreground: oklch(0.141 0.005 285.823); - --primary: oklch(0.21 0.006 285.885); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.967 0.001 286.375); - --secondary-foreground: oklch(0.21 0.006 285.885); - --muted: oklch(0.967 0.001 286.375); - --muted-foreground: oklch(0.552 0.016 285.938); - --accent: oklch(0.967 0.001 286.375); - --accent-foreground: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.13 0.028 261.692); + --primary: oklch(0.21 0.034 264.665); + --primary-foreground: oklch(0.985 0.002 247.839); + --secondary: oklch(0.967 0.003 264.542); + --secondary-foreground: oklch(0.21 0.034 264.665); + --muted: oklch(0.967 0.003 264.542); + --muted-foreground: oklch(0.551 0.027 264.364); + --accent: oklch(0.967 0.003 264.542); + --accent-foreground: oklch(0.21 0.034 264.665); --destructive: oklch(0.577 0.245 27.325); - --border: oklch(0.92 0.004 286.32); - --input: oklch(0.92 0.004 286.32); - --ring: oklch(0.705 0.015 286.067); + --border: oklch(0.928 0.006 264.531); + --input: oklch(0.928 0.006 264.531); + --ring: oklch(0.707 0.022 261.325); --chart-1: oklch(0.646 0.222 41.116); --chart-2: oklch(0.6 0.118 184.704); --chart-3: oklch(0.398 0.07 227.392); --chart-4: oklch(0.828 0.189 84.429); --chart-5: oklch(0.769 0.188 70.08); - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.141 0.005 285.823); - --sidebar-primary: oklch(0.21 0.006 285.885); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.967 0.001 286.375); - --sidebar-accent-foreground: oklch(0.21 0.006 285.885); - --sidebar-border: oklch(0.92 0.004 286.32); - --sidebar-ring: oklch(0.705 0.015 286.067); + --sidebar: oklch(0.985 0.002 247.839); + --sidebar-foreground: oklch(0.13 0.028 261.692); + --sidebar-primary: oklch(0.21 0.034 264.665); + --sidebar-primary-foreground: oklch(0.985 0.002 247.839); + --sidebar-accent: oklch(0.967 0.003 264.542); + --sidebar-accent-foreground: oklch(0.21 0.034 264.665); + --sidebar-border: oklch(0.928 0.006 264.531); + --sidebar-ring: oklch(0.707 0.022 261.325); + --background: oklch(1 0 0); + --foreground: oklch(0.13 0.028 261.692); } .dark { - --background: oklch(0.141 0.005 285.823); - --foreground: oklch(0.985 0 0); - --card: oklch(0.21 0.006 285.885); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.21 0.006 285.885); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.92 0.004 286.32); - --primary-foreground: oklch(0.21 0.006 285.885); - --secondary: oklch(0.274 0.006 286.033); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.274 0.006 286.033); - --muted-foreground: oklch(0.705 0.015 286.067); - --accent: oklch(0.274 0.006 286.033); - --accent-foreground: oklch(0.985 0 0); + --background: oklch(0.13 0.028 261.692); + --foreground: oklch(0.985 0.002 247.839); + --card: oklch(0.21 0.034 264.665); + --card-foreground: oklch(0.985 0.002 247.839); + --popover: oklch(0.21 0.034 264.665); + --popover-foreground: oklch(0.985 0.002 247.839); + --primary: oklch(0.928 0.006 264.531); + --primary-foreground: oklch(0.21 0.034 264.665); + --secondary: oklch(0.278 0.033 256.848); + --secondary-foreground: oklch(0.985 0.002 247.839); + --muted: oklch(0.278 0.033 256.848); + --muted-foreground: oklch(0.707 0.022 261.325); + --accent: oklch(0.278 0.033 256.848); + --accent-foreground: oklch(0.985 0.002 247.839); --destructive: oklch(0.704 0.191 22.216); --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); - --ring: oklch(0.552 0.016 285.938); + --ring: oklch(0.551 0.027 264.364); --chart-1: oklch(0.488 0.243 264.376); --chart-2: oklch(0.696 0.17 162.48); --chart-3: oklch(0.769 0.188 70.08); --chart-4: oklch(0.627 0.265 303.9); --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.21 0.006 285.885); - --sidebar-foreground: oklch(0.985 0 0); + --sidebar: oklch(0.21 0.034 264.665); + --sidebar-foreground: oklch(0.985 0.002 247.839); --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.274 0.006 286.033); - --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-primary-foreground: oklch(0.985 0.002 247.839); + --sidebar-accent: oklch(0.278 0.033 256.848); + --sidebar-accent-foreground: oklch(0.985 0.002 247.839); --sidebar-border: oklch(1 0 0 / 10%); - --sidebar-ring: oklch(0.552 0.016 285.938); + --sidebar-ring: oklch(0.551 0.027 264.364); } @theme inline { diff --git a/components.json b/components.json index a64445d..87838e7 100644 --- a/components.json +++ b/components.json @@ -6,10 +6,11 @@ "tailwind": { "config": "", "css": "app/globals.css", - "baseColor": "zinc", + "baseColor": "gray", "cssVariables": true, "prefix": "" }, + "iconLibrary": "lucide", "aliases": { "components": "@/components", "utils": "@/lib/utils", @@ -17,5 +18,5 @@ "lib": "@/lib", "hooks": "@/hooks" }, - "iconLibrary": "lucide" + "registries": {} } diff --git a/components/chat/ChatHeader.tsx b/components/chat/ChatHeader.tsx new file mode 100644 index 0000000..e7b46d5 --- /dev/null +++ b/components/chat/ChatHeader.tsx @@ -0,0 +1,18 @@ +"use client"; + +// import { Separator } from "@/components/ui/separator"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; + +export default function ChatHeader() { + return ( +
+ + AI + +
+

Chatbot

+

Ask me anything

+
+
+ ); +} diff --git a/components/chat/ChatInput.tsx b/components/chat/ChatInput.tsx new file mode 100644 index 0000000..8142348 --- /dev/null +++ b/components/chat/ChatInput.tsx @@ -0,0 +1,33 @@ +"use client"; + +import type { ChangeEvent, FormEvent } from "react"; +import { Button } from "@/components/ui/button"; +import { Textarea } from "@/components/ui/textarea"; + +export default function ChatInput({ + input, + handleInputChange, + handleSubmit, +}: { + input: string; + handleInputChange: (e: ChangeEvent) => void; + handleSubmit: (e: FormEvent) => void; +}) { + return ( +
+