# Session MonkChat
Autor: Jonathan Fernando Costa Galo - INFO C
Número: 24
[toc]
### Fotos do site em anexo:
#### Normal:

#### Responsivo:

### Link do Código em React:
https://codesandbox.io/s/monkchat-27buy?file=/src/pages/home/Index-responsivo.css
### Código em React (Faixa 1)
```htmlmixed=
export default function Faixa1() {
return (
<div class="container">
<div class="cabecalho">
<img
src={require("../../assets/images/logo1-1.webp")}
class="parte1-img1"
alt="Descr"
/>
<img
src={require("../../assets/images/Line1-1.webp")}
class="parte2-img2"
alt="Descr"
/>
<div class="parte3">MonkChat</div>
</div>
<div class="conteudo">
<div class="conteudo-direita">
<div class="direita-cima">
<div class="conteudo1-linha1">
<div class="linha1-parte1">Sala:</div>
<textarea class="linha1-parte2">SangueNosOio</textarea>
</div>
<div class="conteudo1-linha2">
<div class="linha2-parte1">Nick:</div>
<textarea class="linha2-parte2">JojoLindo1609</textarea>
</div>
<div class="conteudo1-linha3">
<button class="botao-cima1">Criar</button>
<button class="botao-cima2">Entrar</button>
</div>
</div>
<div class="direita-baixo">
<div class="conteudo2-linha1">Mensagem:</div>
<textarea class="conteudo2-linha2">Opa, tudo bem aí??</textarea>
<div class="conteudo2-linha3"></div>
<button class="botao-baixo1">Enviar</button>
</div>
</div>
<div class="conteudo-2">
<div class="botao-restart">
<img
src={require("../../assets/images/Group1.webp")}
class="restart"
alt="Descr"
/>
</div>
<div class="conteudo-esquerda">
<div class="esquerda-chat">
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
<div class="chat-comentario1">
(15:02:01) <span class="negrito">Brunex</span> entrou na sala...
</div>
<div class="chat-comentario2">
(15:03:25) <span class="negrito">Brunex</span> fala para{" "}
<span class="negrito">Todos</span>: Opa, tudo bem ai?
</div>
<div class="chat-comentario3">
(15:03:25) <span class="negrito">Brunex</span> saiu da sala...
</div>
</div>
</div>
</div>
</div>
</div>
);
}
```
### Código em React (Index.js)
```htmlmixed=
import Faixa1 from './Faixa1'
import './Index.css'
import './Index-responsivo.css'
import './../../../public/fonts/comum.css'
export default function Index() {
return (
<div class="container-site">
<Faixa1 />
</div>
)
}
```
### Código CSS (Index.css)
```css=
.container {
display: flex;
flex-direction: column;
background-color: #583bbf;
padding: 2em 2em;
height: 100vh;
width: 100vw;
}
.cabecalho {
display: flex;
flex-direction: row;
margin: 20px 0px;
align-items: center;
}
.conteudo {
display: flex;
flex-direction: row;
background: rgba(0, 0, 0, 0.12);
margin: 30px 30px 30px;
height: 73%;
border-radius: 4px;
}
.conteudo-direita {
display: flex;
flex-direction: column;
margin: 40px 40px 40px;
}
.conteudo1-linha1 {
display: flex;
flex-direction: row;
margin: 0px 0px 10px 0px;
}
.conteudo1-linha2 {
display: flex;
flex-direction: row;
margin: 0px 0px 10px 0px;
}
.conteudo1-linha3 {
display: flex;
flex-direction: row;
margin: 0px 0px 10px 0px;
justify-content: flex-end;
}
.botao-cima1 {
background: #50b4bf;
border: none;
padding: 5px 15px;
border-radius: 20px;
font: 16px Montserrat;
color: #ffffff;
font-weight: bold;
margin: 0px 10px 0px 0px;
}
.botao-cima2 {
background: #50b4bf;
border: none;
padding: 5px 15px;
border-radius: 20px;
font: 16px Montserrat;
color: #ffffff;
font-weight: bold;
}
.botao-baixo1 {
background: #50b4bf;
border: none;
padding: 5px 30px;
border-radius: 20px;
font: 16px Montserrat;
color: #ffffff;
font-weight: bold;
}
.conteudo-2 {
display: flex;
flex-direction: column;
}
.conteudo-esquerda {
display: flex;
flex-direction: column;
width: 845px;
height: 85%;
background: #c041e0;
margin: 5px 0px 40px;
border-radius: 4px;
overflow-y: auto;
}
.parte3 {
font: 36px Montserrat;
color: #ffffff;
font-weight: bold;
}
.linha1-parte1 {
font: 24px Montserrat;
color: #ffffff;
font-weight: bold;
margin: 0px 15px 0px 0px;
}
.linha2-parte1 {
font: 24px Montserrat;
color: #ffffff;
font-weight: bold;
margin: 0px 10px 0px 0px;
}
.conteudo2-linha1 {
font: 24px Montserrat;
color: #ffffff;
font-weight: bold;
margin: 0px 0px 7px 0px;
}
.chat-comentario1 {
font: 16px Montserrat;
color: #ffffff;
margin: 20px 20px 10px 20px;
}
.chat-comentario2 {
font: 16px Montserrat;
color: #ffffff;
margin: 10px 20px 10px 20px;
}
.chat-comentario3 {
font: 16px Montserrat;
color: #ffffff;
margin: 10px 20px 10px 20px;
}
.span {
font-weight: bold;
}
.botao-restart {
}
.botao-restart-fundo {
opacity: 0.2;
}
.restart {
color: white;
}
.negrito{
font-weight: bold;
}
.linha1-parte2{
border-radius: 5px;
height: 30px;
font: 16px Montserrat;
color: #000000;
}
.linha2-parte2{
border-radius: 5px;
height: 30px;
font: 16px Montserrat;
color: #000000;
}
.conteudo2-linha2{
border-radius: 5px;
height: 10em;
width: 17.2em;
margin: 0px 0px 7px 0px;
font: 16px Montserrat;
color: #000000;
}
.conteudo-esquerda::-webkit-scrollbar-track
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 10px;
background-color: #3E006F;
}
.conteudo-esquerda::-webkit-scrollbar
{
width: 7px;
background-color: #3E006F;
border-radius: 10px;
}
.conteudo-esquerda::-webkit-scrollbar-thumb
{
border-radius: 10px;
background-color: #ffffff;
}
.parte1-img1{
margin: 0px 15px 0px 0px;
}
.parte2-img2{
margin: 0px 15px 0px 0px;
}
.direita-baixo{
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.restart{
margin: 10px 10px 0px 10px;
}
.botao-restart{
display: flex;
flex-direction: row;
justify-content: flex-end;
}
```
### Código CSS (Index-responsivo.css)
Obs: Coloquei uma formatação de tela de 375x1024
```css=
@media (max-width: 1024px) {
.container {
justify-content: center;
padding: 0px 32px 32px 32px;
}
.cabecalho{
display: flex;
flex-direction: column;
justify-content: center;
margin: 20px;
}
.conteudo{
display: flex;
flex-direction: column;
margin: 0px;
}
.conteudo1-linha3{
display: flex;
flex-direction: column;
}
.botao-cima1{
margin: 0px 0px 10px 0px;
}
.conteudo2-linha2{
width: 14.2em;
}
.parte2-img2{
display: none;
}
.botao-cima2{
margin: 0px 0px 0px;
}
.conteudo-esquerda{
overflow-x: auto;
width: 14.2em;
height: 10em;
}
.conteudo-2{
align-items: center;
}
.botao-restart{
margin: 10px;
}
}
```
### Código CSS (comum.css)
```css=
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Montserrat&display=swap");
body {
margin: 0;
width: 100%;
}
* {
box-sizing: border-box;
}
```
## Casos de Uso: Funcionalidades
>[color=#C2C2C2]
>
>
### Criar Sala
>[color=#0A2463]
>
>**Descrição:** O usuário poderá criar uma sala para se comunicar com os demais usuários do Chat.
>**Regras:**
>1) Não pode haver duas salas com o mesmo nome.
>2) Não pode haver dois usuários com o mesmo nome.
>3) Não é permitido palavrões.
>4) É necessário um nickname para criar a sala.
>5) Não é permitido criar a sala tendo o nome como ofensivos ou algo relacionado.
>6) Não é permitido criar varias salas ao mesmo tempo.
>7) Máximo 20 caractéres, mínimo de 3 caractéres.
>
>**Evento:** Clicar no botão e automaticamente entrar e criar uma sala no site.
### Entrar na Sala
>[color=#2680A6]
>
>**Descrição:** O usuário poderá se conectar a uma sala e se comunicar com os outros usuários do MonkChat.
>**Regras:**
>1) O usuário só poderá se conectar a uma sala já criada.
>2) Não pode haver dois usuários com o mesmo nome.
>3) Não é permitido palavrões.
>4) É necessário um nickname para entrar na sala.
>5) Não é permitido entrar na sala tendo a sala ou o nome como ofensivos ou algo relacionado.
>6) Máximo 20 caractéres, mínimo de 3 caractéres.
>
>**Evento:** Clicar no botão e entrar em uma sala já criada.
### Enviar Mensagem
>[color=#C2C2C2]
>
>**Descrição:** Envia uma mensagem ao destinatário escolhido.
>**Regras:**
>1) Não é permitido enviar mensagens ofensivas ou discursos de ódio.
>2) Não é permitido o mesmo usuário mandar mensagens simultaneamente.
>3) É necessário o usuário escolher o destinatário.
>4) Máximo de 500 caractéres por mensagem.
>
>**Evento:** Escrever a mensagem na caixa de texto e envia-la apertando o botão "Enter".
### Buscar Mensagem
>[color=#0A2463]
>
>**Descrição:** O usuário pode recarregar o chat, atualizando para ver se chegou mais mensagens;
>**Regras:**
>1) Apertar depois de 20 segundos;
>
>**Evento:** Clicar no botão de recaregar.
## Codigos do Visual Studio
#### Conteudo.js
```javascript=
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { ContainerConteudo } from './conteudo.styled'
import { ChatButton, ChatInput, ChatTextArea } from '../../components/outros/inputs'
import LoadingBar from 'react-top-loading-bar'
import { useState, useRef } from 'react';
import Api from '../../service/api';
const api = new Api();
export default function Conteudo() {
const [chat, setChat] = useState([]);
const [sala, setSala] = useState('');
const [usu, setUsu] = useState('');
const [msg, setMsg] = useState('')
const loading = useRef(null);
const atualizar = async () => {
loading.current.continuousStart();
const mensagens = await api.listarMensagens(1);
console.log(mensagens);
setChat(mensagens)
loading.current.complete();
}
const enviarMensagem = async () => {
const r = await api.inserirMensagem(sala, usu, msg);
console.log(r);
if(!r.erro)
toast.success("Lacrou Mona!!")
else
toast.error(`${r.erro}`)
await atualizar();
}
return (
<ContainerConteudo>
<ToastContainer/>
<LoadingBar color = "994eff" ref={loading} height={6}/>
' <div className="container-form">
<div className="box-sala">
<div>
<div className="label">Sala</div>
<ChatInput value={sala} onChange={e => setSala(e.target.value)} />
</div>
<div>
<div className="label">Nick</div>
<ChatInput value={usu} onChange={e => setUsu(e.target.value)} />
</div>
<div>
<ChatButton> Criar </ChatButton>
<ChatButton> Entrar </ChatButton>
</div>
</div>
<div className="box-mensagem">
<div className="label">Mensagem</div>
<ChatTextArea value={msg} onChange={e => setMsg(e.target.value)} />
<ChatButton onClick={enviarMensagem} className="btn-enviar"> Enviar </ChatButton>
</div>
</div>
<div className="container-chat">
<img onClick={atualizar}
className="chat-atualizar"
src="/assets/images/atualizar.png" alt="" />
<div className="chat">
{chat.map(x =>
<div>
<div className="chat-message">
<div>({new Date(x.dt_mensagem.replace('Z', '')).toLocaleTimeString()})</div>
<div><b>{x.tb_usuario.nm_usuario}</b> fala para <b>Todos</b>:</div>
<div> {x.ds_mensagem} </div>
</div>
</div>
)}
</div>
</div>'
</ContainerConteudo>
)
}
```
#### API/src/models/Index.js
```javascript=
import db from './db.js';
import express from 'express'
import cors from 'cors'
const app = express();
app.use(cors());
app.use(express.json());
app.post('/chat', async (req, resp) => {
try {
let chat = req.body;
if(!chat.mensagem||chat.mensagem=="")
return resp.send({erro:"Se ferrou!!"});
let sala = await db.tb_sala.findOne({ where: { nm_sala: chat.sala.nome } });
let usu = await db.tb_usuario.findOne({ where: { nm_usuario: chat.usuario.nome } })
let mensagem = {
id_sala: sala.id_sala,
id_usuario: usu.id_usuario,
ds_mensagem: chat.mensagem,
dt_mensagem: new Date()
}
let r = await db.tb_chat.create(mensagem);
resp.send(r);
} catch (e) {
resp.send('Deu erro');
console.log(e.toString());
}
});
app.get('/chat/:salaId', async (req, resp) => {
try {
let mensagens = await
db.tb_chat.findAll({
where: {
id_sala: req.params.salaId
},
order: [['id_chat', 'desc']],
include: ['tb_usuario', 'tb_sala'],
});
resp.send(mensagens);
} catch (e) {
resp.send(e.toString())
}
})
app.get('/usuario', async(req, resp) => {
let usuarios = await db.tb_usuario.findAll();
resp.send(usuarios)
})
app.post('/usuario', async(req, resp) => {
let usuario = req.body;
let usuarioInserir = {
nm_usuario: usuario.nome
}
let r = await db.tb_usuario.create(usuarioInserir);
resp.send(r);
})
app.listen(process.env.PORT,
x => console.log(`>> Server up at port ${process.env.PORT}`))
```