File size: 9,086 Bytes
24d40b9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

import { useState } from "react";
import { Send, Search } from "lucide-react";
import AppLayout from "@/components/layout/AppLayout";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Avatar } from "@/components/ui/avatar";
import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";
import { motion } from "framer-motion";
import { ThemeToggle } from "@/components/theme/ThemeToggle";

// Sample data for messages
const initialContacts = [
  { id: 1, name: "AI Assistant", avatar: "A", lastMessage: "How can I help with your finances?", time: "10:30 AM", unread: 2 },
  { id: 2, name: "Budget Bot", avatar: "B", lastMessage: "Your weekly spending report is ready", time: "Yesterday", unread: 0 },
  { id: 3, name: "Investment Advisor", avatar: "I", lastMessage: "Consider these stocks for your portfolio", time: "Yesterday", unread: 1 },
  { id: 4, name: "Expense Tracker", avatar: "E", lastMessage: "You've exceeded your dining budget", time: "Monday", unread: 0 },
  { id: 5, name: "Financial Coach", avatar: "F", lastMessage: "Let's review your saving goals", time: "08/12/23", unread: 0 },
];

const initialMessages = [
  { id: 1, sender: "client", text: "Hello! I need some help understanding my recent transactions.", time: "10:30 AM" },
  { id: 2, sender: "me", text: "Hi there! I'd be happy to help you analyze your spending patterns. What specifically would you like to know?", time: "10:32 AM" },
  { id: 3, sender: "client", text: "I noticed some unusual activity in my account", time: "10:33 AM" },
  { id: 4, sender: "me", text: "I can check that for you. Could you tell me which transactions look suspicious?", time: "10:35 AM" },
  { id: 5, sender: "me", text: "Based on your spending history, the transaction at 'Tech Store' for $349.99 is unusual for you.", time: "10:36 AM" },
  { id: 6, sender: "client", text: "Yes, that's the one I was concerned about. I don't remember making that purchase.", time: "10:38 AM" },
];

const Messages = () => {
  const [contacts, setContacts] = useState(initialContacts);
  const [selectedContact, setSelectedContact] = useState(initialContacts[0]);
  const [messages, setMessages] = useState(initialMessages);
  const [newMessage, setNewMessage] = useState("");
  const [searchTerm, setSearchTerm] = useState("");

  const handleSendMessage = () => {
    if (newMessage.trim() === "") return;
    
    const message = {
      id: messages.length + 1,
      sender: "me",
      text: newMessage,
      time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
    };
    
    setMessages([...messages, message]);
    setNewMessage("");
  };

  const filteredContacts = contacts.filter(contact => 
    contact.name.toLowerCase().includes(searchTerm.toLowerCase())
  );

  return (
    <AppLayout>

      <div className="max-w-6xl mx-auto h-full p-4">

        <div className="flex justify-between items-center mb-4">

          <h1 className="text-xl font-bold text-slate-800 dark:text-white">Messages</h1>

          <ThemeToggle />

        </div>

        

        <div className="flex h-[calc(100vh-180px)] rounded-2xl overflow-hidden bg-white/80 dark:bg-violet-darker/90 backdrop-blur-lg border border-slate-200 dark:border-violet-muted/20 shadow-lg">

          {/* Contacts sidebar */}

          <div className="w-full max-w-xs border-r border-slate-200 dark:border-violet-muted/20 hidden md:flex flex-col">

            <div className="p-3 border-b border-slate-200 dark:border-violet-muted/20">

              <div className="relative">

                <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-slate-400 dark:text-violet-light/50 h-4 w-4" />

                <Input

                  placeholder="Search contacts..."

                  className="pl-10 bg-slate-50 dark:bg-violet-darker border-slate-200 dark:border-violet-muted/30 text-slate-800 dark:text-white"

                  value={searchTerm}

                  onChange={(e) => setSearchTerm(e.target.value)}

                />

              </div>

            </div>

            

            <ScrollArea className="flex-1">

              {filteredContacts.map(contact => (

                <div 

                  key={contact.id}

                  className={cn(

                    "p-3 flex items-center gap-3 cursor-pointer hover:bg-slate-50 dark:hover:bg-violet-muted/10 transition-colors",

                    selectedContact.id === contact.id ? "bg-slate-50 dark:bg-violet-muted/10" : ""

                  )}

                  onClick={() => setSelectedContact(contact)}

                >

                  <Avatar className={cn(

                    "h-10 w-10 text-white",

                    selectedContact.id === contact.id 

                      ? "bg-primary dark:bg-violet" 

                      : "bg-blue-600 dark:bg-violet-muted"

                  )}>

                    <div>{contact.avatar}</div>

                  </Avatar>

                  

                  <div className="flex-1 min-w-0">

                    <div className="flex justify-between items-center">

                      <span className="font-medium truncate text-slate-800 dark:text-white">{contact.name}</span>

                      <span className="text-xs text-slate-500 dark:text-violet-light/70">{contact.time}</span>

                    </div>

                    <p className="text-sm text-slate-500 dark:text-violet-light/50 truncate">{contact.lastMessage}</p>

                  </div>

                  

                  {contact.unread > 0 && (

                    <div className="bg-blue-600 dark:bg-violet text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">

                      {contact.unread}

                    </div>

                  )}

                </div>

              ))}

            </ScrollArea>

          </div>

          

          {/* Chat area */}

          <div className="flex-1 flex flex-col">

            <div className="p-3 border-b border-slate-200 dark:border-violet-muted/20 flex items-center gap-3">

              <Avatar className="h-8 w-8 bg-blue-600 dark:bg-violet text-white md:hidden">

                <div>{selectedContact.avatar}</div>

              </Avatar>

              <div>

                <h3 className="font-medium text-slate-800 dark:text-white">{selectedContact.name}</h3>

              </div>

            </div>

            

            <ScrollArea className="flex-1 p-4">

              <div className="space-y-4">

                {messages.map((message, index) => (

                  <motion.div 

                    key={message.id} 

                    initial={{ opacity: 0, y: 10 }}

                    animate={{ opacity: 1, y: 0 }}

                    transition={{ duration: 0.3, delay: index * 0.1 }}

                    className={cn(

                      "flex",

                      message.sender === "me" ? "justify-end" : "justify-start"

                    )}

                  >

                    <div 

                      className={cn(

                        "max-w-[80%] p-3 rounded-2xl shadow-sm",

                        message.sender === "me" 

                          ? "bg-blue-600 dark:bg-violet text-white rounded-tr-none" 

                          : "bg-slate-100 dark:bg-violet-muted/30 text-slate-800 dark:text-white rounded-tl-none"

                      )}

                    >

                      <p>{message.text}</p>

                      <span className={cn(

                        "text-xs block mt-1",

                        message.sender === "me" 

                          ? "text-white/70" 

                          : "text-slate-500 dark:text-violet-light/70"

                      )}>

                        {message.time}

                      </span>

                    </div>

                  </motion.div>

                ))}

              </div>

            </ScrollArea>

            

            <div className="p-3 border-t border-slate-200 dark:border-violet-muted/20 flex items-center gap-2">

              <Input

                placeholder="Type a message..."

                value={newMessage}

                onChange={(e) => setNewMessage(e.target.value)}

                onKeyDown={(e) => {

                  if (e.key === "Enter") {

                    handleSendMessage();

                  }

                }}

                className="flex-1 bg-slate-50 dark:bg-violet-darker border-slate-200 dark:border-violet-muted/30 text-slate-800 dark:text-white"

              />

              <Button size="icon" className="bg-blue-600 hover:bg-blue-700 dark:bg-violet dark:hover:bg-violet-dark" onClick={handleSendMessage}>

                <Send size={18} />

              </Button>

            </div>

          </div>

        </div>

      </div>

    </AppLayout>
  );
};

export default Messages;