mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-07-09 06:58:06 +00:00
image users
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -1,204 +0,0 @@
|
|||||||
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 (
|
|
||||||
<>
|
|
||||||
<Button
|
|
||||||
colorScheme={"purple"}
|
|
||||||
onClick={onOpen}
|
|
||||||
leftIcon={<RiEditBoxLine />}
|
|
||||||
>
|
|
||||||
Modifier les images
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
blockScrollOnMount={false}
|
|
||||||
size={"4xl"}
|
|
||||||
isOpen={isOpen}
|
|
||||||
onClose={onClose}
|
|
||||||
scrollBehavior={"inside"}
|
|
||||||
>
|
|
||||||
<ModalOverlay />
|
|
||||||
<ModalContent>
|
|
||||||
<ModalHeader>Modification des images</ModalHeader>
|
|
||||||
<ModalCloseButton />
|
|
||||||
<ModalBody>
|
|
||||||
<Grid
|
|
||||||
templateColumns={`repeat(${listImage.length + 1}, 1fr)`}
|
|
||||||
gap={5}
|
|
||||||
>
|
|
||||||
{listImage.map((image, index) => (
|
|
||||||
<GridItem key={index}>
|
|
||||||
<Flex direction={"column"} gap={"1rem"}>
|
|
||||||
<Image src={image} />
|
|
||||||
<Button
|
|
||||||
id={"" + index}
|
|
||||||
colorScheme={"red"}
|
|
||||||
onClick={(e) => {
|
|
||||||
deleteImage(`${listImage[index]}`);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Supprimer l'image
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</GridItem>
|
|
||||||
))}
|
|
||||||
{listImage.length < 5 ? (
|
|
||||||
<GridItem width={"100%"}>
|
|
||||||
<Input
|
|
||||||
type={"file"}
|
|
||||||
height={"100%"}
|
|
||||||
accept={"image/png, image/jpeg, image/webp"}
|
|
||||||
onInput={({ target }) => {
|
|
||||||
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);
|
|
||||||
}}
|
|
||||||
></Input>
|
|
||||||
</GridItem>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</ModalBody>
|
|
||||||
|
|
||||||
<ModalFooter>
|
|
||||||
<Button
|
|
||||||
colorScheme="purple"
|
|
||||||
mr={3}
|
|
||||||
onClick={(e) => {
|
|
||||||
setUserData({
|
|
||||||
...userData,
|
|
||||||
images: [...listImage],
|
|
||||||
});
|
|
||||||
onClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,11 @@ export default function LeftPanel(props) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { user } = props;
|
const { user } = props;
|
||||||
|
|
||||||
|
const formateDate = (dateString) => {
|
||||||
|
var options = { year: "numeric", month: "long", day: "numeric" };
|
||||||
|
return new Date(dateString).toLocaleDateString([], options);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
width={"20vw"}
|
width={"20vw"}
|
||||||
@@ -23,12 +28,17 @@ export default function LeftPanel(props) {
|
|||||||
<Flex direction={"column"} height={"100%"} margin={"10%"}>
|
<Flex direction={"column"} height={"100%"} margin={"10%"}>
|
||||||
<Box>
|
<Box>
|
||||||
<Image src={user.images[0]} borderRadius={"1rem"} />
|
<Image src={user.images[0]} borderRadius={"1rem"} />
|
||||||
<Box mt={"1vh"}>
|
<Box mt={"1rem"}>
|
||||||
<Text fontSize={"1.5rem"} fontWeight={"bold"}>
|
<Flex align={"center"} justifyContent="space-between">
|
||||||
{user.firstName} {user.lastName}
|
<Text fontSize={"1.5rem"} fontWeight={"bold"}>
|
||||||
</Text>
|
{user.firstName} {user.lastName}
|
||||||
<Text as="i" fontWeight={"bold"}>
|
</Text>
|
||||||
"{user.aPropos}"
|
<Text fontSize={"1rem"} fontWeight={"bold"}>
|
||||||
|
{formateDate(user.birthdate)}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
<Text mt={"3rem"} as="i" fontWeight={"bold"}>
|
||||||
|
"{user.bio}"
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default function Dashboard() {
|
|||||||
minH={"100vh"}
|
minH={"100vh"}
|
||||||
>
|
>
|
||||||
<GridItem area={"1 / 1 / 3 / 2"}>
|
<GridItem area={"1 / 1 / 3 / 2"}>
|
||||||
<LeftPanel user={refinedUser} />
|
<LeftPanel user={user} />
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem area={"1 / 2 / 3 / 4"}>
|
<GridItem area={"1 / 2 / 3 / 4"}>
|
||||||
<Box py={3}>
|
<Box py={3}>
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import {
|
|||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
import ModalModifyImages from "@/components/ModalModifyImages";
|
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 { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
@@ -33,6 +35,8 @@ import { useForm, Controller } from "react-hook-form";
|
|||||||
export default function UserProfile() {
|
export default function UserProfile() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -82,6 +86,7 @@ export default function UserProfile() {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
toast({
|
toast({
|
||||||
|
position:'top',
|
||||||
title: `Modifications effectuées`,
|
title: `Modifications effectuées`,
|
||||||
status: "success",
|
status: "success",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
@@ -92,6 +97,7 @@ export default function UserProfile() {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
toast({
|
toast({
|
||||||
title: `Erreur lors de l'envoi des modifications`,
|
title: `Erreur lors de l'envoi des modifications`,
|
||||||
|
position :'top',
|
||||||
status: "error",
|
status: "error",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
@@ -299,6 +305,24 @@ export default function UserProfile() {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
<Divider colorScheme={"purple"} />
|
<Divider colorScheme={"purple"} />
|
||||||
|
<Box my={"1rem"}>
|
||||||
|
<Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"passion"}>
|
||||||
|
Centre d'intéret :
|
||||||
|
</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name={"passion"}
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<>
|
||||||
|
<ProfileBadgeList passions={user.passion !== undefined ? user.passion : []}/>
|
||||||
|
<ModalChoosePassion user={user}/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Divider colorScheme={"purple"} />
|
||||||
<Box my={"1rem"}>
|
<Box my={"1rem"}>
|
||||||
<Box>
|
<Box>
|
||||||
<FormLabel as={"legend"} htmlFor={"gender"}>
|
<FormLabel as={"legend"} htmlFor={"gender"}>
|
||||||
@@ -316,9 +340,6 @@ export default function UserProfile() {
|
|||||||
defaultValue={
|
defaultValue={
|
||||||
user.gender === null ? Gender.UNKNOWN : user.gender
|
user.gender === null ? Gender.UNKNOWN : user.gender
|
||||||
}
|
}
|
||||||
// onChange={(value) => {
|
|
||||||
// setUserData({ ...userData, gender: value });
|
|
||||||
// }}
|
|
||||||
>
|
>
|
||||||
<HStack spacing={"0.5rem"}>
|
<HStack spacing={"0.5rem"}>
|
||||||
<Radio value={Gender.MALE}>
|
<Radio value={Gender.MALE}>
|
||||||
@@ -372,7 +393,7 @@ export default function UserProfile() {
|
|||||||
</Flex> */}
|
</Flex> */}
|
||||||
</Box>
|
</Box>
|
||||||
<Divider colorScheme={"purple"} />
|
<Divider colorScheme={"purple"} />
|
||||||
<Center my={"1rem"}>
|
<Center gap={"1rem"} my={"1rem"}>
|
||||||
<Button
|
<Button
|
||||||
colorScheme={"purple"}
|
colorScheme={"purple"}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
@@ -380,6 +401,13 @@ export default function UserProfile() {
|
|||||||
>
|
>
|
||||||
Sauvegarder les modifications
|
Sauvegarder les modifications
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
colorScheme={"purple"}
|
||||||
|
variant='outline'
|
||||||
|
onClick={() => router.push("/dashboard")}
|
||||||
|
>
|
||||||
|
Retour
|
||||||
|
</Button>
|
||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
Reference in New Issue
Block a user