Display Chats in dashboard + autoscroll chat to bottom

Took 1 hour 11 minutes
This commit is contained in:
Lucàs
2023-05-20 22:10:27 +02:00
parent 6cb47c25e9
commit 57a0c057ab
9 changed files with 150 additions and 126 deletions
+27 -11
View File
@@ -1,9 +1,9 @@
import {Button, Container, Flex, Input} from '@chakra-ui/react';
import {Button, Container, Flex, FormControl, Input} from '@chakra-ui/react';
import Head from 'next/head';
import {websiteName} from '@/lib/constants';
import {useSession} from 'next-auth/react';
import {useRouter} from 'next/router';
import {useEffect, useState} from 'react';
import {useEffect, useRef, useState} from 'react';
import MessageList from '@/components/chat/MessageList';
@@ -30,19 +30,29 @@ export default function ChatId() {
const soc = io();
soc.on('connect', () => console.log('connected'));
soc.on('allOldMessages', (allOldMessages: Message[]) => setMessages(allOldMessages));
soc.on('newIncomingMessage', (newIncomingMessage: Message) => setMessages(messages => [...messages, newIncomingMessage]));
soc.on('allOldMessages',
(allOldMessages: Message[]) => setMessages(allOldMessages));
soc.on('newIncomingMessage',
(newIncomingMessage: Message) => setMessages(
messages => [...messages, newIncomingMessage]));
setSocket(soc);
});
};
const handleSubmit = () => {
const handleSubmit = (evt) => {
evt.preventDefault()
if (text !== '' && socket && session?.user) {
socket.emit('createdMessage', {text, sender: session.user.id});
setText('');
}
};
const AlwaysScrollToBottom = () => {
const elementRef = useRef();
useEffect(() => elementRef.current.scrollIntoView());
return <div ref={elementRef}/>;
};
if (status === 'loading') return <LoadingPage/>;
return (
<>
@@ -51,12 +61,18 @@ export default function ChatId() {
<Container>
<MessageList user={session.user as User} messages={messages}/>
<Flex gap={5} mt={5}>
<Input type={'text'} colorScheme={'purple'}
onChange={evt => setText(evt.target.value)} value={text}/>
<Button colorScheme={'purple'}
onClick={handleSubmit}>Envoyer</Button>
</Flex>
<form onSubmit={handleSubmit}>
<FormControl>
<Flex gap={5} py={5}>
<Input type={'text'}
onChange={evt => setText(evt.target.value)}
value={text}/>
<Button type={'submit'} colorScheme={'purple'}>Envoyer</Button>
</Flex>
</FormControl>
</form>
<AlwaysScrollToBottom/>
</Container>
</>
);
+1 -4
View File
@@ -7,8 +7,5 @@ export default function Chat() {
const {data: session, status} = useSession({required: true});
if (status === 'loading') return <LoadingPage/>;
if (session)
return (
<ChatList user={session.user as User}/>
);
return <ChatList user={session.user as User}/>;
}
+91 -77
View File
@@ -1,25 +1,34 @@
import { Grid, GridItem, Box, useToast, useDisclosure } from "@chakra-ui/react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { useState } from "react";
import {
Grid,
GridItem,
Box,
useToast,
useDisclosure,
Card, CardBody, CardHeader, Heading,
} from '@chakra-ui/react';
import {useSession} from 'next-auth/react';
import {useRouter} from 'next/router';
import type { Session } from "@/models/auth/Session";
import CardUser from "../components/layout/dashboard/card_user/CardUser";
import SearchFailCard from "../components/layout/dashboard/card_user/SearchFailCard";
import type {Session} from '@/models/auth/Session';
import CardUser from '../components/layout/dashboard/card_user/CardUser';
import SearchFailCard
from '../components/layout/dashboard/card_user/SearchFailCard';
import LeftPanel from "../components/layout/dashboard/left_panel/LeftPanel";
import ModalMatch from "@/components/layout/dashboard/match_notification/ModalMatch";
import Head from "next/head";
import { websiteName } from "@/lib/constants";
import { useQuery } from "@tanstack/react-query";
import LoadingPage from "@/components/LoadingPage";
import { Notification, NotificationType } from "@prisma/client";
import LeftPanel from '../components/layout/dashboard/left_panel/LeftPanel';
import ModalMatch
from '@/components/layout/dashboard/match_notification/ModalMatch';
import Head from 'next/head';
import {websiteName} from '@/lib/constants';
import {useQuery} from '@tanstack/react-query';
import LoadingPage from '@/components/LoadingPage';
import {Notification, NotificationType, User} from '@prisma/client';
import ChatList from '@/components/chat/ChatList';
export default function Dashboard() {
const router = useRouter();
const toast = useToast({ position: "top", isClosable: true });
const toast = useToast({position: 'top', isClosable: true});
const { data: session, status } = useSession();
const {data: session, status} = useSession({required: true});
const {
isLoading,
@@ -28,18 +37,18 @@ export default function Dashboard() {
error,
refetch: refetchLoggedUser,
} = useQuery({
queryKey: ["LoggedUser"],
enabled: status === "authenticated",
queryKey: ['LoggedUser'],
enabled: status === 'authenticated',
queryFn: async () => {
const { user } = session as unknown as Session;
const {user} = session as unknown as Session;
return fetch(`/api/users/${user.id}?include=Notification`)
.then((res) => {
return res.json();
})
.catch((err) => {
return err;
});
.then((res) => {
return res.json();
})
.catch((err) => {
return err;
});
},
});
@@ -49,84 +58,89 @@ export default function Dashboard() {
isLoading: isLoadingListUsers,
error: errorListUsers,
} = useQuery({
queryKey: ["ListUsers"],
enabled: status === "authenticated" && !isLoading,
queryKey: ['ListUsers'],
enabled: status === 'authenticated' && !isLoading,
queryFn: async () => {
return fetch(`/api/user/userDashboard?userID=${loggedUser.id}`) //exclure les profils déjà like ou dislike
.then((res) => res.json())
.catch((err) => {
return err;
});
return fetch(
`/api/user/userDashboard?userID=${loggedUser.id}`) //exclure les profils déjà like ou dislike
.then((res) => res.json())
.catch((err) => {
return err;
});
},
});
if (isLoading) {
if (status === "unauthenticated") router.push("/login");
return <LoadingPage />;
if (status === 'unauthenticated') router.push('/login');
return <LoadingPage/>;
}
if (isError) {
toast({
title: `Erreur lors de la récupération des données du profil`,
status: "error",
position: "top",
status: 'error',
position: 'top',
});
if (status === "unauthenticated") router.push("/");
if (status === 'unauthenticated') router.push('/');
}
let modal;
if (loggedUser?.Notification?.length > 0) {
const matchNotification = loggedUser.Notification.filter(
(notif: Notification) =>
notif.type === NotificationType.NEW_MATCH &&
notif.hasBeenConsulted === false
(notif: Notification) =>
notif.type === NotificationType.NEW_MATCH &&
notif.hasBeenConsulted === false,
);
modal = matchNotification.map((notif: Notification) => {
return (
<ModalMatch notif={notif} key={notif.id} loggedUser={loggedUser} />
<ModalMatch notif={notif} key={notif.id} loggedUser={loggedUser}/>
);
});
}
if (status === 'loading') return <LoadingPage/>;
return (
<>
{modal}
<>
{modal}
<Head>
<title>{websiteName} | Dashboard</title>
</Head>
<Head>
<title>{websiteName} | Dashboard</title>
</Head>
<Grid
templateColumns={"repeat(5, 1fr)"}
templateRows={"repeat(2, 1fr)"}
gap={5}
minH={"100vh"}
>
<GridItem area={"1 / 1 / 3 / 2"}>
<LeftPanel user={loggedUser} />
</GridItem>
<GridItem area={"1 / 2 / 3 / 4"}>
<Box py={3}>
{isLoadingListUsers ? (
<LoadingPage />
) : isErrorListUsers ||
listUsers === undefined ||
listUsers.users === undefined ||
listUsers.users.length === 0 ? (
<SearchFailCard />
) : (
<CardUser
users={listUsers.users}
loggedUser={loggedUser}
refetchLoggedUser={refetchLoggedUser}
/>
)}
</Box>
</GridItem>
<GridItem area={"1 / 4 / 2 / 6"}>{/*Right top*/}</GridItem>
<GridItem area={"2 / 4 / 3 / 6"}>{/*Right Bottom*/}</GridItem>
</Grid>
</>
<Grid templateColumns={'repeat(5, 1fr)'}
templateRows={'repeat(2, 1fr)'}
gap={5}
minH={'100vh'}>
<GridItem area={'1 / 1 / 3 / 2'}>
<LeftPanel user={loggedUser}/>
</GridItem>
<GridItem area={'1 / 2 / 3 / 4'}>
<Box py={3}>
{isLoadingListUsers
? (<LoadingPage/>)
: (isErrorListUsers || !listUsers || !listUsers.users ||
listUsers.users.length === 0)
? <SearchFailCard/>
: <CardUser users={listUsers.users} loggedUser={loggedUser}
refetchLoggedUser={refetchLoggedUser}/>
}
</Box>
</GridItem>
<GridItem area={'1 / 4 / 2 / 6'}>
<Box py={3} pr={3}>
<Card w={"100%"} h={"100%"} borderRadius={"1rem"}>
<CardHeader>
<Heading cursor={"pointer"} size='md' onClick={() => {router.push('/chat')}}>Conversations</Heading>
</CardHeader>
<CardBody>
<ChatList user={session?.user as User}/>
</CardBody>
</Card>
</Box>
</GridItem>
<GridItem area={'2 / 4 / 3 / 6'}>{/*Right Bottom*/}</GridItem>
</Grid>
</>
);
}