134 lines
4.5 KiB
TypeScript
134 lines
4.5 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { MessageCircle, Sparkles, X } from 'lucide-react';
|
|
|
|
interface ChatPromptBubbleProps {
|
|
message: string;
|
|
isVisible: boolean;
|
|
onClose: () => void;
|
|
onChatClick: () => void;
|
|
autoCloseDuration?: number; // milliseconds
|
|
}
|
|
|
|
export default function ChatPromptBubble({
|
|
message,
|
|
isVisible,
|
|
onClose,
|
|
onChatClick,
|
|
autoCloseDuration = 6000
|
|
}: ChatPromptBubbleProps) {
|
|
const [isAnimatingOut, setIsAnimatingOut] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (isVisible) {
|
|
// Auto-close after duration
|
|
const timer = setTimeout(() => {
|
|
handleClose();
|
|
}, autoCloseDuration);
|
|
|
|
return () => clearTimeout(timer);
|
|
}
|
|
}, [isVisible, autoCloseDuration]);
|
|
|
|
const handleClose = () => {
|
|
setIsAnimatingOut(true);
|
|
// Wait for animation to complete before actually closing
|
|
setTimeout(() => {
|
|
setIsAnimatingOut(false);
|
|
onClose();
|
|
}, 300);
|
|
};
|
|
|
|
const handleChatClick = () => {
|
|
handleClose();
|
|
onChatClick();
|
|
};
|
|
|
|
if (!isVisible && !isAnimatingOut) return null;
|
|
|
|
return (
|
|
<div
|
|
className={`fixed bottom-24 right-4 sm:right-6 z-[200] max-w-[320px] transition-all duration-300 ${
|
|
isAnimatingOut
|
|
? 'animate-out slide-out-to-right-4 fade-out'
|
|
: 'animate-in slide-in-from-right-4 fade-in'
|
|
}`}
|
|
style={{
|
|
bottom: 'max(6rem, calc(6rem + env(safe-area-inset-bottom)))'
|
|
}}
|
|
>
|
|
{/* Chat Bubble Container */}
|
|
<div className="relative group">
|
|
{/* Glow Effect */}
|
|
<div className="absolute -inset-1 bg-gradient-to-r from-blue-500 to-purple-500 rounded-2xl blur opacity-30 group-hover:opacity-50 animate-pulse"></div>
|
|
|
|
{/* Main Bubble */}
|
|
<div className="relative bg-gradient-to-br from-blue-600 to-purple-600 rounded-2xl shadow-2xl overflow-hidden border border-white/20">
|
|
{/* Shimmer Effect */}
|
|
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent -translate-x-full animate-[shimmer_2s_infinite]"></div>
|
|
|
|
{/* Close Button */}
|
|
<button
|
|
onClick={handleClose}
|
|
className="absolute top-2 right-2 p-1 rounded-full bg-white/10 hover:bg-white/20 transition-colors"
|
|
aria-label="Cerrar"
|
|
>
|
|
<X size={14} className="text-white" />
|
|
</button>
|
|
|
|
{/* Content */}
|
|
<div className="p-4 pr-8">
|
|
{/* AI Icon with Animation */}
|
|
<div className="flex items-start gap-3 mb-3">
|
|
<div className="relative">
|
|
{/* Pulsing Ring */}
|
|
<div className="absolute inset-0 w-10 h-10 bg-white/20 rounded-full animate-ping"></div>
|
|
<div className="relative w-10 h-10 bg-white/20 rounded-full flex items-center justify-center backdrop-blur-sm">
|
|
<Sparkles size={20} className="text-white animate-pulse" />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Message */}
|
|
<div className="flex-1 pt-1">
|
|
<p className="text-white text-sm font-medium leading-relaxed">
|
|
{message}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{/* CTA Button */}
|
|
<button
|
|
onClick={handleChatClick}
|
|
className="w-full mt-2 flex items-center justify-center gap-2 bg-white/20 hover:bg-white/30 backdrop-blur-sm text-white font-semibold py-2.5 px-4 rounded-lg transition-all duration-200 hover:scale-[1.02] active:scale-[0.98] border border-white/30"
|
|
>
|
|
<MessageCircle size={18} />
|
|
<span>Chatear ahora</span>
|
|
<span className="text-lg">→</span>
|
|
</button>
|
|
</div>
|
|
|
|
{/* Badge "IA En Línea" */}
|
|
<div className="absolute -top-2 -left-2">
|
|
<div className="bg-green-500 text-white text-xs font-bold px-2 py-1 rounded-full shadow-lg flex items-center gap-1 border border-white/30">
|
|
<div className="w-1.5 h-1.5 bg-white rounded-full animate-pulse"></div>
|
|
<span>IA En Línea</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Tail/Pointer */}
|
|
<div className="absolute -bottom-2 right-6 w-4 h-4 bg-gradient-to-br from-blue-600 to-purple-600 rotate-45 border-r border-b border-white/20"></div>
|
|
</div>
|
|
|
|
{/* Shimmer Keyframe */}
|
|
<style jsx>{`
|
|
@keyframes shimmer {
|
|
0% { transform: translateX(-100%); }
|
|
100% { transform: translateX(100%); }
|
|
}
|
|
`}</style>
|
|
</div>
|
|
);
|
|
}
|