---
# System prepended metadata

title: 'MonkChat: Análise, Banco de Dados e ReactJs | Linguagem de Programação'

---

# 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
![](https://i.imgur.com/BkmNpii.png)

### 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

![](https://i.imgur.com/1DxzgQQ.png)


### 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

![](https://i.imgur.com/TA67xP0.png)

**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;
}
```


