From cfd1137c2d0ee8935e6b3c63106c9ef5fe495724 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Mon, 14 Feb 2022 21:43:12 +0300 Subject: [PATCH] feat: render all users in sidebar chat --- src/components/Chat/Sidebar/Users/Users.tsx | 16 ++++++----- src/components/Chat/Window/Window.tsx | 29 +++++++++++++++----- src/components/Layout/Layout.tsx | 7 ----- src/hooks/queries/index.ts | 2 ++ src/hooks/queries/user/useFetchUsers.ts | 30 +++++++++++++++++++++ src/pages/auth/auth.tsx | 2 +- src/pages/course/course.tsx | 2 +- src/pages/courses/courses.tsx | 7 ++--- src/services/UserService.ts | 3 ++- src/types/index.d.ts | 7 +++++ 10 files changed, 79 insertions(+), 26 deletions(-) create mode 100644 src/hooks/queries/user/useFetchUsers.ts diff --git a/src/components/Chat/Sidebar/Users/Users.tsx b/src/components/Chat/Sidebar/Users/Users.tsx index a908aeb..55449ca 100644 --- a/src/components/Chat/Sidebar/Users/Users.tsx +++ b/src/components/Chat/Sidebar/Users/Users.tsx @@ -5,6 +5,7 @@ import { User } from './User'; import { useChatContext } from '../../context'; import { useRootStore } from '@educt/hooks/useRootStore'; import { Skeleton } from '@chakra-ui/react'; +import { useFetchUsers } from '@educt/hooks/queries'; const Wrapper: React.FC = ({ children }) => { return ( @@ -15,9 +16,9 @@ const Wrapper: React.FC = ({ children }) => { }; const Users: React.FC = observer(() => { + const { data: users } = useFetchUsers(); const { onlineStore } = useRootStore(); const { search } = useChatContext(); - const { users } = onlineStore; if (users === null) return ( @@ -27,17 +28,18 @@ const Users: React.FC = observer(() => { ); - const filtered = !search ? users : users.filter(u => u.userName.toLocaleLowerCase().includes(search)); + const filtered = (!search ? users : users.filter(u => u.fullname.toLocaleLowerCase().includes(search))).sort(user => + !onlineStore.isOnline(user.id) ? 1 : -1 + ); const isEmpty = filtered.length === 0; return ( {!isEmpty ? ( - filtered.map(u => ( - - - - + filtered.map(user => ( + + + )) ) : ( diff --git a/src/components/Chat/Window/Window.tsx b/src/components/Chat/Window/Window.tsx index 219f70c..0ab74f4 100644 --- a/src/components/Chat/Window/Window.tsx +++ b/src/components/Chat/Window/Window.tsx @@ -1,6 +1,19 @@ import React, { ChangeEvent } from 'react'; import axios from 'axios'; -import { GridItem, GridItemProps, Flex, Box, Icon, Text, Input, Heading, IconButton, Divider } from '@chakra-ui/react'; +import { Link as ReactRouterLink } from 'react-router-dom'; +import { + GridItem, + GridItemProps, + Flex, + Box, + Icon, + Text, + Input, + Heading, + IconButton, + Divider, + Link, +} from '@chakra-ui/react'; import { MdOutlineChat, MdSend } from 'react-icons/md'; import { MessageList } from './Message'; import { SocketContext } from '@educt/contexts'; @@ -80,13 +93,12 @@ const Window: React.FC = props => { data: { history }, } = await UserServiceInstance.fetchChatHistory(chatId); - // TODO add type for message const messages = history.map(message => { return { - isMyMessage: message.from === me.id, + isMyMessage: message.from === me?.id, content: message.content, time: new Date(message.time).toLocaleTimeString(), - userName: message.from === me.id ? me.fullname : user.fullname, + userName: message.from === me?.id ? me.fullname : user.fullname, }; }); @@ -161,11 +173,16 @@ const Window: React.FC = props => { return ( - + {isMe && me ? 'Favorites' : selectedUser.fullname} - + {!isMe && ( + + See profile + + )} +
onSubmit(e)}> diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index d2a41e9..daffccc 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -62,13 +62,6 @@ const Layout: React.FC = ({ children, roles }) => { } }, [socket]); - /** - * Emit online status of user - */ - useEffect(() => { - socket?.emit('user:status'); - }, []); - return ( <>
diff --git a/src/hooks/queries/index.ts b/src/hooks/queries/index.ts index 95d8a7e..2f8dced 100644 --- a/src/hooks/queries/index.ts +++ b/src/hooks/queries/index.ts @@ -25,6 +25,7 @@ import { useDetachStudents } from './course/useDetachStudents'; /** * User */ +import { useFetchUsers } from './user/useFetchUsers'; import { useFetchUser } from './user/useFetchUser'; import { useCreateUser } from './user/useCreateUser'; import { useDeleteUser } from './user/useDeleteUser'; @@ -58,6 +59,7 @@ export { useCreateLesson, useDeleteLesson, useUpdateLesson, + useFetchUsers, useFetchUser, useCreateUser, useDeleteUser, diff --git a/src/hooks/queries/user/useFetchUsers.ts b/src/hooks/queries/user/useFetchUsers.ts new file mode 100644 index 0000000..baa2458 --- /dev/null +++ b/src/hooks/queries/user/useFetchUsers.ts @@ -0,0 +1,30 @@ +import useAsync from '@educt/hooks/useAsync'; +import { IUser } from '@educt/interfaces'; +import { UserServiceInstance } from '@educt/services'; +import { FetchUsersParamsType } from '@educt/types'; +import { useEffect } from 'react'; +import { useErrorHandler } from 'react-error-boundary'; + +const useFetchUsers = (params?: FetchUsersParamsType | undefined) => { + const handleError = useErrorHandler(); + + const fetch = async (params?: FetchUsersParamsType | undefined) => { + try { + const result = await UserServiceInstance.fetchAll(params); + return result.data; + } catch (error) { + handleError(error); + return Promise.reject(error); + } + }; + + const { execute: fetchUsers, ...state } = useAsync>(fetch); + + useEffect(() => { + fetchUsers(params); + }, []); + + return { ...state }; +}; + +export { useFetchUsers }; diff --git a/src/pages/auth/auth.tsx b/src/pages/auth/auth.tsx index 1a28914..9c1632b 100644 --- a/src/pages/auth/auth.tsx +++ b/src/pages/auth/auth.tsx @@ -43,7 +43,7 @@ const AuthPage: React.FC = ({ title }) => { - + diff --git a/src/pages/course/course.tsx b/src/pages/course/course.tsx index 4122d4c..7cd5141 100644 --- a/src/pages/course/course.tsx +++ b/src/pages/course/course.tsx @@ -104,7 +104,7 @@ const CoursePage: React.FC = () => { Students: - + {course.students.map(student => ( ))} diff --git a/src/pages/courses/courses.tsx b/src/pages/courses/courses.tsx index 61ca3ce..2235536 100644 --- a/src/pages/courses/courses.tsx +++ b/src/pages/courses/courses.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { observer } from 'mobx-react'; /** * Types @@ -9,8 +10,9 @@ import { IPageProps } from '@educt/interfaces'; * Components */ import { Page } from '@educt/components/PageElements'; -import { CreateButton } from '@educt/components/Buttons'; import { Box } from '@chakra-ui/layout'; +import { CreateButton } from '@educt/components/Buttons'; +import { CoursesTabs } from './components'; import LoadingPage from '@educt/components/LoadingPage'; import CourseList from './components/CourseList'; import CategoryList from './components/CategoryList'; @@ -22,7 +24,6 @@ import CourseItem from './components/CourseList/CourseItem'; */ import { useRootStore } from '@educt/hooks/useRootStore'; import { useHistory } from 'react-router'; -import { CoursesTabs } from './components'; /** * Courses page @@ -53,4 +54,4 @@ const CoursesPage: React.FC = () => { ); }; -export default CoursesPage; +export default observer(CoursesPage); diff --git a/src/services/UserService.ts b/src/services/UserService.ts index 74bbc57..f94b7cd 100644 --- a/src/services/UserService.ts +++ b/src/services/UserService.ts @@ -8,6 +8,7 @@ import { UpdateUserParamsType, UpdateUserContactsParamsType, UpdateUserInfoParamsType, + HistoryMessageType, } from '@educt/types'; class UserService { @@ -170,7 +171,7 @@ class UserService { * @param chatId Chat id * @returns Array of messages */ - public async fetchChatHistory(chatId: string): Promise> { + public async fetchChatHistory(chatId: string): Promise> { const result = await this.api.get(`v1/me/messages/${chatId}`); return result.data; } diff --git a/src/types/index.d.ts b/src/types/index.d.ts index e673964..d4a4bd4 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -69,6 +69,13 @@ export type MessageType = { isMyMessage: boolean; }; +export type HistoryMessageType = { + from: string; + to: string; + content: string; + time: string; +}; + /** * Change email page context */