Skip to content

Commit b21dcce

Browse files
optimization
1 parent acb0c84 commit b21dcce

File tree

2 files changed

+99
-125
lines changed

2 files changed

+99
-125
lines changed

components/chat-input.tsx

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { AiOutlineEnter } from "react-icons/ai";
2+
import { Button } from "./ui/button";
3+
import Textarea from "react-textarea-autosize";
4+
5+
export default function ChatInput({
6+
input,
7+
inputRef,
8+
handleInputChange,
9+
handleSubmit,
10+
}: {
11+
input: string;
12+
inputRef: React.RefObject<HTMLTextAreaElement>;
13+
handleInputChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
14+
handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
15+
}) {
16+
return (
17+
<form
18+
onSubmit={handleSubmit}
19+
className="fixed bottom-0 left-0 right-0 flex justify-center bg-gradient-to-t from-zinc-100 to-transparent backdrop-blur-lg dark:from-black/70">
20+
<div className="mt-6 w-full max-w-2xl items-center px-6">
21+
<div className="relative flex w-full items-center">
22+
<Textarea
23+
ref={inputRef}
24+
name="message"
25+
rows={1}
26+
maxRows={5}
27+
tabIndex={0}
28+
placeholder="Ask me anything..."
29+
spellCheck={false}
30+
value={input}
31+
className="rounded-fill min-h-12 w-full resize-none rounded-[28px] border border-input bg-muted pb-1 pl-4 pr-10 pt-3 text-sm shadow-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#74B202] focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
32+
onChange={handleInputChange}
33+
onKeyDown={(e) => {
34+
if (
35+
e.key === "Enter" &&
36+
!e.shiftKey &&
37+
!e.nativeEvent.isComposing
38+
) {
39+
e.preventDefault();
40+
if (input.trim().length > 0) {
41+
handleSubmit(
42+
e as unknown as React.FormEvent<HTMLFormElement>,
43+
);
44+
}
45+
}
46+
}}
47+
/>
48+
<Button
49+
type="submit"
50+
size="icon"
51+
variant="ghost"
52+
className="absolute right-2 top-1/2 mr-1 -translate-y-1/2 transform"
53+
disabled={input.length === 0}>
54+
<AiOutlineEnter size={20} />
55+
</Button>
56+
</div>
57+
<p className="p-2 text-center text-xs text-zinc-400">
58+
This is a demo chatbot. Built by{" "}
59+
<a
60+
target="_blank"
61+
rel="noopener noreferrer"
62+
className="underline underline-offset-2 transition-all duration-150 ease-linear md:hover:text-emerald-600 dark:md:hover:text-emerald-300"
63+
href="https://lakshb.dev">
64+
lakshb.dev
65+
</a>{" "}
66+
</p>
67+
</div>
68+
</form>
69+
);
70+
}

components/chat.tsx

Lines changed: 29 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
"use client";
22

3-
import { useChat } from "ai/react";
43
import { cn } from "@/lib/utils";
5-
import { useRef, useEffect } from "react";
4+
import { useChat } from "ai/react";
5+
import ChatInput from "./chat-input";
6+
import Markdown from "react-markdown";
67
import { BsNvidia } from "react-icons/bs";
7-
import { AiOutlineEnter } from "react-icons/ai";
8+
import { useRef, useEffect } from "react";
89
import { FaUserAstronaut } from "react-icons/fa";
9-
import Textarea from "react-textarea-autosize";
10-
import { Button } from "./ui/button";
11-
import Markdown from "react-markdown";
10+
import { IoLogoVercel } from "react-icons/io5";
1211

1312
export const chatSample = {
1413
messages: [
@@ -81,72 +80,23 @@ export default function Chat() {
8180

8281
if (messages.length === 0) {
8382
return (
84-
<div className="stretch mx-auto flex w-full max-w-xl flex-col py-24">
85-
<div className="items-strart mb-4 flex whitespace-pre-wrap p-2">
86-
<div
87-
className={cn(
88-
"flex size-8 shrink-0 select-none items-center justify-center rounded-lg border shadow",
89-
"bg-primary text-primary-foreground",
90-
)}>
91-
<BsNvidia />
92-
</div>
93-
<Markdown className="prose prose-sm dark:prose-invert prose-pre:bg-zinc-200 prose-pre:text-primary dark:prose-pre:bg-zinc-900 prose-pre:text-wrap prose-headings:m-0 prose-p:m-0 prose-ul:m-0 prose-blockquote:m-0 prose-ol:m-0 prose-img:m-0 ml-6">
94-
Hello, I am Nvidia. It's nice to meet you. How can I help you today?
95-
</Markdown>
96-
</div>
83+
<div className="stretch mx-auto flex w-full max-w-xl flex-col items-center py-24">
84+
<h1 className="text-center text-5xl font-bold tracking-tighter">
85+
Nvidia NIM + Vercel AI SDK Chatbot Demo
86+
</h1>
9787

98-
<form
99-
onSubmit={handleSubmit}
100-
className="fixed bottom-0 left-0 right-0 flex justify-center bg-gradient-to-t from-zinc-100 to-transparent backdrop-blur-lg dark:from-black/70">
101-
<div className="mb-3 mt-6 w-full max-w-2xl items-center px-6">
102-
<div className="relative flex w-full items-center">
103-
<Textarea
104-
ref={inputRef}
105-
name="message"
106-
rows={1}
107-
maxRows={5}
108-
tabIndex={0}
109-
placeholder="Ask me anything..."
110-
spellCheck={false}
111-
value={input}
112-
className="rounded-fill min-h-12 w-full resize-none rounded-full border border-input bg-muted pb-1 pl-4 pr-10 pt-3 text-sm shadow-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
113-
onChange={handleInputChange}
114-
onKeyDown={(e) => {
115-
if (
116-
e.key === "Enter" &&
117-
!e.shiftKey &&
118-
!e.nativeEvent.isComposing
119-
) {
120-
e.preventDefault();
121-
if (input.trim().length > 0) {
122-
handleSubmit(
123-
e as unknown as React.FormEvent<HTMLFormElement>,
124-
);
125-
}
126-
}
127-
}}
128-
/>
129-
<Button
130-
type="submit"
131-
size="icon"
132-
variant="ghost"
133-
className="absolute right-2 top-1/2 -translate-y-1/2 transform"
134-
disabled={input.length === 0}>
135-
<AiOutlineEnter size={20} />
136-
</Button>
137-
</div>
138-
<p className="p-4 text-center text-xs">
139-
This is a demo chatbot. Built by{" "}
140-
<a
141-
target="_blank"
142-
rel="noopener noreferrer"
143-
className="underline underline-offset-2 transition-all duration-150 ease-linear md:hover:text-emerald-600 dark:md:hover:text-emerald-300"
144-
href="https://lakshb.dev">
145-
lakshb.dev
146-
</a>
147-
</p>
88+
<div className="mt-6 flex items-center justify-center gap-4">
89+
<BsNvidia className="mr-4 size-20 text-[#74B202]" />
90+
<span className="text-8xl">+</span>
91+
<IoLogoVercel className="size-20" />
14892
</div>
149-
</form>
93+
94+
<ChatInput
95+
input={input}
96+
inputRef={inputRef}
97+
handleInputChange={handleInputChange}
98+
handleSubmit={handleSubmit}
99+
/>
150100
</div>
151101
);
152102
}
@@ -159,10 +109,10 @@ export default function Chat() {
159109
className="items-strart mb-4 flex whitespace-pre-wrap p-2">
160110
<div
161111
className={cn(
162-
"flex size-8 shrink-0 select-none items-center justify-center rounded-lg border shadow",
112+
"flex size-8 shrink-0 select-none items-center justify-center rounded-lg",
163113
m.role === "user"
164-
? "bg-background"
165-
: "bg-primary text-primary-foreground",
114+
? "border bg-background"
115+
: "border border-[#628f10] bg-[#74B202] text-primary-foreground",
166116
)}>
167117
{m.role === "user" ? <FaUserAstronaut /> : <BsNvidia />}
168118
</div>
@@ -172,58 +122,12 @@ export default function Chat() {
172122
</div>
173123
))}
174124

175-
<form
176-
onSubmit={handleSubmit}
177-
className="fixed bottom-0 left-0 right-0 flex justify-center bg-gradient-to-t from-zinc-100 to-transparent backdrop-blur-lg dark:from-black/70">
178-
<div className="mb-3 mt-6 w-full max-w-2xl items-center px-6">
179-
<div className="relative flex w-full items-center">
180-
<Textarea
181-
ref={inputRef}
182-
name="message"
183-
rows={1}
184-
maxRows={5}
185-
tabIndex={0}
186-
placeholder="Ask me anything..."
187-
spellCheck={false}
188-
value={input}
189-
className="rounded-fill min-h-12 w-full resize-none rounded-full border border-input bg-muted pb-1 pl-4 pr-10 pt-3 text-sm shadow-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
190-
onChange={handleInputChange}
191-
onKeyDown={(e) => {
192-
if (
193-
e.key === "Enter" &&
194-
!e.shiftKey &&
195-
!e.nativeEvent.isComposing
196-
) {
197-
e.preventDefault();
198-
if (input.trim().length > 0) {
199-
handleSubmit(
200-
e as unknown as React.FormEvent<HTMLFormElement>,
201-
);
202-
}
203-
}
204-
}}
205-
/>
206-
<Button
207-
type="submit"
208-
size="icon"
209-
variant="ghost"
210-
className="absolute right-2 top-1/2 -translate-y-1/2 transform"
211-
disabled={input.length === 0}>
212-
<AiOutlineEnter size={20} />
213-
</Button>
214-
</div>
215-
<p className="p-4 text-center text-xs">
216-
This is a demo chatbot. Built by{" "}
217-
<a
218-
target="_blank"
219-
rel="noopener noreferrer"
220-
className="underline underline-offset-2 transition-all duration-150 ease-linear md:hover:text-emerald-600 dark:md:hover:text-emerald-300"
221-
href="https://lakshb.dev">
222-
lakshb.dev
223-
</a>
224-
</p>
225-
</div>
226-
</form>
125+
<ChatInput
126+
input={input}
127+
inputRef={inputRef}
128+
handleInputChange={handleInputChange}
129+
handleSubmit={handleSubmit}
130+
/>
227131
</div>
228132
);
229133
}

0 commit comments

Comments
 (0)