Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # src/pages/graphique.tsx # src/pages/map.tsx
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 108 KiB |
@@ -1,13 +1,13 @@
|
|||||||
import {useState} from 'react';
|
import { useState } from "react";
|
||||||
import {Flex, IconButton} from '@chakra-ui/react';
|
import { Flex, IconButton } from "@chakra-ui/react";
|
||||||
import {BiLeftArrowAlt, BiRightArrowAlt} from 'react-icons/bi';
|
import { BiLeftArrowAlt, BiRightArrowAlt } from "react-icons/bi";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
images: string[];
|
images: string[];
|
||||||
borderRadius?: string | number;
|
borderRadius?: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Carousel = ({images, borderRadius: bRadius}: Props) => {
|
const Carousel = ({ images, borderRadius: bRadius }: Props) => {
|
||||||
const [currentIndex, setCurrentIndex] = useState(0);
|
const [currentIndex, setCurrentIndex] = useState(0);
|
||||||
|
|
||||||
const handleClickPrevious = () => {
|
const handleClickPrevious = () => {
|
||||||
@@ -18,22 +18,39 @@ const Carousel = ({images, borderRadius: bRadius}: Props) => {
|
|||||||
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'];
|
if (images.length === 0) images = ["blank_profile_picture.webp"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex px={2} align="center" borderRadius={bRadius} overflow={'hidden'}
|
<Flex
|
||||||
justify={'space-between'} bgColor={'purple.50'} height={500}
|
px={2}
|
||||||
bgImage={images[currentIndex]} bgSize={'cover'}
|
align="center"
|
||||||
bgRepeat={'no-repeat'} bgPosition={'center'} width={'100%'}>
|
borderRadius={bRadius}
|
||||||
<IconButton aria-label="left-arrow" borderRadius="full"
|
overflow={"hidden"}
|
||||||
onClick={handleClickPrevious}>
|
justify={"space-between"}
|
||||||
<BiLeftArrowAlt/>
|
bgColor={"purple.50"}
|
||||||
</IconButton>
|
height={500}
|
||||||
|
bgImage={images[currentIndex]}
|
||||||
|
bgSize={"contain"}
|
||||||
|
bgRepeat={"no-repeat"}
|
||||||
|
bgPosition={"center"}
|
||||||
|
width={"100%"}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
aria-label="left-arrow"
|
||||||
|
borderRadius="full"
|
||||||
|
onClick={handleClickPrevious}
|
||||||
|
>
|
||||||
|
<BiLeftArrowAlt />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
<IconButton aria-label="left-arrow" borderRadius="full" onClick={handleClickNext}>
|
<IconButton
|
||||||
<BiRightArrowAlt/>
|
aria-label="left-arrow"
|
||||||
</IconButton>
|
borderRadius="full"
|
||||||
</Flex>
|
onClick={handleClickNext}
|
||||||
|
>
|
||||||
|
<BiRightArrowAlt />
|
||||||
|
</IconButton>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,28 @@
|
|||||||
import { Flex } from "@chakra-ui/react";
|
import {Flex} from '@chakra-ui/react';
|
||||||
import { MapContainer, TileLayer } from "react-leaflet";
|
import {MapContainer, TileLayer} from 'react-leaflet';
|
||||||
import SimpleMarkerBar from "./SimpleMarkerBar";
|
import SimpleMarkerBar from './SimpleMarkerBar';
|
||||||
import "leaflet/dist/leaflet.css";
|
import 'leaflet/dist/leaflet.css';
|
||||||
|
|
||||||
type MapBarProps = {
|
type MapBarProps = {
|
||||||
lat: string;
|
lat: string;
|
||||||
lon: string;
|
lon: string;
|
||||||
name: string;
|
name: string;
|
||||||
align: "left" | "right";
|
align: 'left' | 'right';
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function MapBar({ lat, lon, name, align }: MapBarProps) {
|
export default function MapBar({lat, lon, name}: MapBarProps) {
|
||||||
return (
|
return (
|
||||||
<Flex justifyContent={align}>
|
|
||||||
<MapContainer
|
<MapContainer
|
||||||
center={[Number(lat), Number(lon)]}
|
center={[Number(lat), Number(lon)]}
|
||||||
zoom={13}
|
zoom={13}
|
||||||
minZoom={6}
|
minZoom={6}
|
||||||
zoomControl={false}
|
zoomControl={false}
|
||||||
style={{ width: "100%", height: "20rem" }}
|
style={{width: '100%', height: '20rem'}}>
|
||||||
>
|
|
||||||
<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'
|
||||||
/>
|
/>
|
||||||
<SimpleMarkerBar lat={lat} lon={lon} name={name} />
|
<SimpleMarkerBar lat={lat} lon={lon} name={name}/>
|
||||||
</MapContainer>
|
</MapContainer>
|
||||||
</Flex>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type {Message as MessageType} from '@prisma/client';
|
import type {Message as MessageType, User} from '@prisma/client';
|
||||||
import MessageText from '@/components/chat/MessageText';
|
import MessageText from '@/components/chat/MessageText';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import MessageMap from '@/components/chat/MessageMap';
|
import MessageMap from '@/components/chat/MessageMap';
|
||||||
@@ -6,9 +6,10 @@ import MessageMap from '@/components/chat/MessageMap';
|
|||||||
type Props = {
|
type Props = {
|
||||||
align: "left" | 'right'
|
align: "left" | 'right'
|
||||||
message: MessageType
|
message: MessageType
|
||||||
|
user?: User
|
||||||
}
|
}
|
||||||
|
|
||||||
const Message = ({message, align}: Props) => {
|
const Message = ({message, align, user}: Props) => {
|
||||||
if (message.text.match(/<!.+>/g)) {
|
if (message.text.match(/<!.+>/g)) {
|
||||||
const regex = /<!lon=(?<lon>-?\d+\.\d+),lat=(?<lat>-?\d+\.\d+),name=(?<name>.+)>/g;
|
const regex = /<!lon=(?<lon>-?\d+\.\d+),lat=(?<lat>-?\d+\.\d+),name=(?<name>.+)>/g;
|
||||||
const p = regex.exec(message.text)?.groups as unknown as {
|
const p = regex.exec(message.text)?.groups as unknown as {
|
||||||
@@ -16,12 +17,10 @@ const Message = ({message, align}: Props) => {
|
|||||||
lat: number
|
lat: number
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
if (p) return <MessageMap align={align} point={p}/>
|
if (p) return <MessageMap user={user} align={align} point={p}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <MessageText user={user} message={message} align={align} />
|
||||||
<MessageText message={message} align={align} />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Message;
|
export default Message;
|
||||||
@@ -1,19 +1,24 @@
|
|||||||
import type {Message as MessageType, User} from '@prisma/client';
|
import type {Message as MessageType, User, Chat} from '@prisma/client';
|
||||||
import Message from '@/components/chat/Message';
|
import Message from '@/components/chat/Message';
|
||||||
import {Flex} from '@chakra-ui/react';
|
import {Flex} from '@chakra-ui/react';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
user: User,
|
user: User,
|
||||||
messages: MessageType[]
|
messages: MessageType[]
|
||||||
|
chat: Chat & { User: User[] }
|
||||||
}
|
}
|
||||||
|
|
||||||
const MessageList = ({messages, user}: Props) => (
|
const MessageList = ({messages, user, chat}: Props) => {
|
||||||
<Flex direction={'column'} gap={1} justifyContent={'flex-end'}>
|
if (chat?.User)
|
||||||
{messages.map((message, index) => <Message
|
return (
|
||||||
align={user.id === message.UserID ? 'right' : 'left'} key={index}
|
<Flex direction={'column'} gap={1} justifyContent={'flex-end'}>
|
||||||
message={message}/>,
|
{messages.map((message, index) =>
|
||||||
)}
|
<Message user={chat.User.find(u => u.id === message.UserID)}
|
||||||
</Flex>
|
align={user.id === message.UserID ? 'right' : 'left'}
|
||||||
);
|
key={index} message={message}/>,
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default MessageList;
|
export default MessageList;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import {Box, Flex, Text} from '@chakra-ui/react';
|
import {Avatar, Box, Flex, Text} from '@chakra-ui/react';
|
||||||
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import {User} from '@prisma/client';
|
||||||
|
|
||||||
const MapBarWithNoSSR = dynamic(() => import('./MapBar'), {
|
const MapBarWithNoSSR = dynamic(() => import('./MapBar'), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@@ -13,16 +14,18 @@ type Props = {
|
|||||||
lat: string;
|
lat: string;
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
user?: User
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function MessageMap({align, point}: Props) {
|
export default function MessageMap({align, point, user}: Props) {
|
||||||
const {lon, lat, name} = point;
|
const {lon, lat, name} = point;
|
||||||
return (
|
return (
|
||||||
<Flex justifyContent={align}>
|
<Flex justifyContent={align} gap={2}>
|
||||||
|
{user && align === "left" && <Avatar src={`/${user.images[0]}`} name={`${user.firstName} ${user.lastName}`}/>}
|
||||||
<Box w={'50%'} bg={'purple.500'} borderRadius={10} p={2}>
|
<Box w={'50%'} bg={'purple.500'} borderRadius={10} p={2}>
|
||||||
<MapBarWithNoSSR lon={lon} lat={lat} name={name}/>
|
<MapBarWithNoSSR lon={lon} lat={lat} name={name}/>
|
||||||
{/*<Text align={align}>{lon}, {lat}, {name}</Text>*/}
|
|
||||||
</Box>
|
</Box>
|
||||||
|
{user && align === "right" && <Avatar src={`/${user.images[0]}`} name={`${user.firstName} ${user.lastName}`}/>}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
import {Flex, Text} from '@chakra-ui/react';
|
import {Avatar, Flex, Text} from '@chakra-ui/react';
|
||||||
import type {Message as MessageType, User} from '@prisma/client';
|
import type {Message as MessageType, User} from '@prisma/client';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
align: 'left' | 'right'
|
align: 'left' | 'right'
|
||||||
message: MessageType
|
message: MessageType,
|
||||||
|
user?: User
|
||||||
}
|
}
|
||||||
|
|
||||||
const MessageText = ({message, align}: Props) => (
|
const MessageText = ({message, align, user}: Props) => (
|
||||||
<Flex justifyContent={align}>
|
|
||||||
|
<Flex justifyContent={align} gap={2}>
|
||||||
|
{user && align === "left" && <Avatar src={`/${user.images[0]}`} name={`${user.firstName} ${user.lastName}`}/>}
|
||||||
<Text maxW={'70%'} w={'fit-content'} bg={'purple.500'} borderRadius={10}
|
<Text maxW={'70%'} w={'fit-content'} bg={'purple.500'} borderRadius={10}
|
||||||
color={'white'} px={'10px'} py={'5px'}>
|
color={'white'} px={'10px'} py={'5px'}>
|
||||||
{message.text}
|
{message.text}
|
||||||
</Text>
|
</Text>
|
||||||
|
{user && align === "right" && <Avatar src={`/${user.images[0]}`} name={`${user.firstName} ${user.lastName}`}/>}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -17,16 +17,21 @@ import PassionTagList from "@/components/layout/dashboard/card_user/PassionTagLi
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import SearchFailCard from "./SearchFailCard";
|
import SearchFailCard from "./SearchFailCard";
|
||||||
import LoadingPage from "@/components/LoadingPage";
|
import LoadingPage from "@/components/LoadingPage";
|
||||||
import {User} from '@prisma/client';
|
import { User } from "@prisma/client";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
users: User[]
|
users: User[];
|
||||||
loggedUser: User
|
loggedUser: User;
|
||||||
setMatch: any
|
setMatch: any;
|
||||||
refetchLoggedUser: any
|
refetchLoggedUser: any;
|
||||||
}
|
};
|
||||||
|
|
||||||
export default function CardUser({users, loggedUser, setMatch, refetchLoggedUser}: Props) {
|
export default function CardUser({
|
||||||
|
users,
|
||||||
|
loggedUser,
|
||||||
|
setMatch,
|
||||||
|
refetchLoggedUser,
|
||||||
|
}: Props) {
|
||||||
const toast = useToast({
|
const toast = useToast({
|
||||||
position: "top",
|
position: "top",
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
@@ -174,7 +179,9 @@ export default function CardUser({users, loggedUser, setMatch, refetchLoggedUser
|
|||||||
<Heading size={"sm"} fontWeight={"bold"} mb="0.5rem">
|
<Heading size={"sm"} fontWeight={"bold"} mb="0.5rem">
|
||||||
A propos :
|
A propos :
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text as="i">"{listUsers[0].bio}"</Text>
|
<Text as="i" fontWeight={"bold"}>
|
||||||
|
{listUsers[0].bio && `"${listUsers[0].bio}"`}
|
||||||
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -33,11 +33,12 @@ export default function LeftPanel(props) {
|
|||||||
bg={"#faf9ff"}
|
bg={"#faf9ff"}
|
||||||
>
|
>
|
||||||
<Flex direction={"column"} height={"100%"} margin={"10%"}>
|
<Flex direction={"column"} height={"100%"} margin={"10%"}>
|
||||||
<Box>
|
<Flex direction={"column"} align={"center"}>
|
||||||
<Image
|
<Image
|
||||||
src={user.images[0] ?? "/blank_profile_picture.webp"}
|
src={user.images[0] ?? "/blank_profile_picture.webp"}
|
||||||
objectFit={"contain"}
|
objectFit={"contain"}
|
||||||
borderRadius={"1rem"}
|
borderRadius={"1rem"}
|
||||||
|
maxHeight={"50vh"}
|
||||||
/>
|
/>
|
||||||
<Box mt={"2rem"}>
|
<Box mt={"2rem"}>
|
||||||
<Flex align={"center"} justifyContent="space-between" mb={"1rem"}>
|
<Flex align={"center"} justifyContent="space-between" mb={"1rem"}>
|
||||||
@@ -53,23 +54,26 @@ export default function LeftPanel(props) {
|
|||||||
{user.bio && `"${user.bio}"`}
|
{user.bio && `"${user.bio}"`}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Flex>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Flex
|
<Flex
|
||||||
gap={2}
|
gap={2}
|
||||||
direction={"column"}
|
direction={"column"}
|
||||||
mt={"1vh"}
|
mt={"1vh"}
|
||||||
spacing={3.5}
|
spacing={3.5}
|
||||||
alignContent={"bottom"}>
|
alignContent={"bottom"}
|
||||||
|
>
|
||||||
<LeftPanelButton
|
<LeftPanelButton
|
||||||
leftIcon={<FaMapMarkedAlt />}
|
leftIcon={<FaMapMarkedAlt />}
|
||||||
onClickHandler={() => router.push("/map")}>
|
onClickHandler={() => router.push("/map")}
|
||||||
|
>
|
||||||
Carte
|
Carte
|
||||||
</LeftPanelButton>
|
</LeftPanelButton>
|
||||||
|
|
||||||
<LeftPanelButton
|
<LeftPanelButton
|
||||||
leftIcon={<BsFillPersonFill />}
|
leftIcon={<BsFillPersonFill />}
|
||||||
onClickHandler={() => router.push("/profile")}>
|
onClickHandler={() => router.push("/profile")}
|
||||||
|
>
|
||||||
Profil
|
Profil
|
||||||
</LeftPanelButton>
|
</LeftPanelButton>
|
||||||
|
|
||||||
@@ -82,7 +86,8 @@ export default function LeftPanel(props) {
|
|||||||
<LeftPanelButton
|
<LeftPanelButton
|
||||||
variant={"outline"}
|
variant={"outline"}
|
||||||
leftIcon={<BiLogOut />}
|
leftIcon={<BiLogOut />}
|
||||||
onClickHandler={() => signOut({ callbackUrl: "/" })}>
|
onClickHandler={() => signOut({ callbackUrl: "/" })}
|
||||||
|
>
|
||||||
Déconnexion
|
Déconnexion
|
||||||
</LeftPanelButton>
|
</LeftPanelButton>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export default function ModalModifyImages(props) {
|
|||||||
<GridItem key={index}>
|
<GridItem key={index}>
|
||||||
<Flex
|
<Flex
|
||||||
bg={"purple.100"}
|
bg={"purple.100"}
|
||||||
height={"95%"}
|
height={"60vh"}
|
||||||
direction={"column"}
|
direction={"column"}
|
||||||
gap={"1rem"}
|
gap={"1rem"}
|
||||||
justifyContent={"space-between"}
|
justifyContent={"space-between"}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button, Container,
|
||||||
FormControl,
|
FormControl,
|
||||||
FormErrorMessage,
|
FormErrorMessage,
|
||||||
FormLabel,
|
FormLabel,
|
||||||
@@ -60,7 +60,7 @@ export default function settings() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container>
|
||||||
<Box as="form" id="form_passion" width={'80%'}
|
<Box as="form" id="form_passion" width={'80%'}
|
||||||
onSubmit={handleSubmit(savePassion)}>
|
onSubmit={handleSubmit(savePassion)}>
|
||||||
<FormControl isInvalid={errors.name as boolean | undefined}>
|
<FormControl isInvalid={errors.name as boolean | undefined}>
|
||||||
@@ -77,7 +77,7 @@ export default function settings() {
|
|||||||
Submit
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box, Button,
|
||||||
Container,
|
Container,
|
||||||
Flex,
|
Flex,
|
||||||
FormControl,
|
FormControl,
|
||||||
IconButton,
|
IconButton,
|
||||||
Input,
|
Input,
|
||||||
Text
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import {websiteName} from '@/lib/constants';
|
import {websiteName} from '@/lib/constants';
|
||||||
@@ -19,7 +18,8 @@ import {io, Socket} from 'socket.io-client';
|
|||||||
import {Chat, Message, User} from '@prisma/client';
|
import {Chat, Message, User} from '@prisma/client';
|
||||||
import LoadingPage from '@/components/LoadingPage';
|
import LoadingPage from '@/components/LoadingPage';
|
||||||
import Navbar from '@/components/Navbar';
|
import Navbar from '@/components/Navbar';
|
||||||
import {ArrowForwardIcon, CalendarIcon} from '@chakra-ui/icons';
|
|
||||||
|
import {ArrowForwardIcon} from '@chakra-ui/icons';
|
||||||
import {FaMapMarkedAlt} from 'react-icons/fa';
|
import {FaMapMarkedAlt} from 'react-icons/fa';
|
||||||
|
|
||||||
export default function ChatId() {
|
export default function ChatId() {
|
||||||
@@ -84,8 +84,8 @@ export default function ChatId() {
|
|||||||
|
|
||||||
<Navbar/>
|
<Navbar/>
|
||||||
|
|
||||||
<Container pt={20} bgColor={'white'}>
|
<Container maxW={'container.md'} pt={20} bgColor={'white'}>
|
||||||
<MessageList user={session.user as User} messages={messages}/>
|
<MessageList chat={chatInfo} user={session.user as User} messages={messages}/>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
@@ -103,6 +103,8 @@ export default function ChatId() {
|
|||||||
</form>
|
</form>
|
||||||
<AlwaysScrollToBottom/>
|
<AlwaysScrollToBottom/>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
|
<Button m={3} position={'fixed'} bottom={0} onClick={() => router.push("/dashboard")}>Tableau de bord</Button>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -3,32 +3,36 @@ import {
|
|||||||
GridItem,
|
GridItem,
|
||||||
Box,
|
Box,
|
||||||
useToast,
|
useToast,
|
||||||
useDisclosure,
|
Card,
|
||||||
Card, CardBody, CardHeader, Heading,
|
CardBody,
|
||||||
} from '@chakra-ui/react';
|
CardHeader,
|
||||||
import {useSession} from 'next-auth/react';
|
Heading,
|
||||||
import {useRouter} from 'next/router';
|
} from "@chakra-ui/react";
|
||||||
|
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 CardUser from '../components/layout/dashboard/card_user/CardUser';
|
import CardUser from "../components/layout/dashboard/card_user/CardUser";
|
||||||
import SearchFailCard
|
import SearchFailCard from "../components/layout/dashboard/card_user/SearchFailCard";
|
||||||
from '../components/layout/dashboard/card_user/SearchFailCard';
|
|
||||||
|
|
||||||
import LeftPanel from '../components/layout/dashboard/left_panel/LeftPanel';
|
import LeftPanel from "../components/layout/dashboard/left_panel/LeftPanel";
|
||||||
import ModalMatch
|
import ModalMatch from "@/components/layout/dashboard/match_notification/ModalMatch";
|
||||||
from '@/components/layout/dashboard/match_notification/ModalMatch';
|
import Head from "next/head";
|
||||||
import Head from 'next/head';
|
import { websiteName } from "@/lib/constants";
|
||||||
import {websiteName} from '@/lib/constants';
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import {useQuery} from '@tanstack/react-query';
|
import LoadingPage from "@/components/LoadingPage";
|
||||||
import LoadingPage from '@/components/LoadingPage';
|
import { Notification, NotificationType, User } from "@prisma/client";
|
||||||
import {Notification, NotificationType, User} from '@prisma/client';
|
import ChatList from "@/components/chat/ChatList";
|
||||||
import ChatList from '@/components/chat/ChatList';
|
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const toast = useToast({position: 'top', isClosable: true});
|
const toast = useToast({ position: "top", isClosable: true });
|
||||||
|
|
||||||
const {data: session, status} = useSession({required: true});
|
const { data: session, status } = useSession({ required: true });
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["ListUsers"] });
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading,
|
isLoading,
|
||||||
@@ -37,18 +41,18 @@ export default function Dashboard() {
|
|||||||
error,
|
error,
|
||||||
refetch: refetchLoggedUser,
|
refetch: refetchLoggedUser,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ['LoggedUser'],
|
queryKey: ["LoggedUser"],
|
||||||
enabled: status === 'authenticated',
|
enabled: status === "authenticated",
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {user} = session as unknown as Session;
|
const { user } = session as unknown as Session;
|
||||||
|
|
||||||
return fetch(`/api/users/${user.id}?include=Notification`)
|
return fetch(`/api/users/${user.id}?include=Notification`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
return res.json();
|
return res.json();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
return err;
|
return err;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -58,89 +62,104 @@ export default function Dashboard() {
|
|||||||
isLoading: isLoadingListUsers,
|
isLoading: isLoadingListUsers,
|
||||||
error: errorListUsers,
|
error: errorListUsers,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ['ListUsers'],
|
queryKey: ["ListUsers"],
|
||||||
enabled: status === 'authenticated' && !isLoading,
|
enabled: status === "authenticated" && !isLoading,
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
return fetch(
|
return fetch(`/api/user/userDashboard?userID=${loggedUser.id}`) //exclure les profils déjà like ou dislike
|
||||||
`/api/user/userDashboard?userID=${loggedUser.id}`) //exclure les profils déjà like ou dislike
|
.then((res) => res.json())
|
||||||
.then((res) => res.json())
|
.catch((err) => {
|
||||||
.catch((err) => {
|
return err;
|
||||||
return err;
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
if (status === 'unauthenticated') router.push('/login');
|
if (status === "unauthenticated") router.push("/login");
|
||||||
return <LoadingPage/>;
|
return <LoadingPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isError) {
|
if (isError) {
|
||||||
toast({
|
toast({
|
||||||
title: `Erreur lors de la récupération des données du profil`,
|
title: `Erreur lors de la récupération des données du profil`,
|
||||||
status: 'error',
|
status: "error",
|
||||||
position: 'top',
|
position: "top",
|
||||||
});
|
});
|
||||||
if (status === 'unauthenticated') router.push('/');
|
if (status === "unauthenticated") router.push("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
let modal;
|
let modal;
|
||||||
|
|
||||||
if (loggedUser?.Notification?.length > 0) {
|
if (loggedUser?.Notification?.length > 0) {
|
||||||
const matchNotification = loggedUser.Notification.filter(
|
const matchNotification = loggedUser.Notification.filter(
|
||||||
(notif: Notification) =>
|
(notif: Notification) =>
|
||||||
notif.type === NotificationType.NEW_MATCH &&
|
notif.type === NotificationType.NEW_MATCH &&
|
||||||
notif.hasBeenConsulted === false,
|
notif.hasBeenConsulted === false
|
||||||
);
|
);
|
||||||
modal = matchNotification.map((notif: Notification) => {
|
modal = matchNotification.map((notif: Notification) => {
|
||||||
return (
|
return (
|
||||||
<ModalMatch notif={notif} key={notif.id} loggedUser={loggedUser}/>
|
<ModalMatch notif={notif} key={notif.id} loggedUser={loggedUser} />
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === 'loading') return <LoadingPage/>;
|
if (status === "loading") return <LoadingPage />;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{modal}
|
{modal}
|
||||||
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>{websiteName} | Dashboard</title>
|
<title>{websiteName} | Dashboard</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<Grid templateColumns={'repeat(5, 1fr)'}
|
<Grid
|
||||||
templateRows={'repeat(2, 1fr)'}
|
templateColumns={"repeat(5, 1fr)"}
|
||||||
gap={5}
|
templateRows={"repeat(2, 1fr)"}
|
||||||
minH={'100vh'}>
|
gap={5}
|
||||||
<GridItem area={'1 / 1 / 3 / 2'}>
|
minH={"100vh"}
|
||||||
<LeftPanel user={loggedUser}/>
|
>
|
||||||
</GridItem>
|
<GridItem area={"1 / 1 / 3 / 2"}>
|
||||||
<GridItem area={'1 / 2 / 3 / 4'}>
|
<LeftPanel user={loggedUser} />
|
||||||
<Box py={3}>
|
</GridItem>
|
||||||
{isLoadingListUsers
|
<GridItem area={"1 / 2 / 3 / 4"}>
|
||||||
? (<LoadingPage/>)
|
<Box py={3}>
|
||||||
: (isErrorListUsers || !listUsers || !listUsers.users ||
|
{isLoadingListUsers ? (
|
||||||
listUsers.users.length === 0)
|
<LoadingPage />
|
||||||
? <SearchFailCard/>
|
) : isErrorListUsers ||
|
||||||
: <CardUser users={listUsers.users} loggedUser={loggedUser}
|
!listUsers ||
|
||||||
refetchLoggedUser={refetchLoggedUser}/>
|
!listUsers.users ||
|
||||||
}
|
listUsers.users.length === 0 ? (
|
||||||
</Box>
|
<SearchFailCard />
|
||||||
</GridItem>
|
) : (
|
||||||
<GridItem area={'1 / 4 / 2 / 6'}>
|
<CardUser
|
||||||
<Box py={3} pr={3}>
|
users={listUsers.users}
|
||||||
<Card w={"100%"} h={"100%"} borderRadius={"1rem"}>
|
loggedUser={loggedUser}
|
||||||
<CardHeader>
|
refetchLoggedUser={refetchLoggedUser}
|
||||||
<Heading cursor={"pointer"} size='md' onClick={() => {router.push('/chat')}}>Conversations</Heading>
|
/>
|
||||||
</CardHeader>
|
)}
|
||||||
<CardBody>
|
</Box>
|
||||||
<ChatList user={session?.user as User}/>
|
</GridItem>
|
||||||
</CardBody>
|
<GridItem area={"1 / 4 / 2 / 6"}>
|
||||||
</Card>
|
<Box py={3} pr={3}>
|
||||||
</Box>
|
<Card w={"100%"} h={"100%"} borderRadius={"1rem"}>
|
||||||
</GridItem>
|
<CardHeader>
|
||||||
<GridItem area={'2 / 4 / 3 / 6'}>{/*Right Bottom*/}</GridItem>
|
<Heading
|
||||||
</Grid>
|
cursor={"pointer"}
|
||||||
</>
|
size="md"
|
||||||
|
onClick={() => {
|
||||||
|
router.push("/chat");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Conversations
|
||||||
|
</Heading>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<ChatList user={session?.user as User} />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</Box>
|
||||||
|
</GridItem>
|
||||||
|
<GridItem area={"2 / 4 / 3 / 6"}>{/*Right Bottom*/}</GridItem>
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default function Map() {
|
|||||||
enabled: status === "authenticated",
|
enabled: status === "authenticated",
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { user } = session as unknown as Session;
|
const { user } = session as unknown as Session;
|
||||||
console.log(loggedUser.location.length);
|
|
||||||
return fetch(`/api/users/${user.id}`)
|
return fetch(`/api/users/${user.id}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
return res.json();
|
return res.json();
|
||||||
@@ -56,8 +56,9 @@ export default function Map() {
|
|||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ["listBars"],
|
queryKey: ["listBars"],
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
|
enabled:
|
||||||
enabled: Boolean(loggedUser) && loggedUser.location.length > 0,
|
Boolean(loggedUser) &&
|
||||||
|
(loggedUser.location?.length > 0 || location[0] !== null),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
///Utiliser api de noratim
|
///Utiliser api de noratim
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import CustomSlider from "@/components/layout/profile/CustomSlider";
|
|||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
export default function UserProfile() {
|
export default function UserProfile() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -45,6 +45,8 @@ export default function UserProfile() {
|
|||||||
const [showTooltipDistance, setShowTooltipDistance] = useState(false);
|
const [showTooltipDistance, setShowTooltipDistance] = useState(false);
|
||||||
const [sliderDistanceValue, setSliderDistanceValue] = useState<number>(0);
|
const [sliderDistanceValue, setSliderDistanceValue] = useState<number>(0);
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
@@ -147,6 +149,7 @@ export default function UserProfile() {
|
|||||||
status: "success",
|
status: "success",
|
||||||
isClosable: true,
|
isClosable: true,
|
||||||
});
|
});
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["user"] });
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
setCurrentlyLoading(false);
|
setCurrentlyLoading(false);
|
||||||
|
|||||||