diff --git a/public/blank_profile_picture.webp b/public/blank_profile_picture.webp new file mode 100644 index 0000000..f177a45 Binary files /dev/null and b/public/blank_profile_picture.webp differ diff --git a/src/components/BottomBar.tsx b/src/components/BottomBar.tsx index 0a23dcb..0b6cab3 100644 --- a/src/components/BottomBar.tsx +++ b/src/components/BottomBar.tsx @@ -1,24 +1,30 @@ -import { - Box, - Flex, - Text, - Button, - Image, - } from '@chakra-ui/react'; - - - export default function BottomBar(props) { - - const {variant, saveData} = props; - - return ( - - - - - - ); - - } - \ No newline at end of file +import { Box, Flex, Text, Button, Image } from "@chakra-ui/react"; +import { useRouter } from "next/router"; + +export default function BottomBar(props) { + const router = useRouter(); + + const { variant, saveData } = props; + + return ( + + + + + + ); +} diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx index 40af98b..ba248e9 100644 --- a/src/components/Carousel.tsx +++ b/src/components/Carousel.tsx @@ -1,45 +1,55 @@ -import {useState} from 'react'; -import {Flex, IconButton} from '@chakra-ui/react'; +import { useState } from "react"; +import { Flex, IconButton } from "@chakra-ui/react"; import { BiLeftArrowAlt, BiRightArrowAlt } from "react-icons/bi"; interface Props { - images: string[] + images: string[]; borderRadius?: string | number; } -const Carousel = ({images, borderRadius: bRadius}: Props) => { +const Carousel = ({ images, borderRadius: bRadius }: Props) => { const [currentIndex, setCurrentIndex] = useState(0); const handleClickPrevious = () => { - setCurrentIndex( - (currentIndex === 0) - ? images.length - 1 : currentIndex - 1, - ); + setCurrentIndex(currentIndex === 0 ? images.length - 1 : currentIndex - 1); }; const handleClickNext = () => { - setCurrentIndex( - (currentIndex === images.length - 1) - ? 0 : currentIndex + 1, - ); + setCurrentIndex(currentIndex === images.length - 1 ? 0 : currentIndex + 1); }; + if (images.length === 0) images = ["blank_profile_picture.webp"]; + return ( - + + + + - - - - - - - - - + + + + ); }; diff --git a/src/components/ModalModifyImages.jsx b/src/components/ModalModifyImages.jsx new file mode 100644 index 0000000..f8c902b --- /dev/null +++ b/src/components/ModalModifyImages.jsx @@ -0,0 +1,94 @@ +import { + Button, + Flex, + Grid, + GridItem, + Image, + Input, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + useDisclosure, +} from "@chakra-ui/react"; +import { RiEditBoxLine } from "react-icons/ri"; + +export default function ModalModifyImages(props) { + const { isOpen, onOpen, onClose } = useDisclosure(); + const { images, userData, setUserData } = props; + return ( + <> + + + + + + Modification des images + + + + {images.map((image, index) => ( + + + + + + + ))} + {images.length < 5 ? ( + + { + setUserData({ + ...userData, + images: [...images, e.target.files[0].name], + }); + }} + > + + ) : ( + <> + )} + + + + + + + + + + ); +} diff --git a/src/components/layout/dashboard/left_panel/LeftPanel.jsx b/src/components/layout/dashboard/left_panel/LeftPanel.jsx index 38027de..433725f 100644 --- a/src/components/layout/dashboard/left_panel/LeftPanel.jsx +++ b/src/components/layout/dashboard/left_panel/LeftPanel.jsx @@ -1,53 +1,62 @@ -import { - Card, - Flex, - Box, - Image, - Text, - Spacer, -} from '@chakra-ui/react'; -import {useRouter} from 'next/router'; +import { Card, Flex, Box, Image, Text, Spacer } from "@chakra-ui/react"; +import { useRouter } from "next/router"; -import {AiFillMessage} from 'react-icons/ai'; -import {BsFillPersonFill} from 'react-icons/bs'; -import {BiLogOut} from 'react-icons/bi'; +import { AiFillMessage } from "react-icons/ai"; +import { BsFillPersonFill } from "react-icons/bs"; +import { BiLogOut } from "react-icons/bi"; -import LeftPanelButton - from '@/components/layout/dashboard/left_panel/LeftPanelButton'; -import {signOut} from 'next-auth/react'; +import LeftPanelButton from "@/components/layout/dashboard/left_panel/LeftPanelButton"; +import { signOut } from "next-auth/react"; export default function LeftPanel(props) { const router = useRouter(); - const {user} = props; + const { user } = props; return ( - - + + - - - + + + {user.firstName} {user.lastName} - + "{user.aPropos}" - - - - } - onClickHandler={() => router.push('/dashboard')}> + + + } + onClickHandler={() => router.push("/dashboard")} + > Messages - } - onClickHandler={() => router.push('/dashboard')}> + } + onClickHandler={() => router.push("/userProfile")} + > Profile - } - onClickHandler={() => signOut({callbackUrl: "/"})}> + } + onClickHandler={() => signOut({ callbackUrl: "/" })} + > Deconnexion diff --git a/src/models/form/userData.ts b/src/models/form/userData.ts new file mode 100644 index 0000000..83b6736 --- /dev/null +++ b/src/models/form/userData.ts @@ -0,0 +1,11 @@ +export class UserData { + constructor( + public email: string = "", + public firstName: string = "", + public lastName: string = "", + public bio: string = "", + public location: string = "", + public images: string[] = [], + public birthdate: Date = new Date() + ) {} +} diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 20e5d22..09b9b7a 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -1,56 +1,57 @@ -import {Grid, GridItem, Text, Box} from '@chakra-ui/react'; -import {useSession} from 'next-auth/react'; -import {useRouter} from 'next/router'; +import { Grid, GridItem, Text, Box } from "@chakra-ui/react"; +import { useSession } from "next-auth/react"; +import { useRouter } from "next/router"; -import type {Session} from '@/models/auth/Session'; -import CardUser from '../components/layout/dashboard/card_user/CardUser'; -import LeftPanel from '../components/layout/dashboard/left_panel/LeftPanel'; -import Head from 'next/head'; -import {websiteName} from '@/lib/constants'; -import Navbar from '@/components/Navbar'; +import type { Session } from "@/models/auth/Session"; +import CardUser from "../components/layout/dashboard/card_user/CardUser"; +import LeftPanel from "../components/layout/dashboard/left_panel/LeftPanel"; +import Head from "next/head"; +import { websiteName } from "@/lib/constants"; +import Navbar from "@/components/Navbar"; export default function Dashboard() { const router = useRouter(); - const {data: session, status} = useSession(); + const { data: session, status } = useSession(); - if (status === 'loading') return Loading...; - if (status === 'unauthenticated') router.push('/login'); + if (status === "loading") return Loading...; + if (status === "unauthenticated") router.push("/login"); - if (status === 'authenticated') { - const {user} = session as unknown as Session; + if (status === "authenticated") { + const { user } = session as unknown as Session; // il faudra l'enlever const refinedUser = { ...user, age: 21, - aPropos: 'Je suis la personne fictive la plus fictive', - images: ['135538.webp'], - passions: ['Sport', 'Voiture', 'Cuisine'], + aPropos: "Je suis la personne fictive la plus fictive", + images: ["135538.webp"], + passions: ["Sport", "Voiture", "Cuisine"], }; return ( - <> - {websiteName} | Dashboard + <> + + {websiteName} | Dashboard + - - - - - - - - - - - - {/*Right top*/} - - - {/*Right Bottom*/} - - - + + + + + + + + + + {/*Right top*/} + {/*Right Bottom*/} + + ); } -} \ No newline at end of file +} diff --git a/src/pages/userProfile.tsx b/src/pages/userProfile.tsx index 38691c2..fa9b030 100644 --- a/src/pages/userProfile.tsx +++ b/src/pages/userProfile.tsx @@ -1,120 +1,206 @@ import { useSession } from "next-auth/react"; 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 { Box, Button, Center, Container, Divider, Editable, EditableInput, EditablePreview, EditableTextarea, Flex, Spacer, Text, useToast } from "@chakra-ui/react"; +import { + Box, + Button, + Center, + Container, + Divider, + Editable, + EditableInput, + EditablePreview, + EditableTextarea, + Flex, + Spacer, + Text, + useDisclosure, + useToast, +} from "@chakra-ui/react"; -import {RiEditBoxLine} from "react-icons/ri" +import { RiEditBoxLine } from "react-icons/ri"; import BottomBar from "@/components/BottomBar"; +import ModalModifyImages from "@/components/ModalModifyImages"; + import { useState } from "react"; export default function UserProfile() { const router = useRouter(); - const {data: session, status} = useSession(); + const toast = useToast(); + const { data: session, status } = useSession(); const [isLoading, setIsLoading] = useState(false); + const { isOpen, onOpen, onClose } = useDisclosure(); // faire un model avec toutes les infos de user - const [loginData, setLoginData] = useState(new userData()); - - - const toast = useToast(); + const [userData, setUserData] = useState({}); - // if (status === 'unauthenticated') router.push('/login'); - - // if (status === 'authenticated') { - // const {user} = session as unknown as Session; + if (status === "unauthenticated") router.push("/login"); + if (status === "authenticated") { + const { user } = session as unknown as Session; const saveData = () => { - // let {email, firstName, lastName, password, confirmPassword} = registerData; - toast({ - title: `Modifications effectuées`, - status: "success", - isClosable: true, - }) - // const options = { - // method: 'POST', - // headers: {'Content-Type': 'application/json'}, - // body: JSON.stringify(userData), - // }; - - // setIsLoading(true); - // fetch('/api/users', options).then(() => { - // setIsLoading(false) - // toast({ - // title: `Modifications effectuées`, - // status: "success", - // isClosable: true, - // }) + const options = { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(userData), + }; - // }).catch(() => { - // setIsLoading(false); - // toast({ - // title: `Erreur lors de l'envoi des modifications`, - // status: "error", - // isClosable: true, - // }) - // }); + setIsLoading(true); + + fetch(`/api/users/${user.id}`, options) + .then(() => { + 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, + }); + }); }; const formateDate = (dateString: string) => { - var options = { year: 'numeric', month: 'long', day: 'numeric' }; - return new Date(dateString).toLocaleDateString([],options); - } - - var dateString = "2018-05-18T04:00:00.000Z" - console.log(formateDate(dateString)); - - - const refinedUser = { - // ...user, - firstName: "Jean", - lastName: "Dujardin", - birthdate: formateDate(new Date), - aPropos: 'Je suis la personne fictive la plus fictive', - images: ['135538.webp'], - passions: ['Sport', 'Voiture', 'Cuisine'], + var options = { year: "numeric", month: "long", day: "numeric" }; + 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 ( - - - - - + + + + - + {/* {modal} */} + {!userData.images ? ( + + ) : ( + + )} - Modifiez les champs en les selectionnants - - - + + Modifiez les champs en les selectionnants + + + + Prénom : - {value = refinedUser.lastName}}> + { + setUserData({ ...userData, lastName: value }); + }} + > - + Nom : - refinedUser.firstName = value}> + { + setUserData({ ...userData, firstName: value }); + }} + > - + Date de naissance : - - {refinedUser.birthdate} + + {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 }); + }} + > + + + + - + ); - // } -} \ No newline at end of file + } +} diff --git a/yarn.lock b/yarn.lock index 8be858d..0137191 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1050,14 +1050,9 @@ dependencies: "glob" "7.1.7" -"@next/swc-linux-x64-gnu@13.2.3": - "integrity" "sha512-w5MyxPknVvC9LVnMenAYMXMx4KxPwXuJRMQFvY71uXg68n7cvcas85U5zkdrbmuZ+JvsO5SIG8k36/6X3nUhmQ==" - "resolved" "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.2.3.tgz" - "version" "13.2.3" - -"@next/swc-linux-x64-musl@13.2.3": - "integrity" "sha512-CTeelh8OzSOVqpzMFMFnVRJIFAFQoTsI9RmVJWW/92S4xfECGcOzgsX37CZ8K982WHRzKU7exeh7vYdG/Eh4CA==" - "resolved" "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.2.3.tgz" +"@next/swc-win32-x64-msvc@13.2.3": + "integrity" "sha512-aLG2MaFs4y7IwaMTosz2r4mVbqRyCnMoFqOcmfTi7/mAS+G4IMH0vJp4oLdbshqiVoiVuKrAfqtXj55/m7Qu1Q==" + "resolved" "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.2.3.tgz" "version" "13.2.3" "@nodelib/fs.scandir@2.1.5":