diff --git a/src/backend/api.js b/src/backend/api.js index 2a92b0b..6e34813 100644 --- a/src/backend/api.js +++ b/src/backend/api.js @@ -2,10 +2,10 @@ import {getConfigValue} from "@brojs/cli"; const LOCAL = "http://localhost:8099"; -const DEV = "https://dev.bro-js.ru/enterfront"; +const DEV = "https://dev.bro-js.ru"; const SERVER = ""; -export const BASE_API_URL = LOCAL + getConfigValue("enterfront.api"); +export const BASE_API_URL = LOCAL + getConfigValue("enterfront.api") + "/enterfront"; // fetch(`${BASE_API_URL}/books/list`) @@ -22,12 +22,7 @@ export async function post(path, body) { }); console.log("Initial data from API:", res) - - const txt = await res.text(); - console.log("Initial text from API:", txt) - - const data = JSON.parse(txt); - + const data = JSON.parse(await res.text()); console.log("Data from API:", data) if (res.status === 200) { @@ -51,6 +46,7 @@ export async function get(path){ } }); + console.log("Data from API:", res) const data = await res.json(); if (res.status === 200) { diff --git a/src/components/home/ChatsList.jsx b/src/components/home/ChatsList.jsx index 493e4b3..acb1f65 100644 --- a/src/components/home/ChatsList.jsx +++ b/src/components/home/ChatsList.jsx @@ -1,9 +1,44 @@ -import React from 'react'; +import React, {useEffect, useState} from 'react'; import Card from "./Card.jsx"; +import {get} from "../../backend/api"; +import {displayMessage} from "../../backend/notifications/notifications"; +import {MessageType} from "../../backend/notifications/message"; const ChatsList = (props) => { const { chats } = props; + const [customChats, setCustomChats] = useState([]); + + const updateList = async () => { + const username = localStorage.getItem("username"); + if (!username) {return null;} + + const updatedChats = await Promise.all( + chats.map(async (chat) => { + const interlocutorId = chat.id1 === username ? chat.id2 : chat.id1 + + const {ok, data} = await get('/auth/' + interlocutorId); + if (!ok) { + displayMessage(data.message, MessageType.ERROR); + return null; + } + + const interlocutor = data.user; + + return { + id: interlocutorId, + name: interlocutor.nickname, + lastMessage: chat.messages.length > 0 ? chat.messages[chat.messages.length - 1].data : "", + } + }) + ); + + setCustomChats(updatedChats.filter(chat => chat !== null)); + }; + + useEffect(() => {updateList().then();}, [chats]) + + const colorMap = { orange: 'FFA500FF', aqua: '00FFFFFF', @@ -19,13 +54,14 @@ const ChatsList = (props) => { function getColor(chatId) { const keys = Object.keys(colorMap); - const index = chatId % keys.length; + const numericId = Array.from(chatId).reduce((sum, char) => sum + char.charCodeAt(0), 0); + const index = numericId % keys.length; return colorMap[keys[index]]; } return (
- {chats.map((item, index) => ( + {customChats.map((item, index) => ( { const {ok, data} = await get('/auth/' + username); if (!ok) { - displayMessage("Some error with auth", MessageType.ERROR); + displayMessage("Some error with auth:" + data.message, MessageType.ERROR); return; } diff --git a/src/pages/Chat.jsx b/src/pages/Chat.jsx index fc3b392..b94ea38 100644 --- a/src/pages/Chat.jsx +++ b/src/pages/Chat.jsx @@ -74,7 +74,7 @@ const emojis = [ ]; const Chat = () => { - const [interlocutorId, setInterlocutorId] = useState(0); + const [interlocutorId, setInterlocutorId] = useState(""); const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(""); const [showEmojiPicker, setShowEmojiPicker] = useState(false); @@ -83,7 +83,8 @@ const Chat = () => { const navigate = useNavigate(); useEffect(() => { - const id = parseInt(localStorage.getItem("interlocutorId"), 10) || 0; + // const id = parseInt(localStorage.getItem("interlocutorId"), 10) || 0; + const id = localStorage.getItem("interlocutorId") setInterlocutorId(id); socket.current = new WebSocket("ws://localhost:8080"); diff --git a/src/pages/Home.jsx b/src/pages/Home.jsx index 7d29b33..a3f1037 100644 --- a/src/pages/Home.jsx +++ b/src/pages/Home.jsx @@ -1,64 +1,30 @@ -import React from "react"; +import React, {useEffect, useState} from "react"; import HomeTitle from "../components/home/HomeTitle.jsx"; import ChatsList from "../components/home/ChatsList.jsx"; import Header from "../components/home/Header.jsx"; +import {displayMessage} from "../backend/notifications/notifications"; +import {MessageType} from "../backend/notifications/message"; +import {get} from "../backend/api"; const Home = () => { + const [chats, setChats] = useState([]) - // temp for testing - const chats = [ - { - name: "Alice Johnson", - id: 123456, - lastMessage: "See you later!" - }, - { - name: "Bob Smith", - id: 654321, - lastMessage: "Got it, thanks!" - }, - { - name: "Charlie Brown", - id: 234567, - lastMessage: "How's the project going? How's the project going? How's the project going?" + - "How's the project going? How's the project going?" - }, - { - name: "David Clark", - id: 765432, - lastMessage: "I'll send the files." - }, - { - name: "Eve Adams", - id: 345678, - lastMessage: "Let's meet tomorrow." - }, - { - name: "Frank Wright", - id: 876543, - lastMessage: "Can you review this?" - }, - { - name: "Grace Lee", - id: 456789, - lastMessage: "Thanks for your help!" - }, - { - name: "Hannah Scott", - id: 987654, - lastMessage: "See you at the meeting." - }, - { - name: "Ian Davis", - id: 567890, - lastMessage: "Let me know when you're free." - }, - { - name: "Jill Thompson", - id: 678901, - lastMessage: "I'll catch up with you later." + async function retrieveChats() { + const username = localStorage.getItem("username"); + if (!username) { + displayMessage("You're not logged in!", MessageType.WARN); + return; } - ]; + + const {ok, data} = await get('/chat/list/' + username); + if (!ok) { + displayMessage(data.message, MessageType.ERROR); + return; + } + setChats(data.chats); + } + + useEffect(() => {retrieveChats().then()}, []) return (
diff --git a/stubs/api/auth/index.js b/stubs/api/auth/index.js index 485aab8..e9d6177 100644 --- a/stubs/api/auth/index.js +++ b/stubs/api/auth/index.js @@ -9,7 +9,7 @@ const TOKEN_KEY = process.env.TOKEN_KEY; module.exports = authRouter; -const { users, getUserFromDB } = require('../db'); +const { addUserToDB, getUserFromDB } = require('../db'); // Get a user by its id @@ -67,7 +67,7 @@ authRouter.post('/reg', (req, res) => { // Add to 'DB' const newUser = {id: name, password: password, nickname: nickname}; - users.push(newUser); + addUserToDB(newUser) res.status(200).send({user: newUser}); }) diff --git a/stubs/api/change/index.js b/stubs/api/change/index.js index 959e935..37c3d98 100644 --- a/stubs/api/change/index.js +++ b/stubs/api/change/index.js @@ -2,7 +2,7 @@ const changeRouter = require('express').Router(); module.exports = changeRouter; -const { users, getUserFromDB } = require('../db'); +const { users, getUserFromDB, deleteUserFromDB, addUserToDB } = require('../db'); const jwt = require("jsonwebtoken"); @@ -18,29 +18,50 @@ changeRouter.post('/nickname', (req, res) => { res.status(401).send({message: 'Invalid credentials (id)'}); } - // Delete the old one - const index = users.findIndex(item => item.id === id); - if (index !== -1) { - users.splice(index, 1); // Remove the old user - } - - // Insert updated - users.push({ + const updatedUser = { "nickname": newNickname, "password": user.password, "id": user.id - }); + }; + + // Delete the old one + deleteUserFromDB(id) + + // Insert updated + addUserToDB(updatedUser); res.status(200).send({}); }); changeRouter.post('/password', (req, res) => { const { id, newPassword } = req.body; - // ... + console.log("Request password in /change:", id); + + const user = getUserFromDB(id); + + // Invalid identification + if (!user) { + res.status(401).send({message: 'Invalid credentials (id)'}); + } + + // Delete the old one + deleteUserFromDB(id) + + // Insert updated + const updatedUser = { + "nickname": user.nickname, + "password": newPassword, + "id": user.id + }; + addUserToDB(updatedUser); + + res.status(200).send({}); }); changeRouter.delete('/:id', (req, res) => { const { id } = req.params; - // ... + console.log("Request delete in /change:", id); + + deleteUserFromDB(id); }); diff --git a/stubs/api/chat/chats.json b/stubs/api/chat/chats.json index dc6e34f..394f979 100644 --- a/stubs/api/chat/chats.json +++ b/stubs/api/chat/chats.json @@ -65,6 +65,160 @@ } ] }, + { + "id1": "alice", + "id2": "evead", + "messages": [ + { + "data": "Eve, do you have the meeting details?", + "senderId": "alice" + }, + { + "data": "Yes, I just sent them to you.", + "senderId": "evead" + }, + { + "data": "Got it, thanks!", + "senderId": "alice" + }, + { + "data": "You're welcome.", + "senderId": "evead" + } + ] + }, + { + "id1": "alice", + "id2": "frank", + "messages": [ + { + "data": "Can you review this document for me?", + "senderId": "alice" + }, + { + "data": "Sure, I'll take a look.", + "senderId": "frank" + }, + { + "data": "Thanks, much appreciated!", + "senderId": "alice" + }, + { + "data": "No problem.", + "senderId": "frank" + } + ] + }, + { + "id1": "alice", + "id2": "grace", + "messages": [ + { + "data": "Hey Grace, let's meet up for coffee!", + "senderId": "alice" + }, + { + "data": "Sounds good, when are you free?", + "senderId": "grace" + }, + { + "data": "How about tomorrow afternoon?", + "senderId": "alice" + }, + { + "data": "Works for me!", + "senderId": "grace" + } + ] + }, + { + "id1": "alice", + "id2": "hanna", + "messages": [ + { + "data": "Hannah, do you have a moment?", + "senderId": "alice" + }, + { + "data": "Sure, what's up?", + "senderId": "hanna" + }, + { + "data": "Just wanted to check on the report.", + "senderId": "alice" + }, + { + "data": "I'll send it soon.", + "senderId": "hanna" + } + ] + }, + { + "id1": "alice", + "id2": "ianda", + "messages": [ + { + "data": "Ian, have you completed the review?", + "senderId": "alice" + }, + { + "data": "Yes, I sent my feedback.", + "senderId": "ianda" + }, + { + "data": "Thanks for that.", + "senderId": "alice" + }, + { + "data": "Anytime!", + "senderId": "ianda" + } + ] + }, + { + "id1": "alice", + "id2": "jillt", + "messages": [ + { + "data": "Jill, let's schedule a catch-up meeting.", + "senderId": "alice" + }, + { + "data": "Sounds good, when works for you?", + "senderId": "jillt" + }, + { + "data": "Tomorrow afternoon?", + "senderId": "alice" + }, + { + "data": "That works for me!", + "senderId": "jillt" + } + ] + }, + { + "id1": "alice", + "id2": "evead", + "messages": [ + { + "data": "Eve, did you send the schedule?", + "senderId": "alice" + }, + { + "data": "Yes, just sent it.", + "senderId": "evead" + }, + { + "data": "Thanks, much appreciated!", + "senderId": "alice" + }, + { + "data": "No problem!", + "senderId": "evead" + } + ] + }, { "id1": "bobsm", "id2": "charl", diff --git a/stubs/api/chat/index.js b/stubs/api/chat/index.js index 88032d7..5ba9ced 100644 --- a/stubs/api/chat/index.js +++ b/stubs/api/chat/index.js @@ -2,10 +2,11 @@ const chatRouter = require('express').Router(); module.exports = chatRouter; -const { users, chats, getUserFromDB, getChatFromDB } = require('../db'); +const { getChatFromDB, getUsersChats, addChatToDB } = require('../db'); -chatRouter.get('/:id1/:id2', (req, res) => { +chatRouter.get('/item/:id1/:id2', (req, res) => { const { id1, id2 } = req.params; + console.log("Request get in /chat:", id1, id2) const chat = getChatFromDB(id1, id2); @@ -15,3 +16,40 @@ chatRouter.get('/:id1/:id2', (req, res) => { res.status(404).send({message: 'Chat was not found'}); } }) + +chatRouter.post('/item/:id1/:id2', (req, res) => { + const { id1, id2 } = req.params; + console.log("Request post in /chat:", id1, id2) + + const chat = getChatFromDB(id1, id2); + + if (chat) { + // Chat already exists + res.status(200).send({chat}); + } else { + // Creating new chat + const newChat = { + id1: id1, + id2: id2, + messages: [] + } + + addChatToDB(newChat); + + res.status(200).send({newChat}); + } +}) + +chatRouter.get('/list/:id', (req, res) => { + const { id } = req.params; + + console.log("Request get /list in /chat:", id); + + const userChats = getUsersChats(id); + + if (!userChats) { + res.status(404).send({message: 'Error with retrieving chats'}); + } else { + res.status(200).send({chats: userChats}); + } +}) diff --git a/stubs/api/db.js b/stubs/api/db.js index 20c1c03..6ac90f4 100644 --- a/stubs/api/db.js +++ b/stubs/api/db.js @@ -15,6 +15,17 @@ const getUserFromDB = (userID) => { } } +const deleteUserFromDB = (userID) => { + const index = users.findIndex(item => item.id === userID); + if (index !== -1) { + users.splice(index, 1); + } +} + +const addUserToDB = (user) => { + users.push(user); +} + const getChatFromDB = (firstID, secondID) => { if (!firstID || !secondID) {return false;} @@ -29,4 +40,31 @@ const getChatFromDB = (firstID, secondID) => { } } -module.exports = {users, chats, getUserFromDB, getChatFromDB} +const getUsersChats = (userID) => { + if (!userID) {return false;} + + const userChats = chats.filter((chat) => (chat.id1 === userID || chat.id2 === userID)); + + if (userChats) { + return userChats; + } else { + return false; + } +} + +const deleteChatFromDB = (firstID, secondID) => { + const index = chats.findIndex(item => + (item.id1 === firstID && item.id2 === secondID) || (item.id1 === secondID && item.id2 === firstID)); + + if (index !== -1) { + chats.splice(index, 1); + } +} + +const addChatToDB = (chat) => { + chats.push(chat); +} + + +module.exports = {users, chats, getUserFromDB, getChatFromDB, addUserToDB, + deleteUserFromDB, addChatToDB, deleteChatFromDB, getUsersChats} diff --git a/stubs/api/index.js b/stubs/api/index.js index 17f1ced..86894a8 100644 --- a/stubs/api/index.js +++ b/stubs/api/index.js @@ -12,6 +12,6 @@ module.exports = router; // router.use(delay(300)); // router.use('/books', delay, booksRouter); -router.use('/auth', authRouter); -router.use('/change', verify, changeRouter); -router.use('/chat', verify, chatRouter) +router.use('/enterfront/auth', authRouter); +router.use('/enterfront/change', verify, changeRouter); +router.use('/enterfront/chat', verify, chatRouter)