anotherath commited on
Commit
fe7c2ba
·
1 Parent(s): 4d613a5

update phần avatar, update phần create space

Browse files
src/components/ChatArea.jsx CHANGED
@@ -244,10 +244,15 @@ function ChatArea({ activeView, activeRoom }) {
244
  // Convert API messages to UI format
245
  const apiMessages = sortedDmMessages.map((msg) => {
246
  const isOwn = msg.sender_id === currentUser?.id;
247
- const sender = isOwn ? "You" : (msg.sender?.display_name || "Unknown");
 
 
248
  const avatar = isOwn
249
- ? (currentUser?.name?.charAt(0).toUpperCase() || "Y")
250
  : (msg.sender?.display_name?.charAt(0).toUpperCase() || "?");
 
 
 
251
 
252
  const date = new Date(msg.created_at);
253
  const timestamp = isNaN(date.getTime())
@@ -258,6 +263,7 @@ function ChatArea({ activeView, activeRoom }) {
258
  id: msg.id,
259
  sender,
260
  avatar,
 
261
  timestamp,
262
  content: msg.content,
263
  isPinned: false,
@@ -323,8 +329,8 @@ function ChatArea({ activeView, activeRoom }) {
323
  const tempId = `temp-${Date.now()}`;
324
  const optimisticMsg = {
325
  id: tempId,
326
- sender: "You",
327
- avatar: currentUser?.name?.charAt(0).toUpperCase() || "Y",
328
  timestamp: new Date().toLocaleTimeString("vi-VN", {
329
  hour: "2-digit",
330
  minute: "2-digit",
@@ -357,7 +363,7 @@ function ChatArea({ activeView, activeRoom }) {
357
  created_at: optimisticMsg.created_at,
358
  sender: {
359
  id: currentUser?.id,
360
- display_name: currentUser?.name || "You",
361
  avatar_url: currentUser?.avatar || null,
362
  },
363
  pending: true,
@@ -458,9 +464,9 @@ function ChatArea({ activeView, activeRoom }) {
458
  dispatch(cancelReply());
459
  }}
460
  onShowProfile={(senderName) => {
461
- if (isDM && dmUser && senderName !== "You") {
462
  dispatch(setSelectedUser(dmUser));
463
- } else if (senderName !== "You") {
464
  dispatch(
465
  setSelectedUser({
466
  id: senderName.toLowerCase(),
 
244
  // Convert API messages to UI format
245
  const apiMessages = sortedDmMessages.map((msg) => {
246
  const isOwn = msg.sender_id === currentUser?.id;
247
+ const sender = isOwn
248
+ ? (currentUser?.display_name || currentUser?.name || "Bạn")
249
+ : (msg.sender?.display_name || "Unknown");
250
  const avatar = isOwn
251
+ ? (currentUser?.display_name?.charAt(0).toUpperCase() || currentUser?.name?.charAt(0).toUpperCase() || "B")
252
  : (msg.sender?.display_name?.charAt(0).toUpperCase() || "?");
253
+ const color = isOwn
254
+ ? (currentUser?.color || null)
255
+ : (msg.sender?.color || null);
256
 
257
  const date = new Date(msg.created_at);
258
  const timestamp = isNaN(date.getTime())
 
263
  id: msg.id,
264
  sender,
265
  avatar,
266
+ color,
267
  timestamp,
268
  content: msg.content,
269
  isPinned: false,
 
329
  const tempId = `temp-${Date.now()}`;
330
  const optimisticMsg = {
331
  id: tempId,
332
+ sender: currentUser?.display_name || currentUser?.name || "Bạn",
333
+ avatar: currentUser?.display_name?.charAt(0).toUpperCase() || currentUser?.name?.charAt(0).toUpperCase() || "B",
334
  timestamp: new Date().toLocaleTimeString("vi-VN", {
335
  hour: "2-digit",
336
  minute: "2-digit",
 
363
  created_at: optimisticMsg.created_at,
364
  sender: {
365
  id: currentUser?.id,
366
+ display_name: currentUser?.display_name || currentUser?.name || "Bạn",
367
  avatar_url: currentUser?.avatar || null,
368
  },
369
  pending: true,
 
464
  dispatch(cancelReply());
465
  }}
466
  onShowProfile={(senderName) => {
467
+ if (isDM && dmUser && senderName !== (currentUser?.display_name || currentUser?.name)) {
468
  dispatch(setSelectedUser(dmUser));
469
+ } else if (senderName !== (currentUser?.display_name || currentUser?.name)) {
470
  dispatch(
471
  setSelectedUser({
472
  id: senderName.toLowerCase(),
src/components/chatarea/ChatHeader.jsx CHANGED
@@ -31,7 +31,7 @@ function UserAvatar({ name, avatarUrl, isOnline, isDark, isBot, color }) {
31
  return (
32
  <div className="relative flex-shrink-0">
33
  <div
34
- className="w-9 h-9 rounded-full flex items-center justify-center text-sm font-semibold overflow-hidden"
35
  style={{
36
  background: userColor,
37
  color: textColor,
 
31
  return (
32
  <div className="relative flex-shrink-0">
33
  <div
34
+ className="w-9 h-9 rounded-lg flex items-center justify-center text-sm font-semibold overflow-hidden"
35
  style={{
36
  background: userColor,
37
  color: textColor,
src/components/chatarea/ChatMessages.jsx CHANGED
@@ -13,11 +13,11 @@ function ChatMessage({
13
  onShowProfile,
14
  isSending,
15
  }) {
16
- const senderColor = getUserColor(msg.sender);
17
  const [showActions, setShowActions] = useState(false);
18
  const [reactions, setReactions] = useState(msg.reactions || []);
19
  const [showPicker, setShowPicker] = useState(false);
20
- const isOwnMessage = msg.sender === "You";
21
 
22
  const handleAddReaction = (emoji) => {
23
  const existing = reactions.find((r) => r.emoji === emoji);
@@ -59,7 +59,7 @@ function ChatMessage({
59
  />
60
 
61
  <div
62
- className="w-9 h-9 rounded-full flex items-center justify-center text-sm font-semibold shrink-0 cursor-pointer"
63
  style={{
64
  background: msg.isBot ? "var(--tertiary-active)" : senderColor,
65
  color: msg.isBot
@@ -166,7 +166,7 @@ function TypingIndicator({ isDark }) {
166
  return (
167
  <div className="flex gap-3 px-3 py-2">
168
  <div
169
- className="w-9 h-9 rounded-full flex items-center justify-center text-sm font-semibold shrink-0"
170
  style={{
171
  background: "var(--tertiary-active)",
172
  color: "var(--tertiary)",
@@ -205,7 +205,7 @@ function MessageSkeleton({ isDark, width = "75%", showSecondLine = true }) {
205
  return (
206
  <div className="flex gap-3 px-3 py-3 animate-pulse">
207
  <div
208
- className="w-9 h-9 rounded-full flex-shrink-0"
209
  style={{
210
  background: isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)",
211
  }}
@@ -254,7 +254,7 @@ function EmptyChatState({ dmUser, isDark, hasNoSelection }) {
254
  return (
255
  <div className="flex flex-col items-center justify-center px-6 text-center">
256
  <div
257
- className="w-20 h-20 rounded-full flex items-center justify-center mb-5"
258
  style={{
259
  background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)",
260
  }}
 
13
  onShowProfile,
14
  isSending,
15
  }) {
16
+ const senderColor = getUserColor(msg.sender, msg.color);
17
  const [showActions, setShowActions] = useState(false);
18
  const [reactions, setReactions] = useState(msg.reactions || []);
19
  const [showPicker, setShowPicker] = useState(false);
20
+ const isOwnMessage = msg.isOwn;
21
 
22
  const handleAddReaction = (emoji) => {
23
  const existing = reactions.find((r) => r.emoji === emoji);
 
59
  />
60
 
61
  <div
62
+ className="w-9 h-9 rounded-lg flex items-center justify-center text-sm font-semibold shrink-0 cursor-pointer"
63
  style={{
64
  background: msg.isBot ? "var(--tertiary-active)" : senderColor,
65
  color: msg.isBot
 
166
  return (
167
  <div className="flex gap-3 px-3 py-2">
168
  <div
169
+ className="w-9 h-9 rounded-lg flex items-center justify-center text-sm font-semibold shrink-0"
170
  style={{
171
  background: "var(--tertiary-active)",
172
  color: "var(--tertiary)",
 
205
  return (
206
  <div className="flex gap-3 px-3 py-3 animate-pulse">
207
  <div
208
+ className="w-9 h-9 rounded-lg flex-shrink-0"
209
  style={{
210
  background: isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)",
211
  }}
 
254
  return (
255
  <div className="flex flex-col items-center justify-center px-6 text-center">
256
  <div
257
+ className="w-20 h-20 rounded-lg flex items-center justify-center mb-5"
258
  style={{
259
  background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)",
260
  }}
src/components/chatarea/MentionSuggestions.jsx CHANGED
@@ -85,7 +85,7 @@ function MentionSuggestions({
85
  onMouseEnter={() => setSelectedIndex(index)}
86
  >
87
  <div
88
- className="w-7 h-7 rounded-full flex items-center justify-center text-xs font-semibold flex-shrink-0"
89
  style={{
90
  background: user.isBot
91
  ? "var(--tertiary-active)"
 
85
  onMouseEnter={() => setSelectedIndex(index)}
86
  >
87
  <div
88
+ className="w-7 h-7 rounded-lg flex items-center justify-center text-xs font-semibold flex-shrink-0"
89
  style={{
90
  background: user.isBot
91
  ? "var(--tertiary-active)"
src/components/createspace/CreateSpace.jsx CHANGED
@@ -43,7 +43,9 @@ import {
43
  PiFire,
44
  PiSnowflake,
45
  } from "react-icons/pi";
 
46
  import { cancelCreateSpace } from "../../store/slices/appSlice";
 
47
 
48
  const spaceIcons = [
49
  { id: "graduation", icon: PiGraduationCap, label: "Tốt nghiệp" },
@@ -95,6 +97,64 @@ function CreateSpace() {
95
  const [spaceName, setSpaceName] = useState("");
96
  const [spaceIcon, setSpaceIcon] = useState(spaceIcons[0].id);
97
  const [spaceDescription, setSpaceDescription] = useState("");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  const handleSubmit = () => {
100
  if (spaceName.trim()) {
@@ -106,6 +166,7 @@ function CreateSpace() {
106
  name: spaceName.trim(),
107
  icon: spaceIcon,
108
  description: spaceDescription.trim(),
 
109
  hasNotification: false,
110
  };
111
  console.log("Creating space:", newSpace);
@@ -241,6 +302,151 @@ function CreateSpace() {
241
  />
242
  </div>
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  {/* Preview */}
245
  {spaceName && (
246
  <div>
 
43
  PiFire,
44
  PiSnowflake,
45
  } from "react-icons/pi";
46
+ import { FiSearch, FiX } from "react-icons/fi";
47
  import { cancelCreateSpace } from "../../store/slices/appSlice";
48
+ import { dmService } from "../../services/dm.service";
49
 
50
  const spaceIcons = [
51
  { id: "graduation", icon: PiGraduationCap, label: "Tốt nghiệp" },
 
97
  const [spaceName, setSpaceName] = useState("");
98
  const [spaceIcon, setSpaceIcon] = useState(spaceIcons[0].id);
99
  const [spaceDescription, setSpaceDescription] = useState("");
100
+
101
+ // Members state
102
+ const [members, setMembers] = useState([]);
103
+ const [searchQuery, setSearchQuery] = useState("");
104
+ const [searchResults, setSearchResults] = useState([]);
105
+ const [isSearching, setIsSearching] = useState(false);
106
+ const searchTimeoutRef = useState(null);
107
+
108
+ // Search users - only trigger on Enter key
109
+ const handleSearch = async (query) => {
110
+ setSearchQuery(query);
111
+
112
+ if (!query.trim()) {
113
+ setSearchResults([]);
114
+ setIsSearching(false);
115
+ return;
116
+ }
117
+ };
118
+
119
+ const handleSearchKeyDown = async (e) => {
120
+ if (e.key === 'Enter') {
121
+ e.preventDefault();
122
+ const query = searchQuery.trim();
123
+
124
+ if (!query) {
125
+ setSearchResults([]);
126
+ return;
127
+ }
128
+
129
+ setIsSearching(true);
130
+ try {
131
+ const { data } = await dmService.searchUsers(query);
132
+ const users = (data.users || []).map((user) => ({
133
+ id: user.id,
134
+ name: user.display_name || user.email || "Unknown",
135
+ avatar: user.avatar_url || null,
136
+ email: user.email || "",
137
+ }));
138
+ setSearchResults(users);
139
+ } catch {
140
+ setSearchResults([]);
141
+ } finally {
142
+ setIsSearching(false);
143
+ }
144
+ }
145
+ };
146
+
147
+ // Add member
148
+ const addMember = (user) => {
149
+ if (!members.some((m) => m.id === user.id)) {
150
+ setMembers([...members, user]);
151
+ }
152
+ };
153
+
154
+ // Remove member
155
+ const removeMember = (userId) => {
156
+ setMembers((prev) => prev.filter((m) => m.id !== userId));
157
+ };
158
 
159
  const handleSubmit = () => {
160
  if (spaceName.trim()) {
 
166
  name: spaceName.trim(),
167
  icon: spaceIcon,
168
  description: spaceDescription.trim(),
169
+ members: members.map((m) => m.id),
170
  hasNotification: false,
171
  };
172
  console.log("Creating space:", newSpace);
 
302
  />
303
  </div>
304
 
305
+ {/* Members */}
306
+ <div>
307
+ <h3
308
+ className="text-sm font-semibold mb-3"
309
+ style={{ color: "var(--text-primary)" }}
310
+ >
311
+ Thêm thành viên
312
+ </h3>
313
+
314
+ {/* Search input */}
315
+ <div className="relative mb-3">
316
+ {isSearching ? (
317
+ <div className="absolute left-3 top-1/2 -translate-y-1/2">
318
+ <div className="w-4 h-4 border-2 border-t-transparent rounded-full animate-spin"
319
+ style={{ borderColor: "var(--text-muted)", borderTopColor: "transparent" }}
320
+ />
321
+ </div>
322
+ ) : (
323
+ <button
324
+ onClick={() => handleSearchKeyDown({ key: 'Enter', preventDefault: () => {} })}
325
+ className="absolute left-3 top-1/2 -translate-y-1/2 hover:opacity-70 transition-opacity"
326
+ style={{ color: "var(--text-muted)" }}
327
+ >
328
+ <FiSearch size={16} />
329
+ </button>
330
+ )}
331
+ <input
332
+ type="text"
333
+ value={searchQuery}
334
+ onChange={(e) => handleSearch(e.target.value)}
335
+ onKeyDown={handleSearchKeyDown}
336
+ placeholder="Nhập tên và nhấn Enter để tìm..."
337
+ className="w-full pl-9 pr-3 py-2 rounded-md text-sm border outline-none"
338
+ style={{
339
+ background: "var(--input-bg)",
340
+ borderColor: "var(--input-border)",
341
+ color: "var(--input-text)",
342
+ }}
343
+ onFocus={(e) =>
344
+ (e.currentTarget.style.borderColor = "var(--primary)")
345
+ }
346
+ onBlur={(e) =>
347
+ (e.currentTarget.style.borderColor = "var(--input-border)")
348
+ }
349
+ />
350
+ </div>
351
+
352
+ {/* Selected members - chips */}
353
+ {members.length > 0 && (
354
+ <div className="mb-3">
355
+ <div
356
+ className="text-xs font-medium mb-2"
357
+ style={{ color: "var(--text-secondary)" }}
358
+ >
359
+ Đã chọn ({members.length})
360
+ </div>
361
+ <div className="flex flex-wrap gap-2">
362
+ {members.map((member) => (
363
+ <div
364
+ key={member.id}
365
+ className="flex items-center gap-2 px-3 py-1.5 rounded-full text-sm"
366
+ style={{
367
+ background: "var(--primary-active)",
368
+ color: "var(--primary)",
369
+ }}
370
+ >
371
+ <div
372
+ className="w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-semibold"
373
+ style={{
374
+ background: "var(--primary)",
375
+ color: "#fff",
376
+ }}
377
+ >
378
+ {member.name?.charAt(0)?.toUpperCase() || "?"}
379
+ </div>
380
+ <span className="font-medium">{member.name}</span>
381
+ <button
382
+ onClick={() => removeMember(member.id)}
383
+ className="ml-1 hover:opacity-70"
384
+ >
385
+ <FiX size={14} />
386
+ </button>
387
+ </div>
388
+ ))}
389
+ </div>
390
+ </div>
391
+ )}
392
+
393
+ {/* Search results with checkbox - keep showing after select */}
394
+ {searchResults.length > 0 && (
395
+ <div>
396
+ <div
397
+ className="text-xs font-medium mb-2"
398
+ style={{ color: "var(--text-secondary)" }}
399
+ >
400
+ Kết quả tìm kiếm
401
+ </div>
402
+ <div className="space-y-1">
403
+ {searchResults.map((user) => {
404
+ const isSelected = members.some((m) => m.id === user.id);
405
+ return (
406
+ <label
407
+ key={user.id}
408
+ className="flex items-center gap-3 px-3 py-2 rounded-md cursor-pointer transition-colors hover:opacity-80"
409
+ >
410
+ <div
411
+ className="w-8 h-8 rounded-full flex items-center justify-center text-xs font-semibold"
412
+ style={{
413
+ background: "var(--primary-active)",
414
+ color: "var(--primary)",
415
+ }}
416
+ >
417
+ {user.name?.charAt(0)?.toUpperCase() || "?"}
418
+ </div>
419
+ <div className="flex-1 min-w-0">
420
+ <div
421
+ className="text-sm font-medium truncate"
422
+ style={{ color: "var(--text-primary)" }}
423
+ >
424
+ {user.name}
425
+ </div>
426
+ </div>
427
+ <input
428
+ type="checkbox"
429
+ checked={isSelected}
430
+ onChange={() => {
431
+ if (isSelected) {
432
+ removeMember(user.id);
433
+ } else {
434
+ addMember(user);
435
+ }
436
+ }}
437
+ className="w-4 h-4 cursor-pointer"
438
+ style={{
439
+ accentColor: "var(--primary)",
440
+ }}
441
+ />
442
+ </label>
443
+ );
444
+ })}
445
+ </div>
446
+ </div>
447
+ )}
448
+ </div>
449
+
450
  {/* Preview */}
451
  {spaceName && (
452
  <div>
src/components/memberlist/DMProfile.jsx CHANGED
@@ -41,7 +41,7 @@ function UserAvatar({ name, avatarUrl, isOnline, isDark, isBot, color }) {
41
  return (
42
  <div className="relative shrink-0">
43
  <div
44
- className="w-16 h-16 rounded-full flex items-center justify-center text-2xl font-semibold overflow-hidden"
45
  style={{
46
  background: userColor,
47
  color: textColor,
@@ -60,15 +60,6 @@ function UserAvatar({ name, avatarUrl, isOnline, isDark, isBot, color }) {
60
  getInitials(name)
61
  )}
62
  </div>
63
- {!isBot && (
64
- <div
65
- className="absolute bottom-0.5 right-0.5 w-3 h-3 rounded-full border-2"
66
- style={{
67
- borderColor: isDark ? "var(--bg-surface-secondary)" : "#fff",
68
- background: isOnline ? "var(--online)" : "var(--offline)",
69
- }}
70
- />
71
- )}
72
  </div>
73
  );
74
  }
@@ -90,7 +81,8 @@ function DMProfile({ isDark, dmUser }) {
90
  .getUserProfile(dmUser.id)
91
  .then(({ data }) => {
92
  const color = data?.user?.color || data?.color || null;
93
- const displayName = data?.user?.display_name || data?.display_name || null;
 
94
  const avatarUrl = data?.user?.avatar_url || data?.avatar_url || null;
95
  if (mounted && color) {
96
  setProfileColor(color);
@@ -105,7 +97,7 @@ function DMProfile({ isDark, dmUser }) {
105
  ...(displayName && { display_name: displayName }),
106
  ...(avatarUrl && { avatar_url: avatarUrl }),
107
  },
108
- })
109
  );
110
  }
111
  })
 
41
  return (
42
  <div className="relative shrink-0">
43
  <div
44
+ className="w-16 h-16 rounded-lg flex items-center justify-center text-2xl font-semibold overflow-hidden"
45
  style={{
46
  background: userColor,
47
  color: textColor,
 
60
  getInitials(name)
61
  )}
62
  </div>
 
 
 
 
 
 
 
 
 
63
  </div>
64
  );
65
  }
 
81
  .getUserProfile(dmUser.id)
82
  .then(({ data }) => {
83
  const color = data?.user?.color || data?.color || null;
84
+ const displayName =
85
+ data?.user?.display_name || data?.display_name || null;
86
  const avatarUrl = data?.user?.avatar_url || data?.avatar_url || null;
87
  if (mounted && color) {
88
  setProfileColor(color);
 
97
  ...(displayName && { display_name: displayName }),
98
  ...(avatarUrl && { avatar_url: avatarUrl }),
99
  },
100
+ }),
101
  );
102
  }
103
  })
src/components/memberlist/MemberItem.jsx CHANGED
@@ -13,7 +13,7 @@ function MemberItem({ isDark, member, onClick }) {
13
  onClick={() => onClick?.()}
14
  >
15
  <div
16
- className="w-8 h-8 rounded-full flex items-center justify-center text-[13px] font-semibold flex-shrink-0 relative"
17
  style={{
18
  background: member.isBot ? "var(--tertiary-active)" : memberColor,
19
  color: member.isBot
 
13
  onClick={() => onClick?.()}
14
  >
15
  <div
16
+ className="w-8 h-8 rounded-lg flex items-center justify-center text-[13px] font-semibold flex-shrink-0 relative"
17
  style={{
18
  background: member.isBot ? "var(--tertiary-active)" : memberColor,
19
  color: member.isBot
src/components/memberlist/UserProfilePopup.jsx CHANGED
@@ -55,7 +55,7 @@ function UserProfilePopup({
55
  {/* Avatar */}
56
  <div className="px-4 -mt-8">
57
  <div
58
- className="w-16 h-16 rounded-full flex items-center justify-center text-2xl font-semibold border-4 relative"
59
  style={{
60
  background: userColor,
61
  color: isDark ? "var(--bg-surface)" : "#fff",
 
55
  {/* Avatar */}
56
  <div className="px-4 -mt-8">
57
  <div
58
+ className="w-16 h-16 rounded-lg flex items-center justify-center text-2xl font-semibold border-4 relative"
59
  style={{
60
  background: userColor,
61
  color: isDark ? "var(--bg-surface)" : "#fff",
src/components/roomlist/DMList.jsx CHANGED
@@ -43,7 +43,7 @@ function UserAvatar({ name, avatarUrl, isOnline, isDark, isBot, color }) {
43
  return (
44
  <div className="relative flex-shrink-0">
45
  <div
46
- className="w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold overflow-hidden"
47
  style={{
48
  background: userColor,
49
  color: textColor,
@@ -96,7 +96,7 @@ function NoResultsState({ isDark }) {
96
  return (
97
  <div className="flex flex-col items-center justify-center py-10 px-4 text-center">
98
  <div
99
- className="w-14 h-14 rounded-full flex items-center justify-center mb-3"
100
  style={{
101
  background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)",
102
  }}
@@ -120,7 +120,7 @@ function EmptyState({ isDark, onStartChat }) {
120
  return (
121
  <div className="flex flex-col items-center justify-center py-10 px-4 text-center">
122
  <div
123
- className="w-16 h-16 rounded-full flex items-center justify-center mb-4"
124
  style={{
125
  background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)",
126
  }}
 
43
  return (
44
  <div className="relative flex-shrink-0">
45
  <div
46
+ className="w-10 h-10 rounded-lg flex items-center justify-center text-sm font-semibold overflow-hidden"
47
  style={{
48
  background: userColor,
49
  color: textColor,
 
96
  return (
97
  <div className="flex flex-col items-center justify-center py-10 px-4 text-center">
98
  <div
99
+ className="w-14 h-14 rounded-lg flex items-center justify-center mb-3"
100
  style={{
101
  background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)",
102
  }}
 
120
  return (
121
  <div className="flex flex-col items-center justify-center py-10 px-4 text-center">
122
  <div
123
+ className="w-16 h-16 rounded-lg flex items-center justify-center mb-4"
124
  style={{
125
  background: isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)",
126
  }}
src/components/settings/UserProfile.jsx CHANGED
@@ -108,7 +108,7 @@ const UserProfile = forwardRef(function UserProfile(_, ref) {
108
  >
109
  <div className="flex items-center gap-4">
110
  <div
111
- className="w-14 h-14 rounded-full flex items-center justify-center text-xl font-semibold"
112
  style={{
113
  background: usernameColors.find((c) => c.value === usernameColor)?.hex || "var(--primary)",
114
  color: isDark ? "var(--bg-surface)" : "#fff",
@@ -198,7 +198,7 @@ const UserProfile = forwardRef(function UserProfile(_, ref) {
198
  <button
199
  key={`${color.value}-${usernameColor}`}
200
  onClick={() => handleColorChange(color.value)}
201
- className="w-8 h-8 rounded-full flex items-center justify-center border-2 transition-all"
202
  style={{
203
  background: color.hex,
204
  borderColor:
 
108
  >
109
  <div className="flex items-center gap-4">
110
  <div
111
+ className="w-14 h-14 rounded-lg flex items-center justify-center text-xl font-semibold"
112
  style={{
113
  background: usernameColors.find((c) => c.value === usernameColor)?.hex || "var(--primary)",
114
  color: isDark ? "var(--bg-surface)" : "#fff",
 
198
  <button
199
  key={`${color.value}-${usernameColor}`}
200
  onClick={() => handleColorChange(color.value)}
201
+ className="w-8 h-8 rounded-lg flex items-center justify-center border-2 transition-all"
202
  style={{
203
  background: color.hex,
204
  borderColor: