ChenyuRabbitLove's picture
feat: add embeddedable chat component
c4412d0
// External dependencies
import Image from "next/image";
import { MessageSquareShare } from "lucide-react";
// Internal UI components
import { Card, CardContent } from "@/components/ui/card";
import { ChatBot } from "@/app/(audiences)/for-students/data/chatbots";
// Component props interface
interface ChatBotCardProps {
chatbot: ChatBot;
}
/**
* ChatBotCard - A responsive card component that displays chatbot information
* Features:
* - Optimized image loading with WebP support and PNG fallback
* - Hover animations and transitions
* - Gradient text effects
* - Decorative corner accent
*/
export default function ChatBotCard({ chatbot }: ChatBotCardProps) {
// Extract base name from icon path for use in both WebP and PNG sources
const baseIconName = chatbot.icon.split(".")[0];
return (
<Card className="group relative overflow-hidden bg-background-primary/50 shadow-sm transition-all hover:shadow-xl hover:-translate-y-1 backdrop-blur-sm border-2 border-border/40 hover:border-primary/20 duration-300 aspect-square">
<CardContent className="p-8 h-full flex flex-col">
{/* Avatar section with modern image format optimization */}
<div className="flex-shrink-0 mb-6">
<picture>
{/* WebP format for modern browsers */}
<source
srcSet={`/chatbots/${baseIconName}.webp`}
type="image/webp"
/>
{/* PNG fallback for older browsers */}
<Image
src={`/chatbots/${baseIconName}.png`}
alt={chatbot.title}
width={64}
height={64}
className="relative rounded-lg transform group-hover:scale-105 transition duration-300"
/>
</picture>
</div>
{/* Main content section with flex layout for dynamic spacing */}
<div className="flex-1 flex flex-col">
{/* Title with gradient text effect and hover animation */}
<h3 className="text-xl font-bold text-text-primary truncate bg-gradient-to-r from-[#FF6B6B] via-[#4ECDC4] to-[#45B7D1] bg-clip-text text-transparent group-hover:tracking-wide transition-all duration-300 mb-3">
{chatbot.title}
</h3>
{/* Description with line clamping for consistent card heights */}
<p className="text-base text-text-secondary line-clamp-3 mb-6 flex-1 leading-relaxed">
{chatbot.description}
</p>
{/* Interactive chat button with hover and active states */}
<button
className="flex-shrink-0 inline-flex items-center justify-center rounded-full bg-primary w-12 h-12 text-white transition-all duration-300 hover:scale-110 active:scale-95 hover:bg-primary/90 ml-auto"
aria-label="開始對話"
>
<MessageSquareShare className="w-6 h-6 group-hover:animate-pulse" />
</button>
</div>
</CardContent>
{/* Decorative gradient corner accent with hover animation */}
<div className="absolute top-0 right-0 w-20 h-20 overflow-hidden">
<div className="absolute top-0 right-0 w-16 h-16 bg-gradient-to-bl from-primary/10 via-primary/5 to-transparent transform rotate-45 translate-x-10 -translate-y-10 group-hover:translate-x-8 group-hover:-translate-y-8 transition-transform duration-300" />
</div>
</Card>
);
}