← back to Dear Bubbe Nextjs
feat(bubbe.ai): free chat — 3 messages before Google sign-in (mobile-first)
c7ca51c24d9c4cce76edb2a80ca5444824a322c2 · 2026-07-16 16:53:14 -0700 · Steve Abrams
- page.tsx: render chat for guests instead of hard-redirecting to /auth/signin
- MobileBubbe/DesktopBubbe: gate send after 3 free messages (localStorage), then trigger Google sign-in
- restores the intended '3 free messages' onboarding so mobile users can chat immediately
Files touched
M app/page.tsxM components/DesktopBubbe.tsxM components/MobileBubbe.tsx
Diff
commit c7ca51c24d9c4cce76edb2a80ca5444824a322c2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jul 16 16:53:14 2026 -0700
feat(bubbe.ai): free chat — 3 messages before Google sign-in (mobile-first)
- page.tsx: render chat for guests instead of hard-redirecting to /auth/signin
- MobileBubbe/DesktopBubbe: gate send after 3 free messages (localStorage), then trigger Google sign-in
- restores the intended '3 free messages' onboarding so mobile users can chat immediately
---
app/page.tsx | 26 +++++++++-----------------
components/DesktopBubbe.tsx | 21 +++++++++++++++++++--
components/MobileBubbe.tsx | 22 +++++++++++++++++++---
3 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/app/page.tsx b/app/page.tsx
index a9aae6e..7987913 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -12,29 +12,21 @@ export default function Home() {
useEffect(() => {
if (status === 'loading') return
-
- // Redirect to sign-in if not authenticated
- if (!session) {
- router.push('/auth/signin')
- return
- }
-
- // Check if profile setup is complete
- const profileData = localStorage.getItem('bubbeProfile')
- if (!profileData) {
- router.push('/auth/profile-setup')
+
+ // Guests chat freely (gated after a few messages inside the chat component).
+ // Only signed-in users without a profile get sent to profile setup.
+ if (session) {
+ const profileData = localStorage.getItem('bubbeProfile')
+ if (!profileData) {
+ router.push('/auth/profile-setup')
+ }
}
}, [session, status, router])
- // Show loading while checking auth
+ // Show loading only while auth state is resolving
if (status === 'loading') {
return <LoadingScreen />
}
- // Show loading while redirecting
- if (!session) {
- return <LoadingScreen />
- }
-
return <BubbeResponsive />
}
\ No newline at end of file
diff --git a/components/DesktopBubbe.tsx b/components/DesktopBubbe.tsx
index 8271672..6497593 100644
--- a/components/DesktopBubbe.tsx
+++ b/components/DesktopBubbe.tsx
@@ -1,8 +1,10 @@
'use client'
import { useState, useEffect, useRef } from 'react'
+import { useSession, signIn } from 'next-auth/react'
export default function DesktopBubbe() {
+ const { data: session } = useSession()
const [messages, setMessages] = useState<Array<{id: string, role: 'user' | 'assistant', content: string}>>([])
const [textInput, setTextInput] = useState('')
const [isLoading, setIsLoading] = useState(false)
@@ -165,13 +167,28 @@ export default function DesktopBubbe() {
const handleSendMessage = async (text: string) => {
if (!text.trim()) return
-
+
+ // Free-chat gate: guests get 3 free messages, then Google sign-in is required.
+ if (!session) {
+ const used = parseInt(localStorage.getItem('bubbeFreeMessages') || '0', 10)
+ if (used >= 3) {
+ setMessages(prev => [...prev, {
+ id: Date.now().toString(),
+ role: 'assistant' as const,
+ content: "Enough freebies, bubbeleh! Sign in with Google so I remember who you are — then we can really talk. Nu, what are you waiting for?"
+ }])
+ signIn('google')
+ return
+ }
+ localStorage.setItem('bubbeFreeMessages', String(used + 1))
+ }
+
const userMessage = {
id: Date.now().toString(),
role: 'user' as const,
content: text.trim()
}
-
+
setMessages(prev => [...prev, userMessage])
setTextInput('')
setIsLoading(true)
diff --git a/components/MobileBubbe.tsx b/components/MobileBubbe.tsx
index f157e0a..5c160c3 100644
--- a/components/MobileBubbe.tsx
+++ b/components/MobileBubbe.tsx
@@ -1,7 +1,7 @@
'use client'
import { useState, useEffect, useRef } from 'react'
-import { useSession, signOut } from 'next-auth/react'
+import { useSession, signOut, signIn } from 'next-auth/react'
export default function MobileBubbe() {
// Start with welcome screen
@@ -151,13 +151,29 @@ export default function MobileBubbe() {
const handleSendMessage = async (text: string) => {
if (!text.trim()) return
-
+
+ // Free-chat gate: guests get 3 free messages, then Google sign-in is required
+ // (keeps memory/profiles for signed-in users without blocking the first hello).
+ if (!session) {
+ const used = parseInt(localStorage.getItem('bubbeFreeMessages') || '0', 10)
+ if (used >= 3) {
+ setMessages(prev => [...prev, {
+ id: Date.now().toString(),
+ role: 'assistant' as const,
+ content: "Enough freebies, bubbeleh! Sign in with Google so I remember who you are — then we can really talk. Nu, what are you waiting for?"
+ }])
+ signIn('google')
+ return
+ }
+ localStorage.setItem('bubbeFreeMessages', String(used + 1))
+ }
+
const userMessage = {
id: Date.now().toString(),
role: 'user' as const,
content: text.trim()
}
-
+
setMessages(prev => [...prev, userMessage])
setTextInput('')
setIsLoading(true)
← 242ce89 deploy(bubbe.ai): OpenAI-primary chat, drop standalone for n
·
back to Dear Bubbe Nextjs
·
auto-save: 2026-07-16T17:13:50 (2 files) — components/Deskto bffe4c6 →