anotherath commited on
Commit
12a94f6
·
1 Parent(s): b4bf04d

sửa giao diện dark mode cho sáng hơn chút

Browse files
src/components/roomlist/DMList.jsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useState } from "react";
2
  import { useSelector, useDispatch } from "react-redux";
3
  import { FiMessageSquare, FiUserPlus, FiSearch } from "react-icons/fi";
4
  import { setActiveRoom } from "../../store/slices/appSlice";
@@ -211,8 +211,14 @@ function DMList({ activeRoom, setActiveRoom: setActiveRoomProp }) {
211
  const dispatch = useDispatch();
212
  const { isDark } = useSelector((state) => state.theme);
213
  const { loading: dmLoading, conversations, conversationsFetched } = useSelector((state) => state.dm);
 
214
  const [sentRequests, setSentRequests] = useState([]);
215
 
 
 
 
 
 
216
  const {
217
  items,
218
  onlineStatus,
 
1
+ import { useState, useEffect } from "react";
2
  import { useSelector, useDispatch } from "react-redux";
3
  import { FiMessageSquare, FiUserPlus, FiSearch } from "react-icons/fi";
4
  import { setActiveRoom } from "../../store/slices/appSlice";
 
211
  const dispatch = useDispatch();
212
  const { isDark } = useSelector((state) => state.theme);
213
  const { loading: dmLoading, conversations, conversationsFetched } = useSelector((state) => state.dm);
214
+ console.log("[DMList] Render, conversations:", conversations.length, "fetched:", conversationsFetched);
215
  const [sentRequests, setSentRequests] = useState([]);
216
 
217
+ useEffect(() => {
218
+ console.log("[DMList] MOUNTED");
219
+ return () => console.log("[DMList] UNMOUNTED");
220
+ }, []);
221
+
222
  const {
223
  items,
224
  onlineStatus,
src/hooks/useDMList.js CHANGED
@@ -43,6 +43,7 @@ function matchesStudyBot(query) {
43
  export function useDMList() {
44
  const dispatch = useDispatch();
45
  const { conversations, onlineUsers, conversationsFetched } = useSelector((state) => state.dm);
 
46
 
47
  const [searchResults, setSearchResults] = useState([]);
48
  const [searchQuery, setSearchQuery] = useState("");
@@ -54,10 +55,14 @@ export function useDMList() {
54
  const processedMessageIds = useRef(new Set());
55
 
56
  // Fetch conversations on mount — only if not already fetched
 
57
  useEffect(() => {
58
  if (conversationsFetched) return; // Skip: already cached
 
 
59
  dispatch(fetchConversations());
60
- }, [dispatch, conversationsFetched]);
 
61
 
62
  // Listen to realtime updates via WebSocket
63
  useEffect(() => {
 
43
  export function useDMList() {
44
  const dispatch = useDispatch();
45
  const { conversations, onlineUsers, conversationsFetched } = useSelector((state) => state.dm);
46
+ console.log("[useDMList] Hook called, conversations:", conversations.length, "fetched:", conversationsFetched);
47
 
48
  const [searchResults, setSearchResults] = useState([]);
49
  const [searchQuery, setSearchQuery] = useState("");
 
55
  const processedMessageIds = useRef(new Set());
56
 
57
  // Fetch conversations on mount — only if not already fetched
58
+ const isFetchingRef = useRef(false);
59
  useEffect(() => {
60
  if (conversationsFetched) return; // Skip: already cached
61
+ if (isFetchingRef.current) return; // Prevent duplicate requests
62
+ isFetchingRef.current = true;
63
  dispatch(fetchConversations());
64
+ // eslint-disable-next-line react-hooks/exhaustive-deps
65
+ }, [dispatch]);
66
 
67
  // Listen to realtime updates via WebSocket
68
  useEffect(() => {
src/services/dm.service.js CHANGED
@@ -7,7 +7,14 @@ export const dmService = {
7
  createOrGetConversation: (userId) => api.post("/dms", { userId }),
8
 
9
  /** Get list of conversations */
10
- getConversations: (params) => api.get("/dms", { params }),
 
 
 
 
 
 
 
11
 
12
  // === Messages ===
13
 
 
7
  createOrGetConversation: (userId) => api.post("/dms", { userId }),
8
 
9
  /** Get list of conversations */
10
+ getConversations: async (params) => {
11
+ const response = await api.get("/dms", { params });
12
+ console.log("[dmService.getConversations] API response:", {
13
+ count: response.data?.data?.length || response.data?.conversations?.length || response.data?.length || 0,
14
+ data: response.data,
15
+ });
16
+ return response;
17
+ },
18
 
19
  // === Messages ===
20
 
src/store/slices/dmSlice.js CHANGED
@@ -8,9 +8,13 @@ export const fetchConversations = createAsyncThunk(
8
  "dm/fetchConversations",
9
  async (_, { rejectWithValue }) => {
10
  try {
 
11
  const { data } = await dmService.getConversations({ page: 1, limit: 20 });
12
- return data.data || data.conversations || data || [];
 
 
13
  } catch (err) {
 
14
  return rejectWithValue(err.response?.data?.message || "Không thể tải danh sách trò chuyện");
15
  }
16
  }
@@ -243,6 +247,7 @@ const dmSlice = createSlice({
243
  .addCase(fetchConversations.fulfilled, (state, action) => {
244
  state.loading = false;
245
  state.conversations = action.payload;
 
246
  })
247
  .addCase(fetchConversations.rejected, (state, action) => {
248
  state.loading = false;
 
8
  "dm/fetchConversations",
9
  async (_, { rejectWithValue }) => {
10
  try {
11
+ console.log("[fetchConversations] Calling API...");
12
  const { data } = await dmService.getConversations({ page: 1, limit: 20 });
13
+ const result = data.data || data.conversations || data || [];
14
+ console.log("[fetchConversations] Result:", { count: result.length, ids: result.map(c => c.id) });
15
+ return result;
16
  } catch (err) {
17
+ console.error("[fetchConversations] Error:", err);
18
  return rejectWithValue(err.response?.data?.message || "Không thể tải danh sách trò chuyện");
19
  }
20
  }
 
247
  .addCase(fetchConversations.fulfilled, (state, action) => {
248
  state.loading = false;
249
  state.conversations = action.payload;
250
+ state.conversationsFetched = true;
251
  })
252
  .addCase(fetchConversations.rejected, (state, action) => {
253
  state.loading = false;
src/styles/theme.css CHANGED
@@ -15,19 +15,19 @@
15
  /* ===================== DARK MODE ===================== */
16
  .dark {
17
  /* === SURFACE COLORS === */
18
- --bg-surface: #1a1f35;
19
- --bg-surface-secondary: #222842;
20
- --bg-surface-tertiary: #2a3050;
21
 
22
  /* === BORDER COLORS === */
23
- --border-primary: #333a5c;
24
- --border-secondary: #3d4568;
25
 
26
  /* === TEXT COLORS === */
27
- --text-primary: #e8ecf4;
28
- --text-secondary: #b0bdd0;
29
- --text-tertiary: #8899b5;
30
- --text-muted: #6b7a99;
31
 
32
  /* === BRAND COLORS === */
33
  --primary: #a3a6ff;
@@ -43,28 +43,28 @@
43
  --tertiary-active: #ac8aff26;
44
 
45
  /* === INPUT COLORS === */
46
- --input-bg: #222842;
47
- --input-border: #333a5c;
48
- --input-text: #e8ecf4;
49
- --input-placeholder: #8899b5;
50
 
51
  /* === HOVER COLORS === */
52
- --hover-primary: #2a3050;
53
- --hover-secondary: #333a5c;
54
 
55
  /* === CARD/BG COLORS === */
56
- --card-bg: #222842;
57
- --card-bg-secondary: #2a3050;
58
 
59
  /* === STATUS COLORS === */
60
  --online: #69f6b8;
61
- --offline: #8899b5;
62
  --notification: #a3a6ff;
63
  --danger: #ff6b6b;
64
 
65
  /* === SCROLLBAR === */
66
- --scrollbar-thumb: #3d4568;
67
- --scrollbar-thumb-hover: #4d5578;
68
  }
69
 
70
  /* ===================== LIGHT MODE ===================== */
 
15
  /* ===================== DARK MODE ===================== */
16
  .dark {
17
  /* === SURFACE COLORS === */
18
+ --bg-surface: #1e2238;
19
+ --bg-surface-secondary: #252b4a;
20
+ --bg-surface-tertiary: #2e3558;
21
 
22
  /* === BORDER COLORS === */
23
+ --border-primary: #3d4568;
24
+ --border-secondary: #4a5478;
25
 
26
  /* === TEXT COLORS === */
27
+ --text-primary: #f0f3f8;
28
+ --text-secondary: #c4d0e4;
29
+ --text-tertiary: #9aadcc;
30
+ --text-muted: #7a8db0;
31
 
32
  /* === BRAND COLORS === */
33
  --primary: #a3a6ff;
 
43
  --tertiary-active: #ac8aff26;
44
 
45
  /* === INPUT COLORS === */
46
+ --input-bg: #252b4a;
47
+ --input-border: #3d4568;
48
+ --input-text: #f0f3f8;
49
+ --input-placeholder: #9aadcc;
50
 
51
  /* === HOVER COLORS === */
52
+ --hover-primary: #2e3558;
53
+ --hover-secondary: #3d4568;
54
 
55
  /* === CARD/BG COLORS === */
56
+ --card-bg: #252b4a;
57
+ --card-bg-secondary: #2e3558;
58
 
59
  /* === STATUS COLORS === */
60
  --online: #69f6b8;
61
+ --offline: #9aadcc;
62
  --notification: #a3a6ff;
63
  --danger: #ff6b6b;
64
 
65
  /* === SCROLLBAR === */
66
+ --scrollbar-thumb: #4a5478;
67
+ --scrollbar-thumb-hover: #5a6488;
68
  }
69
 
70
  /* ===================== LIGHT MODE ===================== */