feat(Like / dislike API ): more efficient api + checks and returns if match

This commit is contained in:
Laurian-Dufrechou
2023-05-03 00:35:40 +02:00
parent edcf469c29
commit a2ffdf1edb
5 changed files with 195 additions and 82 deletions
@@ -34,94 +34,76 @@ export default function CardUser({
const [listUsers, setListUsers] = useState(users);
const likeMutation = useMutation({
mutationKey: "like",
mutationFn: async (id) => {
let jsonLikes = { UserLikes: { connect: [] } };
const likePostOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
idUser: loggedUser.id,
idUserLiked: id,
}),
};
let newUserLikesList = [...userLikes, id];
newUserLikesList.forEach((id) => {
jsonLikes.UserLikes.connect.push({ id: id });
});
return fetch(`/api/users/${loggedUser.id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(jsonLikes),
})
.then((res) => {
setListUsers(listUsers.slice(1));
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",
});
try {
const res = await fetch(`/api/user/like`, likePostOptions);
const response = await res.json();
return response;
} catch (err) {
return err;
}
},
onSuccess: (data) => {
if (data.error) {
toast({
title: "Erreur",
description: "Une erreur est survenue",
status: "error",
});
return;
}
setListUsers(listUsers.slice(1));
setUserLikes([...userLikes, data.userLiked]);
toast({
title: "J'aime",
description: "Votre action a bien été prise en compte",
status: "success",
});
//tester si match et afficher un truc
},
});
const dislikeMutation = useMutation({
mutationKey: "dislike",
mutationFn: async (id) => {
let jsonDislikes = { UserDislikes: { connect: [] } };
const dislikePostOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
idUser: loggedUser.id,
idUserDisliked: id,
}),
};
let newUserDislikesList = [...userDislikes, id];
newUserDislikesList.forEach((id) => {
jsonDislikes.UserDislikes.connect.push({ id: id });
});
return fetch(`/api/users/${loggedUser.id}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(jsonDislikes),
})
.then((res) => {
setListUsers(listUsers.slice(1));
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,
});
try {
const res = await fetch(`/api/user/dislike`, dislikePostOptions);
const response = await res.json();
return response;
} catch (err) {
return err;
}
},
onSuccess: (data) => {
if (data.error) {
toast({
title: "Erreur",
description: "Une erreur est survenue",
status: "error",
duration: 2000,
});
return;
}
setListUsers(listUsers.slice(1));
setUserDislikes([...userDislikes, data.userDisliked]);
toast({
title: "J'aime pas",
description: "Votre action a bien été prise en compte",
@@ -147,7 +129,7 @@ export default function CardUser({
},
});
const formateDateToAge = (birthdate) => {
const formateDateToAge = (birthdate: Date) => {
const date = new Date(birthdate);
var ageDifMs = Date.now() - date.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
@@ -177,6 +159,7 @@ export default function CardUser({
<Flex gap={1}>
<IconButton
aria-label="like"
borderRadius={"1rem"}
colorScheme={"purple"}
onClick={() => {
@@ -186,6 +169,7 @@ export default function CardUser({
<BiHeart />
</IconButton>
<IconButton
aria-label="dislike"
borderRadius={"1rem"}
colorScheme={"purple"}
variant={"outline"}
@@ -0,0 +1,36 @@
import {
Editable,
EditablePreview,
FormControl,
FormHelperText,
FormLabel,
UseEditableProps,
} from "@chakra-ui/react";
type CustomEditableProps = {
id: string;
label: string;
helperText?: string;
} & UseEditableProps;
export default function CustomEditable(props: CustomEditableProps) {
const { label, id, helperText = "", ...UseEditableProps } = props;
return (
<FormControl>
<FormLabel as="legend" htmlFor={id}>
{label}
</FormLabel>
<Editable
{...UseEditableProps}
fontWeight="bold"
isDisabled={true}
placeholder={"Non renseigné"}
color={"gray.500"}
>
<EditablePreview />
</Editable>
<FormHelperText>{helperText}</FormHelperText>
</FormControl>
);
}
+39
View File
@@ -0,0 +1,39 @@
const { PrismaClient } = require("@prisma/client");
const post = async (req, res) => {
const { idUser, idUserDisliked } = req.body;
const prisma = new PrismaClient();
try {
await prisma.user.update({
where: {
id: idUser,
},
data: {
UserDislikes: {
connect: {
id: idUserDisliked,
},
},
},
});
res.status(200).json({
success: true,
message: "disliked",
userDisliked: idUserDisliked,
});
} catch (err) {
res.status(500).json({
success: false,
error: err,
message: "Error",
});
}
};
export default (req, res) => {
req.method === "POST"
? post(req, res)
: res.status(404).send({ message: "Wrong method, please use POST" });
};
+56
View File
@@ -0,0 +1,56 @@
const { PrismaClient } = require("@prisma/client");
import { NotificationType } from "@prisma/client";
const post = async (req, res) => {
const { idUser, idUserLiked } = req.body;
const prisma = new PrismaClient();
try {
const likedByList = await prisma.user.findUnique({
where: {
id: idUser,
},
select: {
OtherUserLikesID: true,
},
});
const match = likedByList.OtherUserLikesID.includes(idUserLiked);
//faire une notification mais faut qu'on regarde un meilleur moyen dans la BD
await prisma.user.update({
where: {
id: idUser,
},
data: {
UserLikes: {
connect: {
id: idUserLiked,
},
},
},
});
res.status(200).json({
success: true,
message: "Liked",
match: match,
userLiked: idUserLiked,
});
} catch (err) {
console.log(err);
res.status(500).json({
success: false,
error: err,
message: "Error",
});
}
};
export default (req, res) => {
req.method === "POST"
? post(req, res)
: res.status(404).send({ message: "Wrong method, please use POST" });
};
+8 -10
View File
@@ -9,6 +9,7 @@ import {
Center,
Container,
Divider,
Editable,
Flex,
FormHelperText,
FormLabel,
@@ -22,6 +23,7 @@ import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePass
import ProfileTagList from "@/components/layout/user_profile/ProfileTagList";
import LoadingPage from "@/components/LoadingPage";
import CustomEditable from "@/components/layout/user_profile/CustomEditable";
import CustomFalseEditable from "@/components/layout/user_profile/CustomFalseEditable";
import CustomEditableArea from "@/components/layout/user_profile/CustomEditableArea";
import CustomRadioGender from "@/components/layout/user_profile/CustomRadioGender";
import CustomRangeSlider from "@/components/layout/user_profile/CustomRangeSlider";
@@ -206,16 +208,14 @@ export default function UserProfile() {
/>
</Box>
<Box>
<CustomEditable
name="birthdate"
isDisabled={true}
<CustomFalseEditable
id="birthdate"
defaultValue={
userData.birthdate === undefined ||
userData.birthdate === null
? "Non renseigné"
: formateDate(userData.birthdate.toString())
}
control={control}
label={"Date de naissance :"}
/>
</Box>
@@ -223,15 +223,14 @@ export default function UserProfile() {
<Divider colorScheme={"purple"} />
<Flex justify={"space-between"} my={"1rem"}>
<Box>
<CustomEditable
name="location"
<CustomFalseEditable
id="location"
isDisabled={true}
defaultValue={
userData.location === null || userData.location === ""
? "Rendez vous sur la carte"
: userData.location
}
control={control}
label={"Ville :"}
helperText={
"Ce champ est modifié automatiquement depuis la carte"
@@ -239,11 +238,10 @@ export default function UserProfile() {
/>
</Box>
<Box>
<CustomEditable
name="email"
<CustomFalseEditable
id="email"
isDisabled={true}
defaultValue={userData.email}
control={control}
label={"Adresse mail :"}
/>
</Box>