feat: render all users in sidebar chat

This commit is contained in:
Sergey Yarkov 2022-02-14 21:43:12 +03:00
parent ce5411bd50
commit cfd1137c2d
10 changed files with 79 additions and 26 deletions

View File

@ -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<StackProps> = ({ children }) => {
return (
@ -15,9 +16,9 @@ const Wrapper: React.FC<StackProps> = ({ 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(() => {
</Wrapper>
);
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 (
<Wrapper>
{!isEmpty ? (
filtered.map(u => (
<User key={u.userId} id={u.userId}>
<User.Avatar isOnline={onlineStore.isOnline(u.userId) || false} fullname={u.userName} />
<User.Info fullname={u.userName} lastMessage={''} />
<User.Time time={'2h'} />
filtered.map(user => (
<User key={user.id} id={user.id}>
<User.Avatar isOnline={onlineStore.isOnline(user.id) || false} fullname={user.fullname} />
<User.Info fullname={user.fullname} lastMessage={''} />
</User>
))
) : (

View File

@ -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 (
<Wrapper {...props}>
<Flex flexDir={'column'}>
<Box my='3'>
<Flex my='3' alignItems={'flex-end'} justifyContent={'space-between'}>
<Heading as='h2' fontWeight={'semibold'} fontSize='3xl'>
{isMe && me ? 'Favorites' : selectedUser.fullname}
</Heading>
</Box>
{!isMe && (
<Link as={ReactRouterLink} to={`/user/${selectedUser.id}`} textDecor='underline'>
See profile
</Link>
)}
</Flex>
<Divider my='2' />
<MessageList messages={messages} />
<form onSubmit={e => onSubmit(e)}>

View File

@ -62,13 +62,6 @@ const Layout: React.FC<ILayoutProps> = ({ children, roles }) => {
}
}, [socket]);
/**
* Emit online status of user
*/
useEffect(() => {
socket?.emit('user:status');
}, []);
return (
<>
<Header>

View File

@ -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,

View File

@ -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<IUser[], Parameters<typeof fetch>>(fetch);
useEffect(() => {
fetchUsers(params);
}, []);
return { ...state };
};
export { useFetchUsers };

View File

@ -43,7 +43,7 @@ const AuthPage: React.FC<IPageProps> = ({ title }) => {
</Helmet>
<Box maxW='md' mx='auto' mt='20'>
<Logo mx='auto' h='14' mb={{ base: '10', md: '10' }} />
<Card>
<Card p='6'>
<AuthForm />
</Card>
</Box>

View File

@ -104,7 +104,7 @@ const CoursePage: React.FC<IPageProps> = () => {
<Text fontSize={'sm'} mr='2'>
Students:
</Text>
<AvatarGroup size='sm' max={2}>
<AvatarGroup size='sm' max={3}>
{course.students.map(student => (
<Avatar key={student.id} name={student.fullname} />
))}

View File

@ -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<IPageProps> = () => {
);
};
export default CoursesPage;
export default observer(CoursesPage);

View File

@ -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<IApiRespose<{ history: unknown[] }>> {
public async fetchChatHistory(chatId: string): Promise<IApiRespose<{ history: HistoryMessageType[] }>> {
const result = await this.api.get(`v1/me/messages/${chatId}`);
return result.data;
}

View File

@ -69,6 +69,13 @@ export type MessageType = {
isMyMessage: boolean;
};
export type HistoryMessageType = {
from: string;
to: string;
content: string;
time: string;
};
/**
* Change email page context
*/