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 [listUsers, setListUsers] = useState(users);
const likeMutation = useMutation({ const likeMutation = useMutation({
mutationKey: "like",
mutationFn: async (id) => { 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]; try {
const res = await fetch(`/api/user/like`, likePostOptions);
newUserLikesList.forEach((id) => { const response = await res.json();
jsonLikes.UserLikes.connect.push({ id: id }); return response;
}); } catch (err) {
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; return err;
}); }
}, },
onError: (err) => { onSuccess: (data) => {
if (data.error) {
toast({ toast({
title: "Erreur", title: "Erreur",
description: "Une erreur est survenue", description: "Une erreur est survenue",
status: "error", status: "error",
}); });
}, return;
onSuccess: (data) => { }
setListUsers(listUsers.slice(1));
setUserLikes([...userLikes, data.userLiked]);
toast({ toast({
title: "J'aime", title: "J'aime",
description: "Votre action a bien été prise en compte", description: "Votre action a bien été prise en compte",
status: "success", status: "success",
}); });
//tester si match et afficher un truc
}, },
}); });
const dislikeMutation = useMutation({ const dislikeMutation = useMutation({
mutationKey: "dislike",
mutationFn: async (id) => { 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]; try {
const res = await fetch(`/api/user/dislike`, dislikePostOptions);
newUserDislikesList.forEach((id) => { const response = await res.json();
jsonDislikes.UserDislikes.connect.push({ id: id }); return response;
}); } catch (err) {
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; return err;
}); }
}, },
onError: (err) => { onSuccess: (data) => {
if (data.error) {
toast({ toast({
title: "Erreur", title: "Erreur",
description: "Une erreur est survenue", description: "Une erreur est survenue",
status: "error", status: "error",
duration: 2000, duration: 2000,
}); });
}, return;
onSuccess: (data) => { }
setListUsers(listUsers.slice(1));
setUserDislikes([...userDislikes, data.userDisliked]);
toast({ toast({
title: "J'aime pas", title: "J'aime pas",
description: "Votre action a bien été prise en compte", 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); const date = new Date(birthdate);
var ageDifMs = Date.now() - date.getTime(); var ageDifMs = Date.now() - date.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch var ageDate = new Date(ageDifMs); // miliseconds from epoch
@@ -177,6 +159,7 @@ export default function CardUser({
<Flex gap={1}> <Flex gap={1}>
<IconButton <IconButton
aria-label="like"
borderRadius={"1rem"} borderRadius={"1rem"}
colorScheme={"purple"} colorScheme={"purple"}
onClick={() => { onClick={() => {
@@ -186,6 +169,7 @@ export default function CardUser({
<BiHeart /> <BiHeart />
</IconButton> </IconButton>
<IconButton <IconButton
aria-label="dislike"
borderRadius={"1rem"} borderRadius={"1rem"}
colorScheme={"purple"} colorScheme={"purple"}
variant={"outline"} 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, Center,
Container, Container,
Divider, Divider,
Editable,
Flex, Flex,
FormHelperText, FormHelperText,
FormLabel, FormLabel,
@@ -22,6 +23,7 @@ import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePass
import ProfileTagList from "@/components/layout/user_profile/ProfileTagList"; import ProfileTagList from "@/components/layout/user_profile/ProfileTagList";
import LoadingPage from "@/components/LoadingPage"; import LoadingPage from "@/components/LoadingPage";
import CustomEditable from "@/components/layout/user_profile/CustomEditable"; 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 CustomEditableArea from "@/components/layout/user_profile/CustomEditableArea";
import CustomRadioGender from "@/components/layout/user_profile/CustomRadioGender"; import CustomRadioGender from "@/components/layout/user_profile/CustomRadioGender";
import CustomRangeSlider from "@/components/layout/user_profile/CustomRangeSlider"; import CustomRangeSlider from "@/components/layout/user_profile/CustomRangeSlider";
@@ -206,16 +208,14 @@ export default function UserProfile() {
/> />
</Box> </Box>
<Box> <Box>
<CustomEditable <CustomFalseEditable
name="birthdate" id="birthdate"
isDisabled={true}
defaultValue={ defaultValue={
userData.birthdate === undefined || userData.birthdate === undefined ||
userData.birthdate === null userData.birthdate === null
? "Non renseigné" ? "Non renseigné"
: formateDate(userData.birthdate.toString()) : formateDate(userData.birthdate.toString())
} }
control={control}
label={"Date de naissance :"} label={"Date de naissance :"}
/> />
</Box> </Box>
@@ -223,15 +223,14 @@ export default function UserProfile() {
<Divider colorScheme={"purple"} /> <Divider colorScheme={"purple"} />
<Flex justify={"space-between"} my={"1rem"}> <Flex justify={"space-between"} my={"1rem"}>
<Box> <Box>
<CustomEditable <CustomFalseEditable
name="location" id="location"
isDisabled={true} isDisabled={true}
defaultValue={ defaultValue={
userData.location === null || userData.location === "" userData.location === null || userData.location === ""
? "Rendez vous sur la carte" ? "Rendez vous sur la carte"
: userData.location : userData.location
} }
control={control}
label={"Ville :"} label={"Ville :"}
helperText={ helperText={
"Ce champ est modifié automatiquement depuis la carte" "Ce champ est modifié automatiquement depuis la carte"
@@ -239,11 +238,10 @@ export default function UserProfile() {
/> />
</Box> </Box>
<Box> <Box>
<CustomEditable <CustomFalseEditable
name="email" id="email"
isDisabled={true} isDisabled={true}
defaultValue={userData.email} defaultValue={userData.email}
control={control}
label={"Adresse mail :"} label={"Adresse mail :"}
/> />
</Box> </Box>