# MonkChat: Análise, Banco de Dados e ReactJs | Linguagem de Programação
**Autor**: Vitório Trindade Santana
**Turma**: Informática C
**Número**: 50
[toc]
## Links
Link do projeto: https://codesandbox.io/s/monk-react-qnxnv?file=/src/index.js
Link para vizualização do projeto: https://qnxnv.csb.app/
## Análise
### Caso de uso

### Funcionalidades
>**Criar Sala**
>[color=darkblue]
>Descrição: Tendo colocado o nome de usuário e o nome da sala (ambos válidos), o usuário poderá criar uma sala e após isso convidar mais pessoas para entrar na sua sala e interagir com eles no app através das mensagens.
>Regras: 1- Não poderá ser criada duas ou mais salas com o mesmo nome; 2- É obrigatório o preenchimento dos campos "sala" e "nick"; 3- O nome da sala tem que ter pelo menos 5 caracteres e no máximo 20; 4- O máximo de caracteres para o nome do usuário é de 20.
>Evento: Depois de preenchido os campos de sala e nick, o usuário irá clicar no botão de criar a sala.
>**Entrar em uma Sala**
>[color=darkblue]
>Descrição: Tendo o nome de uma sala já criada o usuário poderá entrar na mesma preenchendo corretamente os campos de nick e sala, preenchendo o da sala com o nome da que o mesmo deseja entrar e interagir.
>Regras: 1- Não é possível entrar em uma sala que não foi criada; 2- Não é possível entrar com o mesmo nick de alguém que já está na sala desejada; 3- O nome da sala tem que ter pelo menos 5 caracteres e no máximo 20; 4- É obrigatório o preenchimento dos campos "sala" e "nick"; 5- O máximo de caracteres para o nome do usuário é de 20.
>Evento: Tendo preenchido corretamente os campos de sala e nick, o usuário precisa apenas clicar no botão de entrar.
>**Enviar uma mensagem**
>[color=darkblue]
>Descrição: Após digitar a sua mensagem na área para a digitação o usuário poderá enviar a sua mensagem para os outros integrantes que estão na sala e assim interagir com eles.
>Regras: 1- Não poderá ser enviado uma mensagem com menos de 1 caractere; 2 - A mensagem não poderá ter mais de 150 caracteres; 3 - Um usuário não pode enviar muitas mensagens em um curto período de tempo;
>Evento: Tendo digitado na área de digitação, basta apenas clicar no botão de enviar.
>**Buscar mensagens**
>[color=darkblue]
>Descrição: A partir dessa funcionalidade o usuário poderá carregar as mensagens que foram enviadas na sala por outros usuários, podendo assim interagir com eles e ver as novas mensagens.
>Regras: 1- Não poderá carregar as mensagens no mesmo instante após essa funcionalidade tiver sido usada, terá um tempo de intervalo para o uso da mesma.
>Evento: Clique no botão de recarregar as mensagens.
## Modelagem do Banco de Dados
### DB Designer

### Script
```sql=
create table tb_sala (
id_sala int PRIMARY key AUTO_INCREMENT,
nm_sala varchar(15)
);
create table tb_usuario (
id_usuario int PRIMARY key AUTO_INCREMENT,
nm_nick varchar(20)
);
create table tb_chat (
id_chat int PRIMARY key AUTO_INCREMENT,
id_sala int,
id_usuario int,
ds_mensagem varchar(150),
dt_mensagem datetime,
FOREIGN KEY (id_sala) REFERENCES tb_sala (id_sala),
FOREIGN KEY (id_usuario) REFERENCES tb_usuario (id_usuario)
);
```
## ReactJs
### Organização de componentes e arquivos

**Obs: Não coloquei o conteúdo do arquivo index.html pois no mesmo só tinha sido colocado por mim as fontes.**
### Cabecalho
**Index Cabecalho**
```javascript=
import { Barra, ContainerCabecalho } from './styled.js'
export default function Cabecalho() {
return(
<ContainerCabecalho>
<div className="t1-imagem-logo"> <img src={require("../../../public/assets/images/logomonk.png")} /> </div>
<Barra/>
<div className="t1-nome-monk"> MonkChat </div>
</ContainerCabecalho>
)
}
```
**Cabecalho Styled**
```javascript=
import styled from "styled-components";
const ContainerCabecalho = styled.div`
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 2em;
.t1-imagem-logo img {
width: 5em;
height: 3.8em;
}
.t1-nome-monk {
font: 2em Montserrat-SemiBold;
font-weight: 600px;
color: white;
}
@media (max-width: 1024px) {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 2em;
.t1-nome-monk {
margin-bottom: 1em;
}
}
`;
const Barra = styled.div`
margin: 0em 1.2em;
background: linear-gradient(180deg, #ba9d4c -10.17%, #f3d991 115.25%);
width: 4px;
height: 3em;
margin: 0em 1em;
border-radius: 1em;
@media (max-width: 1024px) {
display: none;
}
`;
export { Barra, ContainerCabecalho };
```
### Outros
**Input styled**
```javascript=
import styled from "styled-components";
const Input = styled.input`
font: 700 0.8em Montserrat-SemiBold;
border-radius: 0.45em;
border: none;
outline: none;
padding: 0.5em 0.8em;
cursor: text;
@media (max-width: 1024px) {
width: 100%;
padding: 0.5em 0.7em;
}
`;
export { Input };
```
**Botão styled**
```javascript=
import styled from "styled-components";
const Botao = styled.button`
font: 0.75em Montserrat-SemiBold;
color: white;
background-color: #50b4bf;
border-radius: 2em;
border: none;
outline: none;
padding: 0.4em 1.6em;
@media (max-width: 1024px) {
border-radius: 0.3em;
width: 100%;
}
`;
export { Botao };
```
### Chat e conteúdo
**Conteúdo**
```javascript=
import { ConteudoStyled } from './conteudo-styled'
import Chat from './chat'
import { Botao } from '../outros/botao'
import { Input } from '../../components/outros/input'
export default function Conteudo() {
return(
<ConteudoStyled >
<div className="t1-sala-e-mensagens">
<div className="t1-sala-informacoes">
<div className="t1-nome-sala">
<div className="t1-texto-sala"> Sala: </div>
<div className="t1-input-sala"> <Input /> </div>
</div>
<div className="t1-usuario">
<div className="t1-texto-usuario"> Nick: </div>
<div className="t1-input-sala"> <Input /> </div>
</div>
<div className="t1-botoes-entrar">
<div className="t1-botao-criar"> <Botao> Criar </Botao> </div>
<div className="t1-botao-entrar"> <Botao> Entrar </Botao> </div>
</div>
</div>
<div className="t1-campo-mensagem">
<div className="t1-texto-mensagem"> Mensagem: </div>
<div className="t1-area-digitacao"> <textarea rows="12" cols="32" placeholder="Digite aqui a sua mensagem!"></textarea> </div>
<div className="t1-botao-enviar"> <Botao> Enviar </Botao> </div>
</div>
</div>
<Chat/>
</ConteudoStyled>
)
}
```
**Conteúdo Styled**
```javascript=
import styled from "styled-components";
const ConteudoStyled = styled.div`
display: flex;
flex-direction: row;
background-color: #4d34a8;
padding: 1.5em 5em 2.5em 5em;
width: 100%;
.t1-sala-e-mensagens {
display: flex;
flex-direction: column;
padding-top: 1.8em;
margin-right: 6em;
}
.t1-sala-informacoes {
margin-bottom: 2.5em;
}
.t1-nome-sala {
margin-bottom: 0.3em;
}
.t1-usuario {
margin-bottom: 0.6em;
}
.t1-nome-sala,
.t1-usuario {
display: flex;
flex-direction: row;
align-items: center;
}
.t1-texto-sala {
margin-bottom: 0.2em;
}
.t1-texto-sala,
.t1-texto-usuario {
font: 1.1em Montserrat-SemiBold;
color: white;
flex-grow: 1;
}
.t1-botoes-entrar {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.t1-botao-criar {
margin-right: 0.3em;
}
.t1-campo-mensagem {
display: flex;
flex-direction: column;
}
.t1-texto-mensagem {
font: 1.3em Montserrat-SemiBold;
color: white;
margin-bottom: 0.3em;
}
.t1-area-digitacao {
margin-bottom: 0.4em;
}
.t1-area-digitacao textarea {
padding: 0.7em 0.9em;
border: none;
border-radius: 0.3em;
outline: none;
resize: none;
cursor: text;
font: 700 0.8em Montserrat-SemiBold;
}
.t1-botao-enviar {
align-self: flex-end;
}
@media (max-width: 1024px) {
display: flex;
flex-direction: column;
padding: 1em 1.5em;
width: 100%;
.t1-sala-e-mensagens {
padding-top: 1.8em;
width: 100%;
}
.t1-sala-informacoes {
margin-bottom: 2.5em;
}
.t1-texto-sala,
.t1-texto-usuario {
margin-right: 1.5em;
flex-grow: 0;
}
.t1-texto-sala {
margin-right: 1.65em;
}
.t1-nome-sala {
margin-bottom: 0.3em;
}
.t1-usuario {
margin-bottom: 1.5em;
}
.t1-input-sala {
flex-grow: 1;
}
.t1-botao-criar {
margin-bottom: 0.3em;
}
.t1-botoes-entrar {
display: flex;
flex-direction: column;
width: 100%;
}
.t1-botao-criar {
margin: 0em 0em 0.5em 0em;
}
.t1-campo-mensagem {
display: flex;
flex-direction: column;
width: 100%;
margin-bottom: 1.4em;
}
.t1-texto-mensagem {
font: 1.3em Montserrat-SemiBold;
color: white;
margin-bottom: 0.3em;
}
.t1-area-digitacao {
margin-bottom: 0.5em;
}
.t1-area-digitacao textarea {
width: 100%;
font: 700 0.8em Montserrat-SemiBold;
}
.t1-botao-enviar {
align-self: center;
width: 100%;
}
}
`;
export { ConteudoStyled };
```
**Chat**
```javascript=
import { ChatStyled } from './chat-styled'
export default function Chat() {
return (
<ChatStyled>
<div className="t1-botao-recarregar"> <img src={require("../../../public/assets/images/reload.png")} /> </div>
<div className="t1-campo-mensagens">
<div className="t1-mensagem">
<div className="t1-horario"> (15:02:01) </div> <a className="t1-nome-usuario"> Brunex </a> entrou na sala
</div>
<div className="t1-mensagem">
<div className="t1-horario"> (15:02:25) </div> <a className="t1-nome-usuario"> Brunex </a> fala para <a className="t1-para-quem"> Todos:</a> Opa, tudo bem ai?
</div>
<div className="t1-mensagem">
<div className="t1-horario"> (15:02:25) </div> <a className="t1-nome-usuario"> Brunex </a> saiu da sala...
</div>
</div>
</ChatStyled>
)
}
```
**Chat Styled**
```javascript=
import styled from "styled-components";
const ChatStyled = styled.div`
flex-grow: 1;
.t1-botao-recarregar {
display: flex;
justify-content: flex-end;
margin-bottom: 1em;
}
.t1-botao-recarregar img {
width: 0.9em;
height: 0.96em;
}
.t1-campo-mensagens {
background-color: #6237b3;
border-radius: 0.2em;
width: 100%;
height: 24.8em;
padding: 1em;
overflow-y: auto;
}
.t1-campo-mensagens::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius: 10px;
background-color: #3e006f;
}
.t1-campo-mensagens::-webkit-scrollbar {
width: 0.3em;
background-color: #3e006f;
border-radius: 0.6em;
}
.t1-campo-mensagens::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background-color: #cbcbcb;
}
.t1-mensagem {
display: flex;
flex-direction: row;
flex-wrap: wrap;
font: 0.8em Montserrat-SemiBold;
color: white;
text-align: center;
margin-bottom: 0.7em;
}
.t1-horario {
font: 700 1em Montserrat-SemiBold;
margin-right: 0.4em;
}
.t1-nome-usuario {
font: 1em Montserrat-SemiBold;
margin-right: 0.4em;
}
.t1-para-quem {
font: 1em Montserrat-SemiBold;
margin: 0em 0.4em;
}
@media (max-width: 1024px) {
.t1-botao-recarregar {
margin-bottom: 1em;
}
.t1-botao-recarregar img {
width: 1.2em;
height: 1.3em;
}
.t1-campo-mensagens {
background-color: #6237b3;
border-radius: 0.2em;
width: 100%;
height: 15em;
padding: 1em;
margin-bottom: 1em;
}
.t1-mensagem {
flex-wrap: wrap;
margin-bottom: 1.5em;
}
.t1-horario {
margin-right: 100%;
}
.t1-para-quem {
margin: 0em 0.2em;
}
}
`;
export { ChatStyled };
```
**Index**
```javascript=
import Cabecalho from "../../components/cabecalho/";
import { Container } from "./styled.js";
import Conteudo from "./conteudo";
export default function MonkChat() {
return (
<Container>
<Cabecalho />
<Conteudo />
</Container>
);
}
```
**Container Styled**
```javascript=
import styled from "styled-components";
const Container = styled.div`
background-color: #583bbf;
display: flex;
flex-direction: column;
padding: 2em 4em 0em 4em;
height: 100vh;
min-width: 850px;
@media (max-width: 1024px) {
padding: 2em 1.5em;
height: 100%;
min-width: 100%;
}
`;
export { Container };
```
### Index.Js
```javascript=
import "./index.css";
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import Routes from "./routes.js";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Routes />
</StrictMode>,
rootElement
);
```
### Routes
```javascript=
import { BrowserRouter, Switch, Route } from "react-router-dom";
import MonkChat from "../src/pages/monkchat/";
export default function Routes() {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact={true} component={MonkChat} />
</Switch>
</BrowserRouter>
);
}
```
### Index.Css
```css=
body {
margin: 0px;
}
* {
box-sizing: border-box;
cursor: default;
}
```