1 import { useState } from "react";
2 import { Button } from "@/components/ui/button";
3 import { Input } from "@/components/ui/input";
4 import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
5 import { Bot, Send, X, User, Sparkles } from "lucide-react";
6 import { motion, AnimatePresence } from "framer-motion";
7 import { ScrollArea } from "@/components/ui/scroll-area";
8
9 type Message = {
10 role: "user" | "assistant";
11 content: string;
12 };
13
14 export default function AIAssistant() {
15 const [isOpen, setIsOpen] = useState(false);
16 const [messages, setMessages] = useState<Message[]>([
17 { role: "assistant", content: "Hello! I'm your JCRguru AI Assistant. How can I help you with your repair today?" }
18 ]);
19 const [input, setInput] = useState("");
20 const [isTyping, setIsTyping] = useState(false);
21
22 const handleSend = async () => {
23 if (!input.trim()) return;
24
25 const userMessage: Message = { role: "user", content: input };
26 setMessages(prev => [...prev, userMessage]);
27 setInput("");
28 setIsTyping(true);
29
30 // Mock AI Response - In production, this would call your server/AI API
31 setTimeout(() => {
32 const assistantMessage: Message = {
33 role: "assistant",
34 content: `I've analyzed your query about "${input}". Based on our technical database, I recommend checking the voltage rails first. Would you like me to pull up the relevant circuit diagram?`
35 };
36 setMessages(prev => [...prev, assistantMessage]);
37 setIsTyping(false);
38 }, 1500);
39 };
40
41 return (
42 <>
43 {/* Floating Toggle Button */}
44 <button
45 onClick={() => setIsOpen(true)}
46 className="fixed bottom-24 right-6 h-14 w-14 rounded-2xl bg-primary text-white shadow-glass flex items-center justify-center hover:scale-110 transition-transform z-40"
47 >
48 <Bot className="h-6 w-6" />
49 <div className="absolute -top-1 -right-1 h-4 w-4 bg-emerald-500 rounded-full border-2 border-background animate-pulse" />
50 </button>
51
52 <AnimatePresence>
53 {isOpen && (
54 <motion.div
55 initial={{ opacity: 0, y: 20, scale: 0.95 }}
56 animate={{ opacity: 1, y: 0, scale: 1 }}
57 exit={{ opacity: 0, y: 20, scale: 0.95 }}
58 className="fixed bottom-24 right-6 w-[90vw] max-w-[400px] h-[500px] z-50 flex flex-col"
59 >
60 <Card className="flex-1 border-border/40 shadow-glass-lg rounded-[2.5rem] overflow-hidden bg-card/60 backdrop-blur-3xl flex flex-col">
61 <CardHeader className="bg-primary/10 border-b border-border/40 py-4 flex flex-row items-center justify-between">
62 <div className="flex items-center gap-3">
63 <div className="h-10 w-10 rounded-xl bg-primary flex items-center justify-center">
64 <Bot className="h-5 w-5 text-white" />
65 </div>
66 <div>
67 <CardTitle className="text-sm font-bold">Technical AI</CardTitle>
68 <div className="flex items-center gap-1 text-[10px] text-emerald-500 font-bold uppercase">
69 <div className="h-1.5 w-1.5 rounded-full bg-emerald-500" /> Online
70 </div>
71 </div>
72 </div>
73 <Button variant="ghost" size="icon" onClick={() => setIsOpen(false)} className="rounded-full h-8 w-8">
74 <X className="h-4 w-4" />
75 </Button>
76 </CardHeader>
77
78 <CardContent className="flex-1 flex flex-col p-0">
79 <ScrollArea className="flex-1 p-4">
80 <div className="space-y-4">
81 {messages.map((msg, i) => (
82 <div key={i} className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"}`}>
83 <div className={`max-w-[80%] p-4 rounded-[1.5rem] text-sm ${
84 msg.role === "user"
85 ? "bg-primary text-white rounded-tr-none"
86 : "bg-muted/40 backdrop-blur-sm rounded-tl-none"
87 }`}>
88 {msg.content}
89 </div>
90 </div>
91 ))}
92 {isTyping && (
93 <div className="flex justify-start">
94 <div className="bg-muted/40 p-4 rounded-[1.5rem] rounded-tl-none flex gap-1">
95 <div className="h-1.5 w-1.5 bg-muted-foreground/40 rounded-full animate-bounce" />
96 <div className="h-1.5 w-1.5 bg-muted-foreground/40 rounded-full animate-bounce delay-100" />
97 <div className="h-1.5 w-1.5 bg-muted-foreground/40 rounded-full animate-bounce delay-200" />
98 </div>
99 </div>
100 )}
101 </div>
102 </ScrollArea>
103
104 <div className="p-4 border-t border-border/40 bg-muted/20">
105 <div className="flex gap-2">
106 <Input
107 value={input}
108 onChange={(e) => setInput(e.target.value)}
109 onKeyPress={(e) => e.key === "Enter" && handleSend()}
110 placeholder="Ask for repair help..."
111 className="rounded-xl bg-background border-none focus-visible:ring-primary/20 h-11"
112 />
113 <Button onClick={handleSend} className="rounded-xl h-11 w-11 p-0 shadow-lg">
114 <Send className="h-4 w-4" />
115 </Button>
116 </div>
117 </div>
118 </CardContent>
119 </Card>
120 </motion.div>
121 )}
122 </AnimatePresence>
123 </>
124 );
125 }