add working ban, invite, mute, admin, change name/pass. no verified perm, reset the add friend/ban user to when it worked

This commit is contained in:
kinou-p 2023-06-17 02:08:55 +02:00
parent b84c64254d
commit 5b1a1487e1
12 changed files with 845 additions and 128 deletions

6
.env
View File

@ -14,9 +14,9 @@
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf" NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
# BASE_URL=http://localhost # BASE_URL=http://localhost
BASE_URL=92.143.191.152 BASE_URL=localhost
REACT_APP_BASE_URL=92.143.191.152 REACT_APP_BASE_URL=localhost
REDIRECT_URI=http://92.143.191.152/api/auth/login REDIRECT_URI=http://localhost/api/auth/login
#postgres var #postgres var
# POSTGRES_HOST=127.0.0.1 # POSTGRES_HOST=127.0.0.1
# DB_TYPE=postgres # DB_TYPE=postgres

View File

@ -1,3 +1,15 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* app.controller.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
/* Updated: 2023/06/17 01:47:43 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { Controller, Request, Req, Get, Post, UseGuards, Redirect, Res, Body, UploadedFile, UseInterceptors} from '@nestjs/common'; import { Controller, Request, Req, Get, Post, UseGuards, Redirect, Res, Body, UploadedFile, UseInterceptors} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express'; import { FileInterceptor } from '@nestjs/platform-express';
@ -93,12 +105,16 @@ export class AppController {
const conv = { const conv = {
id: null, id: null,
name: req.user.username + ", " + data.username, name: req.user.username + ", " + data.username,
banned: null, banned: [],
admin: null, admin: [],
messages: null, muted: [],
members: [], members: [],
owner: req.user.username, owner: req.user.username,
password: null,
messages: null,
group: false, group: false,
private: false,
}; };
conv.members.push(req.user.username); conv.members.push(req.user.username);
conv.members.push(data.username); conv.members.push(data.username);
@ -441,4 +457,42 @@ export class AppController {
// res.json(messages); // res.json(messages);
} }
@Post('/ban')
async banUser(@Body() data: any) {
return await this.chatService.banUser(data.convId, data.username)
}
@Post('/name')
async setName(@Body() data: any) {
//find conv
// data.convId
return await this.chatService.setName(data.convId, data.name)
}
@Post('/invite')
async inviteUser(@Body() data: any) {
return await this.chatService.inviteUser(data.convId, data.username)
}
@Post('/password')
async setPassword(@Body() data: any) {
return await this.chatService.setPassword(data.convId, data.password)
}
@Post('/admin')
async setAdmin(@Body() data: any) {
return await this.chatService.setAdmin(data.convId, data.username)
}
@Post('/mute')
async muteUser(@Body() data: any) {
return await this.chatService.muteUser(data.convId, data.username)
}
@Post('/private')
async setPrivate(@Body() data: any) {
return await this.chatService.setPrivate(data.convId)
}
} }

View File

@ -1,7 +1,14 @@
// import { Injectable } from '@nestjs/common'; /* ************************************************************************** */
/* */
// @Injectable() /* ::: :::::::: */
// export class ConvService {} /* chat.service.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
/* Updated: 2023/06/17 01:48:15 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
@ -11,6 +18,7 @@ import { Message } from '../model/chat.entity';
import { ArrayContains } from "typeorm" import { ArrayContains } from "typeorm"
import { query } from 'express'; import { query } from 'express';
import { InitializeOnPreviewAllowlist } from '@nestjs/core';
@Injectable() @Injectable()
@ -19,16 +27,13 @@ export class ChatService {
@InjectRepository(Message) private messageRepository: Repository<Message>, @InjectRepository(Message) private messageRepository: Repository<Message>,
) {} ) {}
async createConv(conv: Conv): Promise<Conv> { async save(conv: Conv): Promise<Conv> {
return await this.chatRepository.save(conv); return await this.chatRepository.save(conv);
} }
async createConv(conv: Conv): Promise<Conv> {
return await this.chatRepository.save(conv);
// SELECT "conv"."id" AS "conv_id", "conv"."members" AS "conv_members", "conv"."name" AS "conv_name", "conv"."banned" AS "conv_banned", "conv"."admin" AS "conv_admin", "conv"."messages" AS "conv_messages" FROM "conv" "conv" WHERE $1 = ANY("conv"."members") }
// import { createConnection } from 'typeorm';
async getConv(username: string): Promise<Conv[]>{ async getConv(username: string): Promise<Conv[]>{
// username = "apommier" // username = "apommier"
@ -44,56 +49,76 @@ async findConv(number: number){
return conv; return conv;
} }
// Usage
// const user = 'user1';
// findConvsContainingUser(user)
// .then((convs) => {
// console.log('Convs containing user:', convs);
// })
// .catch((error) => {
// console.error('Error:', error);
// });
// return await this.chatRepository.findOneBy({
// members: { $in: [username] },
// });
// return await this.chatRepository.find()
// return await this.chatRepository.findOneBy({
// members: ArrayContains(["apommier"]),
// })
// console.log(`get conv username= ${username} `)
// let test = await this.chatRepository.find({
// where : {
// members: { $all: ["apommier"] },
// }})
// console.log(`test= ${test}`)
// return test
// }
//
// message
//
async createMessage(message: Message): Promise<Message> { async createMessage(message: Message): Promise<Message> {
return await this.messageRepository.save(message); return await this.messageRepository.save(message);
} }
async getMessages(convId: number): Promise<Message[]> { async getMessages(convId: number): Promise<Message[]> {
// return await this.messageRepository.find({
// where: {
// convId: convId,
// },
// });
const convs = await this.chatRepository const convs = await this.chatRepository
.query("SELECT * FROM \"message\" WHERE $1 = message.convid;", [convId]) .query("SELECT * FROM \"message\" WHERE $1 = message.convid;", [convId])
return (convs) return (convs)
} }
async banUser(convId: number, username: string) {
const conv = await this.findConv(convId);
conv.banned = conv.banned || [];
if (conv.banned.find(item => item === username))
return (1);
conv.banned.push(username);
this.save(conv);
}
async inviteUser(convId: number, username: string) {
// const conv = await this.findConv(convId);
// this.save(conv);
//find user
//add in chanInvite chanID
//save user
}
async setPassword(convId: number, password: string) {
//verify is user is admin ?
const conv = await this.findConv(convId);
conv.password = password
this.save(conv);
}
async muteUser(convId: number, username: string) {
const conv = await this.findConv(convId);
conv.muted = conv.muted || [];
if (conv.muted.find(item => item === username))
return (1);
conv.muted.push(username);
this.save(conv);
}
async setAdmin(convId: number, username: string) {
const conv = await this.findConv(convId);
conv.admin = conv.admin || [];
if (conv.admin.find(item => item === username))
return (1);
conv.admin.push(username);
this.save(conv);
}
async setPrivate(convId: number) {
const conv = await this.findConv(convId);
if (conv.private === true)
conv.private = false;
else
conv.private = true;
this.save(conv);
}
async setName(convId: number, name: string) {
const conv = await this.findConv(convId);
conv.name = name;
this.save(conv);
}
} }

View File

@ -1,3 +1,15 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* chat.entity.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:20 by apommier #+# #+# */
/* Updated: 2023/06/17 01:31:29 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity } from 'typeorm'; import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity } from 'typeorm';
@Entity() @Entity()
@ -14,18 +26,27 @@ import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, BaseEntity }
@Column({ nullable: true }) @Column({ nullable: true })
group: boolean group: boolean
@Column({ nullable: true })
private: boolean
// @Column() // @Column()
// members: string;// arry ??? one to many ??? // members: string;// arry ??? one to many ???
@Column('text', { array: true, nullable: true }) @Column('text', { array: true, nullable: true })
banned: string[]; banned: string[];
@Column('text', { array: true, nullable: true })
muted: string[];
@Column('text', { array: true, nullable: true }) @Column('text', { array: true, nullable: true })
admin: string[]; admin: string[];
@Column({ nullable: true }) @Column({ nullable: true })
owner: string; owner: string;
@Column({ nullable: true })
password: string;
@Column({ nullable: true }) @Column({ nullable: true })
messages: string; messages: string;

View File

@ -1,3 +1,15 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* users.service.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:07 by apommier #+# #+# */
/* Updated: 2023/06/17 01:00:08 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';

View File

@ -1,2 +1,2 @@
REACT_APP_BASE_URL=92.143.191.152 REACT_APP_BASE_URL=localhost
# REACT_APP_BASE_URL=192.168.1.19 # REACT_APP_BASE_URL=192.168.1.19

View File

@ -0,0 +1,362 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Chats.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 00:59:57 by apommier #+# #+# */
/* Updated: 2023/06/17 01:24:24 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import React, { useState, useEffect, useRef } from "react";
import io from 'socket.io-client';
import '../../styles/Messages.css'
import styled from "styled-components";
import DefaultPic from '../../assets/profile.jpg'
import api from '../../script/axiosApi';
import { motion , AnimatePresence} from "framer-motion";
import Modal from "./Modal";
import Message from "./Message"
// import Input from "./Input";
//react icons
import { TbSend } from 'react-icons/tb';
import { ImBlocked } from 'react-icons/im';
import { MdOutlineGroupAdd } from 'react-icons/md';
import { GrAdd } from 'react-icons/gr';
import { RiListSettingsLine } from 'react-icons/ri'
import { Rank } from "../../DataBase/DataRank";
import GreenAlert from "../Alert/GreenAlert";
import RedAlert from "../Alert/RedAlert";
import YellowAlert from "../Alert/YellowAlert";
import ModalSetting from "./ModalSetting";
const TouchDiv = styled.div`
margin-left: 10px;
margin-right: 4px;
margin-bottom: 21px;
margin-top: 21px;
cursor: pointer;
justify-content: space-around;
&:hover {
color: #F4F3EF;
}
`
const UserChat = styled.div `
padding: 5px;
display: flex;
align-items: center;
gap: 5px;
color: white;
cursor: pointer;
&:hover{
background-color: #3e3c61;
}
&:active {
filter: black;
}
`
// const SideSpan = styled.span`
// font-size: 18px;
// font-weight: 500;
// `
const SideP = styled.p`
font-size: 14px;
color: lightgray;
margin-left: 15px;
`
//========================================================================================================
//========================================================================================================
// Logical part
//========================================================================================================
//========================================================================================================
function Chats(){
const [isLoading, setIsLoading] = useState(true);
const [conversations, setConversation] = useState([]);
const [user, setUser] = useState(null);
const [currentChat, setCurrentChat] = useState(false); // false is good?
const [messages, setMessage] = useState([]);
const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState("");
const socket = useRef();
useEffect(()=> {
const getConv = async ()=>{
try{
const convs = await api.get("/conv")
const tmpUser = await api.get("/profile")
console.log(convs);
setUser(tmpUser.data);
setConversation(convs.data);
// return tmpUser;
// console.log(`user= ${tmpUser.data.username}`);
// console.log(`user= ${tmpUser.data.nickname}`);
// console.log(`user= ${tmpUser.data}`);
socket.current = io("ws://localhost:4001");
console.log(`connection....`);
socket.current.emit('connection', {username: tmpUser.data.username})
// const socket = io("http://localhost:4001", {
// query: {
// username: user.username,
// },});
socket.current.on('message', (data) => { //data should be a message ?
console.log(`message received data= ${data.sender}`)
console.log(`message received data= ${data.convId}`)
console.log(`message received data= ${data.sender}`)
console.log(`current chat = ${currentChat}`)
setIncomingMessage(data);
});
setIsLoading(false)
}
catch(err){
console.log(err);
}
};
getConv();
}, [])
useEffect(()=> {
if (currentChat)
console.log(currentChat.id)
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
if (currentChat !== null && currentChat.id === incomingMessage.convId)
setMessage((prev) => [...prev, incomingMessage]);
}, [incomingMessage, currentChat])
useEffect(()=> {
const getMessage = async ()=>
{
const data = {convId: currentChat.id};
try {
const res = await api.post('/getMessage', data);
setMessage(res.data);
} catch(err) {
}
}
getMessage();
}, [currentChat]);
const handleSubmit = async (e)=>{
e.preventDefault();
// console.log(`e= ${e.key}`)
// console.log(`name= ${user.username}`)
const message = {
sender: user.username,
text: newMessages,
convId: currentChat.id,
members: null
};
try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message);
const convMember = await api.post('/member', message);
message.members = convMember.data.members;
console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]);
setNewMessage("");
socket.current.emit('sendMessage', message);
}
catch(err){
console.log(err)
}
}
const handleKeyPress = async (e)=>{
// console.log(`e in press= ${e.key}`)
if (e.key !== "Enter")
return ;
// console.log(`name= ${user.username}`)
const message = {
sender: user.username,
text: newMessages,
convId: currentChat.id,
members: null
};
try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message);
const convMember = await api.post('/member', message);
message.members = convMember.data.members;
console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]);
setNewMessage("");
socket.current.emit('sendMessage', message);
}
catch(err){
console.log(err)
}
}
const [friend, setFriend] = useState("");
const [modalOpen, setModalOpen] = useState(false);
const [addFriend, setAddFriend] = useState(false);
const [block, setBlock] = useState(false);
const [setting, setSetting] = useState(false);
const close = () => setModalOpen(false);
const open = () => setModalOpen(true);
const closeAddFriend = () => setAddFriend(false);
const closeBlock = () => setBlock(false);
const closeSetting = () => setSetting(false);
const handleFriend = e => {
setFriend(e.target.value)
};
//========================================================================================================
//========================================================================================================
// HTML
//========================================================================================================
//========================================================================================================
return (
<div className="chat">
<div className='navbar'>
<img src={DefaultPic} alt="profile" className="pic"/>
<span>
{isLoading ? (
<h4>Loading...</h4>
) : (
<h4>{user.nickname}</h4>
)}
</span>
<div className="end">
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/>
<TouchDiv>
<motion.div
onClick={() => (addFriend ? setAddFriend(false) : setAddFriend(true))}>
<MdOutlineGroupAdd/>
{/* {console.log("find = ",find) && setFind(true)} */}
</motion.div>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{addFriend && <GreenAlert handleClose={closeAddFriend} text={friend + " was successfuly added"}/>}
</AnimatePresence>
{/* {console.log("find2 = ", find) && find && <BasicAlert modalOpen={find} handleClose={setFind(false)}/>} */}
</TouchDiv>
<TouchDiv>
<motion.div
onClick={() => (block ? setBlock(false) : setBlock(true))}
>
<ImBlocked/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{block && <RedAlert handleClose={closeBlock} text={friend + " was successfuly blocked"}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
{currentChat ? (
<TouchDiv>
<motion.div
onClick={() => (setting ? setSetting(false) : setSetting(true))}
>
<RiListSettingsLine/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
):("")}
</div>
</div>
<div className="messages_box">
<div className="contact">
<UserChat>
<motion.div className="newMessage"
onClick={() => (modalOpen ? close() : open())}
>
<GrAdd/>
<span>New Conversation</span>
</motion.div>
{modalOpen && <Modal modalOpen={modalOpen} handleClose={close}/>}
</UserChat>
{conversations.map((c, index ) => {
return (
<div key={index}
onClick={() => setCurrentChat(c)}>
<UserChat>
<img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar">
<span>{c.name}</span>
<SideP>Desc?</SideP>
</div>
</UserChat>
</div>
)})}
</div>
{
currentChat ? (
<>
<div className="messages">
<div className="scroll">
{messages.map(m=>(
<Message message = {m} own={m.sender === user.username} user={m}/>
))}
</div>
{/* <Input/> */}
<div className="input">
<input
onKeyDown={handleKeyPress}
type="text"
placeholder="What do you want to say"
onChange={(e) => setNewMessage(e.target.value)}
value={newMessages}
/>
<div className="send">
<TbSend onClick={handleSubmit}></TbSend>
</div>
</div>
</div>
</>
) : (
<div className="messages">
<span className="noConv">Open a conversation</span>
</div>
)}
</div>
</div>
// </div>
);
}
export default Chats

View File

@ -15,11 +15,13 @@ import { TbSend } from 'react-icons/tb';
import { ImBlocked } from 'react-icons/im'; import { ImBlocked } from 'react-icons/im';
import { MdOutlineGroupAdd } from 'react-icons/md'; import { MdOutlineGroupAdd } from 'react-icons/md';
import { GrAdd } from 'react-icons/gr'; import { GrAdd } from 'react-icons/gr';
import { RiListSettingsLine } from 'react-icons/ri'
import { Rank } from "../../DataBase/DataRank"; import { Rank } from "../../DataBase/DataRank";
import GreenAlert from "../Alert/GreenAlert"; import GreenAlert from "../Alert/GreenAlert";
import RedAlert from "../Alert/RedAlert"; import RedAlert from "../Alert/RedAlert";
import YellowAlert from "../Alert/YellowAlert"; import YellowAlert from "../Alert/YellowAlert";
import ModalSetting from "./ModalSetting";
const TouchDiv = styled.div` const TouchDiv = styled.div`
@ -80,14 +82,7 @@ function Chats(){
const [incomingMessage, setIncomingMessage] = useState(""); const [incomingMessage, setIncomingMessage] = useState("");
const socket = useRef(); const socket = useRef();
// Socket handler
// socket.on('message', (data) => { //data should be a message ?
// console.log(`message received data= ${data}`)
// setMessage([...messages, data]);
// });
//End of socket handler
useEffect(()=> { useEffect(()=> {
@ -98,19 +93,9 @@ function Chats(){
console.log(convs); console.log(convs);
setUser(tmpUser.data); setUser(tmpUser.data);
setConversation(convs.data); setConversation(convs.data);
// return tmpUser;
// console.log(`user= ${tmpUser.data.username}`);
// console.log(`user= ${tmpUser.data.nickname}`);
// console.log(`user= ${tmpUser.data}`);
socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001'); socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001');
console.log(`connection....`); console.log(`connection....`);
socket.current.emit('connection', {username: tmpUser.data.username}) socket.current.emit('connection', {username: tmpUser.data.username})
// const socket = io("http://localhost:4001", {
// query: {
// username: user.username,
// },});
socket.current.on('message', (data) => { //data should be a message ? socket.current.on('message', (data) => { //data should be a message ?
console.log(`message received data= ${data.sender}`) console.log(`message received data= ${data.sender}`)
console.log(`message received data= ${data.convId}`) console.log(`message received data= ${data.convId}`)
@ -137,23 +122,6 @@ function Chats(){
setMessage((prev) => [...prev, incomingMessage]); setMessage((prev) => [...prev, incomingMessage]);
}, [incomingMessage, currentChat]) }, [incomingMessage, currentChat])
// useEffect(()=> {
// const getConv = async ()=>{
// try{
// const convs = await api.get("/conv")
// const tmpUser = await api.get("/profile")
// console.log(convs);
// setUser(tmpUser);
// setConversation(convs.data);
// }
// catch(err){
// console.log(err);
// }
// };
// getConv();
// }, [])
useEffect(()=> { useEffect(()=> {
const getMessage = async ()=> const getMessage = async ()=>
{ {
@ -234,8 +202,12 @@ function Chats(){
const [showAddFriendAlert, setShowAddFriendAlert] = useState(false); const [showAddFriendAlert, setShowAddFriendAlert] = useState(false);
const [showBlockAlert, setShowBlockAlert] = useState(false); const [showBlockAlert, setShowBlockAlert] = useState(false);
const [setting, setSetting] = useState(false);
const close = () => setModalOpen(false); const close = () => setModalOpen(false);
const open = () => setModalOpen(true); const open = () => setModalOpen(true);
// const closeAddFriend = () => setAddFriend(false);
// const closeBlock = () => setBlock(false);
const closeSetting = () => setSetting(false);
// const closeAddFriend = () => setAddFriend(false); // const closeAddFriend = () => setAddFriend(false);
@ -294,7 +266,6 @@ function Chats(){
setShowBlockAlert(false); setShowBlockAlert(false);
}; };
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// HTML // HTML
@ -304,19 +275,6 @@ function Chats(){
return ( return (
<div className="chat"> <div className="chat">
{/* <div className='navbar'>
<img src={DefaultPic} alt="profile" className="pic"/>
<span>
{isLoading ? (
<h4>Loading...</h4>
) : (
<h4>{user.nickname}</h4>
// <h4>{user.username}</h4>
)}
</span>
</div> */}
<div className='navbar'> <div className='navbar'>
<img src={DefaultPic} alt="profile" className="pic"/> <img src={DefaultPic} alt="profile" className="pic"/>
@ -327,11 +285,6 @@ function Chats(){
<h4>{user.nickname}</h4> <h4>{user.nickname}</h4>
)} )}
</span> </span>
{/* work here bitch */}
{/* <div className="end"> {/* <div className="end">
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/> <input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/>
<TouchDiv> <TouchDiv>
@ -359,7 +312,24 @@ function Chats(){
</AnimatePresence> </AnimatePresence>
</motion.div> </motion.div>
</TouchDiv> </TouchDiv>
{currentChat ? (
<TouchDiv>
<motion.div
onClick={() => (setting ? setSetting(false) : setSetting(true))}
>
<RiListSettingsLine/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
):("")}
</div> */} </div> */}
<div className="end"> <div className="end">
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend} /> <input className="lookForFriends" type="text" value={friend} onChange={handleFriend} />
<TouchDiv> <TouchDiv>
@ -391,11 +361,6 @@ function Chats(){
</div> </div>
</div> </div>
<div className="messages_box"> <div className="messages_box">
<div className="contact"> <div className="contact">

View File

@ -0,0 +1,230 @@
import { motion } from "framer-motion";
import Backdrop from "../Sidebar/Backdrop";
import { Rank } from "../../DataBase/DataRank"
import '../../styles/Messages.css'
import { useState, useEffect } from "react";
import { GrAdd } from "react-icons/gr";
import { Link } from "react-router-dom";
import api from "../../script/axiosApi";
const dropIn = {
hidden:{y:"-100vh",
opacity: 0,},
visible:{y: "0",
opacity: 0,
transotion:{
duration:0.1,
type:"spring",
damping: 100,
stiffness: 500,
}},
exit:{y: "100vh",
opacity: 0,},
};
const ModalSetting = ({handleClose, convId}) => {
const [password, setPassword] = useState(false);
const [users, setUsers] = useState([]);
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
const [selectedUser, setSelectedUser] = useState([]);
const [newName, setNewName] = useState("");
const [newPassword, setNewPassword] = useState("");
useEffect(()=> {
console.log("convid =", convId)
const getUsers = async ()=>{
try {
const tmpUsers = await api.get("/users");
console.log("users=", tmpUsers.data);
setUsers(tmpUsers.data);
} catch(err){
console.log(err)
}
}
getUsers();
}, []);
// const [multi, setMulti] = useState(false);
// const [selectedOptionArray, setSelectedOptionArray] = useState([]);
const handleOptionChange = (selectId, selectedOption) => {
console.log("tag= ", selectTags)
console.log("option= ", selectedOption)
setSelectTag((prevTags) =>
prevTags.map((tag) =>
tag.id === selectId ? { ...tag, selectedOption } : tag
)
);
setSelectedUser(selectedOption)
};
const handleCheckPass = (e) => {
setPassword(e.target.checked);
console.log("password??", e.target.checked)
}
const handleCheckPriv = (e) => {
// setPassword(e.target.checked);
if (e.target.checked)
{
console.log("chack true", e.target.checked)
try{
api.post("/private", {convId: convId})
} catch(err) {
console.log(err);
}
}
else
{
console.log("chack false", e.target.checked)
try{
api.post("/private", {convId: convId})
} catch(err) {
console.log(err);
}
}
}
const handleName = async (e)=>{
if (e.key !== "Enter")
return ;
try{
api.post("/name", {convId: convId, name: newName})
} catch(err) {
console.log(err);
}
handleClose();
}
const handlePassword = async (e)=>{
if (e.key !== "Enter")
return ;
try{
api.post("/password", {convId: convId, password: newPassword})
} catch(err) {
console.log(err);
}
handleClose();
}
const handleBan = () => {
// console.log("ban option= ", selectedUser)
try{
api.post("/ban", {convId: convId, username: selectedUser})
} catch(err) {
console.log(err);
}
handleClose();
};
const handleAdmin = () => {
try{
api.post("/admin", {convId: convId, username: selectedUser})
} catch(err) {
console.log(err);
}
handleClose();
};
const handleMute = () => {
try{
api.post("/mute", {convId: convId, username: selectedUser})
} catch(err) {
console.log(err);
}
handleClose();
};
const handleInvite = () => {
try{
api.post("/invite", {convId: convId, username: selectedUser})
} catch(err) {
console.log(err);
}
handleClose();
};
return (
<Backdrop>
<motion.div
onClick={(e) => e.stopPropagation()}
className="modalSetting"
variant={dropIn}
initial="hidden"
animate="visible"
exit="exit"
>
{/* First selection */}
<div className="settingFirstPart">
<div>
<p className="checkbox">Private<input class="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p>
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>
{password ? (
<input
onChange={(e) => setNewPassword(e.target.value)}
onKeyDown={handlePassword}
type="text"
className="in"
placeholder="Password"/>
):
("")}
</div>
<div className="forName">
<input
onChange={(e) => setNewName(e.target.value)}
onKeyDown={handleName}
type="text"
className="in"
placeholder="New Name"
/>
</div>
</div>
{/* Second selection */}
<div className="settingSecondPart">
{selectTags.map((selectTag) => (
<div key={selectTag.id}>
<select
value={selectTag.selectedOption}
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
>
<option value="">
{selectTag.selectedOption ? selectTag.selectedOption : "Select an option"}
</option>
{users.map((item, index) => (
<option key={index} value={item.username}>
{item.username}
</option>
))}
</select>
</div>
))}
<div>
<Link to="#" onClick={handleInvite} className="submit">Send</Link>
<Link to="#" onClick={handleBan} className="submit">Ban</Link>
<Link to="#" onClick={handleMute} className="submit">Mute</Link>
<Link to="#" onClick={handleAdmin} className="submit">Admin</Link>
</div>
</div>
</motion.div>
</Backdrop>
)
}
export default ModalSetting

View File

@ -27,7 +27,7 @@ function HomeLogin()
} }
// else // else
// let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2F" + process.env.REACT_APP_BASE_URL + "%3A80%2Fapi%2Fauth%2Flogin&response_type=code"; // let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2F" + process.env.REACT_APP_BASE_URL + "%3A80%2Fapi%2Fauth%2Flogin&response_type=code";
let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2F92.143.191.152%2Fapi%2Fauth%2Flogin&response_type=code" let path = "https://api.intra.42.fr/oauth/authorize?client_id=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41&redirect_uri=http%3A%2F%2F" + process.env.REACT_APP_BASE_URL + "%2Fapi%2Fauth%2Flogin&response_type=code"
window.location.replace(path); window.location.replace(path);
}; };

View File

@ -1,5 +1,5 @@
.home{ .home{
background-color: black; background-color: rgb(0, 0, 0);
height: 90vh; height: 90vh;
display: flex; display: flex;
align-items: center; align-items: center;
@ -38,6 +38,10 @@ select{
overflow: scroll; overflow: scroll;
} }
::-webkit-scrollbar{
display:none;
}
.newMessage{ .newMessage{
color: white; color: white;
font-size: 18px; font-size: 18px;
@ -46,14 +50,14 @@ select{
.contact{ .contact{
background-color: rgb(46, 46, 46); background-color: rgb(46, 46, 46);
align-items: left; align-items: left;
height: 29.7rem; height: 30.2rem;
overflow: scroll; overflow: scroll;
/* width: 2rem; */ /* width: 2rem; */
/* height: 4rem; */ /* height: 4rem; */
} }
.messages_box{ .messages_box{
background-color: black; background-color: rgb(0, 0, 0);
/* height: 90vh; */ /* height: 90vh; */
display: flex; display: flex;
align-items: center; align-items: center;
@ -73,7 +77,7 @@ select{
.sidebar{ .sidebar{
flex:1; flex:1;
border-right: 1px solid #3e3c61; border-right: 1px solid #3e3c61;
background-color: #060b26; background-color: #a2a3ac;
color: white; color: white;
} }
@ -95,6 +99,7 @@ select{
color: white; color: white;
padding: 3px; padding: 3px;
border-radius: 10px 10px 0px 0px; border-radius: 10px 10px 0px 0px;
margin-top: 0px;
} }
.pic{ .pic{
@ -122,9 +127,9 @@ select{
} }
.messages{ .messages{
background-color: black; background-color: rgb(26, 26, 26);
/* height: calc(100% - 118px); */ /* height: calc(100% - 118px); */
width: 40rem; width: 70%;
overflow: scroll; overflow: scroll;
} }
@ -185,6 +190,7 @@ input{
font-size: 1.2rem; font-size: 1.2rem;
text-decoration: none; text-decoration: none;
font-weight:lighter; font-weight:lighter;
margin: 1%;
} }
.div_submit { .div_submit {
@ -261,3 +267,41 @@ input{
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
} }
.modalSetting{
width: clamp(50%, 700px, 90%);
height: min(50%, 300px);
margin: auto;
padding: 2rem;
border-radius: 12px;
display: flex;
/* flex-direction: column; */
/* align-items: center; */
background-color: #3e3c61;
}
.settingFirstPart{
margin-top: 10%;
margin-left: 15%;
}
.settingSecondPart{
margin-top: 10%;
margin-left: 10%;
/* margin-left: 20%; */
}
.checkbox{
display:flex;
flex-direction:row;
}
input.in{
margin-top: 5%;
margin-left: 0px;
background-color: black;
color: white;
border-radius: 12px;
width: 70%;
}

View File

@ -15,6 +15,10 @@
overflow: scroll; overflow: scroll;
} }
.scroll::-webkit-scrollbar{
display:none;
}
.elements { .elements {
/* display: flex; */ /* display: flex; */
border-width:1px; border-width:1px;