mirror of
https://github.com/LucasVbr/meeting-app.git
synced 2026-07-09 06:58:06 +00:00
feat(invite Match to bar / create chat on match): Modal to invite match to bar/ create chat on match
This commit is contained in:
Generated
+16
@@ -44,6 +44,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
|
"@types/leaflet": "^1.9.3",
|
||||||
"@types/node": "^18.15.1",
|
"@types/node": "^18.15.1",
|
||||||
"next-transpile-modules": "^10.0.0",
|
"next-transpile-modules": "^10.0.0",
|
||||||
"prisma": "^4.11.0",
|
"prisma": "^4.11.0",
|
||||||
@@ -2341,6 +2342,12 @@
|
|||||||
"@types/ms": "*"
|
"@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": {
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
|
"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": {
|
"node_modules/@types/lodash": {
|
||||||
"version": "4.14.192",
|
"version": "4.14.192",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz",
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
|
"@types/leaflet": "^1.9.3",
|
||||||
"@types/node": "^18.15.1",
|
"@types/node": "^18.15.1",
|
||||||
"next-transpile-modules": "^10.0.0",
|
"next-transpile-modules": "^10.0.0",
|
||||||
"prisma": "^4.11.0",
|
"prisma": "^4.11.0",
|
||||||
|
|||||||
@@ -2,12 +2,17 @@ import { MdError } from "react-icons/md";
|
|||||||
import { Button, Text, VStack } from "@chakra-ui/react";
|
import { Button, Text, VStack } from "@chakra-ui/react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
export default function LoadingPage() {
|
export default function ErrorGeolocation() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack justifyContent="center" alignItems="center" height="100vh"
|
<VStack
|
||||||
width="100vw" bg="gray.100">
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
height="100vh"
|
||||||
|
width="100vw"
|
||||||
|
bg="gray.100"
|
||||||
|
>
|
||||||
<MdError color="purple.500" size="50%" />
|
<MdError color="purple.500" size="50%" />
|
||||||
<Text color="purple.500" fontSize="2xl" fontWeight="bold">
|
<Text color="purple.500" fontSize="2xl" fontWeight="bold">
|
||||||
Veillez à autoriser la géolocalisation
|
Veillez à autoriser la géolocalisation
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default function LeftPanel(props) {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Divider mb={"1rem"} />
|
<Divider mb={"1rem"} />
|
||||||
<Text as="i" fontWeight={"bold"}>
|
<Text as="i" fontWeight={"bold"}>
|
||||||
"{user.bio}"
|
{user.bio && `"${user.bio}"`}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { SetStateAction } from "react";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { User } from "@prisma/client";
|
import { User } from "@prisma/client";
|
||||||
import Carousel from "@/components/Carousel";
|
import Carousel from "@/components/Carousel";
|
||||||
@@ -111,7 +110,7 @@ export default function ModalMatch({ notif, loggedUser }: modalMatchProps) {
|
|||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Heading size={"sm"} fontWeight={"bold"}>
|
<Heading size={"sm"} mt={4} fontWeight={"bold"}>
|
||||||
Passions :
|
Passions :
|
||||||
</Heading>
|
</Heading>
|
||||||
{passionLoading ? (
|
{passionLoading ? (
|
||||||
|
|||||||
@@ -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 ? (
|
||||||
|
<chakra.label {...htmlProps} cursor="pointer">
|
||||||
|
<input {...getInputProps()} hidden />
|
||||||
|
<GridItem height={"100%"}>
|
||||||
|
<Card
|
||||||
|
{...getRadioProps()}
|
||||||
|
height={"100%"}
|
||||||
|
outline={state.isChecked ? "3px solid" : "none"}
|
||||||
|
outlineColor={state.isChecked ? "purple.500" : "none"}
|
||||||
|
bg={state.isChecked ? "purple.50" : "white"}
|
||||||
|
>
|
||||||
|
<CardBody>
|
||||||
|
<Flex
|
||||||
|
height={"100%"}
|
||||||
|
direction={"column"}
|
||||||
|
gap={"1rem"}
|
||||||
|
justifyContent={"space-between"}
|
||||||
|
{...getLabelProps()}
|
||||||
|
>
|
||||||
|
<Image src={matchedUser.images[0]}></Image>
|
||||||
|
<Text
|
||||||
|
align={"center"}
|
||||||
|
fontSize={"1.5rem"}
|
||||||
|
fontWeight={"bold"}
|
||||||
|
>
|
||||||
|
{matchedUser.firstName} {matchedUser.lastName}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</GridItem>
|
||||||
|
</chakra.label>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,22 +1,23 @@
|
|||||||
import {MapContainer, TileLayer, Marker, Popup} from 'react-leaflet';
|
import { MapContainer, TileLayer, Marker, useMapEvents } from "react-leaflet";
|
||||||
import {Flex, Text, useToast} from '@chakra-ui/react';
|
import { Flex, Text, useToast } from "@chakra-ui/react";
|
||||||
import MarkerClusterGroup
|
import MarkerClusterGroup from "@christopherpickering/react-leaflet-markercluster";
|
||||||
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 MarkerBar from "./MarkerBar";
|
||||||
import 'leaflet/dist/leaflet.css';
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
export default function MapComponent(props: any) {
|
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({
|
const userIcon = new L.Icon({
|
||||||
iconUrl: 'logo.svg',
|
iconUrl: "logo.svg",
|
||||||
iconSize: [35, 35],
|
iconSize: [35, 35],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -26,10 +27,10 @@ export default function MapComponent(props: any) {
|
|||||||
<>
|
<>
|
||||||
{!toast.isActive(idToastError) &&
|
{!toast.isActive(idToastError) &&
|
||||||
toast({
|
toast({
|
||||||
title: 'Erreur',
|
title: "Erreur",
|
||||||
id: idToastError,
|
id: idToastError,
|
||||||
description: 'Veuillez autoriser la localisation',
|
description: "Veuillez autoriser la localisation",
|
||||||
status: 'error',
|
status: "error",
|
||||||
isClosable: false,
|
isClosable: false,
|
||||||
duration: 100000,
|
duration: 100000,
|
||||||
})}
|
})}
|
||||||
@@ -38,10 +39,13 @@ export default function MapComponent(props: any) {
|
|||||||
</Text>
|
</Text>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Flex>
|
<MapContainer
|
||||||
<MapContainer center={location} zoom={13} minZoom={8}
|
center={location}
|
||||||
|
zoom={13}
|
||||||
|
minZoom={8}
|
||||||
zoomControl={false}
|
zoomControl={false}
|
||||||
style={{width: '100vw', height: '100vw'}}>
|
style={{ width: "100vw", height: "100vw" }}
|
||||||
|
>
|
||||||
<TileLayer
|
<TileLayer
|
||||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
@@ -50,10 +54,11 @@ export default function MapComponent(props: any) {
|
|||||||
<Marker icon={userIcon} position={location}></Marker>
|
<Marker icon={userIcon} position={location}></Marker>
|
||||||
|
|
||||||
<MarkerClusterGroup chunkedLoading showCoverageOnHover={false}>
|
<MarkerClusterGroup chunkedLoading showCoverageOnHover={false}>
|
||||||
{listBars.map((bar: any, index: number) => <MarkerBar key={index} bar={bar}/>)}
|
{listBars.map((bar: any, index: number) => (
|
||||||
|
<MarkerBar key={index} bar={bar} />
|
||||||
|
))}
|
||||||
</MarkerClusterGroup>
|
</MarkerClusterGroup>
|
||||||
</MapContainer>
|
</MapContainer>
|
||||||
</Flex>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { Marker, Popup } from "react-leaflet";
|
import { Marker, Popup } from "react-leaflet";
|
||||||
import "leaflet/dist/leaflet.css";
|
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;
|
const { bar } = props;
|
||||||
|
|
||||||
//changer l'icon
|
const { isOpen, onClose, onOpen } = useDisclosure();
|
||||||
|
|
||||||
const barIcon = new L.Icon({
|
const barIcon = new L.Icon({
|
||||||
iconUrl: "drink_cocktail.png",
|
iconUrl: "drink_cocktail.png",
|
||||||
iconSize: [35, 35],
|
iconSize: [35, 35],
|
||||||
@@ -13,17 +16,19 @@ export default function MarkerBar(props) {
|
|||||||
backgroundColor: "purple",
|
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 (
|
return (
|
||||||
<Marker icon={barIcon} position={location}>
|
<Marker icon={barIcon} position={location}>
|
||||||
<Popup>
|
<Popup>
|
||||||
<Box alignItems={"center"}>
|
<Box align={"center"}>
|
||||||
<Text fontSize={"1rem"} fontWeight={"bold"} align={"center"}>
|
<Text fontSize={"1rem"} fontWeight={"bold"} align={"center"}>
|
||||||
{bar.name || '"Nom du bar"'}
|
{bar.name}
|
||||||
</Text>
|
</Text>
|
||||||
<Button variant={"outline"}>Inviter un match</Button>
|
<Button variant={"outline"} onClick={onOpen}>
|
||||||
|
Inviter un match
|
||||||
|
</Button>
|
||||||
|
<ModalInviteBar bar={bar} isOpen={isOpen} onClose={onClose} />
|
||||||
</Box>
|
</Box>
|
||||||
</Popup>
|
</Popup>
|
||||||
</Marker>
|
</Marker>
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
blockScrollOnMount={false}
|
||||||
|
size={"2xl"}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
scrollBehavior={"inside"}
|
||||||
|
>
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader display={"flex"} alignItems={"center"} gap={2}>
|
||||||
|
Inviter au bar : {bar.name}
|
||||||
|
<Box as="span" fontSize={"3xl"}>
|
||||||
|
🍻
|
||||||
|
</Box>
|
||||||
|
</ModalHeader>
|
||||||
|
<ModalBody>
|
||||||
|
<Grid
|
||||||
|
{...getRootProps()}
|
||||||
|
templateColumns={`repeat(${notificationMatch?.length}, 1fr)`}
|
||||||
|
gap={6}
|
||||||
|
>
|
||||||
|
{!isError && !error
|
||||||
|
? notificationMatch?.map((notif: Notification) => {
|
||||||
|
return (
|
||||||
|
<CardMatchedUser
|
||||||
|
key={notif.MatchedUserID}
|
||||||
|
notif={notif}
|
||||||
|
{...getRadioProps({ value: notif.MatchedUserID })}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: null}
|
||||||
|
</Grid>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
mr={3}
|
||||||
|
isDisabled={value === "-1"}
|
||||||
|
onClick={() => {
|
||||||
|
const { user } = session as unknown as Session;
|
||||||
|
inviteToBar.mutate(user.id);
|
||||||
|
onClose();
|
||||||
|
// Router.push("/chat");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Inviter
|
||||||
|
</Button>
|
||||||
|
<Button variant="ghost" onClick={onClose}>
|
||||||
|
Annuler
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -14,60 +14,58 @@ import {
|
|||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from '@chakra-ui/react';
|
} from "@chakra-ui/react";
|
||||||
import {useQueryClient} from '@tanstack/react-query';
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
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, user, userData, setUserData} = props;
|
const { images, user, userData, setUserData } = props;
|
||||||
const [listImage, setlistImage] = useState(images);
|
const [listImage, setlistImage] = useState(images);
|
||||||
const toast = useToast({position: 'top', isClosable: true});
|
const toast = useToast({ position: "top", isClosable: true });
|
||||||
|
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
|
|
||||||
const uploadImage = async (file) => {
|
const uploadImage = async (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",
|
||||||
body,
|
body,
|
||||||
};
|
};
|
||||||
|
|
||||||
const imagePatchOptions = {
|
const imagePatchOptions = {
|
||||||
method: 'PUT',
|
method: "PUT",
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
images: [...listImage, `imageUsers/${file.name}`],
|
images: [...listImage, `imageUsers/${file.name}`],
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(`/api/file/uploadFile`, imagePostOptions)
|
fetch(`/api/file/uploadFile`, imagePostOptions)
|
||||||
.then(res => {
|
.then((res) => {
|
||||||
fetch(`/api/users/${user.id}`, imagePatchOptions)
|
fetch(`/api/users/${user.id}`, imagePatchOptions)
|
||||||
.then(res => {
|
.then((res) => {
|
||||||
toast({
|
toast({
|
||||||
title: `Ajout d'image effectué`,
|
title: `Ajout d'image effectué`,
|
||||||
status: 'success',
|
status: "success",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
setlistImage([...listImage, `imageUsers/${file.name}`]);
|
setlistImage([...listImage, `imageUsers/${file.name}`]);
|
||||||
// router.reload();
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setIsLoading(false);
|
|
||||||
toast({
|
toast({
|
||||||
title: `Erreur lors de l'ajout des images`,
|
title: `Erreur lors de l'ajout des images`,
|
||||||
status: 'error',
|
status: "error",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
toast({
|
toast({
|
||||||
title: `Erreur lors de l'ajout des images`,
|
title: `Erreur lors de l'ajout des images`,
|
||||||
status: 'error',
|
status: "error",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -84,14 +82,14 @@ export default function ModalModifyImages(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const imageDeleteOptions = {
|
const imageDeleteOptions = {
|
||||||
method: 'DELETE',
|
method: "DELETE",
|
||||||
body: JSON.stringify({fileName: fileName.split('/').pop()}),
|
body: JSON.stringify({ fileName: fileName.split("/").pop() }),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(`/api/file/deleteFile`, imageDeleteOptions).then((res) => {
|
fetch(`/api/file/deleteFile`, imageDeleteOptions).then((res) => {
|
||||||
const imagePatchOptions = {
|
const imagePatchOptions = {
|
||||||
method: 'PUT',
|
method: "PUT",
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
images: [...listImage],
|
images: [...listImage],
|
||||||
}),
|
}),
|
||||||
@@ -100,14 +98,14 @@ export default function ModalModifyImages(props) {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
toast({
|
toast({
|
||||||
title: `Suppression d'image effectué`,
|
title: `Suppression d'image effectué`,
|
||||||
status: 'success',
|
status: "success",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast({
|
toast({
|
||||||
title: `Erreur lors de la suppression des images`,
|
title: `Erreur lors de la suppression des images`,
|
||||||
status: 'error',
|
status: "error",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -116,60 +114,75 @@ export default function ModalModifyImages(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button onClick={onOpen} leftIcon={<RiEditBoxLine/>}>
|
<Button onClick={onOpen} leftIcon={<RiEditBoxLine />}>
|
||||||
Modifier les images
|
Modifier les images
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Modal blockScrollOnMount={false} size={'4xl'} isOpen={isOpen}
|
<Modal
|
||||||
onClose={onClose} scrollBehavior={'inside'}>
|
blockScrollOnMount={false}
|
||||||
<ModalOverlay/>
|
size={"4xl"}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
scrollBehavior={"inside"}
|
||||||
|
>
|
||||||
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
<ModalHeader>Modification des images</ModalHeader>
|
<ModalHeader>Modification des images</ModalHeader>
|
||||||
<ModalCloseButton/>
|
<ModalCloseButton />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Grid templateColumns={`repeat(${listImage.length + 1}, 1fr)`}
|
<Grid
|
||||||
gap={5}>
|
templateColumns={`repeat(${listImage.length + 1}, 1fr)`}
|
||||||
|
gap={5}
|
||||||
|
>
|
||||||
{listImage.map((image, index) => (
|
{listImage.map((image, index) => (
|
||||||
<GridItem key={index}>
|
<GridItem key={index}>
|
||||||
<Flex direction={'column'} gap={'1rem'}>
|
<Flex direction={"column"} gap={"1rem"}>
|
||||||
<Image src={image}/>
|
<Image src={image} />
|
||||||
<Button id={index.toString()} colorScheme={'red'}
|
<Button
|
||||||
onClick={() =>
|
id={index.toString()}
|
||||||
deleteImage(`${listImage[index]}`)}>
|
colorScheme={"red"}
|
||||||
|
onClick={() => deleteImage(`${listImage[index]}`)}
|
||||||
|
>
|
||||||
Supprimer l'image
|
Supprimer l'image
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
))}
|
))}
|
||||||
{listImage.length < 5 && (
|
{listImage.length < 5 && (
|
||||||
<GridItem width={'100%'}>
|
<GridItem width={"100%"}>
|
||||||
<Input type={'file'} height={'100%'}
|
<Input
|
||||||
accept={'image/png, image/jpeg, image/webp'}
|
type={"file"}
|
||||||
onInput={({target}) => {
|
height={"100%"}
|
||||||
|
accept={"image/png, image/jpeg, image/webp"}
|
||||||
|
onInput={({ target }) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const time = date.getTime();
|
const time = date.getTime();
|
||||||
|
|
||||||
const file = target.files[0];
|
const file = target.files[0];
|
||||||
const extension = file.name.split('.').pop();
|
const extension = file.name.split(".").pop();
|
||||||
const newFile = new File(
|
const newFile = new File(
|
||||||
[file],
|
[file],
|
||||||
`${user.id}_${time}.${extension}`,
|
`${user.id}_${time}.${extension}`,
|
||||||
{
|
{
|
||||||
type: file.type,
|
type: file.type,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
uploadImage(newFile);
|
uploadImage(newFile);
|
||||||
}}/>
|
}}
|
||||||
|
/>
|
||||||
</GridItem>
|
</GridItem>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button mr={3} onClick={() => {
|
<Button
|
||||||
client.invalidateQueries('user');
|
mr={3}
|
||||||
|
onClick={() => {
|
||||||
|
client.invalidateQueries("user");
|
||||||
onClose();
|
onClose();
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
|||||||
@@ -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: `<!lon=${bar.geo_point_2d.lon},lat=${bar.geo_point_2d.lat},name=${bar.name}>`,
|
||||||
|
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" });
|
||||||
|
};
|
||||||
@@ -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({
|
await prisma.user.update({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
+27
-29
@@ -1,14 +1,20 @@
|
|||||||
import { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { useToast } from "@chakra-ui/react";
|
|
||||||
import "leaflet/dist/leaflet.css";
|
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
import type { Session } from "@/models/auth/Session";
|
||||||
|
|
||||||
import LoadingPage from "@/components/LoadingPage";
|
import LoadingPage from "@/components/LoadingPage";
|
||||||
import ErrorPage from "@/components/ErrorPage";
|
import ErrorPage from "@/components/ErrorPage";
|
||||||
import ErrorGeolocation from "@/components/ErrorGeolocation";
|
|
||||||
import Navbar from "@/components/Navbar";
|
import Navbar from "@/components/Navbar";
|
||||||
|
import ErrorGeolocation from "@/components/ErrorGeoLocation";
|
||||||
|
|
||||||
|
const MapWithNoSSR = dynamic(
|
||||||
|
() => import("../components/layout/map/MapComponent"),
|
||||||
|
{
|
||||||
|
ssr: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default function Map() {
|
export default function Map() {
|
||||||
const [location, setLocation] = useState([
|
const [location, setLocation] = useState([
|
||||||
@@ -17,8 +23,6 @@ export default function Map() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const [geolocationError, setGeolocationError] = useState(false);
|
const [geolocationError, setGeolocationError] = useState(false);
|
||||||
const toast = useToast({ position: "bottom" });
|
|
||||||
const idSaveToast = "saved_location";
|
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
const [listBars, setListBars] = useState({} as unknown as any);
|
const [listBars, setListBars] = useState({} as unknown as any);
|
||||||
|
|
||||||
@@ -29,6 +33,7 @@ export default function Map() {
|
|||||||
error,
|
error,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ["LoggedUser"],
|
queryKey: ["LoggedUser"],
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
enabled: status === "authenticated",
|
enabled: status === "authenticated",
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { user } = session as unknown as Session;
|
const { user } = session as unknown as Session;
|
||||||
@@ -50,8 +55,11 @@ export default function Map() {
|
|||||||
error: errorListBars,
|
error: errorListBars,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ["listBars"],
|
queryKey: ["listBars"],
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
enabled: !isLoading && location[0] !== null,
|
enabled: !isLoading && location[0] !== null,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
///Utiliser api de noratim
|
||||||
|
|
||||||
let urlBars = new URL(
|
let urlBars = new URL(
|
||||||
"https://data.opendatasoft.com/api/v2/catalog/datasets/osm-fr-bars%40babel/exports/json?"
|
"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({
|
const userSetLocation = useMutation({
|
||||||
mutationKey: "userSetLocation",
|
|
||||||
mutationFn: async (position: string) => {
|
mutationFn: async (position: string) => {
|
||||||
const pos = {
|
const pos = {
|
||||||
location: position,
|
location: position,
|
||||||
@@ -94,14 +101,6 @@ export default function Map() {
|
|||||||
body: JSON.stringify(pos),
|
body: JSON.stringify(pos),
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.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();
|
res.json();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@@ -125,6 +124,13 @@ export default function Map() {
|
|||||||
}, [loggedUser]);
|
}, [loggedUser]);
|
||||||
|
|
||||||
function successPosition(position: GeolocationPosition) {
|
function successPosition(position: GeolocationPosition) {
|
||||||
|
if (
|
||||||
|
position.coords.latitude === location[0] &&
|
||||||
|
position.coords.longitude === location[1]
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setLocation([position.coords.latitude, position.coords.longitude]);
|
setLocation([position.coords.latitude, position.coords.longitude]);
|
||||||
setGeolocationError(false);
|
setGeolocationError(false);
|
||||||
|
|
||||||
@@ -138,29 +144,21 @@ export default function Map() {
|
|||||||
setGeolocationError(true);
|
setGeolocationError(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapWithNoSSR = dynamic(
|
|
||||||
() => import("../components/layout/map/MapComponent"),
|
|
||||||
{
|
|
||||||
ssr: false,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{geolocationError ? (
|
{geolocationError ? (
|
||||||
<ErrorGeolocation />
|
<ErrorGeolocation />
|
||||||
) : isError || isErrorListBars ? (
|
) : isError || isErrorListBars ? (
|
||||||
<ErrorPage />
|
<ErrorPage />
|
||||||
) : isLoading || isLoadingListBars ? (
|
) : isLoading ||
|
||||||
|
isLoadingListBars ||
|
||||||
|
location[0] === null ||
|
||||||
|
location[1] === null ? (
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<Navbar variant={"fixed"} />
|
||||||
<MapWithNoSSR
|
<MapWithNoSSR location={location} listBars={listBars} />
|
||||||
location={location}
|
|
||||||
loggedUser={loggedUser}
|
|
||||||
listBars={listBars}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
+37
-27
@@ -9,15 +9,14 @@ import {
|
|||||||
Center,
|
Center,
|
||||||
Container,
|
Container,
|
||||||
Divider,
|
Divider,
|
||||||
Editable,
|
|
||||||
Flex,
|
Flex,
|
||||||
FormHelperText,
|
|
||||||
FormLabel,
|
FormLabel,
|
||||||
Text,
|
Text,
|
||||||
useToast,
|
useToast,
|
||||||
VStack,
|
VStack,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
|
import { formateDate } from "@/lib/formateDate";
|
||||||
import ModalModifyImages from "@/components/layout/profile/ModalModifyImages";
|
import ModalModifyImages from "@/components/layout/profile/ModalModifyImages";
|
||||||
import ModalChoosePassion from "@/components/layout/profile/ModalChoosePassion";
|
import ModalChoosePassion from "@/components/layout/profile/ModalChoosePassion";
|
||||||
import ProfileTagList from "@/components/layout/profile/ProfileTagList";
|
import ProfileTagList from "@/components/layout/profile/ProfileTagList";
|
||||||
@@ -39,6 +38,7 @@ export default function UserProfile() {
|
|||||||
|
|
||||||
const [currentlyLoading, setCurrentlyLoading] = useState(false);
|
const [currentlyLoading, setCurrentlyLoading] = useState(false);
|
||||||
const [passions, setPassions] = useState([] as any[]);
|
const [passions, setPassions] = useState([] as any[]);
|
||||||
|
const [address, setAddress] = useState({} as any);
|
||||||
|
|
||||||
const [showTooltipAge, setShowTooltipAge] = useState(false);
|
const [showTooltipAge, setShowTooltipAge] = useState(false);
|
||||||
const [sliderAgeValue, setSliderAgeValue] = useState([[] as number[]]);
|
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 (isLoading) {
|
||||||
if (status === "unauthenticated") router.push("/login");
|
if (status === "unauthenticated") router.push("/login");
|
||||||
return <LoadingPage />;
|
return <LoadingPage />;
|
||||||
@@ -131,7 +147,6 @@ export default function UserProfile() {
|
|||||||
status: "success",
|
status: "success",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
// router.reload();
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
setCurrentlyLoading(false);
|
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 (
|
return (
|
||||||
<Box bgColor={"purple.50"}>
|
<Box bgColor={"purple.50"}>
|
||||||
<Container justifyContent={"center"} maxW={"70rem"} mt={"1rem"}>
|
<Container justifyContent={"center"} maxW={"70rem"} mt={"1rem"}>
|
||||||
<Flex flexDirection={"column"} alignItems={"center"} gap={"1rem"}>
|
<Flex flexDirection={"column"} alignItems={"center"} gap={"1rem"}>
|
||||||
<Box width={"50%"}>
|
<Box width={"50%"}>
|
||||||
{userData.images ? (
|
|
||||||
<Carousel
|
<Carousel
|
||||||
images={userData.images}
|
images={
|
||||||
|
userData.images
|
||||||
|
? userData.images
|
||||||
|
: ["blank_profile_picture.webp"]
|
||||||
|
}
|
||||||
borderRadius={"1rem"}
|
borderRadius={"1rem"}
|
||||||
></Carousel>
|
></Carousel>
|
||||||
) : (
|
|
||||||
<Carousel
|
|
||||||
images={userData.images}
|
|
||||||
borderRadius={"1rem"}
|
|
||||||
></Carousel>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
<ModalModifyImages
|
<ModalModifyImages
|
||||||
userData={userData}
|
userData={userData}
|
||||||
@@ -179,7 +186,12 @@ export default function UserProfile() {
|
|||||||
Modifiez les champs en les selectionnants
|
Modifiez les champs en les selectionnants
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Box as="form" onSubmit={handleSubmit(saveData)} width={"80%"}>
|
<Box
|
||||||
|
position={"relative"}
|
||||||
|
as="form"
|
||||||
|
onSubmit={handleSubmit(saveData)}
|
||||||
|
width={"80%"}
|
||||||
|
>
|
||||||
<Flex width={"100%"} justify={"space-between"} mb={"1rem"}>
|
<Flex width={"100%"} justify={"space-between"} mb={"1rem"}>
|
||||||
<Box>
|
<Box>
|
||||||
<CustomEditable
|
<CustomEditable
|
||||||
@@ -210,7 +222,7 @@ export default function UserProfile() {
|
|||||||
<Box>
|
<Box>
|
||||||
<CustomFalseEditable
|
<CustomFalseEditable
|
||||||
id="birthdate"
|
id="birthdate"
|
||||||
defaultValue={
|
value={
|
||||||
userData.birthdate === undefined ||
|
userData.birthdate === undefined ||
|
||||||
userData.birthdate === null
|
userData.birthdate === null
|
||||||
? "Non renseigné"
|
? "Non renseigné"
|
||||||
@@ -225,13 +237,12 @@ export default function UserProfile() {
|
|||||||
<Box>
|
<Box>
|
||||||
<CustomFalseEditable
|
<CustomFalseEditable
|
||||||
id="location"
|
id="location"
|
||||||
isDisabled={true}
|
value={
|
||||||
defaultValue={
|
!addressIsSuccess || addressData === undefined
|
||||||
userData.location === null || userData.location === ""
|
? "Rendez vous sur la carte !"
|
||||||
? "Rendez vous sur la carte"
|
: `${addressData.address.town}, ${addressData.address.county}, ${addressData.address.state}`
|
||||||
: userData.location
|
|
||||||
}
|
}
|
||||||
label={"Ville :"}
|
label={"Adresse :"}
|
||||||
helperText={
|
helperText={
|
||||||
"Ce champ est modifié automatiquement depuis la carte"
|
"Ce champ est modifié automatiquement depuis la carte"
|
||||||
}
|
}
|
||||||
@@ -240,8 +251,7 @@ export default function UserProfile() {
|
|||||||
<Box>
|
<Box>
|
||||||
<CustomFalseEditable
|
<CustomFalseEditable
|
||||||
id="email"
|
id="email"
|
||||||
isDisabled={true}
|
value={userData.email}
|
||||||
defaultValue={userData.email}
|
|
||||||
label={"Adresse mail :"}
|
label={"Adresse mail :"}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -334,7 +344,7 @@ export default function UserProfile() {
|
|||||||
/> */}
|
/> */}
|
||||||
</Box>
|
</Box>
|
||||||
<Divider colorScheme={"purple"} />
|
<Divider colorScheme={"purple"} />
|
||||||
<Center gap={"1rem"} my={"1rem"}>
|
<Center position={"sticky"} bottom={0} gap={"1rem"} my={"1rem"}>
|
||||||
<Button
|
<Button
|
||||||
colorScheme={"purple"}
|
colorScheme={"purple"}
|
||||||
isLoading={currentlyLoading}
|
isLoading={currentlyLoading}
|
||||||
|
|||||||
@@ -1416,6 +1416,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/ms" "*"
|
"@types/ms" "*"
|
||||||
|
|
||||||
|
"@types/geojson@*":
|
||||||
|
"integrity" "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
|
||||||
|
"resolved" "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz"
|
||||||
|
"version" "7946.0.10"
|
||||||
|
|
||||||
"@types/hoist-non-react-statics@^3.3.1":
|
"@types/hoist-non-react-statics@^3.3.1":
|
||||||
"integrity" "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA=="
|
"integrity" "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA=="
|
||||||
"resolved" "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
|
"resolved" "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
|
||||||
@@ -1429,6 +1434,13 @@
|
|||||||
"resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
|
"resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
|
||||||
"version" "0.0.29"
|
"version" "0.0.29"
|
||||||
|
|
||||||
|
"@types/leaflet@^1.9.3":
|
||||||
|
"integrity" "sha512-Caa1lYOgKVqDkDZVWkto2Z5JtVo09spEaUt2S69LiugbBpoqQu92HYFMGUbYezZbnBkyOxMNPXHSgRrRY5UyIA=="
|
||||||
|
"resolved" "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.3.tgz"
|
||||||
|
"version" "1.9.3"
|
||||||
|
dependencies:
|
||||||
|
"@types/geojson" "*"
|
||||||
|
|
||||||
"@types/lodash.mergewith@4.6.7":
|
"@types/lodash.mergewith@4.6.7":
|
||||||
"integrity" "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A=="
|
"integrity" "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A=="
|
||||||
"resolved" "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz"
|
"resolved" "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user