Skip to content

Commit

Permalink
add chat logic, and implement new stuff of match event, and all spec …
Browse files Browse the repository at this point in the history
…test b00tc4mp#95
  • Loading branch information
Fabián Romero authored and Fabián Romero committed Sep 17, 2024
1 parent a3962e1 commit 2daeec4
Show file tree
Hide file tree
Showing 107 changed files with 3,450 additions and 458 deletions.
15 changes: 15 additions & 0 deletions staff/fabian-romero/project/api/handlers/createChatHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { logic } from 'cor'

export default (req, res, next) => {
const { userId } = req

const { targetUserId } = req.params

try {
logic.createChat(userId, targetUserId)
.then(chatId => res.status(201).json(chatId))
.catch(error => next(error))
} catch (error) {
next(error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export default (req, res, next) => {
const { userId } = req

try {
logic.getFavUsers(userId)
.then(users => res.json(users))
logic.getAllChats(userId)
.then(chats => res.json(chats))
.catch(error => next(error))
} catch (error) {
next(error)
Expand Down
15 changes: 15 additions & 0 deletions staff/fabian-romero/project/api/handlers/getChatMessagesHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { logic } from 'cor'

export default (req, res, next) => {
const { userId } = req

const { targetUserId } = req.params

try {
logic.getChatMessages(userId, targetUserId)
.then(messages => res.json(messages))
.catch(error => next(error))
} catch (error) {
next(error)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { logic } from 'cor'

export default (req, res, next) => {
const { userId } = req

const { chatId } = req.params

try {
logic.getChatParticipant(userId, chatId)
.then(chat => res.json(chat))
.catch(error => next(error))
} catch (error) {
next(error)
}
}
12 changes: 10 additions & 2 deletions staff/fabian-romero/project/api/handlers/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import authenticateUserHandler from './authenticateUserHandler.js'
import createChatHandler from './createChatHandler.js'
import deleteUserByIdHandler from './deleteUserByIdHandler.js'
import getAllChatsHandler from './getAllChatsHandler.js'
import getAllProjectsHandler from './getAllProjectsHandler.js'
import getAllInvestorsHandler from './getAllInvestorsHandler.js'
import getAllMatchsHandler from './getAllMatchsHandler.js'
import getFavUsersHandler from './getFavUsersHandler.js'
import getChatMessagesHandler from './getChatMessagesHandler.js'
import getChatParticipantHandler from './getChatParticipantHandler.js'
import toggleDislikeUserHandler from './toggleDislikeUserHandler.js'
import getLikeUsersHandler from './getLikeUsersHandler.js'
import getUserHandler from './getUserHandler.js'
Expand All @@ -16,16 +19,20 @@ import updateAvatarHandler from './updateAvatarHandler.js'
import updateImageHandler from './updateImageHandler.js'
import updateDescriptionHandler from './updateDescriptionHandler.js'
import updatePasswordHandler from './updatePasswordHandler.js'
import sendMessageHandler from './sendMessageHandler.js'
import searchUserHandler from './searchUserHandler.js'

export {

authenticateUserHandler,
createChatHandler,
deleteUserByIdHandler,
getAllChatsHandler,
getAllProjectsHandler,
getAllInvestorsHandler,
getAllMatchsHandler,
getFavUsersHandler,
getChatMessagesHandler,
getChatParticipantHandler,
getLikeUsersHandler,
getUserNameHandler,
getUserHandler,
Expand All @@ -38,5 +45,6 @@ export {
updateImageHandler,
updateDescriptionHandler,
updatePasswordHandler,
sendMessageHandler,
searchUserHandler
}
17 changes: 17 additions & 0 deletions staff/fabian-romero/project/api/handlers/sendMessageHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { logic } from 'cor'

export default (req, res, next) => {
const { userId } = req

const { message } = req.body

const { chatId } = req.params

try {
logic.sendMessage(userId, chatId, message)
.then(() => res.status(201).send())
.catch(error => next(error))
} catch (error) {
next(error)
}
}
27 changes: 19 additions & 8 deletions staff/fabian-romero/project/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import { mongoose } from 'cor'

import { cors, jsonBodyParser, jwtVerifier, errorHandler } from './middlewares/index.js'
import {
authenticateUserHandler,
registerInvestorHandler,
registerProjectHandler,
authenticateUserHandler,
getUserNameHandler,
getUserHandler,
createChatHandler,
sendMessageHandler,
getChatMessagesHandler,
getChatParticipantHandler,
getAllChatsHandler,
getAllProjectsHandler,
getAllInvestorsHandler,
getAllMatchsHandler,
getLikeUsersHandler,
getFavUsersHandler,
deleteUserByIdHandler,
toggleLikeUserHandler,
toggleDislikeUserHandler,
Expand Down Expand Up @@ -51,24 +55,20 @@ mongoose.connect(process.env.MONGODB_URI)

api.get('/users/likes', jwtVerifier, getLikeUsersHandler)

api.get('/users/favs', jwtVerifier, getFavUsersHandler)

api.get('/users/search', jwtVerifier, searchUserHandler)

api.get('/users/match', jwtVerifier, getAllMatchsHandler)

api.get('/users/:targetUserId', jwtVerifier, getUserHandler)

api.delete('/users/:userId', jwtVerifier, deleteUserByIdHandler)
api.get('/users/profile', jwtVerifier, getUserNameHandler)

api.patch('/users/:targetUserId/likes', jwtVerifier, toggleLikeUserHandler)

api.patch('/users/:targetUserId/Dislikes', jwtVerifier, toggleDislikeUserHandler)
api.patch('/users/:targetUserId/dislikes', jwtVerifier, toggleDislikeUserHandler)

api.patch('/users/:targetUserId/favs', jwtVerifier, toggleFavUserHandler)

api.get('/users/profile', jwtVerifier, getUserNameHandler)

api.patch('/users/avatar', jwtVerifier, jsonBodyParser, updateAvatarHandler)

api.patch('/users/image', jwtVerifier, jsonBodyParser, updateImageHandler)
Expand All @@ -77,6 +77,17 @@ mongoose.connect(process.env.MONGODB_URI)

api.patch('/users/:userId/description', jwtVerifier, jsonBodyParser, updateDescriptionHandler)

api.delete('/users/:userId', jwtVerifier, deleteUserByIdHandler)

api.post('/chat/:targetUserId', jwtVerifier, createChatHandler)

api.post('/:chatId/message', jwtVerifier, jsonBodyParser, sendMessageHandler)

api.get('/:targetUserId/messages', jwtVerifier, getChatMessagesHandler)

api.get('/chats', jwtVerifier, getAllChatsHandler)

api.get('/chats/:chatId', jwtVerifier, getChatParticipantHandler)

api.get('/colors/search', (req, res, next) => {
const colors = ['red', 'green', 'blue', 'violette', 'brown', 'yellow']
Expand Down
2 changes: 1 addition & 1 deletion staff/fabian-romero/project/api/test/authenticate-user.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
curl -v http://localhost:8080/users/auth -X POST -d '{"username":"mariaclarita", "password":"123123123"}' -H "Content-Type: application/json"
curl -v http://localhost:8080/users/auth -X POST -d '{"username":"paquito", "password":"123123123"}' -H "Content-Type: application/json"
1 change: 1 addition & 0 deletions staff/fabian-romero/project/api/test/create-chat.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl -v http://localhost:8080/chat/66e4011a44362ef84f4a7322 -X POST -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmU0MDE5MjQ0MzYyZWY4NGY0YTczMmQiLCJyb2xlIjoicHJvamVjdCIsImlhdCI6MTcyNjQ4MTQzNX0.xIHleTgCBpLR1foc7kljf-zUq8zsOmiRoohVNl23r2g" -H "Content-Type: application/json"
1 change: 1 addition & 0 deletions staff/fabian-romero/project/api/test/get-all-chats.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl -v http://localhost:8080/chats -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmU0MDExYTQ0MzYyZWY4NGY0YTczMjIiLCJyb2xlIjoiaW52ZXN0b3IiLCJpYXQiOjE3MjY0ODE1NDh9.A1-VhseYfKaGDpAAAtyxNM0AhgZk_lbhjtOFQGb1Ids"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl -v http://localhost:8080/chats/66e8095e9de1fe35b4df5dae -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmU0MDExYTQ0MzYyZWY4NGY0YTczMjIiLCJyb2xlIjoiaW52ZXN0b3IiLCJpYXQiOjE3MjY0ODE1NDh9.A1-VhseYfKaGDpAAAtyxNM0AhgZk_lbhjtOFQGb1Ids"
1 change: 1 addition & 0 deletions staff/fabian-romero/project/api/test/send-message.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
curl -v 'http://localhost:8080/66e8095e9de1fe35b4df5dae/message' -X POST -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2NmU0MDExYTQ0MzYyZWY4NGY0YTczMjIiLCJyb2xlIjoiaW52ZXN0b3IiLCJpYXQiOjE3MjY0ODE1NDh9.A1-VhseYfKaGDpAAAtyxNM0AhgZk_lbhjtOFQGb1Ids" -H "Content-Type: application/json" -b '{"message":"hello rosafit"}'
7 changes: 5 additions & 2 deletions staff/fabian-romero/project/app/View/common/Alert.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ export default function Alert({ message, onAccept }) {
</Container>

<Container className="fixed w-screen top-0 h-screen flex items-center justify-center">
<Container className="p-4 border bg-white dark:bg-black dark:text-white flex-col">
<Paragraph>{message}</Paragraph>

<Container
className="p-4 border bg-white text-black flex-col">
<Paragraph>{message} ⚡️ </Paragraph>
<Button onClick={onAccept}>Accept</Button>
</Container>

</Container>
</>
}
165 changes: 165 additions & 0 deletions staff/fabian-romero/project/app/View/home/Chat.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { useState, useEffect, useRef } from 'react'
import { useNavigate, useParams } from 'react-router-dom'

import useContext from '../context.js'
import logic from '../../logic'

import Container from '../library/Container'
import Paragraph from '../library/Paragraph'
import Button from '../library/Button'
import Heading from '../library/Heading'
import Image from '../library/Image'
import Form from '../library/Form'
import Message from '../home/Message.jsx'

import Lottie from 'lottie-react'
import SendMessageIconAnimation from '../../public/SendMessageIcon.json'
import BackIconAnimation from '../../public/BackIcon.json'

export default function Chat() {
const [messages, setMessages] = useState([])
const [participantName, setParticipantName] = useState(null)
const [userId, setUserId] = useState(null)
const [avatar, setAvatar] = useState(null)
const [isLooping, setIsLooping] = useState(false)
const navigate = useNavigate()
const { alert } = useContext()
const messagesEndRef = useRef(null)
const { chatId } = useParams()

useEffect(() => {
if (messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
}
}, [messages])

useEffect(() => {
let intervalId

try {
logic.getChatParticipant(chatId)
.then(chat => {
setUserId(chat.participant.id)
setAvatar(chat.participant.avatar)
setParticipantName(chat.participant.name)

loadMessages(chat.participant.id)
.then(() => {
intervalId = setInterval(() => {
loadMessages(chat.participant.id)
}, 3000)
})
})
.catch(error => {
console.error(error)
alert(error.message)
})
} catch (error) {
console.error(error)
alert(error.message)
}

return () => clearInterval(intervalId)
}, [chatId])

const handleSendPrivateMessageSubmit = event => {
event.preventDefault()

const form = event.target
const privateMessageInput = form['private-message-input']
const message = privateMessageInput.value

try {
logic.sendMessage(chatId, message)
.then(() => {
loadMessages(userId)
privateMessageInput.value = ''
})
.catch(error => {
console.error(error)
alert(error.message)
})
} catch (error) {
console.error(error)
alert(error.message)
}
}

const handleClosePrivateChatClick = () => navigate('/chats')

const loadMessages = (participantId) => {
try {
return logic.getChatMessages(participantId)
.then(messages => setMessages(messages))
.catch(error => {
console.error(error)
if (error instanceof NotFoundError) setMessages([])
alert(error.message)
})
} catch (error) {
console.error(error)
alert(error.message)
}
}

const handleMouseEnter = () => {
setIsLooping(true)
}

const handleMouseLeave = () => {
setIsLooping(false)
}

return <>
<Container className="fixed w-full top-0 left-0 z-[9999] bg-cyan-900 h-full "></Container>

<Container className="fixed w-screen h-screen top-0 left-0 z-[10000] flex flex-col justify-between">

<Container className="fixed left-0 top-0 w-full flex justify-between items-center bg-gradient-to-b from-cyan-950 via-gray-900 to-cyan-900 p-2 box-border shadow-lg rounded-b-md bg-opacity-70 text-black z-[10001]">

<Button
onClick={handleClosePrivateChatClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className="w-8 h-8 flex items-center justify-center bg-transparent border border-orange-400 rounded-lg shadow-lg transition-transform transform hover:scale-95">
<Lottie animationData={BackIconAnimation} loop={isLooping} className="w-full h-full" />
</Button>

<Container className="flex items-center gap-3">
<Image src={(!avatar || avatar === null) ? "/profileIcon.svg" : avatar}
className="w-[40px] h-[40px] rounded-xl" />
<Heading className="flex items-center gap-3">
<p className="text-lg font-medium text-orange-400">{participantName} 's Ratch⚡️!</p>
</Heading>
</Container>
</Container>

<Container className="flex flex-col h-screen w-screen overflow-y-auto p-4 bg-gray-100 mt-20">
{messages.length === 0
? <Paragraph className="text-center text-gray-500">No messages yet.</Paragraph>
: messages.map(message => <Message key={message.id} message={message} />)
}
<div ref={messagesEndRef} />
</Container>

<Container className="fixed bottom-0 left-0 w-full flex justify-between items-center bg-gradient-to-b from-cyan-950 via-gray-900 to-cyan-900 p-2 box-border shadow-lg rounded-t-md bg-opacity-70 text-black z-[10001]">

<Form onSubmit={handleSendPrivateMessageSubmit} className="flex items-center w-full">
<textarea
name="private-message-input"
rows="2"
className="rounded-lg w-full h-14 border border-gray-300 bg-gray-100 text p-2"
placeholder="Write here..."
></textarea>
<Button
type="submit"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className="w-8 h-8 flex items-center justify-center bg-transparent border border-orange-400 rounded-lg shadow-lg transition-transform transform hover:scale-95">
<Lottie animationData={SendMessageIconAnimation} loop={false} className="w-full h-full" />
</Button>
</Form>
</Container>
</Container >
</>
}
Loading

0 comments on commit 2daeec4

Please sign in to comment.