mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-05-13 17:21:53 +00:00
feat(Image upload): image upload to ImageUsers folder
Image upload added. Todo : - delete from folder when users delete -add
This commit is contained in:
Generated
+57
@@ -18,6 +18,7 @@
|
|||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"eslint": "8.35.0",
|
"eslint": "8.35.0",
|
||||||
"eslint-config-next": "13.2.3",
|
"eslint-config-next": "13.2.3",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
"formidable": "^2.1.1",
|
"formidable": "^2.1.1",
|
||||||
"framer-motion": "^10.8.5",
|
"framer-motion": "^10.8.5",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
@@ -2722,6 +2723,11 @@
|
|||||||
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
|
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
|
||||||
"optional": true
|
"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": {
|
"node_modules/available-typed-arrays": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz",
|
||||||
"integrity": "sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w=="
|
"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": {
|
"node_modules/commondir": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||||
@@ -3328,6 +3345,14 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/delegates": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
@@ -4165,6 +4190,19 @@
|
|||||||
"is-callable": "^1.1.3"
|
"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": {
|
"node_modules/formidable": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz",
|
||||||
@@ -5547,6 +5585,25 @@
|
|||||||
"node": ">=8.6"
|
"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": {
|
"node_modules/mimic-fn": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"eslint": "8.35.0",
|
"eslint": "8.35.0",
|
||||||
"eslint-config-next": "13.2.3",
|
"eslint-config-next": "13.2.3",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
"formidable": "^2.1.1",
|
"formidable": "^2.1.1",
|
||||||
"framer-motion": "^10.8.5",
|
"framer-motion": "^10.8.5",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
|
|||||||
@@ -12,16 +12,70 @@ import {
|
|||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
Text,
|
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { RiEditBoxLine } from "react-icons/ri";
|
import { RiEditBoxLine } from "react-icons/ri";
|
||||||
|
|
||||||
export default function ModalModifyImages(props) {
|
export default function ModalModifyImages(props) {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
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 [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 (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -51,7 +105,6 @@ export default function ModalModifyImages(props) {
|
|||||||
>
|
>
|
||||||
{listImage.map((image, index) => (
|
{listImage.map((image, index) => (
|
||||||
<GridItem key={index}>
|
<GridItem key={index}>
|
||||||
<Text>{image}</Text>
|
|
||||||
<Flex direction={"column"} gap={"1rem"}>
|
<Flex direction={"column"} gap={"1rem"}>
|
||||||
<Image src={image} />
|
<Image src={image} />
|
||||||
<Button
|
<Button
|
||||||
@@ -75,8 +128,19 @@ export default function ModalModifyImages(props) {
|
|||||||
accept={"image/png, image/jpeg, image/webp"}
|
accept={"image/png, image/jpeg, image/webp"}
|
||||||
onChange={({ target }) => {
|
onChange={({ target }) => {
|
||||||
const file = target.files[0];
|
const file = target.files[0];
|
||||||
setlistImage([...listImage, URL.createObjectURL(file)]);
|
const extension = file.name.split(".").pop();
|
||||||
setFiles([...files, file]);
|
const newFile = new File(
|
||||||
|
[file],
|
||||||
|
`${user.id}_${listImage.length}.${extension}`,
|
||||||
|
{
|
||||||
|
type: file.type,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
uploadImage(newFile);
|
||||||
|
setlistImage([
|
||||||
|
...listImage,
|
||||||
|
URL.createObjectURL(newFile),
|
||||||
|
]);
|
||||||
}}
|
}}
|
||||||
></Input>
|
></Input>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import formidable from "formidable";
|
import formidable from "formidable";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
bodyParser: false,
|
bodyParser: false,
|
||||||
@@ -7,11 +8,14 @@ export const config = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const post = async (req, res) => {
|
const post = async (req, res) => {
|
||||||
const form = new formidable.IncomingForm();
|
const form = new formidable.IncomingForm({
|
||||||
console.log(form);
|
maxFileSize: 5 * 1024 * 1024,
|
||||||
|
uploadDir: "./public/imageUsers",
|
||||||
|
keepExtensions: true,
|
||||||
|
});
|
||||||
form.parse(req, async function (err, fields, files) {
|
form.parse(req, async function (err, fields, files) {
|
||||||
await saveFile(files.file);
|
saveFile(files.file);
|
||||||
return res.status(201).send("");
|
return res.status(201).send("image saved");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,13 +26,19 @@ const saveFile = async (file) => {
|
|||||||
return;
|
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) => {
|
export default (req, res) => {
|
||||||
req.method === "POST"
|
req.method === "POST"
|
||||||
? post(req, res)
|
? post(req, res)
|
||||||
: req.method === "PUT"
|
: req.method === "PUT"
|
||||||
? console.log("PUT")
|
? console.log("PUT")
|
||||||
: req.method === "DELETE"
|
: req.method === "DELETE"
|
||||||
? console.log("DELETE")
|
? deleteImage(req, res)
|
||||||
: req.method === "GET"
|
: req.method === "GET"
|
||||||
? console.log("GET")
|
? console.log("GET")
|
||||||
: res.status(404).send("");
|
: res.status(404).send("");
|
||||||
|
|||||||
+278
-126
@@ -2,6 +2,7 @@ import { useSession } from "next-auth/react";
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import type { Session } from "@/models/auth/Session";
|
import type { Session } from "@/models/auth/Session";
|
||||||
import Carousel from "@/components/Carousel";
|
import Carousel from "@/components/Carousel";
|
||||||
|
import { Gender } from "@prisma/client";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@@ -13,23 +14,29 @@ import {
|
|||||||
EditablePreview,
|
EditablePreview,
|
||||||
EditableTextarea,
|
EditableTextarea,
|
||||||
Flex,
|
Flex,
|
||||||
Spacer,
|
FormControl,
|
||||||
|
FormErrorMessage,
|
||||||
|
FormLabel,
|
||||||
|
HStack,
|
||||||
|
Input,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
import { RiEditBoxLine } from "react-icons/ri";
|
|
||||||
import BottomBar from "@/components/BottomBar";
|
|
||||||
import ModalModifyImages from "@/components/ModalModifyImages";
|
import ModalModifyImages from "@/components/ModalModifyImages";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
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 { handleSubmit, control } = useForm();
|
||||||
|
|
||||||
const [userData, setUserData] = useState({});
|
const [userData, setUserData] = useState({});
|
||||||
const [files, setFiles] = useState([]);
|
const [files, setFiles] = useState([]);
|
||||||
|
|
||||||
@@ -39,22 +46,41 @@ export default function UserProfile() {
|
|||||||
if (status === "authenticated") {
|
if (status === "authenticated") {
|
||||||
const { user } = session as unknown as Session;
|
const { user } = session as unknown as Session;
|
||||||
|
|
||||||
const saveData = () => {
|
const getTextGender = (gender) => {
|
||||||
const options = {
|
switch (gender) {
|
||||||
method: "PUT",
|
case Gender.MALE:
|
||||||
headers: { "Content-Type": "application/json" },
|
return "Homme";
|
||||||
body: JSON.stringify(userData),
|
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) {
|
// if (files.length > 0) {
|
||||||
// files.forEach((file) => {
|
// files.forEach((file) => {
|
||||||
|
// console.log(file);
|
||||||
// const body = new FormData();
|
// const body = new FormData();
|
||||||
// body.append("file", file);
|
// body.append("file", file);
|
||||||
// const imagePostOptions = {
|
// const imagePostOptions = {
|
||||||
// method: "POST",
|
// method: "POST",
|
||||||
// headers: { "Content-Type": "application/json" },
|
// headers: { "Content-Type": "multipart/form-data" },
|
||||||
// body,
|
// body,
|
||||||
// };
|
// };
|
||||||
|
|
||||||
@@ -79,24 +105,28 @@ export default function UserProfile() {
|
|||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fetch(`/api/users/${user.id}`, options)
|
if (Object.keys(trueValues).length > 0) {
|
||||||
.then(() => {
|
setIsLoading(true);
|
||||||
setIsLoading(false);
|
fetch(`/api/users/${user.id}`, options)
|
||||||
toast({
|
.then((res) => {
|
||||||
title: `Modifications effectuées`,
|
console.log(res);
|
||||||
status: "success",
|
setIsLoading(false);
|
||||||
isClosable: true,
|
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) => {
|
const formateDate = (dateString: string) => {
|
||||||
@@ -104,24 +134,9 @@ export default function UserProfile() {
|
|||||||
return new Date(dateString).toLocaleDateString([], options);
|
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 (
|
return (
|
||||||
<Box bgColor={"purple.50"}>
|
<Box bgColor={"purple.50"}>
|
||||||
<Container
|
<Container justifyContent={"center"} maxWidth={"70rem"} mt={"1rem"}>
|
||||||
justifyContent={"center"}
|
|
||||||
maxWidth={"70rem"}
|
|
||||||
mt={"1rem"}
|
|
||||||
bgColor={"purple.50"}
|
|
||||||
>
|
|
||||||
<Flex flexDirection={"column"} alignItems={"center"} gap={"1rem"}>
|
<Flex flexDirection={"column"} alignItems={"center"} gap={"1rem"}>
|
||||||
<Box width={"50%"}>
|
<Box width={"50%"}>
|
||||||
{userData.images ? (
|
{userData.images ? (
|
||||||
@@ -134,10 +149,12 @@ export default function UserProfile() {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{/* {modal} */}
|
{/* {modal} */}
|
||||||
|
|
||||||
{!userData.images ? (
|
{!userData.images ? (
|
||||||
<ModalModifyImages
|
<ModalModifyImages
|
||||||
setUserData={setUserData}
|
setUserData={setUserData}
|
||||||
userData={userData}
|
userData={userData}
|
||||||
|
user={user}
|
||||||
images={user.images}
|
images={user.images}
|
||||||
files={files}
|
files={files}
|
||||||
setFiles={setFiles}
|
setFiles={setFiles}
|
||||||
@@ -146,100 +163,235 @@ export default function UserProfile() {
|
|||||||
<ModalModifyImages
|
<ModalModifyImages
|
||||||
setUserData={setUserData}
|
setUserData={setUserData}
|
||||||
userData={userData}
|
userData={userData}
|
||||||
|
user={user}
|
||||||
images={userData.images}
|
images={userData.images}
|
||||||
files={files}
|
files={files}
|
||||||
setFiles={setFiles}
|
setFiles={setFiles}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Divider />
|
|
||||||
|
<Divider colorScheme={"purple"} />
|
||||||
<Text align={"center"} as="i" color={"grey"}>
|
<Text align={"center"} as="i" color={"grey"}>
|
||||||
Modifiez les champs en les selectionnants
|
Modifiez les champs en les selectionnants
|
||||||
</Text>
|
</Text>
|
||||||
<Box width={"100%"}>
|
|
||||||
<Flex justify={"space-between"} mb={"1rem"}>
|
<form onSubmit={handleSubmit(saveData)}>
|
||||||
<Flex gap={"0.5rem"}>
|
<FormControl width={"100%"}>
|
||||||
<Text margin={"auto"}>Prénom : </Text>
|
<Flex justify={"space-between"} mb={"1rem"}>
|
||||||
<Editable
|
<Box>
|
||||||
id={"lastName"}
|
<FormLabel as="legend" htmlFor={"firstName"}>
|
||||||
|
Prénom :
|
||||||
|
</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name={"firstName"}
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Editable
|
||||||
|
{...field}
|
||||||
|
id={"firstName"}
|
||||||
|
placeholder={"Non renseigné"}
|
||||||
|
as={"b"}
|
||||||
|
defaultValue={
|
||||||
|
user.firstName === null ? "" : user.firstName
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<EditablePreview />
|
||||||
|
<EditableInput />
|
||||||
|
</Editable>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"lastName"}>
|
||||||
|
Nom :
|
||||||
|
</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name={"lastName"}
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Editable
|
||||||
|
{...field}
|
||||||
|
id={"lastName"}
|
||||||
|
as={"b"}
|
||||||
|
placeholder={"Non renseigné"}
|
||||||
|
defaultValue={
|
||||||
|
user.lastName === null ? "" : user.lastName
|
||||||
|
}
|
||||||
|
// onSubmit={(value) => {
|
||||||
|
// setUserData({ ...userData, lastName: value });
|
||||||
|
// }}
|
||||||
|
>
|
||||||
|
<EditablePreview />
|
||||||
|
<EditableInput />
|
||||||
|
</Editable>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"birthdate"}>
|
||||||
|
Date de naissance :
|
||||||
|
</FormLabel>
|
||||||
|
<Editable
|
||||||
|
id={"birthdate"}
|
||||||
|
as="b"
|
||||||
|
color={"grey"}
|
||||||
|
isDisabled={true}
|
||||||
|
defaultValue={
|
||||||
|
user.birthdate === null
|
||||||
|
? "Non renseigné"
|
||||||
|
: formateDate(user.birthdate.toString())
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<EditablePreview />
|
||||||
|
</Editable>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Divider colorScheme={"purple"} />
|
||||||
|
<Flex justify={"space-between"} my={"1rem"}>
|
||||||
|
<Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"location"}>
|
||||||
|
Ville :
|
||||||
|
</FormLabel>
|
||||||
|
<Editable
|
||||||
|
id={"location"}
|
||||||
|
as="b"
|
||||||
|
color={"grey"}
|
||||||
|
isDisabled={true}
|
||||||
|
defaultValue={
|
||||||
|
user.location === null || user.location === ""
|
||||||
|
? "Rendez vous sur la carte"
|
||||||
|
: user.location
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<EditablePreview />
|
||||||
|
</Editable>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"email"}>
|
||||||
|
Adresse mail :
|
||||||
|
</FormLabel>
|
||||||
|
<Editable
|
||||||
|
id={"email"}
|
||||||
|
as="b"
|
||||||
|
color={"grey"}
|
||||||
|
isDisabled={true}
|
||||||
|
defaultValue={user.email}
|
||||||
|
>
|
||||||
|
<EditablePreview />
|
||||||
|
</Editable>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Divider colorScheme={"purple"} />
|
||||||
|
<Box my={"1rem"}>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"bio"}>
|
||||||
|
À propos :
|
||||||
|
</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name={"bio"}
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Editable
|
||||||
|
{...field}
|
||||||
|
id={"bio"}
|
||||||
|
as="b"
|
||||||
|
width={"100%"}
|
||||||
|
placeholder={"Non renseigné"}
|
||||||
|
defaultValue={user.bio === null ? "" : user.bio}
|
||||||
|
onSubmit={(value) => {
|
||||||
|
setUserData({ ...userData, bio: value });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<EditablePreview />
|
||||||
|
<EditableTextarea />
|
||||||
|
</Editable>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Divider colorScheme={"purple"} />
|
||||||
|
<Box my={"1rem"}>
|
||||||
|
<Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"gender"}>
|
||||||
|
Genre :
|
||||||
|
</FormLabel>
|
||||||
|
<Controller
|
||||||
|
name={"gender"}
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<RadioGroup
|
||||||
|
{...field}
|
||||||
|
colorScheme={"purple"}
|
||||||
|
id={"gender"}
|
||||||
|
as="b"
|
||||||
|
defaultValue={
|
||||||
|
user.gender === null ? Gender.UNKNOWN : user.gender
|
||||||
|
}
|
||||||
|
// onChange={(value) => {
|
||||||
|
// setUserData({ ...userData, gender: value });
|
||||||
|
// }}
|
||||||
|
>
|
||||||
|
<HStack spacing={"0.5rem"}>
|
||||||
|
<Radio value={Gender.MALE}>
|
||||||
|
{getTextGender(Gender.MALE)}
|
||||||
|
</Radio>
|
||||||
|
<Radio value={Gender.FEMALE}>
|
||||||
|
{getTextGender(Gender.FEMALE)}
|
||||||
|
</Radio>
|
||||||
|
<Radio value={Gender.OTHER}>
|
||||||
|
{getTextGender(Gender.OTHER)}
|
||||||
|
</Radio>
|
||||||
|
<Radio value={Gender.UNKNOWN}>
|
||||||
|
{getTextGender(Gender.UNKNOWN)}
|
||||||
|
</Radio>
|
||||||
|
</HStack>
|
||||||
|
</RadioGroup>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
{/* <Box>
|
||||||
|
<FormLabel as={"legend"} htmlFor={"preference"}>
|
||||||
|
Préference :
|
||||||
|
</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
id={"preference"}
|
||||||
as="b"
|
as="b"
|
||||||
defaultValue={
|
value={
|
||||||
user.lastName === null || user.lastName === ""
|
user.preference === null
|
||||||
? "Non renseigné"
|
? Gender.UNKNOWN
|
||||||
: user.lastName
|
: user.preference
|
||||||
}
|
}
|
||||||
onSubmit={(value) => {
|
onChange={(value) => {
|
||||||
setUserData({ ...userData, lastName: value });
|
setUserData({ ...userData, preference: value });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditablePreview />
|
<HStack spacing={"0.5rem"}>
|
||||||
<EditableInput />
|
<Radio value={Gender.MALE}>
|
||||||
</Editable>
|
{getTextGender(Gender.MALE)}
|
||||||
</Flex>
|
</Radio>
|
||||||
<Flex gap={"0.5rem"}>
|
<Radio value={Gender.FEMALE}>
|
||||||
<Text margin={"auto"}>Nom : </Text>
|
{getTextGender(Gender.FEMALE)}
|
||||||
<Editable
|
</Radio>
|
||||||
id={"firstName"}
|
<Radio value={Gender.OTHER}>
|
||||||
as="b"
|
{getTextGender(Gender.OTHER)}
|
||||||
defaultValue={
|
</Radio>
|
||||||
user.firstName === null || user.firstName === ""
|
<Radio value={Gender.UNKNOWN}>
|
||||||
? "Non renseigné"
|
{getTextGender(Gender.UNKNOWN)}
|
||||||
: user.firstName
|
</Radio>
|
||||||
}
|
</HStack>
|
||||||
onSubmit={(value) => {
|
</RadioGroup>
|
||||||
setUserData({ ...userData, firstName: value });
|
</Flex> */}
|
||||||
}}
|
</Box>
|
||||||
|
<Divider colorScheme={"purple"} />
|
||||||
|
<Center my={"1rem"}>
|
||||||
|
<Button
|
||||||
|
colorScheme={"purple"}
|
||||||
|
isLoading={isLoading}
|
||||||
|
type="submit"
|
||||||
>
|
>
|
||||||
<EditablePreview />
|
Sauvegarder les modifications
|
||||||
<EditableInput />
|
</Button>
|
||||||
</Editable>
|
</Center>
|
||||||
</Flex>
|
</FormControl>
|
||||||
<Flex gap={"0.5rem"}>
|
</form>
|
||||||
<Text margin={"auto"}>Date de naissance : </Text>
|
|
||||||
<Text margin={"auto"} id={"birthdate"} as="b" color={"grey"}>
|
|
||||||
{user.birthdate === null
|
|
||||||
? "Non renseigné"
|
|
||||||
: formateDate(user.birthdate.toString())}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={"0.5rem"}>
|
|
||||||
<Text>Ville : </Text>
|
|
||||||
<Text id={"location"} as="b" color={"grey"}>
|
|
||||||
{user.location === null || user.location === ""
|
|
||||||
? "Non renseigné"
|
|
||||||
: user.location}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
<Flex>
|
|
||||||
<Text>Adresse mail : </Text>
|
|
||||||
<Text id={"email"} as="b" color={"grey"}>
|
|
||||||
{user.email}
|
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={"0.5rem"}>
|
|
||||||
<Text width={"100%"} align={"right"} margin={"auto"}>
|
|
||||||
À propos :
|
|
||||||
</Text>
|
|
||||||
<Editable
|
|
||||||
id={"bio"}
|
|
||||||
as="b"
|
|
||||||
width={"100%"}
|
|
||||||
defaultValue={
|
|
||||||
user.bio === null || user.bio === ""
|
|
||||||
? "Non renseigné"
|
|
||||||
: user.bio
|
|
||||||
}
|
|
||||||
onSubmit={(value) => {
|
|
||||||
setUserData({ ...userData, bio: value });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<EditablePreview />
|
|
||||||
<EditableTextarea />
|
|
||||||
</Editable>
|
|
||||||
</Flex>
|
|
||||||
{/* préférences / sexe / type de relation recherchés */}
|
|
||||||
</Box>
|
|
||||||
<BottomBar variant={"fixed"} saveData={saveData} />
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Container>
|
</Container>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1684,6 +1684,11 @@
|
|||||||
"resolved" "https://registry.npmjs.org/async/-/async-3.2.4.tgz"
|
"resolved" "https://registry.npmjs.org/async/-/async-3.2.4.tgz"
|
||||||
"version" "3.2.4"
|
"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":
|
"available-typed-arrays@^1.0.5":
|
||||||
"integrity" "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
"integrity" "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
|
||||||
"resolved" "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz"
|
"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"
|
"resolved" "https://registry.npmjs.org/color2k/-/color2k-2.0.2.tgz"
|
||||||
"version" "2.0.2"
|
"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":
|
"commondir@^1.0.1":
|
||||||
"integrity" "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
|
"integrity" "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
|
||||||
"resolved" "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
|
"resolved" "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
|
||||||
@@ -2094,6 +2106,11 @@
|
|||||||
"rimraf" "^3.0.2"
|
"rimraf" "^3.0.2"
|
||||||
"slash" "^3.0.0"
|
"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":
|
"delegates@^1.0.0":
|
||||||
"integrity" "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
|
"integrity" "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
|
||||||
"resolved" "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz"
|
"resolved" "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz"
|
||||||
@@ -2623,6 +2640,15 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"is-callable" "^1.1.3"
|
"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":
|
"formidable@^2.1.1":
|
||||||
"integrity" "sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ=="
|
"integrity" "sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ=="
|
||||||
"resolved" "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz"
|
"resolved" "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz"
|
||||||
@@ -3465,6 +3491,18 @@
|
|||||||
"braces" "^3.0.2"
|
"braces" "^3.0.2"
|
||||||
"picomatch" "^2.3.1"
|
"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":
|
"mimic-fn@^2.1.0":
|
||||||
"integrity" "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
|
"integrity" "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
|
||||||
"resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
|
"resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user