diff --git a/package-lock.json b/package-lock.json
index afee2ad..b89902c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,6 +18,7 @@
"bcrypt": "^5.1.0",
"eslint": "8.35.0",
"eslint-config-next": "13.2.3",
+ "form-data": "^4.0.0",
"formidable": "^2.1.1",
"framer-motion": "^10.8.5",
"fs": "^0.0.1-security",
@@ -2722,6 +2723,11 @@
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
"optional": true
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
"node_modules/available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
@@ -3074,6 +3080,17 @@
"resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz",
"integrity": "sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w=="
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -3328,6 +3345,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@@ -4165,6 +4190,19 @@
"is-callable": "^1.1.3"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/formidable": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz",
@@ -5547,6 +5585,25 @@
"node": ">=8.6"
}
},
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
diff --git a/package.json b/package.json
index e490ec2..d33a693 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"bcrypt": "^5.1.0",
"eslint": "8.35.0",
"eslint-config-next": "13.2.3",
+ "form-data": "^4.0.0",
"formidable": "^2.1.1",
"framer-motion": "^10.8.5",
"fs": "^0.0.1-security",
diff --git a/src/components/ModalModifyImages.jsx b/src/components/ModalModifyImages.jsx
index 66e866b..366f00c 100644
--- a/src/components/ModalModifyImages.jsx
+++ b/src/components/ModalModifyImages.jsx
@@ -12,16 +12,70 @@ import {
ModalFooter,
ModalHeader,
ModalOverlay,
- Text,
useDisclosure,
+ useToast,
} from "@chakra-ui/react";
import { useState } from "react";
import { RiEditBoxLine } from "react-icons/ri";
export default function ModalModifyImages(props) {
const { isOpen, onOpen, onClose } = useDisclosure();
- const { images, userData, setUserData, files, setFiles } = props;
+ const { images, user, userData, setUserData, files, setFiles } = props;
const [listImage, setlistImage] = useState(images);
+ const toast = useToast();
+
+ const uploadImage = async (file) => {
+ console.log(file);
+ const body = new FormData();
+ body.append("file", file);
+ const imagePostOptions = {
+ method: "POST",
+ body,
+ };
+
+ fetch(`/api/file/file`, imagePostOptions)
+ .then((res) => {
+ console.log(res);
+ toast({
+ title: `Ajout d'image effectué`,
+ status: "success",
+ isClosable: true,
+ });
+ })
+ .catch((err) => {
+ toast({
+ title: `Erreur lors de l'ajout des images`,
+ status: "error",
+ isClosable: true,
+ });
+ console.log(err);
+ });
+ };
+
+ const deleteImage = async (fileName) => {
+ const body = new FormData();
+ body.append("fileName", fileName);
+ const imageDeleteOptions = {
+ method: "DELETE",
+ };
+
+ fetch(`/api/file/file/${fileName}`, imageDeleteOptions)
+ .then((res) => {
+ console.log(res);
+ Toast({
+ title: `Suppression d'image effectué`,
+ status: "success",
+ isClosable: true,
+ });
+ })
+ .catch(() => {
+ toast({
+ title: `Erreur lors de la suppression des images`,
+ status: "error",
+ isClosable: true,
+ });
+ });
+ };
return (
<>
@@ -51,7 +105,6 @@ export default function ModalModifyImages(props) {
>
{listImage.map((image, index) => (
- {image}
diff --git a/src/pages/api/file/file.js b/src/pages/api/file/file.js
index 472c495..17a563b 100644
--- a/src/pages/api/file/file.js
+++ b/src/pages/api/file/file.js
@@ -1,5 +1,6 @@
import fs from "fs";
import formidable from "formidable";
+
export const config = {
api: {
bodyParser: false,
@@ -7,11 +8,14 @@ export const config = {
};
const post = async (req, res) => {
- const form = new formidable.IncomingForm();
- console.log(form);
+ const form = new formidable.IncomingForm({
+ maxFileSize: 5 * 1024 * 1024,
+ uploadDir: "./public/imageUsers",
+ keepExtensions: true,
+ });
form.parse(req, async function (err, fields, files) {
- await saveFile(files.file);
- return res.status(201).send("");
+ saveFile(files.file);
+ return res.status(201).send("image saved");
});
};
@@ -22,13 +26,19 @@ const saveFile = async (file) => {
return;
};
+const deleteImage = async (req, res) => {
+ const body = req.body;
+ await fs.unlinkSync(`./public/imageUsers/${body.name}`);
+ res.status(200).send("image deleted");
+};
+
export default (req, res) => {
req.method === "POST"
? post(req, res)
: req.method === "PUT"
? console.log("PUT")
: req.method === "DELETE"
- ? console.log("DELETE")
+ ? deleteImage(req, res)
: req.method === "GET"
? console.log("GET")
: res.status(404).send("");
diff --git a/src/pages/userProfile.tsx b/src/pages/userProfile.tsx
index 3ed3540..91dbe3c 100644
--- a/src/pages/userProfile.tsx
+++ b/src/pages/userProfile.tsx
@@ -2,6 +2,7 @@ import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import type { Session } from "@/models/auth/Session";
import Carousel from "@/components/Carousel";
+import { Gender } from "@prisma/client";
import {
Box,
Button,
@@ -13,23 +14,29 @@ import {
EditablePreview,
EditableTextarea,
Flex,
- Spacer,
+ FormControl,
+ FormErrorMessage,
+ FormLabel,
+ HStack,
+ Input,
+ Radio,
+ RadioGroup,
Text,
- useDisclosure,
useToast,
} from "@chakra-ui/react";
-import { RiEditBoxLine } from "react-icons/ri";
-import BottomBar from "@/components/BottomBar";
import ModalModifyImages from "@/components/ModalModifyImages";
import { useState } from "react";
+import { useForm, Controller } from "react-hook-form";
export default function UserProfile() {
const router = useRouter();
const toast = useToast();
const [isLoading, setIsLoading] = useState(false);
+ const { handleSubmit, control } = useForm();
+
const [userData, setUserData] = useState({});
const [files, setFiles] = useState([]);
@@ -39,22 +46,41 @@ export default function UserProfile() {
if (status === "authenticated") {
const { user } = session as unknown as Session;
- const saveData = () => {
- const options = {
- method: "PUT",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(userData),
- };
+ const getTextGender = (gender) => {
+ switch (gender) {
+ case Gender.MALE:
+ return "Homme";
+ case Gender.FEMALE:
+ return "Femme";
+ case Gender.OTHER:
+ return "Autre";
+ case Gender.UNKNOWN:
+ return "Non renseigné";
+ }
+ };
- setIsLoading(true);
+ const saveData = (values: any) => {
+ const trueValues = Object.keys(values).reduce((acc, key) => {
+ if (values[key] !== "" && values[key] !== undefined) {
+ acc[key] = values[key];
+ }
+ return acc;
+ }, {});
+
+ const options = {
+ method: "PATCH",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(trueValues),
+ };
// if (files.length > 0) {
// files.forEach((file) => {
+ // console.log(file);
// const body = new FormData();
// body.append("file", file);
// const imagePostOptions = {
// method: "POST",
- // headers: { "Content-Type": "application/json" },
+ // headers: { "Content-Type": "multipart/form-data" },
// body,
// };
@@ -79,24 +105,28 @@ export default function UserProfile() {
// });
// }
- fetch(`/api/users/${user.id}`, options)
- .then(() => {
- setIsLoading(false);
- toast({
- title: `Modifications effectuées`,
- status: "success",
- isClosable: true,
+ if (Object.keys(trueValues).length > 0) {
+ setIsLoading(true);
+ fetch(`/api/users/${user.id}`, options)
+ .then((res) => {
+ console.log(res);
+ setIsLoading(false);
+ toast({
+ title: `Modifications effectuées`,
+ status: "success",
+ isClosable: true,
+ });
+ // router.reload();
+ })
+ .catch(() => {
+ setIsLoading(false);
+ toast({
+ title: `Erreur lors de l'envoi des modifications`,
+ status: "error",
+ isClosable: true,
+ });
});
- // router.reload();
- })
- .catch(() => {
- setIsLoading(false);
- toast({
- title: `Erreur lors de l'envoi des modifications`,
- status: "error",
- isClosable: true,
- });
- });
+ }
};
const formateDate = (dateString: string) => {
@@ -104,24 +134,9 @@ export default function UserProfile() {
return new Date(dateString).toLocaleDateString([], options);
};
- // const refinedUser = {
- // // ...user,
- // firstName: "Jean",
- // lastName: "Dujardin",
- // birthdate: formateDate(new Date().toString()),
- // aPropos: "Je suis la personne fictive la plus fictive",
- // images: ["135538.webp"],
- // passions: ["Sport", "Voiture", "Cuisine"],
- // };
-
return (
-
+
{userData.images ? (
@@ -134,10 +149,12 @@ export default function UserProfile() {
)}
{/* {modal} */}
+
{!userData.images ? (
)}
-
+
+
Modifiez les champs en les selectionnants
-
-
-
- Prénom :
-
+
+
+
+
+ Prénom :
+
+ (
+
+
+
+
+ )}
+ />
+
+
+
+ Nom :
+
+ (
+ {
+ // setUserData({ ...userData, lastName: value });
+ // }}
+ >
+
+
+
+ )}
+ />
+
+
+
+ Date de naissance :
+
+
+
+
+
+
+
+
+
+
+ Ville :
+
+
+
+
+
+
+
+ Adresse mail :
+
+
+
+
+
+
+
+
+
+ À propos :
+
+ (
+ {
+ setUserData({ ...userData, bio: value });
+ }}
+ >
+
+
+
+ )}
+ />
+
+
+
+
+
+ Genre :
+
+ (
+ {
+ // setUserData({ ...userData, gender: value });
+ // }}
+ >
+
+
+ {getTextGender(Gender.MALE)}
+
+
+ {getTextGender(Gender.FEMALE)}
+
+
+ {getTextGender(Gender.OTHER)}
+
+
+ {getTextGender(Gender.UNKNOWN)}
+
+
+
+ )}
+ />
+
+ {/*
+
+ Préference :
+
+ {
- setUserData({ ...userData, lastName: value });
+ onChange={(value) => {
+ setUserData({ ...userData, preference: value });
}}
>
-
-
-
-
-
- Nom :
- {
- setUserData({ ...userData, firstName: value });
- }}
+
+
+ {getTextGender(Gender.MALE)}
+
+
+ {getTextGender(Gender.FEMALE)}
+
+
+ {getTextGender(Gender.OTHER)}
+
+
+ {getTextGender(Gender.UNKNOWN)}
+
+
+
+ */}
+
+
+
+
-
- Date de naissance :
-
- {user.birthdate === null
- ? "Non renseigné"
- : formateDate(user.birthdate.toString())}
-
-
-
- Ville :
-
- {user.location === null || user.location === ""
- ? "Non renseigné"
- : user.location}
-
-
-
- Adresse mail :
-
- {user.email}
-
-
-
-
-
- À propos :
-
- {
- setUserData({ ...userData, bio: value });
- }}
- >
-
-
-
-
- {/* préférences / sexe / type de relation recherchés */}
-
-
+ Sauvegarder les modifications
+
+
+
+
diff --git a/yarn.lock b/yarn.lock
index 0568a37..416da0e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1684,6 +1684,11 @@
"resolved" "https://registry.npmjs.org/async/-/async-3.2.4.tgz"
"version" "3.2.4"
+"asynckit@^0.4.0":
+ "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
+ "version" "0.4.0"
+
"available-typed-arrays@^1.0.5":
"integrity" "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
"resolved" "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz"
@@ -1906,6 +1911,13 @@
"resolved" "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz"
"version" "2.0.2"
+"combined-stream@^1.0.8":
+ "integrity" "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="
+ "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
+ "version" "1.0.8"
+ dependencies:
+ "delayed-stream" "~1.0.0"
+
"commondir@^1.0.1":
"integrity" "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
"resolved" "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
@@ -2094,6 +2106,11 @@
"rimraf" "^3.0.2"
"slash" "^3.0.0"
+"delayed-stream@~1.0.0":
+ "integrity" "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+ "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
+ "version" "1.0.0"
+
"delegates@^1.0.0":
"integrity" "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
"resolved" "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz"
@@ -2623,6 +2640,15 @@
dependencies:
"is-callable" "^1.1.3"
+"form-data@^4.0.0":
+ "integrity" "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww=="
+ "resolved" "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz"
+ "version" "4.0.0"
+ dependencies:
+ "asynckit" "^0.4.0"
+ "combined-stream" "^1.0.8"
+ "mime-types" "^2.1.12"
+
"formidable@^2.1.1":
"integrity" "sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ=="
"resolved" "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz"
@@ -3465,6 +3491,18 @@
"braces" "^3.0.2"
"picomatch" "^2.3.1"
+"mime-db@1.52.0":
+ "integrity" "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+ "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
+ "version" "1.52.0"
+
+"mime-types@^2.1.12":
+ "integrity" "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="
+ "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
+ "version" "2.1.35"
+ dependencies:
+ "mime-db" "1.52.0"
+
"mimic-fn@^2.1.0":
"integrity" "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
"resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"