add 2fa and env var(not in conf files)
This commit is contained in:
commit
c02f42ce23
10
containers/api/package-lock.json
generated
10
containers/api/package-lock.json
generated
@ -41,6 +41,7 @@
|
|||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/node": "18.15.11",
|
"@types/node": "18.15.11",
|
||||||
|
"@types/qrcode": "^1.5.0",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
@ -2305,6 +2306,15 @@
|
|||||||
"integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
|
"integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/qrcode": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/qs": {
|
"node_modules/@types/qs": {
|
||||||
"version": "6.9.7",
|
"version": "6.9.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||||
|
|||||||
@ -52,6 +52,7 @@
|
|||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/node": "18.15.11",
|
"@types/node": "18.15.11",
|
||||||
|
"@types/qrcode": "^1.5.0",
|
||||||
"@types/supertest": "^2.0.11",
|
"@types/supertest": "^2.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
||||||
"@typescript-eslint/parser": "^5.0.0",
|
"@typescript-eslint/parser": "^5.0.0",
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import crypto from "crypto";
|
|||||||
import * as OTPAuth from "otpauth";
|
import * as OTPAuth from "otpauth";
|
||||||
import { encode } from "hi-base32";
|
import { encode } from "hi-base32";
|
||||||
|
|
||||||
|
import * as qr from 'qrcode';
|
||||||
|
|
||||||
// [...] Register user
|
// [...] Register user
|
||||||
|
|
||||||
// [...] Login user
|
// [...] Login user
|
||||||
@ -32,6 +34,24 @@ export const generateOTP = async (user) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let otpauth_url = totp.toString();
|
let otpauth_url = totp.toString();
|
||||||
|
const qrCodeDataUrl = await qr.toDataURL(otpauth_url, { errorCorrectionLevel: 'H' });
|
||||||
|
|
||||||
|
const filePath = 'qrcode.png'; // Specify the file path where the QR code should be saved
|
||||||
|
|
||||||
|
qr.toFile(filePath, qrCodeDataUrl, (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
// Handle the error appropriately
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// QR code image has been generated and saved to the file
|
||||||
|
// Or, you can create a buffer of the image data directly
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const res = {
|
const res = {
|
||||||
otpauth_url: otpauth_url,
|
otpauth_url: otpauth_url,
|
||||||
@ -87,7 +107,6 @@ export const generateOTP = async (user) => {
|
|||||||
period: 15,
|
period: 15,
|
||||||
secret: user.otp_base32,
|
secret: user.otp_base32,
|
||||||
});
|
});
|
||||||
|
|
||||||
let delta = totp.validate({ token });
|
let delta = totp.validate({ token });
|
||||||
|
|
||||||
if (delta === null) {
|
if (delta === null) {
|
||||||
|
|||||||
39
containers/react/src/components/Alert/GreenAlert.jsx
Normal file
39
containers/react/src/components/Alert/GreenAlert.jsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import Backdrop from "../Sidebar/Backdrop"
|
||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import { AiOutlineCheckCircle } from "react-icons/ai";
|
||||||
|
import '../../styles/Messages.css'
|
||||||
|
|
||||||
|
|
||||||
|
const dropIn = {
|
||||||
|
hidden: {
|
||||||
|
y: "-100vh",
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
y: "0",
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
y: "-100vh",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function GreenAlert ({handleClose, text}){
|
||||||
|
|
||||||
|
return(
|
||||||
|
<Backdrop>
|
||||||
|
<motion.div
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="greenAlert"
|
||||||
|
variant={dropIn}
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="exit"
|
||||||
|
>
|
||||||
|
<AiOutlineCheckCircle/>
|
||||||
|
<p>{text}</p>
|
||||||
|
</motion.div>
|
||||||
|
{setTimeout(handleClose, 3000)}
|
||||||
|
</Backdrop>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GreenAlert
|
||||||
38
containers/react/src/components/Alert/RedAlert.jsx
Normal file
38
containers/react/src/components/Alert/RedAlert.jsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import Backdrop from "../Sidebar/Backdrop"
|
||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import { BiErrorCircle } from "react-icons/bi";
|
||||||
|
import '../../styles/Messages.css'
|
||||||
|
|
||||||
|
|
||||||
|
const dropIn = {
|
||||||
|
hidden: {
|
||||||
|
y: "-100vh",
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
y: "0",
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
y: "-100vh",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function RedAlert ({handleClose, text}) {
|
||||||
|
return(
|
||||||
|
<Backdrop>
|
||||||
|
<motion.div
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="redAlert"
|
||||||
|
variant={dropIn}
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="exit"
|
||||||
|
>
|
||||||
|
<BiErrorCircle/>
|
||||||
|
<p>{text}</p>
|
||||||
|
</motion.div>
|
||||||
|
{setTimeout(handleClose, 3000)}
|
||||||
|
</Backdrop>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RedAlert
|
||||||
37
containers/react/src/components/Alert/YellowAlert.jsx
Normal file
37
containers/react/src/components/Alert/YellowAlert.jsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import Backdrop from "../Sidebar/Backdrop"
|
||||||
|
import { motion } from 'framer-motion'
|
||||||
|
import { GrTrophy } from "react-icons/gr";
|
||||||
|
import '../../styles/Messages.css'
|
||||||
|
|
||||||
|
const dropIn = {
|
||||||
|
hidden: {
|
||||||
|
y: "-100vh",
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
y: "0",
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
y: "-100vh",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function YellowAlert ({handleClose, text}) {
|
||||||
|
return(
|
||||||
|
<Backdrop>
|
||||||
|
<motion.div
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="yellowAlert"
|
||||||
|
variant={dropIn}
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="exit"
|
||||||
|
>
|
||||||
|
<GrTrophy/>
|
||||||
|
<p>{text}</p>
|
||||||
|
</motion.div>
|
||||||
|
{setTimeout(handleClose, 3000)}
|
||||||
|
</Backdrop>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default YellowAlert
|
||||||
@ -4,6 +4,8 @@ import '../../styles/Messages.css'
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import DefaultPic from '../../assets/profile.jpg'
|
import DefaultPic from '../../assets/profile.jpg'
|
||||||
import api from '../../script/axiosApi';
|
import api from '../../script/axiosApi';
|
||||||
|
import { motion , AnimatePresence} from "framer-motion";
|
||||||
|
import Modal from "./Modal";
|
||||||
|
|
||||||
import Message from "./Message"
|
import Message from "./Message"
|
||||||
// import Input from "./Input";
|
// import Input from "./Input";
|
||||||
@ -12,6 +14,12 @@ import Message from "./Message"
|
|||||||
import { TbSend } from 'react-icons/tb';
|
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 { Rank } from "../../DataBase/DataRank";
|
||||||
|
import GreenAlert from "../Alert/GreenAlert";
|
||||||
|
import RedAlert from "../Alert/RedAlert";
|
||||||
|
import YellowAlert from "../Alert/YellowAlert";
|
||||||
|
|
||||||
|
|
||||||
const TouchDiv = styled.div`
|
const TouchDiv = styled.div`
|
||||||
@ -38,6 +46,9 @@ const UserChat = styled.div `
|
|||||||
&:hover{
|
&:hover{
|
||||||
background-color: #3e3c61;
|
background-color: #3e3c61;
|
||||||
}
|
}
|
||||||
|
&:active {
|
||||||
|
filter: black;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// const SideSpan = styled.span`
|
// const SideSpan = styled.span`
|
||||||
@ -213,6 +224,34 @@ function Chats(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [friend, setFriend] = useState("");
|
||||||
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
const [addFriend, setAddFriend] = useState(false);
|
||||||
|
const [block, setBlock] = useState(false);
|
||||||
|
const close = () => setModalOpen(false);
|
||||||
|
const open = () => setModalOpen(true);
|
||||||
|
const closeAddFriend = () => setAddFriend(false);
|
||||||
|
const closeBlock = () => setBlock(false);
|
||||||
|
|
||||||
|
|
||||||
|
const handleFriend = e => {
|
||||||
|
setFriend(e.target.value)
|
||||||
|
};
|
||||||
|
|
||||||
|
// const findValue = () => {
|
||||||
|
// // setFind(false);
|
||||||
|
// console.log(friend);
|
||||||
|
// Rank.map((tab) => {
|
||||||
|
// if (tab.name === friend)
|
||||||
|
// {
|
||||||
|
// console.log("ok bon");
|
||||||
|
// setFind(true);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// console.log(find);
|
||||||
|
// // if (!find)
|
||||||
|
// };
|
||||||
|
|
||||||
// console.log(`data user1= ${user.username}`)
|
// console.log(`data user1= ${user.username}`)
|
||||||
|
|
||||||
// while (user === null)
|
// while (user === null)
|
||||||
@ -228,7 +267,7 @@ function Chats(){
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="chat">
|
<div className="chat">
|
||||||
<div className='navbar'>
|
{/* <div className='navbar'>
|
||||||
<img src={DefaultPic} alt="profile" className="pic"/>
|
<img src={DefaultPic} alt="profile" className="pic"/>
|
||||||
<span>
|
<span>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@ -238,7 +277,7 @@ function Chats(){
|
|||||||
// <h4>{user.username}</h4>
|
// <h4>{user.username}</h4>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div> */}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -252,33 +291,74 @@ function Chats(){
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<div className="end">
|
<div className="end">
|
||||||
|
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/>
|
||||||
<TouchDiv>
|
<TouchDiv>
|
||||||
<MdOutlineGroupAdd/>
|
<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>
|
||||||
<TouchDiv>
|
<TouchDiv>
|
||||||
|
<motion.div
|
||||||
|
onClick={() => (block ? setBlock(false) : setBlock(true))}
|
||||||
|
>
|
||||||
<ImBlocked/>
|
<ImBlocked/>
|
||||||
|
<AnimatePresence
|
||||||
|
initial={false}
|
||||||
|
onExitComplete={() => null}
|
||||||
|
>
|
||||||
|
{block && <RedAlert handleClose={closeBlock} text={friend + " was successfuly blocked"}/>}
|
||||||
|
</AnimatePresence>
|
||||||
|
</motion.div>
|
||||||
</TouchDiv>
|
</TouchDiv>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{conversations.map(c=> (
|
<div className="messages_box">
|
||||||
<div onClick={() => setCurrentChat(c)}>
|
<div className="contact">
|
||||||
<UserChat>
|
<UserChat>
|
||||||
<img className="pic-user" src={DefaultPic} alt="User" />
|
|
||||||
<div className="infoSideBar">
|
<motion.div className="newMessage"
|
||||||
<span>{c.name}</span>
|
onClick={() => (modalOpen ? close() : open())}
|
||||||
<SideP>Desc?</SideP>
|
>
|
||||||
</div>
|
<GrAdd/>
|
||||||
</UserChat>
|
<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>
|
</div>
|
||||||
))}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
currentChat ? (
|
currentChat ? (
|
||||||
<>
|
<>
|
||||||
<div className="messages">
|
<div className="messages">
|
||||||
{messages.map(m=>(
|
<div className="scroll">
|
||||||
<Message message = {m} own={m.sender === user.username} user={m}/>
|
{messages.map(m=>(
|
||||||
))}
|
<Message message = {m} own={m.sender === user.username} user={m}/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
{/* <Input/> */}
|
{/* <Input/> */}
|
||||||
<div className="input">
|
<div className="input">
|
||||||
<input
|
<input
|
||||||
@ -287,7 +367,7 @@ function Chats(){
|
|||||||
placeholder="What do you want to say"
|
placeholder="What do you want to say"
|
||||||
onChange={(e) => setNewMessage(e.target.value)}
|
onChange={(e) => setNewMessage(e.target.value)}
|
||||||
value={newMessages}
|
value={newMessages}
|
||||||
/>
|
/>
|
||||||
<div className="send">
|
<div className="send">
|
||||||
<TbSend onClick={handleSubmit}></TbSend>
|
<TbSend onClick={handleSubmit}></TbSend>
|
||||||
</div>
|
</div>
|
||||||
@ -295,19 +375,14 @@ function Chats(){
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<span className="noConv">Open a conversation</span>)}
|
<div className="messages">
|
||||||
|
<span className="noConv">Open a conversation</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
// </div>
|
// </div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Chats
|
export default Chats
|
||||||
@ -19,10 +19,10 @@ import DefaultPicture from '../../assets/profile.jpg'
|
|||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
|
|
||||||
const MeStyleP = styled.p`
|
const MeStyleP = styled.p`
|
||||||
background-color: lightgray;
|
background-color: #5843e4;
|
||||||
padding 10px 20px;
|
padding 10px 20px;
|
||||||
border-radius 10px 0px 10px 10px;
|
border-radius 10px 0px 10px 10px;
|
||||||
color: black;
|
color: white;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
113
containers/react/src/components/Messages/Modal.jsx
Normal file
113
containers/react/src/components/Messages/Modal.jsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { motion } from "framer-motion";
|
||||||
|
import Backdrop from "../Sidebar/Backdrop";
|
||||||
|
import { Rank } from "../../DataBase/DataRank"
|
||||||
|
import '../../styles/Messages.css'
|
||||||
|
import { useState } from "react";
|
||||||
|
import { GrAdd } from "react-icons/gr";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
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 Modal = ({handleClose, text}) => {
|
||||||
|
const [multi, setMulti] = useState(false);
|
||||||
|
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
||||||
|
const [selectedOptionArray, setSelectedOptionArray] = useState([]);
|
||||||
|
|
||||||
|
const handleOptionChange = (selectId, selectedOption) => {
|
||||||
|
setSelectTag((prevTags) =>
|
||||||
|
prevTags.map((tag) =>
|
||||||
|
tag.id === selectId ? { ...tag, selectedOption } : tag
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addNewSelectedTag = () => {
|
||||||
|
const newSelectedId = Math.max (...selectTags.map((tag) => tag.id)) + 1;
|
||||||
|
setSelectTag([...selectTags, { id: newSelectedId, selectedOption: ''}]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveSelectedOptions = () => {
|
||||||
|
const selectedOptions = selectTags.map((tag) => tag.selectedOption);
|
||||||
|
setSelectedOptionArray(selectedOptions);
|
||||||
|
}
|
||||||
|
let new_name;
|
||||||
|
return (
|
||||||
|
<Backdrop>
|
||||||
|
<motion.div
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="modal"
|
||||||
|
variant={dropIn}
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="exit"
|
||||||
|
>
|
||||||
|
<p>New Convewrstion</p>
|
||||||
|
|
||||||
|
{/* First selection */}
|
||||||
|
|
||||||
|
<select className="custom-select"
|
||||||
|
onChange={(e) => {
|
||||||
|
const selection = e.target.value;
|
||||||
|
selection === "group" ? setMulti(true) : setMulti(false)
|
||||||
|
}}>
|
||||||
|
<option value="1v1">1v1</option>
|
||||||
|
<option value="group">Group</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
{/* Second selection */}
|
||||||
|
{selectTags.map((selectTag) =>(
|
||||||
|
<div key={selectTag.id}>
|
||||||
|
|
||||||
|
<select
|
||||||
|
value={selectTag.selectedOption}
|
||||||
|
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}>
|
||||||
|
{Rank.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<option value={new_name}>{item.name}</option>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
<div>
|
||||||
|
<h3>Selected Option:</h3>
|
||||||
|
<ul>
|
||||||
|
{selectedOptionArray.map((option, index) => (
|
||||||
|
<li key={index}>{option}</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{multi === true ? (
|
||||||
|
<GrAdd onClick={addNewSelectedTag}/>) : " "}
|
||||||
|
</div>
|
||||||
|
<div className="div_submit">
|
||||||
|
<Link to='#' className="submit" onClick={ saveSelectedOptions}>Submit</Link>
|
||||||
|
|
||||||
|
<Link to="#" className="submit" onClick={handleClose}>Cancel</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</motion.div>
|
||||||
|
</Backdrop>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Modal
|
||||||
@ -7,6 +7,61 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select{
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-ms-appearance: none;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
box-shadow: none;
|
||||||
|
appearance: none;
|
||||||
|
outline: 0;
|
||||||
|
border: 0!important;
|
||||||
|
margin: 5px;
|
||||||
|
font-size: 18px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal{
|
||||||
|
width: clamp(50%, 700px, 90%);
|
||||||
|
height: min(50%, 300px);
|
||||||
|
|
||||||
|
margin: auto;
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll{
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newMessage{
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact{
|
||||||
|
background-color: rgb(46, 46, 46);
|
||||||
|
align-items: left;
|
||||||
|
height: 29.7rem;
|
||||||
|
overflow: scroll;
|
||||||
|
/* width: 2rem; */
|
||||||
|
/* height: 4rem; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages_box{
|
||||||
|
background-color: black;
|
||||||
|
/* height: 90vh; */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
/* position:relative; */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
.container{
|
.container{
|
||||||
border-color: #FFFFFF ;
|
border-color: #FFFFFF ;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -35,9 +90,11 @@
|
|||||||
.navbar{
|
.navbar{
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #000c66;
|
/* background-color: yellow; */
|
||||||
|
background-image: linear-gradient(90deg, #5843e4, #5a0760);
|
||||||
color: white;
|
color: white;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pic{
|
.pic{
|
||||||
@ -65,8 +122,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.messages{
|
.messages{
|
||||||
background-color: #349b83;
|
background-color: black;
|
||||||
height: calc(100% - 118px);
|
/* height: calc(100% - 118px); */
|
||||||
|
width: 40rem;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,4 +173,91 @@ input{
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
color: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit{
|
||||||
|
display: inline-block;
|
||||||
|
color: white;
|
||||||
|
background-color: #5843e4;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight:lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div_submit {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
/* margin-left: 4px;
|
||||||
|
margin-right: 4px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.lookForFriends{
|
||||||
|
color: rgba(255, 255, 255, 0.5);;
|
||||||
|
backdrop-filter: sepia(90%);
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 11rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.greenAlert{
|
||||||
|
width: clamp(50%, 500px, 90%);
|
||||||
|
height: min(50%, 100px);
|
||||||
|
|
||||||
|
margin: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
/* display: flex; */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(0, 86, 27, 0.7);
|
||||||
|
font-size: 25px;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.redAlert{
|
||||||
|
width: clamp(50%, 500px, 90%);
|
||||||
|
height: min(50%, 100px);
|
||||||
|
|
||||||
|
margin: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(133, 6, 6, 0.7);
|
||||||
|
font-size: 25px;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.redAlert{
|
||||||
|
width: clamp(50%, 500px, 90%);
|
||||||
|
height: min(50%, 100px);
|
||||||
|
|
||||||
|
margin: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(133, 6, 6, 0.7);
|
||||||
|
font-size: 25px;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellowAlert{
|
||||||
|
width: clamp(50%, 500px, 90%);
|
||||||
|
height: min(50%, 100px);
|
||||||
|
|
||||||
|
margin: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(212, 175, 55, 0.7);
|
||||||
|
font-size: 25px;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,9 +38,13 @@
|
|||||||
.chat {
|
.chat {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display:inline-block;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat_2{
|
||||||
|
display:flex;
|
||||||
|
}
|
||||||
.chat__sidebar {
|
.chat__sidebar {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #f9f5eb;
|
background-color: #f9f5eb;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user