From 8e021a833d52dc22f8c31b50d9d7b86e9a77dd14 Mon Sep 17 00:00:00 2001 From: Laurian-Dufrechou Date: Thu, 18 May 2023 17:03:45 +0200 Subject: [PATCH] feat(invite Match to bar / create chat on match): Modal to invite match to bar/ create chat on match --- package-lock.json | 16 ++ package.json | 1 + src/components/ErrorGeoLocation.tsx | 11 +- .../layout/dashboard/left_panel/LeftPanel.tsx | 2 +- .../match_notification/ModalMatch.tsx | 3 +- src/components/layout/map/CardMatchedUser.tsx | 83 +++++++ src/components/layout/map/MapComponent.tsx | 95 +++---- src/components/layout/map/MarkerBar.tsx | 21 +- src/components/layout/map/ModalInviteBar.tsx | 161 ++++++++++++ .../layout/profile/ModalModifyImages.tsx | 235 +++++++++--------- src/pages/api/user/inviteToBar.ts | 53 ++++ src/pages/api/user/like.js | 10 +- src/pages/map.tsx | 56 ++--- src/pages/profile.tsx | 70 +++--- yarn.lock | 12 + 15 files changed, 598 insertions(+), 231 deletions(-) create mode 100644 src/components/layout/map/CardMatchedUser.tsx create mode 100644 src/components/layout/map/ModalInviteBar.tsx create mode 100644 src/pages/api/user/inviteToBar.ts diff --git a/package-lock.json b/package-lock.json index 939fc52..ad0079c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/leaflet": "^1.9.3", "@types/node": "^18.15.1", "next-transpile-modules": "^10.0.0", "prisma": "^4.11.0", @@ -2341,6 +2342,12 @@ "@types/ms": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.10", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", + "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==", + "dev": true + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -2355,6 +2362,15 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/leaflet": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.3.tgz", + "integrity": "sha512-Caa1lYOgKVqDkDZVWkto2Z5JtVo09spEaUt2S69LiugbBpoqQu92HYFMGUbYezZbnBkyOxMNPXHSgRrRY5UyIA==", + "dev": true, + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/lodash": { "version": "4.14.192", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz", diff --git a/package.json b/package.json index 9567ced..08b0cd7 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/leaflet": "^1.9.3", "@types/node": "^18.15.1", "next-transpile-modules": "^10.0.0", "prisma": "^4.11.0", diff --git a/src/components/ErrorGeoLocation.tsx b/src/components/ErrorGeoLocation.tsx index 5a9c749..ddd98b7 100644 --- a/src/components/ErrorGeoLocation.tsx +++ b/src/components/ErrorGeoLocation.tsx @@ -2,12 +2,17 @@ import { MdError } from "react-icons/md"; import { Button, Text, VStack } from "@chakra-ui/react"; import { useRouter } from "next/router"; -export default function LoadingPage() { +export default function ErrorGeolocation() { const router = useRouter(); return ( - + Veillez à autoriser la géolocalisation diff --git a/src/components/layout/dashboard/left_panel/LeftPanel.tsx b/src/components/layout/dashboard/left_panel/LeftPanel.tsx index af52b38..03cd047 100644 --- a/src/components/layout/dashboard/left_panel/LeftPanel.tsx +++ b/src/components/layout/dashboard/left_panel/LeftPanel.tsx @@ -49,7 +49,7 @@ export default function LeftPanel(props) { - "{user.bio}" + {user.bio && `"${user.bio}"`} diff --git a/src/components/layout/dashboard/match_notification/ModalMatch.tsx b/src/components/layout/dashboard/match_notification/ModalMatch.tsx index d0711a7..137f992 100644 --- a/src/components/layout/dashboard/match_notification/ModalMatch.tsx +++ b/src/components/layout/dashboard/match_notification/ModalMatch.tsx @@ -14,7 +14,6 @@ import { Text, useDisclosure, } from "@chakra-ui/react"; -import { SetStateAction } from "react"; import { useQuery } from "@tanstack/react-query"; import { User } from "@prisma/client"; import Carousel from "@/components/Carousel"; @@ -111,7 +110,7 @@ export default function ModalMatch({ notif, loggedUser }: modalMatchProps) { - + Passions : {passionLoading ? ( diff --git a/src/components/layout/map/CardMatchedUser.tsx b/src/components/layout/map/CardMatchedUser.tsx new file mode 100644 index 0000000..e55f9bf --- /dev/null +++ b/src/components/layout/map/CardMatchedUser.tsx @@ -0,0 +1,83 @@ +import { + Box, + Card, + CardBody, + chakra, + Flex, + GridItem, + Image, + Spacer, + Text, + useRadio, +} from "@chakra-ui/react"; +import { Notification } from "@prisma/client"; +import { useQuery } from "@tanstack/react-query"; + +type CardMatchedUserProps = { + notif: Notification; +}; + +export default function CardMatchedUser({ + notif, + ...radioProps +}: CardMatchedUserProps) { + const { + isLoading, + isError, + data: matchedUser, + error, + } = useQuery({ + refetchOnWindowFocus: false, + queryKey: ["matchUser", notif.MatchedUserID], + queryFn: async () => { + return fetch(`/api/users/${notif.MatchedUserID}?include=Chat`) + .then((res) => { + return res.json(); + }) + .catch((err) => { + return err; + }); + }, + }); + + const { state, getInputProps, getRadioProps, htmlProps, getLabelProps } = + useRadio(radioProps); + + return ( + <> + {!isLoading ? ( + + + + + + + + + {matchedUser.firstName} {matchedUser.lastName} + + + + + + + ) : null} + + ); +} diff --git a/src/components/layout/map/MapComponent.tsx b/src/components/layout/map/MapComponent.tsx index a65f5a3..d80f6a1 100644 --- a/src/components/layout/map/MapComponent.tsx +++ b/src/components/layout/map/MapComponent.tsx @@ -1,60 +1,65 @@ -import {MapContainer, TileLayer, Marker, Popup} from 'react-leaflet'; -import {Flex, Text, useToast} from '@chakra-ui/react'; -import MarkerClusterGroup - from '@christopherpickering/react-leaflet-markercluster'; +import { MapContainer, TileLayer, Marker, useMapEvents } from "react-leaflet"; +import { Flex, Text, useToast } from "@chakra-ui/react"; +import MarkerClusterGroup from "@christopherpickering/react-leaflet-markercluster"; +import L from "leaflet"; +import { memo, useState } from "react"; -import '@christopherpickering/react-leaflet-markercluster/dist/styles.min.css'; +import "@christopherpickering/react-leaflet-markercluster/dist/styles.min.css"; -import MarkerBar from './MarkerBar'; -import 'leaflet/dist/leaflet.css'; +import MarkerBar from "./MarkerBar"; +import "leaflet/dist/leaflet.css"; export default function MapComponent(props: any) { - const {location, listBars} = props; + const { location, listBars } = props; - const toast = useToast({position: 'bottom'}); + const toast = useToast({ position: "bottom" }); - const idToastError = 'error_location'; + const idToastError = "error_location"; const userIcon = new L.Icon({ - iconUrl: 'logo.svg', + iconUrl: "logo.svg", iconSize: [35, 35], }); return ( - <> - {location[0] === null || location[1] === null ? ( - <> - {!toast.isActive(idToastError) && - toast({ - title: 'Erreur', - id: idToastError, - description: 'Veuillez autoriser la localisation', - status: 'error', - isClosable: false, - duration: 100000, - })} - - Veuillez autoriser la localisation - - - ) : ( - - - - {/* Pour le user */} - + <> + {location[0] === null || location[1] === null ? ( + <> + {!toast.isActive(idToastError) && + toast({ + title: "Erreur", + id: idToastError, + description: "Veuillez autoriser la localisation", + status: "error", + isClosable: false, + duration: 100000, + })} + + Veuillez autoriser la localisation + + + ) : ( + + + {/* Pour le user */} + - - {listBars.map((bar: any, index: number) => )} - - - - )} - + + {listBars.map((bar: any, index: number) => ( + + ))} + + + )} + ); } diff --git a/src/components/layout/map/MarkerBar.tsx b/src/components/layout/map/MarkerBar.tsx index e525012..a51bc94 100644 --- a/src/components/layout/map/MarkerBar.tsx +++ b/src/components/layout/map/MarkerBar.tsx @@ -1,11 +1,14 @@ import { Marker, Popup } from "react-leaflet"; import "leaflet/dist/leaflet.css"; -import { Box, Button, Text } from "@chakra-ui/react"; +import { Box, Button, Text, useDisclosure } from "@chakra-ui/react"; +import ModalInviteBar from "./ModalInviteBar"; +import L, { LatLngTuple } from "leaflet"; -export default function MarkerBar(props) { +export default function MarkerBar(props: any) { const { bar } = props; - //changer l'icon + const { isOpen, onClose, onOpen } = useDisclosure(); + const barIcon = new L.Icon({ iconUrl: "drink_cocktail.png", iconSize: [35, 35], @@ -13,17 +16,19 @@ export default function MarkerBar(props) { backgroundColor: "purple", }); - const location = [bar.geo_point_2d.lat, bar.geo_point_2d.lon]; + const location = [bar.geo_point_2d.lat, bar.geo_point_2d.lon] as LatLngTuple; - //mettre un tooltip... return ( - + - {bar.name || '"Nom du bar"'} + {bar.name} - + + diff --git a/src/components/layout/map/ModalInviteBar.tsx b/src/components/layout/map/ModalInviteBar.tsx new file mode 100644 index 0000000..8efd495 --- /dev/null +++ b/src/components/layout/map/ModalInviteBar.tsx @@ -0,0 +1,161 @@ +import { + Box, + Button, + Card, + CardBody, + Flex, + Grid, + GridItem, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + Text, + useRadio, + useRadioGroup, + useToast, +} from "@chakra-ui/react"; +import { Notification, NotificationType, User } from "@prisma/client"; +import { useMutation, useQuery } from "@tanstack/react-query"; +import { useSession } from "next-auth/react"; +import type { Session } from "@/models/auth/Session"; +import CardMatchedUser from "./CardMatchedUser"; +import { Router } from "next/router"; +import { log } from "console"; + +type ModalInviteBarProps = { + isOpen: boolean; + onClose: () => void; + bar: any; +}; + +export default function ModalInviteBar({ + isOpen, + onClose, + bar, +}: ModalInviteBarProps) { + const { data: session, status } = useSession(); + const toast = useToast(); + + const { value, getRadioProps, getRootProps } = useRadioGroup({ + defaultValue: "-1", + }); + + const inviteToBar = useMutation({ + mutationFn: async (id) => { + const inviteOptions = { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + idUser: id, + idUserMatched: value, + bar: bar, + }), + }; + + try { + const res = await fetch(`/api/user/inviteToBar`, inviteOptions); + const response = await res.json(); + return response; + } catch (err) { + return err; + } + }, + onSuccess: (data) => { + if (data.error) { + toast({ + title: "Erreur", + description: "Une erreur est survenue", + status: "error", + duration: 2000, + }); + return; + } + console.log(data); + }, + }); + + const { + isLoading, + isError, + data: notificationMatch, + error, + } = useQuery({ + queryKey: ["notificationMatch"], + enabled: status === "authenticated", + queryFn: async () => { + const { user } = session as unknown as Session; + + return fetch( + `/api/notifications?where={"$and":{"UserID":"${user.id}", "type":"${NotificationType.NEW_MATCH}"}}` + ) + .then((res) => { + return res.json(); + }) + .catch((err) => { + return err; + }); + }, + }); + + console.log(bar); + + return ( + <> + + + + Inviter au bar : {bar.name} + + 🍻 + + + + + {!isError && !error + ? notificationMatch?.map((notif: Notification) => { + return ( + + ); + }) + : null} + + + + + + + + + + ); +} diff --git a/src/components/layout/profile/ModalModifyImages.tsx b/src/components/layout/profile/ModalModifyImages.tsx index 260a31e..dfdcd34 100644 --- a/src/components/layout/profile/ModalModifyImages.tsx +++ b/src/components/layout/profile/ModalModifyImages.tsx @@ -14,64 +14,62 @@ import { ModalOverlay, useDisclosure, useToast, -} from '@chakra-ui/react'; -import {useQueryClient} from '@tanstack/react-query'; -import {useState} from 'react'; -import {RiEditBoxLine} from 'react-icons/ri'; +} from "@chakra-ui/react"; +import { useQueryClient } from "@tanstack/react-query"; +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 { isOpen, onOpen, onClose } = useDisclosure(); + const { images, user, userData, setUserData } = props; const [listImage, setlistImage] = useState(images); - const toast = useToast({position: 'top', isClosable: true}); + const toast = useToast({ position: "top", isClosable: true }); const client = useQueryClient(); const uploadImage = async (file) => { const body = new FormData(); - body.append('file', file); + body.append("file", file); const imagePostOptions = { - method: 'POST', + method: "POST", body, }; const imagePatchOptions = { - method: 'PUT', - headers: {'Content-Type': 'application/json'}, + 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, + .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}`]); + }) + .catch(() => { + toast({ + title: `Erreur lors de l'ajout des images`, + status: "error", + isClosable: true, + }); }); - console.log(err); + }) + .catch((err) => { + toast({ + title: `Erreur lors de l'ajout des images`, + status: "error", + isClosable: true, }); + console.log(err); + }); }; const deleteImage = async (fileName) => { @@ -84,97 +82,112 @@ export default function ModalModifyImages(props) { } const imageDeleteOptions = { - method: 'DELETE', - body: JSON.stringify({fileName: fileName.split('/').pop()}), + 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'}, + 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, - }); + .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(); + + + + 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); - }}/> - - )} - - + 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); + }} + /> + + )} + + - - - - - - + }} + > + Save + + + + + ); } diff --git a/src/pages/api/user/inviteToBar.ts b/src/pages/api/user/inviteToBar.ts new file mode 100644 index 0000000..cc34a98 --- /dev/null +++ b/src/pages/api/user/inviteToBar.ts @@ -0,0 +1,53 @@ +import { log } from "console"; + +const { PrismaClient } = require("@prisma/client"); + +const post = async (req: any, res: any) => { + const prisma = new PrismaClient(); + + const { idUser, idUserMatched, bar } = req.body; + + try { + const chat = await prisma.chat.findFirst({ + where: { + AND: [ + { User: { some: { id: idUser } } }, + { User: { some: { id: idUserMatched } } }, + ], + }, + include: { + User: true, + }, + }); + + const message = await prisma.message.create({ + data: { + text: ``, + Chat: { + connect: { + id: chat.id, + }, + }, + User: { + connect: { + id: idUser, + }, + }, + }, + }); + + res + .status(200) + .json({ message: "invitation envoyée", message_sent: message }); + } catch (error) { + res.status(400).json({ message: "Something went wrong", error: error }); + } finally { + await prisma.$disconnect(); + } +}; + +export default (req: any, res: any) => { + req.method === "POST" + ? post(req, res) + : res.status(404).send({ message: "Wrong method, please use POST" }); +}; diff --git a/src/pages/api/user/like.js b/src/pages/api/user/like.js index eb2d69a..cfe1940 100644 --- a/src/pages/api/user/like.js +++ b/src/pages/api/user/like.js @@ -50,9 +50,15 @@ const post = async (req, res) => { }, }, }); - } - //faire une notification mais faut qu'on regarde un meilleur moyen dans la BD + await prisma.chat.create({ + data: { + User: { + connect: [{ id: idUserLiked }, { id: idUser }], + }, + }, + }); + } await prisma.user.update({ where: { diff --git a/src/pages/map.tsx b/src/pages/map.tsx index 5bcb0e8..4090d99 100644 --- a/src/pages/map.tsx +++ b/src/pages/map.tsx @@ -1,14 +1,20 @@ -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import dynamic from "next/dynamic"; -import { useToast } from "@chakra-ui/react"; -import "leaflet/dist/leaflet.css"; import { useSession } from "next-auth/react"; import { useMutation, useQuery } from "@tanstack/react-query"; +import type { Session } from "@/models/auth/Session"; import LoadingPage from "@/components/LoadingPage"; import ErrorPage from "@/components/ErrorPage"; -import ErrorGeolocation from "@/components/ErrorGeolocation"; import Navbar from "@/components/Navbar"; +import ErrorGeolocation from "@/components/ErrorGeoLocation"; + +const MapWithNoSSR = dynamic( + () => import("../components/layout/map/MapComponent"), + { + ssr: false, + } +); export default function Map() { const [location, setLocation] = useState([ @@ -17,8 +23,6 @@ export default function Map() { ]); const [geolocationError, setGeolocationError] = useState(false); - const toast = useToast({ position: "bottom" }); - const idSaveToast = "saved_location"; const { data: session, status } = useSession(); const [listBars, setListBars] = useState({} as unknown as any); @@ -29,6 +33,7 @@ export default function Map() { error, } = useQuery({ queryKey: ["LoggedUser"], + refetchOnWindowFocus: false, enabled: status === "authenticated", queryFn: async () => { const { user } = session as unknown as Session; @@ -50,8 +55,11 @@ export default function Map() { error: errorListBars, } = useQuery({ queryKey: ["listBars"], + refetchOnWindowFocus: false, enabled: !isLoading && location[0] !== null, queryFn: async () => { + ///Utiliser api de noratim + let urlBars = new URL( "https://data.opendatasoft.com/api/v2/catalog/datasets/osm-fr-bars%40babel/exports/json?" ); @@ -80,7 +88,6 @@ export default function Map() { }); const userSetLocation = useMutation({ - mutationKey: "userSetLocation", mutationFn: async (position: string) => { const pos = { location: position, @@ -94,14 +101,6 @@ export default function Map() { body: JSON.stringify(pos), }) .then((res) => { - // if (!toast.isActive(idSaveToast)) { - // toast({ - // id: idSaveToast, - // title: "Position enregistrée", - // description: "Votre position a bien été enregistrée", - // status: "success", - // }); - // } res.json(); }) .catch((err) => { @@ -125,6 +124,13 @@ export default function Map() { }, [loggedUser]); function successPosition(position: GeolocationPosition) { + if ( + position.coords.latitude === location[0] && + position.coords.longitude === location[1] + ) { + return; + } + setLocation([position.coords.latitude, position.coords.longitude]); setGeolocationError(false); @@ -138,29 +144,21 @@ export default function Map() { setGeolocationError(true); } - const MapWithNoSSR = dynamic( - () => import("../components/layout/map/MapComponent"), - { - ssr: false, - } - ); - return ( <> {geolocationError ? ( ) : isError || isErrorListBars ? ( - ) : isLoading || isLoadingListBars ? ( + ) : isLoading || + isLoadingListBars || + location[0] === null || + location[1] === null ? ( ) : ( <> - - + + )} diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx index 87ec565..8f7450d 100644 --- a/src/pages/profile.tsx +++ b/src/pages/profile.tsx @@ -9,15 +9,14 @@ import { Center, Container, Divider, - Editable, Flex, - FormHelperText, FormLabel, Text, useToast, VStack, } from "@chakra-ui/react"; +import { formateDate } from "@/lib/formateDate"; import ModalModifyImages from "@/components/layout/profile/ModalModifyImages"; import ModalChoosePassion from "@/components/layout/profile/ModalChoosePassion"; import ProfileTagList from "@/components/layout/profile/ProfileTagList"; @@ -39,6 +38,7 @@ export default function UserProfile() { const [currentlyLoading, setCurrentlyLoading] = useState(false); const [passions, setPassions] = useState([] as any[]); + const [address, setAddress] = useState({} as any); const [showTooltipAge, setShowTooltipAge] = useState(false); const [sliderAgeValue, setSliderAgeValue] = useState([[] as number[]]); @@ -86,6 +86,22 @@ export default function UserProfile() { }, }); + const { data: addressData, isSuccess: addressIsSuccess } = useQuery({ + queryKey: ["address"], + enabled: Boolean(userData?.location), + queryFn: async () => { + const [lat, long] = userData.location.split(","); + + return fetch( + `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${long}` + ) + .then((res) => res.json()) + .catch((err) => { + return err; + }); + }, + }); + if (isLoading) { if (status === "unauthenticated") router.push("/login"); return ; @@ -131,7 +147,6 @@ export default function UserProfile() { status: "success", isClosable: true, }); - // router.reload(); }) .catch((err) => { setCurrentlyLoading(false); @@ -146,27 +161,19 @@ export default function UserProfile() { } }; - const formateDate = (dateString: string) => { - var options = { year: "numeric", month: "long", day: "numeric" }; - return new Date(dateString).toLocaleDateString([], options); - }; - return ( - {userData.images ? ( - - ) : ( - - )} + - + @@ -334,7 +344,7 @@ export default function UserProfile() { /> */} -
+