← back to Dear Bubbe Nextjs
components/MobileStartOverlay.tsx
169 lines
'use client'
import { useState, useEffect } from 'react'
interface MobileStartOverlayProps {
onStart: () => void
show: boolean
}
export default function MobileStartOverlay({ onStart, show }: MobileStartOverlayProps) {
const [isVisible, setIsVisible] = useState(false)
const [hasInteracted, setHasInteracted] = useState(false)
useEffect(() => {
// Check if user has already interacted in this session
const interacted = sessionStorage.getItem('bubbeInteracted')
if (interacted) {
setHasInteracted(true)
return
}
// Show overlay if requested
if (show && !hasInteracted) {
setIsVisible(true)
}
}, [show, hasInteracted])
const handleStart = async () => {
console.log('[MobileOverlay] 📱 User tapped to start - enabling voice features...')
sessionStorage.setItem('bubbeInteracted', 'true')
setHasInteracted(true)
setIsVisible(false)
// Call the start function which will unlock audio and start the conversation
try {
await onStart()
console.log('[MobileOverlay] ✅ Voice features enabled successfully')
} catch (error) {
console.error('[MobileOverlay] ❌ Failed to enable voice features:', error)
}
}
if (!isVisible || hasInteracted) return null
return (
<div
className="fixed inset-0 z-50 bg-gradient-to-br from-purple-900/95 via-pink-800/95 to-indigo-900/95 backdrop-blur-md flex items-center justify-center animate-fade-in cursor-pointer"
onClick={handleStart}
onTouchStart={(e) => {
e.preventDefault()
handleStart()
}}
>
<div className="max-w-md mx-4 text-center" onClick={(e) => e.stopPropagation()}>
{/* Animated Bubbe Avatar */}
<div className="mb-6 relative">
<div className="w-32 h-32 mx-auto bg-gradient-to-br from-pink-400 to-purple-600 rounded-full animate-pulse shadow-2xl flex items-center justify-center">
<span className="text-6xl animate-bounce-slow">👵</span>
</div>
<div className="absolute -bottom-2 left-1/2 transform -translate-x-1/2">
<div className="bg-white/20 backdrop-blur-sm px-3 py-1 rounded-full">
<span className="text-xs text-white font-semibold">TAP TO START</span>
</div>
</div>
</div>
{/* Welcome Text */}
<h1 className="text-3xl font-bold text-white mb-3 animate-slide-up">
Tap anywhere to begin
</h1>
<p className="text-lg text-pink-100 mb-6 animate-slide-up animation-delay-200">
Bubbe is ready to kvetch with you!
</p>
{/* Features */}
<div className="flex justify-center gap-6 mb-8 animate-slide-up animation-delay-400">
<div className="flex items-center gap-2 text-white/80">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" />
</svg>
<span className="text-sm">Voice Chat</span>
</div>
<div className="flex items-center gap-2 text-white/80">
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span className="text-sm">Sass & Wisdom</span>
</div>
</div>
{/* Start Button - Optimized for mobile touch (min 48px height) */}
<button
onClick={handleStart}
className="relative group animate-slide-up animation-delay-600 min-w-[200px]"
>
<div className="absolute inset-0 bg-gradient-to-r from-pink-500 to-purple-600 rounded-full blur-lg opacity-75 group-hover:opacity-100 transition-opacity animate-pulse"></div>
<div className="relative px-8 py-5 min-h-[48px] bg-gradient-to-r from-pink-500 to-purple-600 text-white font-bold text-lg rounded-full shadow-2xl hover:shadow-3xl transform hover:scale-105 transition-all flex items-center justify-center">
<span className="flex items-center gap-3">
<svg className="w-6 h-6 animate-pulse" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" />
</svg>
Start Talking to Bubbe
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</span>
</div>
</button>
{/* Privacy Note */}
<p className="mt-6 text-xs text-white/50 animate-fade-in animation-delay-800">
Microphone permission required for voice chat
</p>
</div>
<style jsx>{`
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes bounce-slow {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.animate-fade-in {
animation: fade-in 0.5s ease-out;
}
.animate-slide-up {
animation: slide-up 0.6s ease-out both;
}
.animate-bounce-slow {
animation: bounce-slow 2s ease-in-out infinite;
}
.animation-delay-200 {
animation-delay: 0.2s;
}
.animation-delay-400 {
animation-delay: 0.4s;
}
.animation-delay-600 {
animation-delay: 0.6s;
}
.animation-delay-800 {
animation-delay: 0.8s;
}
`}</style>
</div>
)
}