mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-05-13 17:21:53 +00:00
feat(UserMatch): Logique des matchs et notifications
Affichage d'un modal lorsqu'une notification de match n'est pas consulté
This commit is contained in:
@@ -61,6 +61,8 @@ model User {
|
||||
Match Match[] @relation(fields: [MatchID], references: [id])
|
||||
|
||||
Notification Notification[]
|
||||
|
||||
NotificationMatchedUser Notification[] @relation("matchedUser")
|
||||
}
|
||||
|
||||
model Notification {
|
||||
@@ -71,6 +73,9 @@ model Notification {
|
||||
|
||||
UserID String @db.ObjectId
|
||||
User User @relation(fields: [UserID], references: [id])
|
||||
|
||||
MatchedUserID String? @db.ObjectId
|
||||
MatchedUser User? @relation("matchedUser", fields: [MatchedUserID], references: [id])
|
||||
}
|
||||
|
||||
model Match {
|
||||
|
||||
@@ -8,20 +8,24 @@ import {
|
||||
Box,
|
||||
CardHeader,
|
||||
useToast,
|
||||
} from '@chakra-ui/react';
|
||||
import Carousel from '../../../Carousel';
|
||||
import {BiHeart} from 'react-icons/bi';
|
||||
import {RxCross1} from 'react-icons/rx';
|
||||
import {useMutation, useQuery} from '@tanstack/react-query';
|
||||
import PassionTagList
|
||||
from '@/components/layout/dashboard/card_user/PassionTagList';
|
||||
import {useState} from 'react';
|
||||
import SearchFailCard from './SearchFailCard';
|
||||
import LoadingPage from '@/components/LoadingPage';
|
||||
} from "@chakra-ui/react";
|
||||
import Carousel from "../../../Carousel";
|
||||
import { BiHeart } from "react-icons/bi";
|
||||
import { RxCross1 } from "react-icons/rx";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import PassionTagList from "@/components/layout/dashboard/card_user/PassionTagList";
|
||||
import { useState } from "react";
|
||||
import SearchFailCard from "./SearchFailCard";
|
||||
import LoadingPage from "@/components/LoadingPage";
|
||||
|
||||
export default function CardUser({users, loggedUser, setMatch}) {
|
||||
export default function CardUser({
|
||||
users,
|
||||
loggedUser,
|
||||
setMatch,
|
||||
refetchLoggedUser,
|
||||
}) {
|
||||
const toast = useToast({
|
||||
position: 'top',
|
||||
position: "top",
|
||||
duration: 2000,
|
||||
isClosable: true,
|
||||
});
|
||||
@@ -30,8 +34,8 @@ export default function CardUser({users, loggedUser, setMatch}) {
|
||||
const likeMutation = useMutation({
|
||||
mutationFn: async (id) => {
|
||||
const likePostOptions = {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
idUser: loggedUser.id,
|
||||
idUserLiked: id,
|
||||
@@ -49,20 +53,20 @@ export default function CardUser({users, loggedUser, setMatch}) {
|
||||
onSuccess: (data) => {
|
||||
if (data.error) {
|
||||
toast({
|
||||
title: 'Erreur',
|
||||
description: 'Une erreur est survenue',
|
||||
status: 'error',
|
||||
title: "Erreur",
|
||||
description: "Une erreur est survenue",
|
||||
status: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (data.match) {
|
||||
setMatch(true);
|
||||
refetchLoggedUser();
|
||||
}
|
||||
setListUsers(listUsers.slice(1));
|
||||
toast({
|
||||
title: 'J\'aime',
|
||||
description: 'Votre action a bien été prise en compte',
|
||||
status: 'success',
|
||||
title: "J'aime",
|
||||
description: "Votre action a bien été prise en compte",
|
||||
status: "success",
|
||||
});
|
||||
|
||||
//tester si match et afficher un truc
|
||||
@@ -72,8 +76,8 @@ export default function CardUser({users, loggedUser, setMatch}) {
|
||||
const dislikeMutation = useMutation({
|
||||
mutationFn: async (id) => {
|
||||
const dislikePostOptions = {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
idUser: loggedUser.id,
|
||||
idUserDisliked: id,
|
||||
@@ -91,18 +95,18 @@ export default function CardUser({users, loggedUser, setMatch}) {
|
||||
onSuccess: (data) => {
|
||||
if (data.error) {
|
||||
toast({
|
||||
title: 'Erreur',
|
||||
description: 'Une erreur est survenue',
|
||||
status: 'error',
|
||||
title: "Erreur",
|
||||
description: "Une erreur est survenue",
|
||||
status: "error",
|
||||
duration: 2000,
|
||||
});
|
||||
return;
|
||||
}
|
||||
setListUsers(listUsers.slice(1));
|
||||
toast({
|
||||
title: 'J\'aime pas',
|
||||
description: 'Votre action a bien été prise en compte',
|
||||
status: 'success',
|
||||
title: "J'aime pas",
|
||||
description: "Votre action a bien été prise en compte",
|
||||
status: "success",
|
||||
duration: 2000,
|
||||
});
|
||||
},
|
||||
@@ -114,11 +118,11 @@ export default function CardUser({users, loggedUser, setMatch}) {
|
||||
data: listPassions,
|
||||
error: passionError,
|
||||
} = useQuery({
|
||||
queryKey: ['passions'],
|
||||
queryKey: ["passions"],
|
||||
queryFn: async () => {
|
||||
return fetch(`/api/passions/`)
|
||||
.then(res => res.json())
|
||||
.catch(err => err);
|
||||
.then((res) => res.json())
|
||||
.catch((err) => err);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -129,55 +133,62 @@ export default function CardUser({users, loggedUser, setMatch}) {
|
||||
return Math.abs(ageDate.getUTCFullYear() - 1970);
|
||||
};
|
||||
|
||||
if (listUsers.length === 0) return <SearchFailCard/>;
|
||||
if (likeMutation.isLoading ||
|
||||
dislikeMutation.isLoading) return <LoadingPage/>;
|
||||
if (listUsers.length === 0) return <SearchFailCard />;
|
||||
if (likeMutation.isLoading || dislikeMutation.isLoading)
|
||||
return <LoadingPage />;
|
||||
|
||||
return (
|
||||
<Card w={'100%'} h={'100%'} borderRadius={'1rem'} overflow={'hidden'}>
|
||||
<Card w={"100%"} h={"100%"} borderRadius={"1rem"} overflow={"hidden"}>
|
||||
<CardHeader>
|
||||
<Carousel borderRadius={'1rem'} images={listUsers?.[0].images}/>
|
||||
<Carousel borderRadius={"1rem"} images={listUsers?.[0].images} />
|
||||
</CardHeader>
|
||||
|
||||
<CardBody>
|
||||
<Flex justify={'space-between'} mb={'20px'}>
|
||||
<Heading fontSize={'1.5rem'} fontWeight={'bold'} flexBasis={'70%'}>
|
||||
{listUsers[0].firstName} {listUsers[0].lastName},{' '}
|
||||
<Flex justify={"space-between"} mb={"20px"}>
|
||||
<Heading fontSize={"1.5rem"} fontWeight={"bold"} flexBasis={"70%"}>
|
||||
{listUsers[0].firstName} {listUsers[0].lastName},{" "}
|
||||
{formateDateToAge(listUsers[0].birthdate)} ans
|
||||
</Heading>
|
||||
|
||||
<Flex gap={1}>
|
||||
<IconButton icon={<BiHeart/>} aria-label="like"
|
||||
borderRadius={'1rem'}
|
||||
onClick={() => likeMutation.mutate(listUsers[0].id)
|
||||
}/>
|
||||
<IconButton icon={<RxCross1/>} aria-label="dislike"
|
||||
borderRadius={'1rem'} variant={'outline'}
|
||||
onClick={() => dislikeMutation.mutate(
|
||||
listUsers[0].id)}/>
|
||||
<IconButton
|
||||
icon={<BiHeart />}
|
||||
aria-label="like"
|
||||
borderRadius={"1rem"}
|
||||
onClick={() => likeMutation.mutate(listUsers[0].id)}
|
||||
/>
|
||||
<IconButton
|
||||
icon={<RxCross1 />}
|
||||
aria-label="dislike"
|
||||
borderRadius={"1rem"}
|
||||
variant={"outline"}
|
||||
onClick={() => dislikeMutation.mutate(listUsers[0].id)}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Box mb={'20px'}>
|
||||
<Heading size={'sm'} fontWeight={'bold'} mb="0.5rem">
|
||||
<Box mb={"20px"}>
|
||||
<Heading size={"sm"} fontWeight={"bold"} mb="0.5rem">
|
||||
A propos :
|
||||
</Heading>
|
||||
<Text as="i">"{listUsers[0].bio}"</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Heading size={'sm'} fontWeight={'bold'}>
|
||||
<Heading size={"sm"} fontWeight={"bold"}>
|
||||
Passions :
|
||||
</Heading>
|
||||
{passionLoading
|
||||
? <Text>Chargement des passions...</Text>
|
||||
: passionIsError
|
||||
? <Text>Erreur lors du chargement des passions</Text>
|
||||
:
|
||||
<PassionTagList passions={listUsers[0].PassionID}
|
||||
{passionLoading ? (
|
||||
<Text>Chargement des passions...</Text>
|
||||
) : passionIsError ? (
|
||||
<Text>Erreur lors du chargement des passions</Text>
|
||||
) : (
|
||||
<PassionTagList
|
||||
passions={listUsers[0].PassionID}
|
||||
userPassions={loggedUser.PassionID}
|
||||
listPassions={listPassions}/>
|
||||
}
|
||||
listPassions={listPassions}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
@@ -1,63 +1,91 @@
|
||||
import {Card, Flex, Box, Image, Text, Spacer, Divider} from '@chakra-ui/react';
|
||||
import {useRouter} from 'next/router';
|
||||
import {
|
||||
Card,
|
||||
Flex,
|
||||
Box,
|
||||
Image,
|
||||
Text,
|
||||
Spacer,
|
||||
Divider,
|
||||
} from "@chakra-ui/react";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import {AiFillMessage} from 'react-icons/ai';
|
||||
import {BsFillPersonFill} from 'react-icons/bs';
|
||||
import {BiLogOut} from 'react-icons/bi';
|
||||
import {FaMapMarkedAlt} from 'react-icons/fa';
|
||||
import { AiFillMessage } from "react-icons/ai";
|
||||
import { BsFillPersonFill } from "react-icons/bs";
|
||||
import { BiLogOut } from "react-icons/bi";
|
||||
import { FaMapMarkedAlt } from "react-icons/fa";
|
||||
|
||||
import LeftPanelButton
|
||||
from '@/components/layout/dashboard/left_panel/LeftPanelButton';
|
||||
import {signOut} from 'next-auth/react';
|
||||
import LeftPanelButton from "@/components/layout/dashboard/left_panel/LeftPanelButton";
|
||||
import { signOut } from "next-auth/react";
|
||||
|
||||
import { formateDate } from "@/lib/formateDate";
|
||||
|
||||
export default function LeftPanel(props) {
|
||||
const router = useRouter();
|
||||
const {user} = props;
|
||||
|
||||
const formateDate = (dateString) => {
|
||||
const options = {year: 'numeric', month: 'long', day: 'numeric'};
|
||||
return new Date(dateString).toLocaleDateString([], options);
|
||||
};
|
||||
const { user } = props;
|
||||
|
||||
return (
|
||||
<Card width={'20vw'} height={'100%'} borderRadius={0} padding={'0px'}
|
||||
bg={'#faf9ff'}>
|
||||
<Flex direction={'column'} height={'100%'} margin={'10%'}>
|
||||
<Card
|
||||
width={"20vw"}
|
||||
height={"100%"}
|
||||
borderRadius={0}
|
||||
padding={"0px"}
|
||||
bg={"#faf9ff"}
|
||||
>
|
||||
<Flex direction={"column"} height={"100%"} margin={"10%"}>
|
||||
<Box>
|
||||
<Image src={user.images[0] ?? '/blank_profile_picture.webp'}
|
||||
objectFit={'contain'} borderRadius={'1rem'}/>
|
||||
<Box mt={'2rem'}>
|
||||
<Flex align={'center'} justifyContent="space-between" mb={'1rem'}>
|
||||
<Text fontSize={'1.5rem'} fontWeight={'bold'}>
|
||||
<Image
|
||||
src={user.images[0] ?? "/blank_profile_picture.webp"}
|
||||
objectFit={"contain"}
|
||||
borderRadius={"1rem"}
|
||||
/>
|
||||
<Box mt={"2rem"}>
|
||||
<Flex align={"center"} justifyContent="space-between" mb={"1rem"}>
|
||||
<Text fontSize={"1.5rem"} fontWeight={"bold"}>
|
||||
{user.firstName} {user.lastName}
|
||||
</Text>
|
||||
<Text fontSize={'1rem'} fontWeight={'bold'}>
|
||||
<Text fontSize={"1rem"} fontWeight={"bold"}>
|
||||
{formateDate(user.birthdate)}
|
||||
</Text>
|
||||
</Flex>
|
||||
<Divider mb={'1rem'}/>
|
||||
<Text as="i" fontWeight={'bold'}>"{user.bio}"</Text>
|
||||
<Divider mb={"1rem"} />
|
||||
<Text as="i" fontWeight={"bold"}>
|
||||
"{user.bio}"
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<Spacer/>
|
||||
<Flex gap={2} direction={'column'} mt={'1vh'}
|
||||
spacing={3.5} alignContent={'bottom'}>
|
||||
<LeftPanelButton leftIcon={<FaMapMarkedAlt/>}
|
||||
onClickHandler={() => router.push('/map')}>
|
||||
<Spacer />
|
||||
<Flex
|
||||
gap={2}
|
||||
direction={"column"}
|
||||
mt={"1vh"}
|
||||
spacing={3.5}
|
||||
alignContent={"bottom"}
|
||||
>
|
||||
<LeftPanelButton
|
||||
leftIcon={<FaMapMarkedAlt />}
|
||||
onClickHandler={() => router.push("/map")}
|
||||
>
|
||||
Carte
|
||||
</LeftPanelButton>
|
||||
|
||||
<LeftPanelButton leftIcon={<AiFillMessage/>}
|
||||
onClickHandler={() => router.push('/dashboard')}>
|
||||
<LeftPanelButton
|
||||
leftIcon={<AiFillMessage />}
|
||||
onClickHandler={() => router.push("/dashboard")}
|
||||
>
|
||||
Messages
|
||||
</LeftPanelButton>
|
||||
|
||||
<LeftPanelButton leftIcon={<BsFillPersonFill/>}
|
||||
onClickHandler={() => router.push('/profile')}>
|
||||
<LeftPanelButton
|
||||
leftIcon={<BsFillPersonFill />}
|
||||
onClickHandler={() => router.push("/profile")}
|
||||
>
|
||||
Profil
|
||||
</LeftPanelButton>
|
||||
<LeftPanelButton variant={'outline'} leftIcon={<BiLogOut/>}
|
||||
onClickHandler={() => signOut({callbackUrl: '/'})}>
|
||||
<LeftPanelButton
|
||||
variant={"outline"}
|
||||
leftIcon={<BiLogOut />}
|
||||
onClickHandler={() => signOut({ callbackUrl: "/" })}
|
||||
>
|
||||
Déconnexion
|
||||
</LeftPanelButton>
|
||||
</Flex>
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Divider,
|
||||
Flex,
|
||||
Heading,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { SetStateAction } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { User } from "@prisma/client";
|
||||
import Carousel from "@/components/Carousel";
|
||||
import { MdWavingHand } from "react-icons/md";
|
||||
import { formateDate } from "@/lib/formateDate";
|
||||
import { Notification } from "@prisma/client";
|
||||
import PassionTagList from "../card_user/PassionTagList";
|
||||
|
||||
type modalMatchProps = {
|
||||
key: string;
|
||||
loggedUser: User;
|
||||
notif: Notification;
|
||||
};
|
||||
|
||||
export default function ModalMatch({ notif, loggedUser }: modalMatchProps) {
|
||||
const handleClose = () => {
|
||||
const options = {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ notificationId: notif.id }),
|
||||
};
|
||||
fetch(`/api/user/consultNotification`, options)
|
||||
.then((res) => res.json())
|
||||
.catch((err) => console.log(err));
|
||||
};
|
||||
|
||||
const { isOpen, onClose } = useDisclosure({
|
||||
defaultIsOpen: true,
|
||||
onClose: () => {
|
||||
handleClose();
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
isLoading,
|
||||
isError,
|
||||
data: matchedUser,
|
||||
error,
|
||||
} = useQuery({
|
||||
enabled: notif !== undefined,
|
||||
queryKey: ["matchUser"],
|
||||
queryFn: async () => {
|
||||
return fetch(`/api/users/${notif.MatchedUserID}`)
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
return err;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
isLoading: passionLoading,
|
||||
isError: passionIsError,
|
||||
data: listPassions,
|
||||
error: passionError,
|
||||
} = useQuery({
|
||||
queryKey: ["passions"],
|
||||
queryFn: async () => {
|
||||
return fetch(`/api/passions/`)
|
||||
.then((res) => res.json())
|
||||
.catch((err) => err);
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{matchedUser && (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay backdropBlur="2px" />
|
||||
<ModalContent>
|
||||
<ModalHeader align="center">
|
||||
<Text color={"purple.500"} fontWeight={"bold"}>
|
||||
Vous avez un nouveau match
|
||||
</Text>
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Carousel borderRadius={"1rem"} images={matchedUser.images} />
|
||||
<Box mt={"2rem"}>
|
||||
<Flex
|
||||
align={"center"}
|
||||
justifyContent="space-between"
|
||||
mb={"1rem"}
|
||||
>
|
||||
<Text fontSize={"1.5rem"} fontWeight={"bold"}>
|
||||
{matchedUser.firstName} {matchedUser.lastName}
|
||||
</Text>
|
||||
<Text fontSize={"1rem"} fontWeight={"bold"}>
|
||||
{formateDate(matchedUser.birthdate)}
|
||||
</Text>
|
||||
</Flex>
|
||||
<Divider mb={"1rem"} />
|
||||
<Text as="i" fontWeight={"bold"}>
|
||||
"{matchedUser.bio}"
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Heading size={"sm"} fontWeight={"bold"}>
|
||||
Passions :
|
||||
</Heading>
|
||||
{passionLoading ? (
|
||||
<Text>Chargement des passions...</Text>
|
||||
) : passionIsError ? (
|
||||
<Text>Erreur lors du chargement des passions</Text>
|
||||
) : (
|
||||
<PassionTagList
|
||||
passions={matchedUser.PassionID}
|
||||
userPassions={loggedUser.PassionID}
|
||||
listPassions={listPassions}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Flex gap={"1rem"}>
|
||||
<Button onClick={onClose}>Fermer</Button>
|
||||
<Button
|
||||
leftIcon={<MdWavingHand />}
|
||||
variant={"ghost"}
|
||||
onClick={onClose}
|
||||
>
|
||||
Saluer
|
||||
</Button>
|
||||
</Flex>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export const formateDate = (dateString: Date) => {
|
||||
const options = { year: "numeric", month: "long", day: "numeric" };
|
||||
return new Date(dateString).toLocaleDateString([], options);
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
const { PrismaClient } = require("@prisma/client");
|
||||
|
||||
const patch = async (req: any, res: any) => {
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const { notificationId } = req.body;
|
||||
|
||||
try {
|
||||
const notification = await prisma.notification.update({
|
||||
where: {
|
||||
id: notificationId,
|
||||
},
|
||||
data: {
|
||||
hasBeenConsulted: true,
|
||||
},
|
||||
});
|
||||
|
||||
res.status(200).json(notification);
|
||||
} catch (error) {
|
||||
res.status(400).json({ message: "Something went wrong" });
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
export default (req: any, res: any) => {
|
||||
req.method === "PATCH"
|
||||
? patch(req, res)
|
||||
: res.status(404).send({ message: "Wrong method, please use POST" });
|
||||
};
|
||||
@@ -21,23 +21,33 @@ const post = async (req, res) => {
|
||||
if (match) {
|
||||
await prisma.notification.create({
|
||||
data: {
|
||||
type: NotificationType.MATCH,
|
||||
user: {
|
||||
type: NotificationType.NEW_MATCH,
|
||||
User: {
|
||||
connect: {
|
||||
id: idUser,
|
||||
},
|
||||
},
|
||||
MatchedUser: {
|
||||
connect: {
|
||||
id: idUserLiked,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.notification.create({
|
||||
data: {
|
||||
type: NotificationType.MATCH,
|
||||
user: {
|
||||
type: NotificationType.NEW_MATCH,
|
||||
User: {
|
||||
connect: {
|
||||
id: idUserLiked,
|
||||
},
|
||||
},
|
||||
MatchedUser: {
|
||||
connect: {
|
||||
id: idUser,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
+22
-17
@@ -1,4 +1,4 @@
|
||||
import { Grid, GridItem, Text, Box, useToast } from "@chakra-ui/react";
|
||||
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";
|
||||
@@ -8,15 +8,16 @@ 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";
|
||||
|
||||
export default function Dashboard() {
|
||||
const router = useRouter();
|
||||
const toast = useToast({ position: "top", isClosable: true });
|
||||
const [newMatch, setNewMatch] = useState(false);
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
@@ -25,13 +26,14 @@ export default function Dashboard() {
|
||||
isError,
|
||||
data: loggedUser,
|
||||
error,
|
||||
refetch: refetchLoggedUser,
|
||||
} = useQuery({
|
||||
queryKey: ["LoggedUser"],
|
||||
enabled: status === "authenticated",
|
||||
queryFn: async () => {
|
||||
const { user } = session as unknown as Session;
|
||||
|
||||
return fetch(`/api/users/${user.id}`)
|
||||
return fetch(`/api/users/${user.id}?include=Notification`)
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
@@ -72,21 +74,25 @@ export default function Dashboard() {
|
||||
if (status === "unauthenticated") router.push("/");
|
||||
}
|
||||
|
||||
/**
|
||||
* UTILISER refetch (image sur discord)
|
||||
* https://tanstack.com/query/v3/docs/react/reference/useQuery ---> tout en bas
|
||||
*
|
||||
* dans onSuccess de useQuery
|
||||
* on filtre l'objet Notification de loggedUser par le type (match)
|
||||
* setMatchNotification = [...filteredNotification],
|
||||
*
|
||||
* et on passe dans le modal la premiere notif de type match
|
||||
* et on enleve au fur et a mesure (sur la BD aussi)
|
||||
*
|
||||
*/
|
||||
let modal;
|
||||
|
||||
if (loggedUser?.Notification?.length > 0) {
|
||||
const matchNotification = loggedUser.Notification.filter(
|
||||
(notif: Notification) =>
|
||||
notif.type === NotificationType.NEW_MATCH &&
|
||||
notif.hasBeenConsulted === false
|
||||
);
|
||||
modal = matchNotification.map((notif: Notification) => {
|
||||
return (
|
||||
<ModalMatch notif={notif} key={notif.id} loggedUser={loggedUser} />
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{modal}
|
||||
|
||||
<Head>
|
||||
<title>{websiteName} | Dashboard</title>
|
||||
</Head>
|
||||
@@ -110,11 +116,10 @@ export default function Dashboard() {
|
||||
listUsers.users.length === 0 ? (
|
||||
<SearchFailCard />
|
||||
) : (
|
||||
// dans cardUser, mettre une liste de user, utiliser le user[0] et quand like ou dislike, supprimer le user[0] de la liste
|
||||
<CardUser
|
||||
users={listUsers.users}
|
||||
loggedUser={loggedUser}
|
||||
setMatch={setNewMatch}
|
||||
refetchLoggedUser={refetchLoggedUser}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user