diff --git a/public/imageUsers/6421d8378e4fd27374c7f334_1680519705034.webp b/public/imageUsers/6421d8378e4fd27374c7f334_1680519705034.webp deleted file mode 100644 index 5d89d78..0000000 Binary files a/public/imageUsers/6421d8378e4fd27374c7f334_1680519705034.webp and /dev/null differ diff --git a/src/components/layout/user_profile/CustomCheckbox.jsx b/src/components/layout/user_profile/CustomCheckbox.jsx new file mode 100644 index 0000000..0717359 --- /dev/null +++ b/src/components/layout/user_profile/CustomCheckbox.jsx @@ -0,0 +1,50 @@ +import { + Badge, + useCheckbox, + Text, + Flex, + chakra, + Box, + Tag, + TagLeftIcon, + TagLabel, +} from "@chakra-ui/react"; + +import { IoAdd, IoRemove } from "react-icons/io5"; + +export default function CustomCheckbox(props) { + const { text, checked, value } = props; + const { state, getInputProps, getCheckboxProps, getLabelProps, htmlProps } = + useCheckbox(props); + + return ( + + + {state.isChecked ? ( + + + {text} + + ) : ( + + + {text} + + )} + + ); +} diff --git a/src/components/layout/user_profile/ModalChoosePassion.jsx b/src/components/layout/user_profile/ModalChoosePassion.jsx new file mode 100644 index 0000000..fcf6bb0 --- /dev/null +++ b/src/components/layout/user_profile/ModalChoosePassion.jsx @@ -0,0 +1,110 @@ +import { + Badge, + Box, + Button, + Flex, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Text, + useCheckbox, + useCheckboxGroup, + useDisclosure, + useToast, +} from "@chakra-ui/react"; +import { useEffect } from "react"; +import { useState } from "react"; +import { RiEditBoxLine } from "react-icons/ri"; +import CustomCheckbox from "./CustomCheckbox"; + +export default function ModalChoosePassion(props) { + const { isOpen, onOpen, onClose } = useDisclosure(); + const { user, passions } = props; + const toast = useToast(); + + const { value, getCheckboxProps } = useCheckboxGroup({ + defaultValue: user.PassionID, + }); + + const savePassions = (PassionID) => { + const options = { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ PassionID }), + }; + + fetch(`/api/users/${user.id}`, options) + .then((res) => res.json()) + .then((data) => { + toast({ + title: "Centres d'intérêts mis à jour", + status: "success", + duration: 9000, + isClosable: true, + }); + onClose(); + }) + .catch((err) => { + console.log(err); + }); + }; + + return ( + <> + + + + + + Choix des centres d'intérèts + + + + {passions !== null ? ( + passions.map((passion, index) => { + return ( + + ); + }) + ) : ( + <> + )} + + + + + + + + + + ); +} diff --git a/src/components/layout/user_profile/ModalModifyImages.jsx b/src/components/layout/user_profile/ModalModifyImages.jsx new file mode 100644 index 0000000..f31de9a --- /dev/null +++ b/src/components/layout/user_profile/ModalModifyImages.jsx @@ -0,0 +1,204 @@ +import { + Button, + Flex, + Grid, + GridItem, + Image, + Input, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + 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, user, userData, setUserData } = props; + const [listImage, setlistImage] = useState(images); + const toast = useToast(); + + const uploadImage = async (file) => { + const body = new FormData(); + body.append("file", file); + const imagePostOptions = { + method: "POST", + body, + }; + + const imagePatchOptions = { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + images: [...listImage, `imageUsers/${file.name}`], + }), + }; + + fetch(`/api/file/uploadFile`, imagePostOptions) + .then((res) => { + fetch(`/api/users/${user.id}`, imagePatchOptions) + .then((res) => { + toast({ + title: `Ajout d'image effectué`, + status: "success", + isClosable: true, + }); + setlistImage([...listImage, `imageUsers/${file.name}`]); + // router.reload(); + }) + .catch(() => { + setIsLoading(false); + toast({ + title: `Erreur lors de l'ajout des images`, + status: "error", + isClosable: true, + }); + }); + }) + .catch((err) => { + toast({ + title: `Erreur lors de l'ajout des images`, + status: "error", + isClosable: true, + }); + console.log(err); + }); + }; + + const deleteImage = async (fileName) => { + let newListImage = listImage; + const index = newListImage.indexOf(fileName); + + if (index > -1) { + newListImage.splice(index, 1); + setlistImage([...newListImage]); + } + + const imageDeleteOptions = { + method: "DELETE", + body: JSON.stringify({ fileName: fileName.split("/").pop() }), + }; + + fetch(`/api/file/deleteFile`, imageDeleteOptions).then((res) => { + const imagePatchOptions = { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + images: [...listImage], + }), + }; + fetch(`/api/users/${user.id}`, imagePatchOptions) + .then((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 ( + <> + + + + + + Modification des images + + + + {listImage.map((image, index) => ( + + + + + + + ))} + {listImage.length < 5 ? ( + + { + const date = new Date(); + const time = date.getTime(); + + const file = target.files[0]; + const extension = file.name.split(".").pop(); + const newFile = new File( + [file], + `${user.id}_${time}.${extension}`, + { + type: file.type, + } + ); + uploadImage(newFile); + }} + > + + ) : ( + <> + )} + + + + + + + + + + ); +} diff --git a/src/components/layout/user_profile/ProfileTagList.jsx b/src/components/layout/user_profile/ProfileTagList.jsx new file mode 100644 index 0000000..2b66100 --- /dev/null +++ b/src/components/layout/user_profile/ProfileTagList.jsx @@ -0,0 +1,16 @@ +import { Flex, Tag } from "@chakra-ui/react"; + +export default function ProfileBadgeList(props) { + const { passions, userPassions } = props; + return ( + + {userPassions.map((idPassion, index) => ( + + {passions !== null && passions !== undefined + ? passions.find((element) => element.id === idPassion).name + : ""} + + ))} + + ); +} diff --git a/src/pages/userProfile.tsx b/src/pages/userProfile.tsx index aa18ccd..c08b0fb 100644 --- a/src/pages/userProfile.tsx +++ b/src/pages/userProfile.tsx @@ -23,21 +23,22 @@ import { RadioGroup, Text, useToast, + VStack, } from "@chakra-ui/react"; import ModalModifyImages from "@/components/layout/user_profile/ModalModifyImages"; import ModalChoosePassion from "@/components/layout/user_profile/ModalChoosePassion"; -import ProfileBadgeList from "@/components/layout/user_profile/ProfileBadgeList"; +import ProfileTagList from "@/components/layout/user_profile/ProfileTagList"; -import { useState } from "react"; +import { useEffect, 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 [passions, setPassions] = useState(null); const { handleSubmit, @@ -45,6 +46,18 @@ export default function UserProfile() { formState: { errors }, } = useForm(); + useEffect(() => { + fetch(`/api/passions`) + .then((res) => res.json()) + .then((data) => { + setPassions([...data]); + }) + .catch((err) => { + console.log(err); + }); + }, []); + // faire un useEffect ou je fetch user + const [userData, setUserData] = useState({}); const { data: session, status } = useSession(); @@ -86,7 +99,7 @@ export default function UserProfile() { .then((res) => { setIsLoading(false); toast({ - position:'top', + position: "top", title: `Modifications effectuées`, status: "success", isClosable: true, @@ -97,7 +110,7 @@ export default function UserProfile() { setIsLoading(false); toast({ title: `Erreur lors de l'envoi des modifications`, - position :'top', + position: "top", status: "error", isClosable: true, }); @@ -310,16 +323,15 @@ export default function UserProfile() { Centre d'intéret : - ( - <> - - - - )} - /> + + + + @@ -403,7 +415,7 @@ export default function UserProfile() {