fixed dropdown menu
This commit is contained in:
8
client/package-lock.json
generated
8
client/package-lock.json
generated
@@ -8,6 +8,8 @@
|
||||
"name": "client",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@preline/dropdown": "^2.5.0",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/socket.io-client": "^1.4.36",
|
||||
@@ -1076,6 +1078,12 @@
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@preline/dropdown": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@preline/dropdown/-/dropdown-2.5.0.tgz",
|
||||
"integrity": "sha512-ydKGBx02eLWzmCn8gkaaTe/gXXqvkZKZCgCYCWETRdy31qhaam43hvJMcpsGOROWSjlPNBgVyGrwYdAgJUO68g==",
|
||||
"license": "Licensed under MIT and Preline UI Fair Use License"
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@preline/dropdown": "^2.5.0",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/socket.io-client": "^1.4.36",
|
||||
|
||||
15
client/src/components/chat/ContactsList.tsx
Normal file
15
client/src/components/chat/ContactsList.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { socket } from '../../socket/socket.tsx';
|
||||
|
||||
function ContactsList() {
|
||||
return (
|
||||
<>
|
||||
<div className="flex-grow overflow-y-auto w-64">
|
||||
<ul className="m-2">
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ContactsList;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { socket } from "../../socket/socket.tsx";
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { socket } from '../../socket/socket.tsx';
|
||||
type ChatMessages = {
|
||||
sender: string;
|
||||
message: string;
|
||||
@@ -26,20 +26,20 @@ function MessagesArea({ messages, setMessages }: MessagesAreaProps) {
|
||||
});
|
||||
};
|
||||
|
||||
socket.on("chat message", (msg: ChatMessages) => {
|
||||
console.log("Received message: ", msg);
|
||||
socket.on('chat message', (msg: ChatMessages) => {
|
||||
console.log('Received message: ', msg);
|
||||
messageHandler(msg);
|
||||
});
|
||||
socket.on("historical", (msg: ChatMessages[]) => {
|
||||
console.log("Received historical messages: ", msg);
|
||||
socket.on('historical', (msg: ChatMessages[]) => {
|
||||
console.log('Received historical messages: ', msg);
|
||||
|
||||
msg.forEach((historicalMsg) => {
|
||||
messageHandler(historicalMsg);
|
||||
});
|
||||
});
|
||||
return () => {
|
||||
socket.off("chat message");
|
||||
socket.off("historical");
|
||||
socket.off('chat message');
|
||||
socket.off('historical');
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -48,7 +48,7 @@ function MessagesArea({ messages, setMessages }: MessagesAreaProps) {
|
||||
}, [messages]);
|
||||
|
||||
const messageList = messages.map((msg) => (
|
||||
<li key={msg.message_id}>
|
||||
<li className="hover:bg-gray-700" key={msg.message_id}>
|
||||
{msg.message_id} {msg.sender}: {msg.message}
|
||||
</li>
|
||||
));
|
||||
|
||||
@@ -3,48 +3,54 @@ import logoutIcon from '../../../assets/logout.svg';
|
||||
import Cookies from 'js-cookie';
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import { UsernameType } from '../../utils/ProtectedRoutes.tsx';
|
||||
import { useState } from 'react';
|
||||
|
||||
function UserProfile() {
|
||||
const { username }: UsernameType = useOutletContext();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
function logout() {
|
||||
Cookies.remove('token');
|
||||
window.location.reload();
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center">
|
||||
<div className="hs-dropdown relative inline-flex">
|
||||
<div className="m-3 rounded-full w-12 h-12 overflow-hidden hs-dropdown-toggle cursor-pointer">
|
||||
<img
|
||||
className="w-full h-full object-cover"
|
||||
src={zdjecie}
|
||||
alt="user profile"
|
||||
draggable={false}
|
||||
aria-haspopup="menu"
|
||||
aria-expanded="false"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="hs-dropdown-menu transition-[opacity,margin] duration-100 hs-dropdown-open:opacity-100 opacity-0 hidden min-w-60 bg-green-50 shadow-md rounded-md mt-2 after:h-4 after:absolute after:-bottom-4 after:start-0 after:w-full before:h-4 before:absolute before:-top-4 before:start-0 before:w-full"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
>
|
||||
<div className="p-1 space-y-0.5 flex">
|
||||
<a
|
||||
className="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-black hover:bg-gray-100 focus:outline-none focus:bg-gray-100"
|
||||
onClick={() => {
|
||||
Cookies.remove('token');
|
||||
window.location.reload();
|
||||
}}
|
||||
>
|
||||
Log out
|
||||
</a>
|
||||
<img className="w-5" src={logoutIcon} alt="Logout" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative inline-block">
|
||||
<div
|
||||
className="flex items-center cursor-pointer hs-dropdown-toggle"
|
||||
onClick={toggleDropdown}
|
||||
>
|
||||
<div className="m-3 rounded-full w-12 h-12 overflow-hidden">
|
||||
<img src={zdjecie} alt="Profile image" className="w-12 h-12" />
|
||||
</div>
|
||||
|
||||
<div className="text-center text-gray-200">
|
||||
<div className="text-gray-200">
|
||||
<p>{username}</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
{isOpen && (
|
||||
<div className="absolute bottom-full left-0 mb-2 w-48 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5">
|
||||
<div
|
||||
className="py-1"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
aria-labelledby="options-menu"
|
||||
>
|
||||
<a
|
||||
className="cursor-pointer px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900 flex"
|
||||
role="menuitem"
|
||||
onClick={logout}
|
||||
>
|
||||
<img className="w-5 mr-2" src={logoutIcon} alt="log out ico" />
|
||||
<p>Log out</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import MessageForm from "../components/chat/MessageForm.tsx";
|
||||
import ContactProfile from "../components/chat/ContactProfile.tsx";
|
||||
import UserProfile from "../components/chat/UserProfile.tsx";
|
||||
import ContactForm from "../components/chat/ContactForm.tsx";
|
||||
import MessagesArea from "../components/chat/MessagesArea.tsx";
|
||||
import { useState } from "react";
|
||||
import MessageForm from '../components/chat/MessageForm.tsx';
|
||||
import ContactProfile from '../components/chat/ContactProfile.tsx';
|
||||
import UserProfile from '../components/chat/UserProfile.tsx';
|
||||
import ContactForm from '../components/chat/ContactForm.tsx';
|
||||
import MessagesArea from '../components/chat/MessagesArea.tsx';
|
||||
import { useState } from 'react';
|
||||
import ContactsList from '../components/chat/ContactsList.tsx';
|
||||
|
||||
type ChatMessages = {
|
||||
sender: string;
|
||||
@@ -14,7 +15,7 @@ type ChatMessages = {
|
||||
};
|
||||
|
||||
function Chat() {
|
||||
const [contact, setContact] = useState<string>("");
|
||||
const [contact, setContact] = useState<string>('');
|
||||
const [messages, setMessages] = useState<ChatMessages[]>([]);
|
||||
return (
|
||||
<>
|
||||
@@ -28,18 +29,7 @@ function Chat() {
|
||||
setMessages={setMessages}
|
||||
/>
|
||||
{/*Contact list*/}
|
||||
<div className="flex-grow overflow-y-auto w-64">
|
||||
<ul className="ml-2">
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
<li>jdjskskbkskskaoso</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ContactsList />
|
||||
<hr />
|
||||
<UserProfile />
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import io from "socket.io-client";
|
||||
import Cookie from "js-cookie";
|
||||
const token = Cookie.get("token");
|
||||
import io from 'socket.io-client';
|
||||
import Cookie from 'js-cookie';
|
||||
const token = Cookie.get('token');
|
||||
//TODO socket is trying to connect on login page fix it
|
||||
const socket = io({
|
||||
auth: {
|
||||
@@ -8,36 +8,36 @@ const socket = io({
|
||||
},
|
||||
});
|
||||
|
||||
socket.on("connect", () => console.log("connected"));
|
||||
socket.on('connect', () => console.log('connected'));
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log("Disconnected from server");
|
||||
socket.on('disconnect', () => {
|
||||
console.log('Disconnected from server');
|
||||
});
|
||||
|
||||
function sendMessage(message: string, recipient: string | null) {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = ("0" + (now.getMonth() + 1)).slice(-2);
|
||||
const day = ("0" + now.getDate()).slice(-2);
|
||||
const month = ('0' + (now.getMonth() + 1)).slice(-2);
|
||||
const day = ('0' + now.getDate()).slice(-2);
|
||||
|
||||
const hour = ("0" + now.getHours()).slice(-2);
|
||||
const minute = ("0" + now.getMinutes()).slice(-2);
|
||||
const second = ("0" + now.getSeconds()).slice(-2);
|
||||
const hour = ('0' + now.getHours()).slice(-2);
|
||||
const minute = ('0' + now.getMinutes()).slice(-2);
|
||||
const second = ('0' + now.getSeconds()).slice(-2);
|
||||
const timestamp = `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
||||
|
||||
socket.emit("chat message", {
|
||||
socket.emit('chat message', {
|
||||
message: message,
|
||||
recipient: recipient,
|
||||
timestamp: timestamp,
|
||||
});
|
||||
}
|
||||
|
||||
function sendContact(recipient: string) {
|
||||
socket.emit("contact", { recipient: recipient });
|
||||
function sendContact(contact: string) {
|
||||
socket.emit('contact', { contact: contact });
|
||||
}
|
||||
|
||||
function sendRequestHistorical(recipient: string) {
|
||||
socket.emit("historical", { recipient: recipient });
|
||||
console.log("Requested historical messages for: ", recipient);
|
||||
socket.emit('historical', { recipient: recipient });
|
||||
console.log('Requested historical messages for: ', recipient);
|
||||
}
|
||||
export { sendMessage, sendContact, sendRequestHistorical, socket };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const { Server } = require("socket.io");
|
||||
const { insertMessage, getMessages } = require("../db/db");
|
||||
const { insertMessage, getMessages, insertContact } = require("../db/db");
|
||||
const { verifyJwtToken } = require("../auth/jwt");
|
||||
const console = require("node:console");
|
||||
|
||||
@@ -47,8 +47,6 @@ function initializeSocket(io) {
|
||||
timestamp,
|
||||
);
|
||||
const message_id = results.message_id;
|
||||
if (message_id) {
|
||||
}
|
||||
console.log("received from chat message", msg);
|
||||
|
||||
io.to(username).to(recipient).emit("chat message", {
|
||||
@@ -71,6 +69,10 @@ function initializeSocket(io) {
|
||||
const messages = await getMessages(username, recipient.recipient);
|
||||
io.to(username).emit("historical", messages);
|
||||
});
|
||||
|
||||
socket.on("contact", (contact) => {
|
||||
insertContact(contact);
|
||||
});
|
||||
socket.on("disconnect", (reason) => {
|
||||
console.log(socket.id, " disconnected due to: ", reason);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user