11import type { ComponentProps } from "react" ;
22import * as Dialog from "@radix-ui/react-dialog" ;
33import * as ScrollArea from "@radix-ui/react-scroll-area" ;
4- import {
5- PenLine ,
6- Trash2 ,
7- X ,
8- ChevronLeft ,
9- ChevronRight ,
10- LogOut ,
11- } from "lucide-react" ;
4+ import { PenLine , Trash2 , X , ChevronLeft , ChevronRight } from "lucide-react" ;
125import type { LucideIcon } from "lucide-react" ;
136import { ChatInput } from "./chat-input" ;
147import { ChatMessage } from "./chat-message" ;
@@ -23,13 +16,6 @@ export interface ChatDialogProps extends ChatWidgetProps {
2316 open ?: boolean ;
2417 onOpenChange ?: ( open : boolean ) => void ;
2518 showTrigger ?: boolean ;
26- user ?: {
27- displayName ?: string | null ;
28- email ?: string | null ;
29- photoURL ?: string | null ;
30- } | null ;
31- onSignOut ?: ( ) => void ;
32- isRateLimited ?: boolean ;
3319}
3420
3521const IconComponent = ( {
@@ -64,9 +50,6 @@ export function ChatDialog({
6450 onDeleteChat,
6551 onUpdateChatTitle,
6652 onToggleFastMode,
67- user,
68- onSignOut,
69- isRateLimited = false ,
7053} : ChatDialogProps ) {
7154 const [ isSidebarCollapsed , setIsSidebarCollapsed ] = useState ( false ) ;
7255 const chatInputRef = useRef < HTMLTextAreaElement > ( null ) ;
@@ -132,7 +115,7 @@ export function ChatDialog({
132115 < Image src = { aptosLogo } alt = "Aptos AI" className = "h-5 w-5" />
133116 Ask AI
134117 </ Dialog . Title >
135- { showSidebar && user && (
118+ { showSidebar && (
136119 < button
137120 onClick = { ( ) => setIsSidebarCollapsed ( ! isSidebarCollapsed ) }
138121 className = "rounded p-1 text-gray-400 hover:bg-[#1F1F1F] hover:text-white"
@@ -146,56 +129,23 @@ export function ChatDialog({
146129 </ div >
147130 </ div >
148131 < div className = "flex items-center gap-4" >
149- { user ? (
150- < div className = "flex items-center gap-3 border-r border-[#1F1F1F] pr-4" >
151- < span className = "text-sm text-gray-300" >
152- { user . displayName || user . email }
153- </ span >
154- { onSignOut && (
155- < button
156- onClick = { onSignOut }
157- className = "rounded p-1.5 text-gray-400 hover:bg-[#1F1F1F] hover:text-white"
158- title = "Sign out"
159- >
160- < IconComponent icon = { LogOut } className = "h-4 w-4" />
161- </ button >
162- ) }
132+ < button
133+ onClick = { handleNewChat }
134+ className = "rounded-lg bg-white px-4 py-1.5 text-sm font-medium text-black hover:bg-gray-100"
135+ >
136+ < div className = "flex items-center gap-2" >
137+ < IconComponent icon = { PenLine } className = "h-4 w-4" />
138+ New chat
163139 </ div >
164- ) : null }
165-
166- { /* Show sign in button if not logged in and not rate limited */ }
167- { ! user && ! isRateLimited && (
140+ </ button >
141+ { currentChatId && (
168142 < button
169- onClick = { onSignOut }
170- className = "rounded-lg bg-blue-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-blue-700 "
143+ onClick = { ( ) => onDeleteChat ?. ( currentChatId ) }
144+ className = "rounded p-2 text-gray-400 hover:bg-[#1F1F1F] hover:text-white "
171145 >
172- Sign in with Google
146+ < IconComponent icon = { Trash2 } className = "h-5 w-5" />
173147 </ button >
174148 ) }
175-
176- { /* Always show New Chat and Delete Chat unless rate limited */ }
177- { ! isRateLimited && (
178- < >
179- < button
180- onClick = { handleNewChat }
181- className = "rounded-lg bg-white px-4 py-1.5 text-sm font-medium text-black hover:bg-gray-100"
182- >
183- < div className = "flex items-center gap-2" >
184- < IconComponent icon = { PenLine } className = "h-4 w-4" />
185- New chat
186- </ div >
187- </ button >
188- { currentChatId && (
189- < button
190- onClick = { ( ) => onDeleteChat ?.( currentChatId ) }
191- className = "rounded p-2 text-gray-400 hover:bg-[#1F1F1F] hover:text-white"
192- >
193- < IconComponent icon = { Trash2 } className = "h-5 w-5" />
194- </ button >
195- ) }
196- </ >
197- ) }
198-
199149 < Dialog . Close className = "rounded p-2 text-gray-400 hover:bg-[#1F1F1F] hover:text-white" >
200150 < IconComponent icon = { X } className = "h-5 w-5" />
201151 </ Dialog . Close >
@@ -210,7 +160,7 @@ export function ChatDialog({
210160 { /* Main Content */ }
211161 < div className = "flex min-h-0 flex-1" >
212162 { /* Sidebar */ }
213- { showSidebar && ( ! user || user ) && ! isRateLimited && (
163+ { showSidebar && (
214164 < ChatSidebar
215165 chats = { chats }
216166 currentChatId = { currentChatId || undefined }
@@ -229,106 +179,62 @@ export function ChatDialog({
229179 < div className = "flex min-h-0 flex-1 flex-col bg-black" >
230180 { /* Messages Area */ }
231181 < div className = "min-h-0 flex-1 overflow-hidden" >
232- { ! user && isRateLimited ? (
233- < div className = "flex h-full items-center justify-center" >
234- < div className = "text-center" >
235- < h2 className = "mb-4 text-xl font-semibold text-white" >
236- Rate Limit Exceeded
237- </ h2 >
238- < p className = "mb-4 text-gray-300" >
239- Please sign in to continue using the chatbot.
240- </ p >
241- < button
242- onClick = { onSignOut }
243- className = "rounded-lg bg-blue-600 px-6 py-2 text-white hover:bg-blue-700"
244- >
245- Sign in with Google
246- </ button >
182+ < ScrollArea . Root className = "h-full" >
183+ < ScrollArea . Viewport
184+ ref = { viewportRef }
185+ className = "h-full w-full"
186+ >
187+ < div className = "flex flex-col gap-4 p-4" >
188+ { hasMoreMessages && (
189+ < button
190+ onClick = { onLoadMore }
191+ className = "mx-auto rounded-lg bg-gray-800 px-4 py-2 text-sm text-gray-300 hover:bg-gray-700"
192+ >
193+ Load more messages
194+ </ button >
195+ ) }
196+ { messages . map ( ( message , index ) => (
197+ < ChatMessage
198+ key = { message . id }
199+ message = { message }
200+ onCopy = { ( ) => onCopyMessage ?.( message . id ) }
201+ onFeedback = { ( feedback ) =>
202+ onMessageFeedback ?.( message . id , feedback )
203+ }
204+ className = { messageClassName }
205+ />
206+ ) ) }
207+ { isTyping && (
208+ < div className = "flex items-center gap-2 text-gray-400" >
209+ < div className = "h-2 w-2 animate-bounce rounded-full bg-gray-400" />
210+ < div className = "h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:0.2s]" />
211+ < div className = "h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:0.4s]" />
212+ </ div >
213+ ) }
247214 </ div >
248- </ div >
249- ) : (
250- < ScrollArea . Root className = "h-full" >
251- < ScrollArea . Viewport
252- ref = { viewportRef }
253- className = "h-full w-full"
254- >
255- < div className = "flex flex-col gap-4 p-4" >
256- { hasMoreMessages && (
257- < button
258- onClick = { onLoadMore }
259- className = "mx-auto rounded-lg bg-gray-800 px-4 py-2 text-sm text-gray-300 hover:bg-gray-700"
260- >
261- Load more messages
262- </ button >
263- ) }
264- { messages . map ( ( message , index ) => (
265- < ChatMessage
266- key = { message . id }
267- message = { message }
268- onCopy = { ( ) => onCopyMessage ?.( message . id ) }
269- onFeedback = { ( feedback ) =>
270- onMessageFeedback ?.( message . id , feedback )
271- }
272- className = { messageClassName }
273- />
274- ) ) }
275- { isTyping && (
276- < div className = "flex items-center gap-2 text-gray-400" >
277- < div className = "h-2 w-2 animate-bounce rounded-full bg-gray-400" />
278- < div className = "h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:0.2s]" />
279- < div className = "h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:0.4s]" />
280- </ div >
281- ) }
282- </ div >
283- </ ScrollArea . Viewport >
284- < ScrollArea . Scrollbar
285- orientation = "vertical"
286- className = "flex w-2.5 touch-none select-none bg-transparent p-[2px]"
287- >
288- < ScrollArea . Thumb className = "relative flex-1 rounded-full bg-gray-800" />
289- </ ScrollArea . Scrollbar >
290- </ ScrollArea . Root >
291- ) }
215+ </ ScrollArea . Viewport >
216+ < ScrollArea . Scrollbar
217+ orientation = "vertical"
218+ className = "flex w-2.5 touch-none select-none bg-transparent p-[2px]"
219+ >
220+ < ScrollArea . Thumb className = "relative flex-1 rounded-full bg-gray-800" />
221+ </ ScrollArea . Scrollbar >
222+ </ ScrollArea . Root >
292223 </ div >
293224
294225 { /* Input Area */ }
295- { ( ! user && ! isRateLimited ) || user ? (
296- < >
297- < div
298- className = "shrink-0 border-t border-[#1F1F1F] bg-[#0F0F0F] px-4"
299- style = { { height : "var(--footer-height)" } }
300- >
301- < ChatInput
302- ref = { chatInputRef }
303- onSend = { onSendMessage }
304- onStop = { onStopGenerating }
305- isLoading = { isGenerating }
306- className = "h-full py-3"
307- />
308- </ div >
309- { /* Disclaimer */ }
310- < div className = "text-center px-4 pb-2 text-xs text-gray-400 bg-[#0F0F0F]" >
311- By messaging AskAptos, you agree to our{ " " }
312- < a
313- href = "https://aptoslabs.com/terms"
314- target = "_blank"
315- rel = "noopener noreferrer"
316- className = "text-blue-400 hover:text-blue-300"
317- >
318- Terms
319- </ a > { " " }
320- and have read our{ " " }
321- < a
322- href = "https://aptoslabs.com/privacy"
323- target = "_blank"
324- rel = "noopener noreferrer"
325- className = "text-blue-400 hover:text-blue-300"
326- >
327- Privacy Policy
328- </ a >
329- </ div >
330- </ >
331- ) : null }
226+ < div
227+ className = "shrink-0 border-t border-[#1F1F1F] bg-[#0F0F0F] px-4"
228+ style = { { height : "var(--footer-height)" } }
229+ >
230+ < ChatInput
231+ ref = { chatInputRef }
232+ onSend = { onSendMessage }
233+ onStop = { onStopGenerating }
234+ isLoading = { isGenerating }
235+ className = "h-full py-3"
236+ />
237+ </ div >
332238 </ div >
333239 </ div >
334240 </ Dialog . Content >
0 commit comments