Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit 186dbcd

Browse files
committed
make firebase login optional
1 parent eac46d1 commit 186dbcd

File tree

3 files changed

+72
-38
lines changed

3 files changed

+72
-38
lines changed

apps/nextra/components/chat-widget/chat-dialog.tsx

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface ChatDialogProps extends ChatWidgetProps {
2727
photoURL?: string | null;
2828
} | null;
2929
onSignOut?: () => void;
30+
isRateLimited?: boolean;
3031
}
3132

3233
const IconComponent = ({
@@ -63,6 +64,7 @@ export function ChatDialog({
6364
onToggleFastMode,
6465
user,
6566
onSignOut,
67+
isRateLimited = false,
6668
}: ChatDialogProps) {
6769
const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
6870
const chatInputRef = useRef<HTMLTextAreaElement>(null);
@@ -155,23 +157,35 @@ export function ChatDialog({
155157
</div>
156158
<div className="flex items-center gap-4">
157159
{user ? (
160+
<div className="flex items-center gap-3 border-r border-[#1F1F1F] pr-4">
161+
<span className="text-sm text-gray-300">
162+
{user.displayName || user.email}
163+
</span>
164+
{onSignOut && (
165+
<button
166+
onClick={onSignOut}
167+
className="rounded p-1.5 text-gray-400 hover:bg-[#1F1F1F] hover:text-white"
168+
title="Sign out"
169+
>
170+
<IconComponent icon={LogOut} className="h-4 w-4" />
171+
</button>
172+
)}
173+
</div>
174+
) : null}
175+
176+
{/* Show sign in button if not logged in and not rate limited */}
177+
{!user && !isRateLimited && (
178+
<button
179+
onClick={onSignOut}
180+
className="rounded-lg bg-blue-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-blue-700"
181+
>
182+
Sign in with Google
183+
</button>
184+
)}
185+
186+
{/* Always show New Chat and Delete Chat unless rate limited */}
187+
{!isRateLimited && (
158188
<>
159-
<div className="flex items-center gap-3 border-r border-[#1F1F1F] pr-4">
160-
<div className="flex items-center gap-2">
161-
<span className="text-sm text-gray-300">
162-
{user.displayName || user.email}
163-
</span>
164-
</div>
165-
{onSignOut && (
166-
<button
167-
onClick={onSignOut}
168-
className="rounded p-1.5 text-gray-400 hover:bg-[#1F1F1F] hover:text-white"
169-
title="Sign out"
170-
>
171-
<IconComponent icon={LogOut} className="h-4 w-4" />
172-
</button>
173-
)}
174-
</div>
175189
<button
176190
onClick={handleNewChat}
177191
className="rounded-lg bg-white px-4 py-1.5 text-sm font-medium text-black hover:bg-gray-100"
@@ -190,7 +204,8 @@ export function ChatDialog({
190204
</button>
191205
)}
192206
</>
193-
) : null}
207+
)}
208+
194209
<Dialog.Close className="rounded p-2 text-gray-400 hover:bg-[#1F1F1F] hover:text-white">
195210
<IconComponent icon={X} className="h-5 w-5" />
196211
</Dialog.Close>
@@ -205,7 +220,7 @@ export function ChatDialog({
205220
{/* Main Content */}
206221
<div className="flex min-h-0 flex-1">
207222
{/* Sidebar */}
208-
{showSidebar && user && (
223+
{showSidebar && (!user || user) && !isRateLimited && (
209224
<ChatSidebar
210225
chats={chats}
211226
currentChatId={currentChatId || undefined}
@@ -224,12 +239,15 @@ export function ChatDialog({
224239
<div className="flex min-h-0 flex-1 flex-col bg-black">
225240
{/* Messages Area */}
226241
<div className="min-h-0 flex-1 overflow-hidden">
227-
{!user ? (
242+
{!user && isRateLimited ? (
228243
<div className="flex h-full items-center justify-center">
229244
<div className="text-center">
230245
<h2 className="mb-4 text-xl font-semibold text-white">
231-
Sign in to Start Chatting
246+
Rate Limit Exceeded
232247
</h2>
248+
<p className="mb-4 text-gray-300">
249+
Please sign in to continue using the chatbot.
250+
</p>
233251
<button
234252
onClick={onSignOut}
235253
className="rounded-lg bg-blue-600 px-6 py-2 text-white hover:bg-blue-700"
@@ -248,12 +266,12 @@ export function ChatDialog({
248266
{hasMoreMessages && (
249267
<button
250268
onClick={onLoadMore}
251-
className="text-sm text-gray-400 hover:text-white"
269+
className="mx-auto rounded-lg bg-gray-800 px-4 py-2 text-sm text-gray-300 hover:bg-gray-700"
252270
>
253-
Load more
271+
Load more messages
254272
</button>
255273
)}
256-
{messages.map((message) => (
274+
{messages.map((message, index) => (
257275
<ChatMessage
258276
key={message.id}
259277
message={message}
@@ -264,22 +282,27 @@ export function ChatDialog({
264282
className={messageClassName}
265283
/>
266284
))}
267-
{(isLoading || isTyping) && (
268-
<div className="flex items-center text-gray-400">
269-
<div className="animate-pulse">...</div>
285+
{isTyping && (
286+
<div className="flex items-center gap-2 text-gray-400">
287+
<div className="h-2 w-2 animate-bounce rounded-full bg-gray-400" />
288+
<div className="h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:0.2s]" />
289+
<div className="h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:0.4s]" />
270290
</div>
271291
)}
272292
</div>
273293
</ScrollArea.Viewport>
274-
<ScrollArea.Scrollbar orientation="vertical">
275-
<ScrollArea.Thumb className="z-50 w-1.5 rounded-full bg-gray-700" />
294+
<ScrollArea.Scrollbar
295+
orientation="vertical"
296+
className="flex w-2.5 touch-none select-none bg-transparent p-[2px]"
297+
>
298+
<ScrollArea.Thumb className="relative flex-1 rounded-full bg-gray-800" />
276299
</ScrollArea.Scrollbar>
277300
</ScrollArea.Root>
278301
)}
279302
</div>
280303

281304
{/* Input Area */}
282-
{user && (
305+
{(!user && !isRateLimited) || user ? (
283306
<div
284307
className="shrink-0 border-t border-[#1F1F1F] bg-[#0F0F0F] px-4"
285308
style={{ height: "var(--footer-height)" }}
@@ -292,7 +315,7 @@ export function ChatDialog({
292315
className="h-full py-3"
293316
/>
294317
</div>
295-
)}
318+
) : null}
296319
</div>
297320
</div>
298321
</Dialog.Content>

apps/nextra/components/chat-widget/chat-message.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,6 @@ export function ChatMessage({
6060
</pre>
6161
);
6262
},
63-
p: ({ children }) => <p className="text-white">{children}</p>,
64-
li: ({ children }) => <li className="text-white">{children}</li>,
65-
a: ({ children, href }) => (
66-
<a href={href} className="text-blue-400 hover:text-blue-300">
67-
{children}
68-
</a>
69-
),
7063
}}
7164
>
7265
{message.content}

apps/nextra/components/chat-widget/index.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@ function ChatDialogContainer() {
4141
const [isAuthenticating, setIsAuthenticating] = useState(false);
4242
const [error, setError] = useState<string | null>(null);
4343
const [user, setUser] = useState<User | null>(null);
44+
const [isRateLimited, setIsRateLimited] = useState(false);
4445

4546
useEffect(() => {
4647
if (!auth) return;
4748
const unsubscribe = auth.onAuthStateChanged((user) => {
4849
setUser(user);
50+
if (user) {
51+
setIsRateLimited(false);
52+
}
4953
});
5054
return () => unsubscribe();
5155
}, []);
@@ -73,13 +77,26 @@ function ChatDialogContainer() {
7377
}
7478
};
7579

80+
const handleSendMessage = async (message: string) => {
81+
try {
82+
await sendMessage(message);
83+
} catch (error: any) {
84+
if (error?.response?.status === 429) {
85+
setIsRateLimited(true);
86+
setError("Rate limit exceeded. Please sign in to continue.");
87+
} else {
88+
setError("Failed to send message. Please try again.");
89+
}
90+
}
91+
};
92+
7693
return (
7794
<>
7895
<ChatDialog
7996
open={isOpen}
8097
onOpenChange={setIsOpen}
8198
messages={messages}
82-
onSendMessage={sendMessage}
99+
onSendMessage={handleSendMessage}
83100
isLoading={isLoading || isAuthenticating}
84101
isGenerating={isGenerating}
85102
isTyping={isTyping}
@@ -99,6 +116,7 @@ function ChatDialogContainer() {
99116
onToggleFastMode={setFastMode}
100117
user={user}
101118
onSignOut={handleSignInOrOut}
119+
isRateLimited={isRateLimited}
102120
/>
103121
{error && (
104122
<div className="fixed bottom-4 right-4 rounded-lg bg-red-500 px-4 py-2 text-white">

0 commit comments

Comments
 (0)