mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-05-13 17:21:53 +00:00
feat(like / dislike): Added possibility to like and dislike
This commit is contained in:
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||
}
|
||||
@@ -40,9 +40,17 @@ model User {
|
||||
UserLikes User[] @relation("Likes", fields: [UserLikesID], references: [id])
|
||||
|
||||
// Les personnes qui aiment l'utilisateur
|
||||
OtherUserLikesID String[] @db.ObjectId
|
||||
OtherUserLikesID String[] @db.ObjectId
|
||||
OtherUserLikes User[] @relation("Likes", fields: [OtherUserLikesID], references: [id])
|
||||
|
||||
// Les personnes que l'utilisateur a dislike
|
||||
UserDislikesID String[] @db.ObjectId
|
||||
UserDislikes User[] @relation("Dislikes", fields: [UserDislikesID], references: [id])
|
||||
|
||||
// Les personnes qui aiment l'utilisateur
|
||||
OtherUserDislikesID String[] @db.ObjectId
|
||||
OtherUserDislikes User[] @relation("Dislikes", fields: [OtherUserDislikesID], references: [id])
|
||||
|
||||
MatchID String[] @db.ObjectId
|
||||
Match Match[] @relation(fields: [MatchID], references: [id])
|
||||
|
||||
|
||||
@@ -7,19 +7,118 @@ import {
|
||||
Heading,
|
||||
Box,
|
||||
CardHeader,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import Carousel from "../../../Carousel";
|
||||
import { BiHeart } from "react-icons/bi";
|
||||
import { RxCross1 } from "react-icons/rx";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
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(props) {
|
||||
const { user, loggedUser, userLiked, setLiked, userDisliked, setDisliked } =
|
||||
props;
|
||||
const {
|
||||
users,
|
||||
loggedUser,
|
||||
userLikes,
|
||||
setUserLikes,
|
||||
userDislikes,
|
||||
setUserDislikes,
|
||||
} = props;
|
||||
|
||||
const [hidden, setHidden] = useState(false);
|
||||
console.log(userLikes);
|
||||
console.log(userDislikes);
|
||||
|
||||
const toast = useToast({
|
||||
position: "top",
|
||||
duration: 3000,
|
||||
isClosable: true,
|
||||
});
|
||||
const [listUsers, setListUsers] = useState(users);
|
||||
|
||||
const likeMutation = useMutation({
|
||||
mutationKey: "like",
|
||||
mutationFn: async (id) => {
|
||||
return fetch(`/api/users/${loggedUser.id}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ UserLikesID: [...userLikes, id] }),
|
||||
})
|
||||
.then((res) => {
|
||||
setUserLikes([...userLikes, user.id]);
|
||||
toast({
|
||||
title: "J'aime",
|
||||
description: "Votre action a bien été prise en compte",
|
||||
status: "success",
|
||||
});
|
||||
res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
return err;
|
||||
});
|
||||
},
|
||||
onError: (err) => {
|
||||
toast({
|
||||
title: "Erreur",
|
||||
description: "Une erreur est survenue",
|
||||
status: "error",
|
||||
duration: 2000,
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
toast({
|
||||
title: "J'aime",
|
||||
description: "Votre action a bien été prise en compte",
|
||||
status: "success",
|
||||
duration: 2000,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const dislikeMutation = useMutation({
|
||||
mutationKey: "dislike",
|
||||
mutationFn: async (id) => {
|
||||
return fetch(`/api/users/${loggedUser.id}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ UserDislikesID: [...userDislikes, id] }),
|
||||
})
|
||||
.then((res) => {
|
||||
setUserDislikes([...userDislikes, user.id]);
|
||||
toast({
|
||||
title: "J'aime pas",
|
||||
description: "Votre action a bien été prise en compte",
|
||||
status: "success",
|
||||
});
|
||||
res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
return err;
|
||||
});
|
||||
},
|
||||
onError: (err) => {
|
||||
toast({
|
||||
title: "Erreur",
|
||||
description: "Une erreur est survenue",
|
||||
status: "error",
|
||||
duration: 2000,
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
toast({
|
||||
title: "J'aime pas",
|
||||
description: "Votre action a bien été prise en compte",
|
||||
status: "success",
|
||||
duration: 2000,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
isLoading: passionLoading,
|
||||
@@ -44,24 +143,25 @@ export default function CardUser(props) {
|
||||
return Math.abs(ageDate.getUTCFullYear() - 1970);
|
||||
};
|
||||
|
||||
if (listUsers.length === 0) {
|
||||
return <SearchFailCard />;
|
||||
}
|
||||
|
||||
if (likeMutation.isLoading || dislikeMutation.isLoading) {
|
||||
return <LoadingPage />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
// position={"absolute"}
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
borderRadius={"1rem"}
|
||||
overflow={"hidden"}
|
||||
hidden={hidden}
|
||||
>
|
||||
<Card w={"100%"} h={"100%"} borderRadius={"1rem"} overflow={"hidden"}>
|
||||
<CardHeader>
|
||||
<Carousel borderRadius={"1rem"} images={user.images} />
|
||||
<Carousel borderRadius={"1rem"} images={listUsers[0].images} />
|
||||
</CardHeader>
|
||||
|
||||
<CardBody>
|
||||
<Flex justify={"space-between"} mb={"20px"}>
|
||||
<Heading fontSize={"1.5rem"} fontWeight={"bold"} flexBasis={"70%"}>
|
||||
{user.firstName} {user.lastName}, {formateDateToAge(user.birthdate)}{" "}
|
||||
ans
|
||||
{listUsers[0].firstName} {listUsers[0].lastName},{" "}
|
||||
{formateDateToAge(listUsers[0].birthdate)} ans
|
||||
</Heading>
|
||||
|
||||
<Flex gap={1}>
|
||||
@@ -69,8 +169,8 @@ export default function CardUser(props) {
|
||||
borderRadius={"1rem"}
|
||||
colorScheme={"purple"}
|
||||
onClick={() => {
|
||||
// setLiked([...userLiked, user.id]);
|
||||
setHidden(true);
|
||||
likeMutation.mutate(listUsers[0].id);
|
||||
setListUsers(listUsers.slice(1));
|
||||
}}
|
||||
>
|
||||
<BiHeart />
|
||||
@@ -79,7 +179,10 @@ export default function CardUser(props) {
|
||||
borderRadius={"1rem"}
|
||||
colorScheme={"purple"}
|
||||
variant={"outline"}
|
||||
// onClick={setDisiked([...userDisliked, user.id])}
|
||||
onClick={() => {
|
||||
dislikeMutation.mutate(listUsers[0].id);
|
||||
setListUsers(listUsers.slice(1));
|
||||
}}
|
||||
>
|
||||
<RxCross1 />
|
||||
</IconButton>
|
||||
@@ -90,7 +193,7 @@ export default function CardUser(props) {
|
||||
<Heading size={"sm"} fontWeight={"bold"} mb="0.5rem">
|
||||
A propos :
|
||||
</Heading>
|
||||
<Text as="i">"{user.bio}"</Text>
|
||||
<Text as="i">"{listUsers[0].bio}"</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
@@ -103,7 +206,7 @@ export default function CardUser(props) {
|
||||
<Text>Erreur lors du chargement des passions</Text>
|
||||
) : (
|
||||
<PassionTagList
|
||||
passions={user.PassionID}
|
||||
passions={listUsers[0].PassionID}
|
||||
userPassions={loggedUser.PassionID}
|
||||
listPassions={listPassions}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
import { error } from "console";
|
||||
|
||||
const { PrismaClient } = require("@prisma/client");
|
||||
|
||||
const get = async (req, res) => {
|
||||
const { preference, excludedId } = req.query;
|
||||
const { preference, excludedId, userLikes, userDislikes } = req.query;
|
||||
|
||||
let userLikesList = userLikes.split(",");
|
||||
let userDislikesList = userDislikes.split(",");
|
||||
if (userLikesList[0] === "") {
|
||||
userLikesList = [];
|
||||
}
|
||||
if (userDislikesList[0] === "") {
|
||||
userDislikesList = [];
|
||||
}
|
||||
|
||||
const excludedIdArray = [excludedId, ...userLikesList, ...userDislikesList];
|
||||
const prisma = new PrismaClient();
|
||||
// a terme mettre l'age, la distance
|
||||
const users = await prisma.user
|
||||
@@ -9,15 +22,16 @@ const get = async (req, res) => {
|
||||
where: {
|
||||
AND: [
|
||||
{ gender: { equals: preference } },
|
||||
{ images: { isEmpty: false }, NOT: { id: { equals: excludedId } } },
|
||||
{ images: { isEmpty: false } },
|
||||
{ id: { notIn: excludedIdArray } },
|
||||
],
|
||||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
return null;
|
||||
return e;
|
||||
});
|
||||
if (!users) {
|
||||
return res.status(500).send({ message: "Internal server error" });
|
||||
return res.status(500).send({ error: "Aucun profil trouvé" });
|
||||
}
|
||||
return res.status(200).send({ users });
|
||||
};
|
||||
|
||||
+22
-18
@@ -1,7 +1,7 @@
|
||||
import { Grid, GridItem, Text, Box, useToast } from "@chakra-ui/react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import type { Session } from "@/models/auth/Session";
|
||||
import CardUser from "../components/layout/dashboard/card_user/CardUser";
|
||||
@@ -16,8 +16,8 @@ import LoadingPage from "@/components/LoadingPage";
|
||||
export default function Dashboard() {
|
||||
const router = useRouter();
|
||||
const toast = useToast({ position: "top", isClosable: true });
|
||||
const [liked, setLiked] = useState(null);
|
||||
const [disliked, setDisliked] = useState(null);
|
||||
const [userLikes, setUserLikes] = useState();
|
||||
const [userDislikes, setUserDislikes] = useState();
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
@@ -32,8 +32,13 @@ export default function Dashboard() {
|
||||
queryFn: async () => {
|
||||
const { user } = session as unknown as Session;
|
||||
|
||||
setUserDislikes([...user.UserDislikesID]);
|
||||
setUserLikes([...user.UserLikesID]);
|
||||
|
||||
return fetch(`/api/users/${user.id}`)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
return err;
|
||||
});
|
||||
@@ -50,7 +55,7 @@ export default function Dashboard() {
|
||||
enabled: status === "authenticated" && !isLoading,
|
||||
queryFn: async () => {
|
||||
return fetch(
|
||||
`/api/user/userDashboard?preference=${loggedUser.gender}&excludedId=${loggedUser.id}`
|
||||
`/api/user/userDashboard?preference=${loggedUser.gender}&excludedId=${loggedUser.id}&userLikes=${loggedUser.UserLikesID}&userDislikes=${loggedUser.UserDislikesID}`
|
||||
) //exclure les profils déjà like ou dislike
|
||||
.then((res) => res.json())
|
||||
.catch((err) => {
|
||||
@@ -93,21 +98,20 @@ export default function Dashboard() {
|
||||
<Box py={3}>
|
||||
{isLoadingListUsers ? (
|
||||
<LoadingPage />
|
||||
) : listUsers.users.length === 0 && listUsers.users === null ? (
|
||||
) : isErrorListUsers ||
|
||||
listUsers.users === undefined ||
|
||||
listUsers.users.length === 0 ? (
|
||||
<SearchFailCard />
|
||||
) : (
|
||||
listUsers.users.map((user: any) => (
|
||||
// dans cardUser, mettre une liste de user, utiliser le user[0] et quand like ou dislike, supprimer le user[0] de la liste
|
||||
<CardUser
|
||||
key={user.id}
|
||||
user={user}
|
||||
loggedUser={loggedUser}
|
||||
userLiked={liked}
|
||||
setLiked={setLiked}
|
||||
userDisliked={disliked}
|
||||
setDisliked={setDisliked}
|
||||
/>
|
||||
))
|
||||
// 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}
|
||||
userLikes={userLikes}
|
||||
setUserLikes={setUserLikes}
|
||||
userDislikes={userDislikes}
|
||||
setUserDislikes={setUserDislikes}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</GridItem>
|
||||
|
||||
Reference in New Issue
Block a user