feat(Preferences): Choose preferences -- Fetch user from pref

This commit is contained in:
Laurian-Dufrechou
2023-04-09 14:27:49 +02:00
parent b2325fee0f
commit d10c7fcc71
7 changed files with 239 additions and 51 deletions
+7
View File
@@ -24,6 +24,13 @@ model User {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Les préférences de l'utilisateur
distance Int @default(100)
ageMax Int @default(99)
ageMin Int @default(18)
prefGender Gender @default(UNKNOWN)
// Liste des chats de l'utilisateur
ChatID String[] @db.ObjectId
Chat Chat[] @relation(fields: [ChatID], references: [id])
+4 -1
View File
@@ -27,8 +27,11 @@ const Carousel = ({ images, borderRadius: bRadius }: Props) => {
borderRadius={bRadius}
overflow={"hidden"}
justify={"space-between"}
bgColor={"purple.50"}
bgImage={images[currentIndex]}
bgSize={"cover"}
bgSize={"contain"}
bgRepeat={"no-repeat"}
bgPosition={"center"}
width={"100%"}
height={500}
>
@@ -28,12 +28,9 @@ export default function CardUser(props) {
setUserDislikes,
} = props;
console.log(userLikes);
console.log(userDislikes);
const toast = useToast({
position: "top",
duration: 3000,
duration: 2000,
isClosable: true,
});
const [listUsers, setListUsers] = useState(users);
@@ -66,7 +63,6 @@ export default function CardUser(props) {
title: "Erreur",
description: "Une erreur est survenue",
status: "error",
duration: 2000,
});
},
onSuccess: (data) => {
@@ -74,7 +70,6 @@ export default function CardUser(props) {
title: "J'aime",
description: "Votre action a bien été prise en compte",
status: "success",
duration: 2000,
});
},
});
@@ -154,7 +149,7 @@ export default function CardUser(props) {
return (
<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>
@@ -39,7 +39,12 @@ export default function LeftPanel(props) {
{user.images.length === 0 ? (
<Image src={"/blank_profile_picture.webp"} borderRadius={"1rem"} />
) : (
<Image src={user.images[0]} borderRadius={"1rem"} />
<Image
src={user.images[0]}
borderRadius={"1rem"}
objectFit={"contain"}
width={"100%"}
/>
)}
<Box mt={"2rem"}>
<Flex align={"center"} justifyContent="space-between" mb={"1rem"}>
+29 -6
View File
@@ -1,9 +1,26 @@
import { error } from "console";
const { PrismaClient } = require("@prisma/client");
const birthDateFromAge = (age) => {
const ageMillis = age * 365 * 24 * 60 * 60 * 1000;
return new Date(new Date().getTime() - ageMillis);
};
const get = async (req, res) => {
const { preference, excludedId, userLikes, userDislikes } = req.query;
const {
preferences: preferencesList,
excludedId,
userLikes,
userDislikes,
} = req.query;
const preferences = preferencesList.split(",");
const prefGender = preferences[0];
const dateAgeMin = birthDateFromAge(preferences[1]);
const dateAgeMax = birthDateFromAge(preferences[2]);
// pas utilisé pour le moment
const distance = preferences[3];
let userLikesList = userLikes.split(",");
let userDislikesList = userDislikes.split(",");
@@ -21,16 +38,22 @@ const get = async (req, res) => {
.findMany({
where: {
AND: [
{ gender: { equals: preference } },
{ gender: { equals: prefGender } },
{
birthdate: {
lte: dateAgeMin.toISOString(),
gte: dateAgeMax.toISOString(),
},
},
{ images: { isEmpty: false } },
{ id: { notIn: excludedIdArray } },
],
},
})
.catch((e) => {
return e;
return [];
});
if (!users) {
if (users.length === 0 || users === undefined || users === null) {
return res.status(500).send({ error: "Aucun profil trouvé" });
}
return res.status(200).send({ users });
+15 -1
View File
@@ -19,6 +19,8 @@ export default function Dashboard() {
const [userLikes, setUserLikes] = useState();
const [userDislikes, setUserDislikes] = useState();
const [preferences, setPreferences] = useState(null);
const { data: session, status } = useSession();
const {
@@ -35,6 +37,13 @@ export default function Dashboard() {
setUserDislikes([...user.UserDislikesID]);
setUserLikes([...user.UserLikesID]);
setPreferences([
user.prefGender,
user.ageMin,
user.ageMax,
user.distance,
]);
return fetch(`/api/users/${user.id}`)
.then((res) => {
return res.json();
@@ -45,6 +54,10 @@ export default function Dashboard() {
},
});
/*
Erreur quand je retourn de userProfile à dashboard
*/
const {
data: listUsers,
isError: isErrorListUsers,
@@ -55,7 +68,7 @@ export default function Dashboard() {
enabled: status === "authenticated" && !isLoading,
queryFn: async () => {
return fetch(
`/api/user/userDashboard?preference=${loggedUser.gender}&excludedId=${loggedUser.id}&userLikes=${loggedUser.UserLikesID}&userDislikes=${loggedUser.UserDislikesID}`
`/api/user/userDashboard?preferences=${preferences}&excludedId=${loggedUser.id}&userLikes=${loggedUser.UserLikesID}&userDislikes=${loggedUser.UserDislikesID}`
) //exclure les profils déjà like ou dislike
.then((res) => res.json())
.catch((err) => {
@@ -99,6 +112,7 @@ export default function Dashboard() {
{isLoadingListUsers ? (
<LoadingPage />
) : isErrorListUsers ||
listUsers === undefined ||
listUsers.users === undefined ||
listUsers.users.length === 0 ? (
<SearchFailCard />
+155 -14
View File
@@ -20,7 +20,16 @@ import {
HStack,
Radio,
RadioGroup,
RangeSlider,
RangeSliderFilledTrack,
RangeSliderThumb,
RangeSliderTrack,
Slider,
SliderFilledTrack,
SliderThumb,
SliderTrack,
Text,
Tooltip,
useToast,
VStack,
} from "@chakra-ui/react";
@@ -30,6 +39,8 @@ import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePass
import ProfileTagList from "@/components/layout/user_profile/ProfileTagList";
import LoadingPage from "@/components/LoadingPage";
import { FaGreaterThan, FaLessThan, FaWalking } from "react-icons/fa";
import { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { useQuery } from "@tanstack/react-query";
@@ -41,6 +52,11 @@ export default function UserProfile() {
const [currentlyLoading, setCurrentlyLoading] = useState(false);
const [passions, setPassions] = useState(null);
const [showTooltipAge, setShowTooltipAge] = useState(true);
const [sliderAgeValue, setSliderAgeValue] = useState([]);
const [showTooltipDistance, setShowTooltipDistance] = useState(true);
const [sliderDistanceValue, setSliderDistanceValue] = useState([]);
const {
handleSubmit,
control,
@@ -71,6 +87,9 @@ export default function UserProfile() {
queryFn: async () => {
const { user } = session as unknown as Session;
setSliderAgeValue([user.ageMin, user.ageMax]);
setSliderDistanceValue(user.distance);
return fetch(`/api/users/${user.id}`)
.then((res) => res.json())
.catch((err) => {
@@ -108,12 +127,19 @@ export default function UserProfile() {
};
const saveData = (values: any) => {
const trueValues = Object.keys(values).reduce((acc, key) => {
if (values[key] !== "" && values[key] !== undefined) {
acc[key] = values[key];
let trueValues = {};
console.log(values);
for (const [key, value] of Object.entries(values)) {
if (value !== "" && value !== undefined) {
if (key === "age") {
trueValues["ageMin"] = value[0];
trueValues["ageMax"] = value[1];
} else {
trueValues[key] = value;
}
}
}
return acc;
}, {});
const options = {
method: "PATCH",
@@ -392,17 +418,31 @@ export default function UserProfile() {
)}
/>
</Box>
{/* <Box>
<FormLabel as={"legend"} htmlFor={"preference"}>
Préference :
</Box>
<Divider colorScheme={"purple"} />
<Box my={"1rem"}>
<Center>
<Text as={"b"} fontSize={"1.5rem"} my={"1rem"}>
Préférences
</Text>
</Center>
<Box my={"1rem"}>
<FormLabel as={"legend"} htmlFor={"prefGender"}>
Genre :
</FormLabel>
<Controller
name={"prefGender"}
control={control}
render={({ field }) => (
<RadioGroup
id={"preference"}
{...field}
colorScheme={"purple"}
id={"prefGender"}
as="b"
value={
userData.preference === null
defaultValue={
userData.prefGender === null
? Gender.UNKNOWN
: userData.preference
: userData.gender
}
>
<HStack spacing={"0.5rem"}>
@@ -420,7 +460,106 @@ export default function UserProfile() {
</Radio>
</HStack>
</RadioGroup>
</Flex> */}
)}
/>
</Box>
<Box>
<FormLabel as={"legend"} htmlFor={"prefGender"}>
Age :
</FormLabel>
<Controller
name={"age"}
control={control}
render={({ field: { onChange } }) => (
<RangeSlider
aria-label={["min", "max"]}
colorScheme={"purple"}
min={18}
max={99}
id={"age"}
color={"pink.500"}
defaultValue={[userData.ageMin, userData.ageMax]}
onChange={(v) => {
setSliderAgeValue(v);
onChange(v);
}}
onMouseEnter={() => setShowTooltipAge(true)}
onMouseLeave={() => setShowTooltipAge(false)}
>
<RangeSliderTrack>
<RangeSliderFilledTrack bgColor={"purple.500"} />
</RangeSliderTrack>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipAge}
label={`${sliderAgeValue[0]}`}
>
<RangeSliderThumb boxSize={6} index={0}>
<Box color={"purple.500"} as={FaLessThan} />
</RangeSliderThumb>
</Tooltip>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipAge}
label={`${sliderAgeValue[1]}`}
>
<RangeSliderThumb boxSize={6} index={1}>
<Box color={"purple.500"} as={FaGreaterThan} />
</RangeSliderThumb>
</Tooltip>
</RangeSlider>
)}
/>
</Box>
{/* <Box>
<FormLabel as={"legend"} htmlFor={"distance"}>
Distance :
</FormLabel>
<Controller
name={"distance"}
control={control}
render={({ field: { onChange } }) => (
<Slider
aria-label={"distance"}
colorScheme={"purple"}
min={20}
max={250}
id={"distance"}
color={"pink.500"}
defaultValue={userData.distance}
onChange={(v) => {
setSliderDistanceValue(v);
onChange(v);
}}
onMouseEnter={() => setShowTooltipDistance(true)}
onMouseLeave={() => setShowTooltipDistance(false)}
>
<SliderTrack>
<SliderFilledTrack bgColor={"purple.500"} />
</SliderTrack>
<Tooltip
hasArrow
bg="purple.500"
color="white"
placement="top"
isOpen={showTooltipDistance}
label={`${sliderDistanceValue} km`}
>
<SliderThumb boxSize={6}>
<Box color={"purple.500"} as={FaWalking} />
</SliderThumb>
</Tooltip>
</Slider>
)}
/>
</Box> */}
</Box>
<Divider colorScheme={"purple"} />
<Center gap={"1rem"} my={"1rem"}>
@@ -434,7 +573,9 @@ export default function UserProfile() {
<Button
colorScheme={"purple"}
variant="outline"
onClick={() => router.push("/dashboard")}
onClick={() => {
router.push("/dashboard");
}}
>
Retour
</Button>