mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-07-09 15:08:06 +00:00
feat(Like / dislike API ): more efficient api + checks and returns if match
This commit is contained in:
@@ -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 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;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onError: (err) => {
|
|
||||||
toast({
|
|
||||||
title: "Erreur",
|
|
||||||
description: "Une erreur est survenue",
|
|
||||||
status: "error",
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
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({
|
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 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;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onError: (err) => {
|
|
||||||
toast({
|
|
||||||
title: "Erreur",
|
|
||||||
description: "Une erreur est survenue",
|
|
||||||
status: "error",
|
|
||||||
duration: 2000,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
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({
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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" });
|
||||||
|
};
|
||||||
@@ -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" });
|
||||||
|
};
|
||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user