├── .env ├── .env.dev ├── .gitignore ├── DOCUMENTOS_DE_APOIO ├── PASSO_A_PASSO_ADICIONAR_UPLOAD_DE_IMAGENS_AO_PROJETO.md ├── PASSO_A_PASSO_CRIAR_ROTA_NA_API.md ├── exemplo_criacao_grafico_estatico │ └── EXEMPLO-GRAFICO-ESTATICO.html ├── exemplo_de_quiz │ ├── EXEMPLO_QUIZZ.html │ └── style.css └── exemplo_de_upload_de_arquivo │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── app.js │ ├── package.json │ ├── public │ ├── index.html │ └── perfil.html │ └── src │ ├── config │ └── configUpload.js │ ├── controllers │ └── usuarioController.js │ ├── database │ ├── config.js │ └── script-exemplo-criacao.sql │ ├── models │ └── usuarioModel.js │ └── routes │ └── usuarioRouter.js ├── LICENSE ├── README.md ├── app.js ├── package.json ├── public ├── assets │ ├── aguarde-orange.gif │ ├── aguarde-pink.gif │ ├── aguarde-pink2.gif │ ├── aguarde-pink3.gif │ ├── circle-loading.gif │ ├── icon │ │ ├── favicon2.ico │ │ └── favicon2.png │ └── imgs │ │ ├── av1.png │ │ ├── av2.png │ │ ├── av3.png │ │ ├── av4.png │ │ ├── av5.png │ │ ├── banner-fundo.jpeg │ │ ├── bg-jelly-fish-para-home.png │ │ ├── bg-jelly-fish-para_outras_pags.png │ │ ├── growth.png │ │ ├── growth_color.png │ │ ├── imagem-apoio.png │ │ ├── lightbulb.png │ │ ├── lightbulb_color.png │ │ ├── missao.png │ │ ├── pessoa1.png │ │ ├── pessoa2.png │ │ ├── pessoa3.png │ │ ├── planet-earth.png │ │ ├── planet-earth_color.png │ │ ├── side-img-contato.png │ │ ├── valores.png │ │ └── visao.png ├── cadastro.html ├── css │ ├── dashboards.css │ └── estilo.css ├── dashboard │ ├── cards.html │ ├── dashboard.html │ ├── edicao-aviso.html │ └── mural.html ├── index.html ├── js │ ├── alerta.js │ └── sessao.js ├── login.html └── simulador.html └── src ├── controllers ├── aquarioController.js ├── avisoController.js ├── empresaController.js ├── medidaController.js └── usuarioController.js ├── database ├── config.js └── script-tabelas.sql ├── models ├── aquarioModel.js ├── avisoModel.js ├── empresaModel.js ├── medidaModel.js └── usuarioModel.js └── routes ├── aquarios.js ├── avisos.js ├── empresas.js ├── index.js ├── medidas.js └── usuarios.js /.env: -------------------------------------------------------------------------------- 1 | AMBIENTE_PROCESSO=producao 2 | 3 | # Configurações de conexão com o banco de dados 4 | DB_HOST='seusDadosAqui' 5 | DB_DATABASE='seusDadosAqui' 6 | DB_USER='seusDadosAqui' 7 | DB_PASSWORD='seusDadosAqui' 8 | DB_PORT='seusDadosAqui' 9 | 10 | # Configurações do servidor de aplicação 11 | APP_PORT=8080 12 | APP_HOST=localhost 13 | 14 | # importante: caso sua senha contenha caracteres especiais, insira-a entre 'aspas' 15 | -------------------------------------------------------------------------------- /.env.dev: -------------------------------------------------------------------------------- 1 | AMBIENTE_PROCESSO=desenvolvimento 2 | 3 | # Configurações de conexão com o banco de dados 4 | DB_HOST=localhost 5 | DB_DATABASE='seusDadosAqui' 6 | DB_USER='seusDadosAqui' 7 | DB_PASSWORD='seusDadosAqui' 8 | DB_PORT=3306 9 | 10 | # Configurações do servidor de aplicação 11 | APP_PORT=3333 12 | APP_HOST=localhost 13 | 14 | # importante: caso sua senha contenha caracteres especiais, insira-a entre 'aspas' 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # A linha abaixo determina que o diretório node_modules não será enviado ao repositório remoto 2 | node_modules 3 | package-lock.json 4 | 5 | .github 6 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/PASSO_A_PASSO_ADICIONAR_UPLOAD_DE_IMAGENS_AO_PROJETO.md: -------------------------------------------------------------------------------- 1 | Caso você queira adicionar a funcionalidade de "upload de imagens" no seu projeto, você pode: 2 | 3 | - OPÇÃO 1 - Criar uma coluna no banco de dados com tipo VARCHAR que irá receber a URL da sua imagem, como por exemplo " http: // meusite. com/ minhaimagem .png". Assim o campo que será preenchido pelo usuário será uma input de texto. 4 | - Prós: Simples de implementar, uma vez que os campos de login e cadastro também são assim. 5 | - Contras: Seu usuário precisará ter a URL da imagem desejada. 6 | - OPÇÃO 2 - Possibilitar o upload das imagens a um diretório no seu próprio projeto, seguindo: [exemplo_de_upload_de_arquivo](https://github.com/BandTec/web-data-viz/tree/main/DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo) 7 | - Prós: Esta implementação simula que há um diretório específico para arquivos multimídia, o que é uma prática de mercado, podendo usar já o conceito de "buckets". 8 | - Contras: Seu repositório pode ficar "pesado", fazendo com que seu git clone fique demorado. Arquivos de imagens e vídeos tendem a ter mais bytes de tamanho, chegando a MBs (megabytes) ou até GBs (gigabytes). 9 | - OPÇÃO 3 - NÃO RECOMENDADO - Criar uma coluna no banco de dados com tipo BLOB (Binary Large Object) que irá receber o arquivo de mídia 10 | - Prós: Você irá pesquisar algo novo. 11 | - Contras: Nem todos os Bancos de Dados suportam este tipo de dado. Trazer a imagem do banco para exibi-la na sua tela pode ser trabalhoso demais e te atrasar em relação a outros entregáveis. 12 | 13 | **Não há a "melhor opção" e nenhuma destas opções "vale mais pontos" ou "seu projeto vai necessariamente ficar melhor porque você escolheu tal opção".** 14 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/PASSO_A_PASSO_CRIAR_ROTA_NA_API.md: -------------------------------------------------------------------------------- 1 | # CRIAR ROTA NA API 2 | 3 | No contexto de Programação WEB, uma "rota" será o nome que daremos aos nossos Endpoints. 4 | Endpoints são as funções disponíveis em nossa API, que aceitam parâmetros e devolvem dados ao cliente que os requisitou. [1] 5 | 6 | Para criar uma nova rota na API, siga esse caminho: 7 | 8 | ### Para esse exemplo, irei criar um cadastro e consulta de carros. 9 | 10 | ### Importando arquivo que contém as rotas 11 | 12 | Abra o arquivo app.js, que fica na raiz diretório **site** e adicione uma linha que contenha uma variável que vai receber o caminho do arquivo da rota que você irá usar! No meu caso vai ficar da seguinte forma: 13 | 14 | ```jsx 15 | var carrosRouter = require("./src/routes/carros"); 16 | ``` 17 | 18 | Abaixo é como deve ficar o arquivo app.js, importando o arquivo **carros.js** da pasta **routes**: 19 | 20 | ```jsx 21 | var app = express(); 22 | 23 | var indexRouter = require("./src/routes/index"); 24 | var usuarioRouter = require("./src/routes/usuarios"); 25 | var avisosRouter = require("./src/routes/avisos"); 26 | var medidasRouter = require("./src/routes/medidas"); 27 | var carrosRouter = require("./src/routes/carros"); 28 | ``` 29 | 30 | ### Criando uma porta de entrada na api 31 | 32 | Ainda na app.js, com a importação criada, é possível criarmos uma “rota”! Como seria? Irei descer mais um pouco o arquivo e iremos nos deparar com o seguinte código e irei adicionar uma “rota” nova para a minha API: 33 | 34 | ```jsx 35 | app.use(cors()); 36 | 37 | app.use("/", indexRouter); 38 | app.use("/usuarios", usuarioRouter); 39 | app.use("/avisos", avisosRouter); 40 | app.use("/medidas", medidasRouter); 41 | app.use("/carros", carrosRouter); 42 | ``` 43 | 44 | **Pode perceber que logo depois de /medidas eu adicionei um /carros e chamei a carrosRouter importada anteriormente!** 45 | 46 | ### Criando arquivo de rota 47 | 48 | Logo após ter feito a primeira “porta de entrada” da nossa API, quando um front-end for acessar essa nossa rota, ele deve colocar /carros/**algumaCoisa**, o que seria esse “alguma coisa”? Dentro de api-site -> src -> routes, irei criar um novo arquivo chamado carros.js que é nesse arquivo que eu importo no [passo 1. Importando arquivo que contém as rotas](about:blank#importando-arquivo-que-cont%C3%A9m-as-rotas) 49 | 50 | No arquivo carros.js dentro do diretório routes. 51 | 52 | **Configuração padrão para indicar o uso da biblioteca do node para criação:** 53 | 54 | ```jsx 55 | var express = require("express"); 56 | var router = express.Router(); 57 | ``` 58 | 59 | **Importando a controller que vai ser criada posteriormente:** 60 | 61 | ```jsx 62 | var carroController = require("../controllers/carroController"); 63 | ``` 64 | 65 | **Criando a rota que vai indicar /carros/cadastrar ao ser acessada pelo front-end. O /cadastrar é do tipo post e o /listar é do tipo get:** 66 | 67 | ```jsx 68 | router.post("/cadastrar", function (req, res) { 69 | // função a ser chamada quando acessar /carros/cadastrar 70 | carroController.cadastrar(req, res); 71 | }); 72 | 73 | router.get("/listar", function (req, res) { 74 | // função a ser chamada quando acessar /carros/listar 75 | carroController.listar(req, res); 76 | }); 77 | ``` 78 | 79 | **Sempre devemos deixar visível (exportar) para outro que assim outro arquivo consiga importar todas as nossas configurações desse arquivo:** 80 | 81 | ```jsx 82 | module.exports = router; 83 | ``` 84 | 85 | Ao final de tudo, teremos o arquivo com essa estrutura: 86 | 87 | ```jsx 88 | var express = require("express"); 89 | var router = express.Router(); 90 | 91 | var carroController = require("../controllers/carroController"); 92 | 93 | router.post("/cadastrar", function (req, res) { 94 | // função a ser chamada quando acessar /carros/cadastrar 95 | carroController.cadastrar(req, res); 96 | }); 97 | 98 | router.get("/listar", function (req, res) { 99 | // função a ser chamada quando acessar /carros/listar 100 | carroController.listar(req, res); 101 | }); 102 | 103 | module.exports = router; 104 | ``` 105 | 106 | ### Criando arquivo controller 107 | 108 | Dentro de api-site -> src -> controller, crie um arquivo chamado carroController.js. 109 | 110 | Dentro do arquivo carroController.js coloque a **carroModel** que fará a conexão com o banco: 111 | 112 | ```jsx 113 | var carroModel = require("../models/carroModel"); 114 | ``` 115 | 116 | Cria a função que vai ser chamada no passo de cima e exporta ela. No final ficará assim: 117 | 118 | ```jsx 119 | var carroModel = require("../models/carroModel"); 120 | 121 | function listar(req, res) { 122 | carroModel.listar().then(function(resultado){ 123 | // precisamos informar que o resultado voltará para o front-end como uma resposta em json 124 | res.status(200).json(resultado); 125 | }).catch(function(erro){ 126 | res.status(500).json(erro.sqlMessage); 127 | }) 128 | } 129 | 130 | function cadastrar(req, res) { 131 | var nome = req.body.nome; 132 | 133 | if (nome == undefined) { 134 | res.status(400).send("Seu nome está undefined!"); 135 | } 136 | 137 | carroModel.cadastrar(nome).then(function(resposta){ 138 | res.status(200).send("Carro criado com sucesso"); 139 | }).catch(function(erro){ 140 | res.status(500).json(erro.sqlMessage); 141 | }) 142 | } 143 | 144 | module.exports = { 145 | listar, 146 | cadastrar 147 | } 148 | ``` 149 | 150 | **Sempre exportando a função que eu criar para poder ser “enxergada” por outro arquivo.** 151 | 152 | ### Criando arquivo models 153 | 154 | Dentro de api-site -> src -> models, crie um arquivo chamado carroModel.js 155 | 156 | Dentro do arquivo importamos a configuração do banco para fazer consultas futuras no banco: 157 | 158 | ```jsx 159 | var database = require("../database/config") 160 | ``` 161 | 162 | Aqui podemos criar a função que fará a comunicação com o banco de dados, onde ela recebe o paramêtro nome e executa uma query de insert com o valor desse nome: 163 | 164 | ```jsx 165 | function listar() { 166 | var instrucao = ` 167 | SELECT * FROM carro; 168 | `; 169 | console.log("Executando a instrução SQL: \n" + instrucao); 170 | return database.executar(instrucao); 171 | } 172 | 173 | function cadastrar(nome) { 174 | var instrucao = ` 175 | INSERT INTO carro (nome) VALUES ('${nome}'); 176 | `; 177 | console.log("Executando a instrução SQL: \n" + instrucao); 178 | return database.executar(instrucao); 179 | } 180 | ``` 181 | 182 | **Sem esquecer de exportar as funções que criamos para serem vistas por outros arquivos** 183 | 184 | ```jsx 185 | module.exports = { 186 | cadastrar, 187 | listar 188 | }; 189 | ``` 190 | 191 | E por fim teremos o arquivo completo com isso: 192 | 193 | ```jsx 194 | var database = require("../database/config") 195 | 196 | function listar() { 197 | var instrucao = ` 198 | SELECT * FROM carro; 199 | `; 200 | console.log("Executando a instrução SQL: \n" + instrucao); 201 | return database.executar(instrucao); 202 | } 203 | 204 | function cadastrar(nome) { 205 | var instrucao = ` 206 | INSERT INTO carro (nome) VALUES ('${nome}'); 207 | `; 208 | console.log("Executando a instrução SQL: \n" + instrucao); 209 | return database.executar(instrucao); 210 | } 211 | 212 | module.exports = { 213 | cadastrar, 214 | listar 215 | }; 216 | ``` 217 | 218 | ### Fontes bibliográficas 219 | 220 | [1] https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/ 221 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_criacao_grafico_estatico/EXEMPLO-GRAFICO-ESTATICO.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Exemplo de como Plotar Gráficos 7 | 8 | 9 | 10 | 11 | 12 | 13 | Gráfico de linhas 14 |
15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_quiz/EXEMPLO_QUIZZ.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Exemplo - Quiz 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 |
17 |
18 | Quantidade de acertos: 19 | Quantidade de erros: 20 |
21 |
22 | Pontuação Final: 23 | *** 24 | 25 | *** 26 |
27 |
28 | 29 |
30 | 31 |
32 | Questão atual: de 33 | questões. 34 |
35 | 36 |
37 | 38 |
39 | 40 |
41 | Escolha uma opção dentre as abaixo: 42 |
43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 | 63 |
64 | 65 | 66 | 67 | 68 |
69 | 70 |
71 |
72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_quiz/style.css: -------------------------------------------------------------------------------- 1 | /* Não usar pure white or pure black: https://uxplanet.org/basicdesign-never-use-pure-black-in-typography-36138a3327a6 */ 2 | /* The 4-point grid system: https://medium.com/@sainzkike/controlling-spacing-in-design-systems-multiple-spacing-9bf1afec87f */ 3 | 4 | :root { 5 | --primary-brand-color: #ED145B; 6 | --secondary-brand-color: #0762C8; 7 | --success: #198754; 8 | --success-dark: #095c36; 9 | --success-light: #9dd3ba; 10 | --warning: #ffc107; 11 | --warning-dark: #705400; 12 | --warning-light: #fdebb3; 13 | --danger: #dc3545; 14 | --danger-dark: #990c19; 15 | --danger-light: #f0c1c6; 16 | --new-gray: #CCCCCC; 17 | --new-black: #212427; 18 | --new-white: #E8E8E8; 19 | } 20 | 21 | body { 22 | color: var(--new-black); 23 | background-color: var(--new-white); 24 | font-family: Verdana, Geneva, Tahoma, sans-serif; 25 | } 26 | 27 | button { 28 | font-family: monospace; 29 | font-weight: bold; 30 | } 31 | 32 | .flex-colunar { 33 | display: flex; 34 | flex-direction: column; 35 | } 36 | 37 | .width-fit-content { 38 | width: fit-content; 39 | } 40 | 41 | .border-primary { 42 | border: 3px solid var(--primary-brand-color); 43 | } 44 | 45 | .border-secondary { 46 | border: 3px solid var(--secondary-brand-color); 47 | } 48 | 49 | .padding-8 { 50 | padding: 8px; 51 | } 52 | 53 | .text-bold { 54 | font-weight: bold; 55 | } 56 | 57 | .text-success-with-bg { 58 | color: var(--success-dark); 59 | background-color: var(--success-light); 60 | } 61 | 62 | .text-warning-with-bg { 63 | color: var(--warning-dark); 64 | background-color: var(--warning-light); 65 | } 66 | 67 | .text-danger-with-bg { 68 | color: var(--danger-dark); 69 | background-color: var(--danger-light); 70 | } 71 | 72 | .text-new-gray { 73 | color: var(--new-gray); 74 | } -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | public/assets -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Fernanda Caramico 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/README.md: -------------------------------------------------------------------------------- 1 | _Implementação de referência de como fazer upload de arquivos e salvar **Local**_ 2 | 3 | # Como usar 4 | 5 | 1. Clone este repositório em sua máquina. 6 | 7 | 8 | 1. Crie, no Banco de Dados, as tabelas necessárias para o funcionamento deste projeto. 9 | - Siga as instruções no arquivo **/site/src/database/script-tabelas.sql** 10 | 11 | 12 | 3. Adicione as credenciais de Banco de Dados no arquivo **/site/src/database/config.js**, seguindo as instruções neste. 13 | 14 | 4. Execute os comandos abaixo: 15 | 16 | ``` 17 | npm i 18 | ``` 19 | _O comando acima irá instalar as bibliotecas necessárias para o funcionamento do projeto. As bibliotecas a serem instaladas estão listadas no arquivo **package.json** então é muito importante que este não seja alterado. Será criada uma nova pasta/diretório chamado **node_modules** quando o comando for finalizado, que é onde as bibliotecas estão localizadas. Não altere a pasta/diretório._ 20 | 21 | ``` 22 | npm start 23 | ``` 24 | 25 | _O comando acima irá iniciar seu projeto e efetuar os comandos de acordo com a sua parametrização feita nos passos anteriores._ 26 | 27 | 6. Para "ver" seu projeto funcionando, acesse em seu navegador o caminho **informado no terminal**. 28 | 29 | 7. Caso queira parar a execução, tecle **CTRL+C** no terminal em que o projeto está rodando. 30 | 31 | 32 | # Como implementar no seu próprio projeto 33 | 34 | 1. Você deve adicionar no seu projeto a dependência multer: 35 | 36 | ``` 37 | npm install multer 38 | ``` 39 | 40 | 2. Criar o arquivo de configuração do multer. 41 | - Exemplo de configuração: [configUpload.js](https://github.com/fernandacaramico/exemplo-upload-imagem-local/blob/main/src/config/configUpload.js) 42 | 43 | 3. Criar uma rota para receber o upload. 44 | - Exemplo de rota: [usuarioRouter.js](https://github.com/fernandacaramico/exemplo-upload-imagem-local/blob/main/src/routes/usuarioRouter.js) 45 | 46 | _Este projeto foi desenvolvido por [@WilliamMN](https://github.com/WilliamMN/)_ -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const cors = require('cors'); 3 | const path = require('path'); 4 | const PORTA = 3000; 5 | 6 | const app = express(); 7 | 8 | const usuarioRouter = require("./src/routes/usuarioRouter"); 9 | 10 | app.use(express.json()); 11 | app.use(express.urlencoded({ extended: true })); 12 | app.use(express.static(path.join(__dirname, "public"))); 13 | 14 | app.use(cors()); 15 | 16 | app.use("/usuarios", usuarioRouter); 17 | 18 | app.listen(PORTA, () => { 19 | console.log(`Servidor do seu site já está rodando! Acesse o caminho a seguir para visualizar: http://localhost:${PORTA}`); 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upload-teste", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node app.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cors": "^2.8.5", 14 | "express": "^4.18.2", 15 | "multer": "^1.4.5-lts.1", 16 | "mysql2": "^3.3.0", 17 | "path": "^0.12.7" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Upload 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/public/perfil.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/src/config/configUpload.js: -------------------------------------------------------------------------------- 1 | const multer = require('multer'); 2 | 3 | // Diretório onde os arquivos serão salvos 4 | // ATENÇÃO: É necessário manter o diretório 'public' para poder utilizar no front-end 5 | const diretorio = 'public/assets/'; 6 | 7 | const storage = multer.diskStorage({ 8 | destination: (req, file, cb) => { 9 | cb(null, diretorio) 10 | }, 11 | 12 | filename: (req, file, cb) => { 13 | const extensaoArquivo = file.originalname.split('.')[1]; 14 | 15 | const novoNomeArquivo = require('crypto') 16 | .randomBytes(64) 17 | .toString('hex'); 18 | 19 | 20 | cb(null, `${novoNomeArquivo}.${extensaoArquivo}`) 21 | } 22 | }); 23 | 24 | module.exports = multer({ storage }); -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/src/controllers/usuarioController.js: -------------------------------------------------------------------------------- 1 | const usuarioModel = require('../models/usuarioModel'); 2 | 3 | 4 | function salvar(req, res) { 5 | const imagem = req.file.filename; 6 | 7 | const {nome, email} = req.body 8 | 9 | const usuario = { nome, email, imagem } 10 | 11 | usuarioModel.salvar(usuario) 12 | .then(resultado => { 13 | res.status(201).send("Usuario criado com sucesso"); 14 | }).catch(err => { 15 | res.status(500).send(err); 16 | }); 17 | } 18 | 19 | function buscarUsuarioPeloId(req, res) { 20 | console.log(req.params.id); 21 | usuarioModel.buscarUsuarioPeloId(req.params.id) 22 | .then(resultado => { 23 | res.json(resultado); 24 | }).catch(err => { 25 | res.status(500).send(err); 26 | }); 27 | } 28 | 29 | module.exports = { salvar, buscarUsuarioPeloId } -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/src/database/config.js: -------------------------------------------------------------------------------- 1 | const mysql = require("mysql2"); 2 | 3 | // CONEXÃO DO MYSQL WORKBENCH (LOCAL) 4 | const mySqlConfig = { 5 | host: "SEU_SERVIDOR", 6 | database: "SEU_BANCO_DE_DADOS", 7 | user: "SEU_USUARIO", 8 | password: "SUA_SENHA", 9 | } 10 | 11 | function executar(instrucao) { 12 | return new Promise(function (resolve, reject) { 13 | var conexao = mysql.createConnection(mySqlConfig); 14 | conexao.connect(); 15 | conexao.query(instrucao, function (erro, resultados) { 16 | conexao.end(); 17 | if (erro) { 18 | reject(erro); 19 | } 20 | console.log(resultados); 21 | resolve(resultados); 22 | }); 23 | conexao.on('error', function (erro) { 24 | return ("ERRO NO MySQL WORKBENCH (Local): ", erro.sqlMessage); 25 | }); 26 | }); 27 | } 28 | 29 | module.exports = { executar } -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/src/database/script-exemplo-criacao.sql: -------------------------------------------------------------------------------- 1 | -- Arquivo de apoio, caso você queira criar tabelas como as aqui criadas para a API funcionar. 2 | -- Você precisa executar os comandos no banco de dados para criar as tabelas, 3 | -- ter este arquivo aqui não significa que a tabela em seu BD estará como abaixo! 4 | 5 | /* 6 | comandos para mysql - banco local 7 | */ 8 | 9 | create database exemplo_upload; 10 | use exemplo_upload; 11 | 12 | create table usuario ( 13 | id int primary key auto_increment, 14 | nome varchar(45), 15 | email varchar(45), 16 | imagem_perfil varchar(255) 17 | ) -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/src/models/usuarioModel.js: -------------------------------------------------------------------------------- 1 | const database = require("../database/config"); 2 | 3 | function salvar(usuario) { 4 | const instrucao = `insert into usuario (nome, email, imagem_perfil) values ('${usuario.nome}', '${usuario.email}', '${usuario.imagem}')`; 5 | 6 | return database.executar(instrucao); 7 | } 8 | 9 | function buscarUsuarioPeloId(id) { 10 | const instrucao = `select * from usuario where id = ${id}`; 11 | 12 | return database.executar(instrucao); 13 | } 14 | 15 | module.exports = { salvar, buscarUsuarioPeloId } -------------------------------------------------------------------------------- /DOCUMENTOS_DE_APOIO/exemplo_de_upload_de_arquivo/src/routes/usuarioRouter.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const upload = require('../config/configUpload'); // ARQUIVO COM A CONFIGURAÇÃO DO UPLOAD 4 | const usuarioController = require('../controllers/usuarioController'); 5 | 6 | router.get("", (req, res) => { 7 | res.render("index") 8 | }); 9 | 10 | // upload.single('foto') vai buscar no json alguma propriedade chamada foto 11 | router.post('/cadastro', upload.single('foto'), (req, res) => { 12 | usuarioController.salvar(req, res); 13 | }); 14 | 15 | router.get('/:id', upload.single('foto'), (req, res) => { 16 | usuarioController.buscarUsuarioPeloId(req, res); 17 | }); 18 | 19 | module.exports = router; 20 | 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 BandTec Digital School - agora é São Paulo Tech School 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | _Web Data Visualization = Visualização de Dados na Web_ 4 | 5 | _Implementação de Referência para o seu Projeto de Primeiro Semestre_ 6 | 7 |
8 | 9 | # Como usar 10 | 11 | 1. Clone este repositório em sua máquina. 12 | 13 | 14 | 1. Crie, no Banco de Dados, as tabelas necessárias para o funcionamento deste projeto. 15 | - Siga as instruções no arquivo **/src/database/script-tabelas.sql** 16 | 17 | 18 | 3. Acesse o arquivo **app.js** e parametrize o ambiente. 19 | - Se você estiver utilizando o Ambiente de Produção (remoto), comente a linha 2 e deixe habilitada a linha 1 onde está o valor **var ambiente_processo = 'producao';** 20 | - Se você estiver utilizando o Ambiente de Desenvolvimento (local), comente a linha 1 e deixe habilitada a linha 2 onde está o valor **var ambiente_processo = 'desenvolvimento';** 21 | 22 | 4. Adicione as credenciais de Banco de Dados no arquivo **.env** ou em **.env.dev**, seguindo as instruções neste. 23 | 24 | 5. Acesse este repositório no seu terminal (GitBash ou VSCode) e execute os comandos abaixo: 25 | 26 | ``` 27 | npm i 28 | ``` 29 | _O comando acima irá instalar as bibliotecas necessárias para o funcionamento do projeto. As bibliotecas a serem instaladas estão listadas no arquivo **package.json** então é muito importante que este não seja alterado. Será criada uma nova pasta/diretório chamado **node_modules** quando o comando for finalizado, que é onde as bibliotecas estão localizadas. Não altere a pasta/diretório._ 30 | 31 | ``` 32 | npm start 33 | ``` 34 | 35 | _O comando acima irá iniciar seu projeto e efetuar os comandos de acordo com a sua parametrização feita nos passos anteriores._ 36 | 37 | 6. Para "ver" seu projeto funcionando, acesse em seu navegador o caminho **informado no terminal**. 38 | 39 | 7. Caso queira parar a execução, tecle **CTRL+C** no terminal em que o projeto está rodando. 40 | 41 | ## Adicionar novo recurso ao projeto 42 | 43 | **"Recurso? O que é?"** Enquanto no Banco de Dados chamamos as tabelas de "entidades", quando tratamos de desenvolvimento WEB usamos a palavra "recurso" para se referir a algo que podemos criar, ler, atualizar ou deletar [1]. Estas ações são conhecidas como CRUD: Create, Read, Update e Delete. Para acessar cada ação, usamos os métodos HTTP: POST, GET, PUT e DELETE [2]. (Há outros verbos, porém com estes já conseguimos efetuar CRUDs). 44 | 45 | **Tabela para ajudar a fazer a associação** 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
C.R.U.DAçãoTraduçãoVerbo HTTP *Comando BD
CCreateCriarPOSTINSERT
RReadLerGETSELECT
UUpdateAtualizarPUTUPDATE
DDeleteDeletarDELETEDELETE
84 | 85 | _* Você verá o verbo HTTP sendo apontado nos arquivos em /routes_ 86 | 87 | **"E no meu projeto, o que seria um recurso?"** Em web-data-viz manipulamos os recursos **usuário**, **aviso** e **medida**. Podemos conferir isso vendo para quais entidades foram criados os caminhos de inserção e captura de dados, que envolve os diretórios **routes**, **controllers** e **models**. 88 | 89 | Abaixo, uma figura que ajuda a compreender o caminho percorrido para, por exemplo, efetuar o cadastro de um usuário: 90 | 91 | 92 | ![image](https://github.com/BandTec/web-data-viz/assets/46379117/e8d63551-6153-4632-93b9-f59a1d2afd3e) 93 | 94 | 95 | **Entendi o que é um recurso e gostaria de adicionar um novo ao meu projeto! Como faz?** 96 | - Primeiro, crie a tabela no Banco de Dados referente a este recurso. Exemplos de recursos comuns de serem adicionados ao projeto no primeiro semestre: Silo, Aquário, Sala, Andar, Endereço, Mercado, Prateleira, Unidade, Carro, Caminhão... 97 | - Assim que criada a tabela, faça todo o caminho de **front-end → routes → controllers → models** replicando o que já existe! 98 | - Exemplo, se você quiser a funcionalidade de adicionar um novo Aquário, deve criar arquivos referentes ao aquario nos diretórios e replicar também as funções. 99 | - Dica: A implementação de AVISO já contém o CRUD completo! :wink: 100 | 101 | ### Fontes bibliográficas 102 | 103 | [1] https://datatracker.ietf.org/doc/html/rfc2396 104 | [2] https://datatracker.ietf.org/doc/html/rfc7231 105 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | // var ambiente_processo = 'producao'; 2 | var ambiente_processo = 'desenvolvimento'; 3 | 4 | var caminho_env = ambiente_processo === 'producao' ? '.env' : '.env.dev'; 5 | // Acima, temos o uso do operador ternário para definir o caminho do arquivo .env 6 | // A sintaxe do operador ternário é: condição ? valor_se_verdadeiro : valor_se_falso 7 | 8 | require("dotenv").config({ path: caminho_env }); 9 | 10 | var express = require("express"); 11 | var cors = require("cors"); 12 | var path = require("path"); 13 | var PORTA_APP = process.env.APP_PORT; 14 | var HOST_APP = process.env.APP_HOST; 15 | 16 | var app = express(); 17 | 18 | var indexRouter = require("./src/routes/index"); 19 | var usuarioRouter = require("./src/routes/usuarios"); 20 | var avisosRouter = require("./src/routes/avisos"); 21 | var medidasRouter = require("./src/routes/medidas"); 22 | var aquariosRouter = require("./src/routes/aquarios"); 23 | var empresasRouter = require("./src/routes/empresas"); 24 | 25 | app.use(express.json()); 26 | app.use(express.urlencoded({ extended: false })); 27 | app.use(express.static(path.join(__dirname, "public"))); 28 | 29 | app.use(cors()); 30 | 31 | app.use("/", indexRouter); 32 | app.use("/usuarios", usuarioRouter); 33 | app.use("/avisos", avisosRouter); 34 | app.use("/medidas", medidasRouter); 35 | app.use("/aquarios", aquariosRouter); 36 | app.use("/empresas", empresasRouter); 37 | 38 | app.listen(PORTA_APP, function () { 39 | console.log(` 40 | ## ## ###### ##### #### ## ###### ## ## ## #### ###### 41 | ## ## ## ## ## ## ## #### ## #### ## ## ## ## 42 | ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## 43 | ## # ## #### ##### ###### ## ## ###### ## ###### ###### ## ## ## ## 44 | ####### ## ## ## ## ## ## ## ## ## ## ## ## ## ## 45 | ### ### ## ## ## ## ## ## ## ## ## ## #### ## ## 46 | ## ## ###### ##### #### ## ## ## ## ## ## #### ###### 47 | \n\n\n 48 | Servidor do seu site já está rodando! Acesse o caminho a seguir para visualizar .: http://${HOST_APP}:${PORTA_APP} :. \n\n 49 | Você está rodando sua aplicação em ambiente de .:${process.env.AMBIENTE_PROCESSO}:. \n\n 50 | \tSe .:desenvolvimento:. você está se conectando ao banco local. \n 51 | \tSe .:producao:. você está se conectando ao banco remoto. \n\n 52 | \t\tPara alterar o ambiente, comente ou descomente as linhas 1 ou 2 no arquivo 'app.js'\n\n`); 53 | }); 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-data-viz", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node app.js", 8 | "dev": "nodemon --exec node app.js" 9 | }, 10 | "author": "Feito pelos desenvolvedores @ São Paulo Tech School / Bandtec Digital School", 11 | "license": "MIT", 12 | "dependencies": { 13 | "cors": "^2.8.5", 14 | "dotenv": "^16.4.5", 15 | "express": "^4.17.1", 16 | "mysql2": "^3.9.4", 17 | "nodemon": "^2.0.7", 18 | "path": "^0.12.7" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/assets/aguarde-orange.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/aguarde-orange.gif -------------------------------------------------------------------------------- /public/assets/aguarde-pink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/aguarde-pink.gif -------------------------------------------------------------------------------- /public/assets/aguarde-pink2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/aguarde-pink2.gif -------------------------------------------------------------------------------- /public/assets/aguarde-pink3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/aguarde-pink3.gif -------------------------------------------------------------------------------- /public/assets/circle-loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/circle-loading.gif -------------------------------------------------------------------------------- /public/assets/icon/favicon2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/icon/favicon2.ico -------------------------------------------------------------------------------- /public/assets/icon/favicon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/icon/favicon2.png -------------------------------------------------------------------------------- /public/assets/imgs/av1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/av1.png -------------------------------------------------------------------------------- /public/assets/imgs/av2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/av2.png -------------------------------------------------------------------------------- /public/assets/imgs/av3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/av3.png -------------------------------------------------------------------------------- /public/assets/imgs/av4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/av4.png -------------------------------------------------------------------------------- /public/assets/imgs/av5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/av5.png -------------------------------------------------------------------------------- /public/assets/imgs/banner-fundo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/banner-fundo.jpeg -------------------------------------------------------------------------------- /public/assets/imgs/bg-jelly-fish-para-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/bg-jelly-fish-para-home.png -------------------------------------------------------------------------------- /public/assets/imgs/bg-jelly-fish-para_outras_pags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/bg-jelly-fish-para_outras_pags.png -------------------------------------------------------------------------------- /public/assets/imgs/growth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/growth.png -------------------------------------------------------------------------------- /public/assets/imgs/growth_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/growth_color.png -------------------------------------------------------------------------------- /public/assets/imgs/imagem-apoio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/imagem-apoio.png -------------------------------------------------------------------------------- /public/assets/imgs/lightbulb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/lightbulb.png -------------------------------------------------------------------------------- /public/assets/imgs/lightbulb_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/lightbulb_color.png -------------------------------------------------------------------------------- /public/assets/imgs/missao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/missao.png -------------------------------------------------------------------------------- /public/assets/imgs/pessoa1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/pessoa1.png -------------------------------------------------------------------------------- /public/assets/imgs/pessoa2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/pessoa2.png -------------------------------------------------------------------------------- /public/assets/imgs/pessoa3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/pessoa3.png -------------------------------------------------------------------------------- /public/assets/imgs/planet-earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/planet-earth.png -------------------------------------------------------------------------------- /public/assets/imgs/planet-earth_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/planet-earth_color.png -------------------------------------------------------------------------------- /public/assets/imgs/side-img-contato.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/side-img-contato.png -------------------------------------------------------------------------------- /public/assets/imgs/valores.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/valores.png -------------------------------------------------------------------------------- /public/assets/imgs/visao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BandTec/web-data-viz/8ccedf197a7d65bd8ccb685573f506f1d02f163c/public/assets/imgs/visao.png -------------------------------------------------------------------------------- /public/cadastro.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Cadastro 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |

AquaTech

23 | 38 |
39 |
40 | 41 | 42 |
43 |
44 |
45 | 46 |
47 |
48 |
49 |
50 |

Bem-vindo!

51 |
52 | 56 |
57 | Código de ativação: 58 | 59 |
60 |
61 | Nome: 62 | 63 |
64 |
65 | E-mail: 66 | 67 |
68 |
69 | Senha: 70 | 71 |
72 |
73 | Confirmação da Senha: 74 | 75 |
76 | 77 |
78 |
79 | 80 |
81 | 82 |
83 |
84 |
85 |
86 | 87 | 88 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /public/css/dashboards.css: -------------------------------------------------------------------------------- 1 | /* pagina mural */ 2 | 3 | @import url('https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); 4 | 5 | body { 6 | margin: 0; 7 | padding: 0; 8 | font-family: 'Barlow', 'Segoe UI', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 9 | } 10 | 11 | .label-captura { 12 | display: flex; 13 | justify-content: center; 14 | } 15 | 16 | .dash-right .avisos { 17 | width: 100%; 18 | color: rgb(216, 216, 216); 19 | font-family: 'Barlow', 'Segoe UI', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 20 | } 21 | 22 | .dash-right .avisos .container { 23 | display: flex; 24 | flex-direction: column; 25 | align-items: center; 26 | } 27 | 28 | .dash-right .avisos .container .div-form { 29 | width: 95%; 30 | } 31 | 32 | .dash-right .avisos .container .div-form #form_postagem { 33 | width: 95%; 34 | } 35 | 36 | .dash-right .avisos .div-form label { 37 | width: 95%; 38 | } 39 | 40 | .dash-right .avisos .div-form input { 41 | width: 95%; 42 | border-radius: 5px; 43 | } 44 | 45 | .dash-right .avisos .div-form textarea { 46 | width: 95%; 47 | border: 3px solid #e6005a; 48 | background-color: white; 49 | border-radius: 5px; 50 | } 51 | 52 | .dash-right .avisos .div-form button { 53 | cursor: pointer; 54 | font-family: 'Barlow', 'Segoe UI', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 55 | border: 0; 56 | border-radius: 5px; 57 | font-weight: 600; 58 | font-size: 18px; 59 | padding: 10px 15px; 60 | color: white; 61 | background-color: #e6005a; 62 | width: 120px; 63 | } 64 | 65 | .publicacao-btn-editar { 66 | cursor: pointer; 67 | font-family: 'Barlow', 'Segoe UI', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 68 | border: 0; 69 | border-radius: 5px; 70 | font-weight: 600; 71 | font-size: 14px; 72 | padding: 5px 8px; 73 | color: white; 74 | background-color: #e6005a; 75 | width: 80px; 76 | } 77 | 78 | .publicacao { 79 | display: flex; 80 | flex-wrap: wrap; 81 | align-content: stretch; 82 | flex-direction: column; 83 | justify-content: center; 84 | align-items: stretch; 85 | border-bottom: 3px solid #e6005a; 86 | padding: 20px; 87 | } 88 | 89 | .publicacao>*:not(:last-child) { 90 | padding: 0 0 10px 0; 91 | } 92 | 93 | .div-results { 94 | width: 100%; 95 | } 96 | 97 | .div-results .feed-container { 98 | background-color: #212124; 99 | border-radius: 5px; 100 | margin-bottom: 80px; 101 | } 102 | 103 | .div-buttons { 104 | display: flex; 105 | justify-content: flex-end; 106 | } 107 | 108 | .div-buttons>* { 109 | margin-left: 30px; 110 | } 111 | 112 | /* pagina graficos */ 113 | 114 | .dash-header { 115 | background-color: #212124; 116 | } 117 | 118 | .dash { 119 | width: 80%; 120 | position: relative; 121 | top: 0; 122 | left: 20%; 123 | background-color: #161618; 124 | height: 100vh; 125 | overflow: auto; 126 | } 127 | 128 | .area-parametros-alerta { 129 | /* border: 2px solid pink; */ 130 | display: flex; 131 | flex-direction: column; 132 | width: 70%; 133 | margin: auto; 134 | margin-top: 10px; 135 | background-color: #212124; 136 | } 137 | 138 | .area-parametros-alerta .titulo-legenda { 139 | color: white; 140 | font-weight: 600; 141 | width: fit-content; 142 | margin: 10px 20px; 143 | } 144 | 145 | .parametros-alerta { 146 | display: flex; 147 | width: 100%; 148 | } 149 | 150 | .item-regua { 151 | width: 20%; 152 | text-align: center; 153 | height: 80px; 154 | display: flex; 155 | flex-direction: column; 156 | justify-content: center; 157 | align-self: center; 158 | } 159 | 160 | .item-regua p { 161 | margin: 0; 162 | font-weight: 500; 163 | } 164 | 165 | .item-regua p:nth-child(2) { 166 | font-weight: 800; 167 | } 168 | 169 | .perigo-frio { 170 | background-color: #5c6bc0; 171 | } 172 | 173 | .perigo-quente { 174 | background-color: #ff7043; 175 | } 176 | 177 | .alerta-frio { 178 | background-color: #42a5f5; 179 | } 180 | 181 | .alerta-quente { 182 | background-color: #ffee58; 183 | } 184 | 185 | .ideal { 186 | background-color: #9ccc65; 187 | } 188 | 189 | .cards { 190 | display: flex; 191 | flex-wrap: wrap; 192 | justify-content: center; 193 | height: 450px; 194 | width: 100%; 195 | align-items: center; 196 | color: white; 197 | } 198 | 199 | .card-aquario { 200 | margin: 2%; 201 | min-width: 40%; 202 | max-width: 50%; 203 | width: fit-content; 204 | flex-wrap: wrap; 205 | display: flex; 206 | /* text-align: center; */ 207 | height: 180px; 208 | /* justify-content: right; */ 209 | background-color: #212124; 210 | font-size: 20px; 211 | } 212 | 213 | .card-aquario h1 { 214 | width: fit-content; 215 | } 216 | 217 | .card-aquario p { 218 | margin: 0; 219 | font-size: 50px; 220 | font-weight: lighter; 221 | text-align: left; 222 | } 223 | 224 | .desc-aquario { 225 | display: flex; 226 | flex-direction: row; 227 | align-items: center; 228 | width: 100%; 229 | } 230 | 231 | .desc-aquario .cor-alerta { 232 | width: 30px; 233 | } 234 | 235 | .title-aquario { 236 | width: 100%; 237 | } 238 | 239 | 240 | .cards h1 { 241 | font-size: 22px; 242 | border-bottom: solid white 1px; 243 | text-align: left; 244 | font-weight: lighter; 245 | margin: 20px; 246 | } 247 | 248 | .temperatura, 249 | .umidade { 250 | margin: 5px; 251 | margin-left: 20px; 252 | width: 75%; 253 | } 254 | 255 | .cor-alerta { 256 | width: 13%; 257 | height: 30%; 258 | border-radius: 50%; 259 | display: inline-block; 260 | } 261 | 262 | .btns-dash { 263 | display: flex; 264 | align-items: center; 265 | justify-content: center; 266 | margin-top: 30px; 267 | flex-wrap: wrap; 268 | padding: 0 30% 0 30%; 269 | } 270 | 271 | .graph { 272 | width: 70%; 273 | margin: auto; 274 | padding-top: 10px; 275 | } 276 | 277 | .tituloGraficos { 278 | color: rgb(216, 216, 216); 279 | display: flex; 280 | justify-content: center; 281 | } 282 | 283 | .btn-chart { 284 | font-family: 'Barlow', 'Segoe UI', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 285 | border: 0; 286 | font-weight: 600; 287 | font-size: 18px; 288 | padding: 10px 15px; 289 | color: #e6005a; 290 | background-color: white; 291 | margin: 5px; 292 | border-radius: 3px; 293 | cursor: pointer 294 | } 295 | 296 | .btn-pink { 297 | color: white; 298 | background-color: #e6005a; 299 | } 300 | 301 | .btn-white { 302 | color: #e6005a; 303 | background-color: white; 304 | 305 | } 306 | 307 | .label-captura { 308 | height: 80px; 309 | } 310 | 311 | .display-none { 312 | display: none; 313 | } 314 | 315 | .display-flex { 316 | display: flex; 317 | } 318 | 319 | .display-block { 320 | display: block; 321 | } 322 | 323 | canvas { 324 | width: 100% !important; 325 | height: 100% !important; 326 | } 327 | 328 | /* PAGINA DOS GRÁFICOS 2023 */ 329 | 330 | .janela { 331 | display: flex; 332 | /* width: 100vw; */ 333 | } 334 | 335 | .header-left a { 336 | text-decoration: none; 337 | color: white; 338 | } 339 | 340 | .header-left { 341 | position: fixed; 342 | top: 0; 343 | left: 0; 344 | z-index: 999; 345 | height: 100vh; 346 | width: 20%; 347 | display: flex; 348 | flex-direction: column; 349 | justify-content: space-evenly; 350 | align-items: center; 351 | border-right: 3px solid #32b9cd; 352 | background-color: #212124; 353 | } 354 | 355 | .dash-right { 356 | display: flex; 357 | width: 70%; 358 | height: fit-content; 359 | background-color: #161618; 360 | position: relative; 361 | top: 0; 362 | left: 25%; 363 | height: 100vh; 364 | overflow: auto; 365 | } 366 | 367 | .header-left h1 { 368 | color: #32b9cd; 369 | } 370 | 371 | .hello { 372 | width: 100%; 373 | display: flex; 374 | justify-content: center; 375 | } 376 | 377 | .hello h3 { 378 | color: #e3b062; 379 | font-weight: 300; 380 | font-size: 1.2rem; 381 | } 382 | 383 | .hello h3 span { 384 | font-weight: 800; 385 | } 386 | 387 | .btn-nav { 388 | width: 40%; 389 | color: white; 390 | background-color: #e6005a; 391 | border-radius: 5px; 392 | text-align: center; 393 | padding: 2% 5%; 394 | } 395 | 396 | .btn-nav-white { 397 | width: 40%; 398 | background-color: white; 399 | border: 3px solid #e6005a; 400 | border-radius: 5px; 401 | text-align: center; 402 | padding: 2% 5%; 403 | } 404 | 405 | .btn-nav-white h3 { 406 | color: #e6005a; 407 | padding: 0; 408 | margin: 0; 409 | } 410 | 411 | .btn-nav h3, 412 | .btn-logout h3 { 413 | margin: 0; 414 | padding: 0; 415 | } 416 | 417 | .btn-logout { 418 | margin: 0; 419 | padding: 0; 420 | width: 20%; 421 | background-color: #32b9cd; 422 | color: white; 423 | border-radius: 10px; 424 | text-align: center; 425 | padding: 10px 15px; 426 | margin-bottom: 100px; 427 | cursor: pointer; 428 | } -------------------------------------------------------------------------------- /public/css/estilo.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); 2 | 3 | body { 4 | margin: 0; 5 | padding: 0; 6 | font-family: 'Barlow', 'Segoe UI', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 7 | background-color: black; 8 | } 9 | 10 | :root { 11 | --tamanho-header: 80px; 12 | --tamanho-banner: calc(100vh - var(--tamanho-header) - var(--tamanho-footer) - 2px); 13 | --tamanho-simulador: calc(100vh - var(--tamanho-header) - var(--tamanho-footer) - 2px); 14 | --tamanho-login: calc(100vh - var(--tamanho-header) - var(--tamanho-footer) - 2px); 15 | --tamanho-footer: 65px; 16 | } 17 | 18 | .container { 19 | display: flex; 20 | width: 80%; 21 | margin: auto; 22 | } 23 | 24 | .header { 25 | height: var(--tamanho-header); 26 | border-bottom: 2px solid #32b9cd; 27 | } 28 | 29 | .header .container { 30 | justify-content: space-between; 31 | align-items: center; 32 | height: 100%; 33 | } 34 | 35 | .header a { 36 | text-decoration: none; 37 | color: #e3b062; 38 | } 39 | 40 | .agora { 41 | font-weight: 800; 42 | } 43 | 44 | .navbar { 45 | width: 300px; 46 | display: flex; 47 | align-items: center; 48 | justify-content: space-between; 49 | list-style: none; 50 | color: #e3b062; 51 | } 52 | 53 | .titulo { 54 | color: #32b9cd; 55 | width: fit-content; 56 | font-weight: 500; 57 | } 58 | 59 | .header h1 { 60 | margin: 0; 61 | } 62 | 63 | /* BANNER */ 64 | 65 | .banner { 66 | height: var(--tamanho-banner); 67 | color: white; 68 | background-image: url('../assets/imgs/bg-jelly-fish-para-home.png'); 69 | background-size: cover; 70 | } 71 | 72 | .banner .container { 73 | justify-content: center; 74 | align-items: center; 75 | height: 100%; 76 | } 77 | 78 | .banner .container p { 79 | width: 50%; 80 | margin: 0; 81 | padding: 0; 82 | font-size: 36px; 83 | } 84 | 85 | .banner .container span { 86 | font-weight: 800; 87 | } 88 | 89 | /* MISSÃO VISÃO VALORES */ 90 | 91 | .social { 92 | background-color: #e5e5e5; 93 | display: flex; 94 | } 95 | 96 | .social .container { 97 | justify-content: center; 98 | } 99 | 100 | .box img { 101 | width: 170px; 102 | } 103 | 104 | .social .container .boxes { 105 | display: flex; 106 | justify-content: space-between; 107 | width: 100%; 108 | padding: 30px 0; 109 | } 110 | 111 | .social p { 112 | text-align: center; 113 | } 114 | 115 | .box { 116 | display: flex; 117 | flex-direction: column; 118 | align-items: center; 119 | } 120 | 121 | /* FOOTER */ 122 | 123 | .footer { 124 | background-color: #32b9cd; 125 | height: 150px; 126 | color: #fff; 127 | display: flex; 128 | font-size: 15px; 129 | } 130 | 131 | .footer .container { 132 | justify-content: center; 133 | text-align: center; 134 | } 135 | 136 | .footer .container .version { 137 | font-size: 12px; 138 | } 139 | 140 | /* LOGIN */ 141 | 142 | .login { 143 | height: var(--tamanho-login); 144 | background-image: url('../assets/imgs/bg-jelly-fish-para-home.png'); 145 | background-size: cover; 146 | } 147 | 148 | .login .container { 149 | justify-content: center; 150 | align-items: center; 151 | height: 100%; 152 | } 153 | 154 | .card { 155 | width: 50%; 156 | background-color: #e5e5e5; 157 | border-radius: 10px; 158 | display: flex; 159 | align-items: center; 160 | justify-content: space-evenly; 161 | color: palevioletred; 162 | flex-direction: column; 163 | height: fit-content; 164 | padding: 20px 0; 165 | } 166 | 167 | .card h2 { 168 | margin: 0; 169 | font-size: 30px; 170 | } 171 | 172 | .formulario { 173 | display: flex; 174 | height: 90%; 175 | width: 80%; 176 | justify-content: space-around; 177 | flex-direction: column; 178 | } 179 | 180 | .formulario span { 181 | font-size: 15px; 182 | font-weight: 800; 183 | } 184 | 185 | .formulario input { 186 | border: 2px solid #32b9cd; 187 | text-align: center; 188 | border-radius: 10px; 189 | margin: 0; 190 | } 191 | 192 | .formulario select { 193 | border: 2px solid #32b9cd; 194 | background-color: white; 195 | color: gray; 196 | height: 36px; 197 | text-align: center; 198 | border-radius: 10px; 199 | margin: 0; 200 | } 201 | 202 | .campo { 203 | display: flex; 204 | flex-direction: column; 205 | justify-content: start; 206 | padding: 5px 0; 207 | } 208 | 209 | .botao { 210 | cursor: pointer; 211 | font-family: "Barlow", sans-serif; 212 | border: 0; 213 | border-radius: 5px; 214 | font-weight: 600; 215 | font-size: 18px; 216 | color: #fff; 217 | background-color: #ED145B; 218 | width: 120px; 219 | height: 30px; 220 | align-self: center; 221 | margin-top: 20px; 222 | } 223 | 224 | .loading-div { 225 | width: 50px; 226 | display: none; 227 | } 228 | 229 | .loading-div img { 230 | height: 50px; 231 | width: 50px; 232 | } 233 | 234 | #div_erros_login { 235 | display: none 236 | } 237 | 238 | /* FORMULARIO */ 239 | 240 | .alerta_erro{ 241 | display: flex; 242 | justify-content: flex-end; 243 | } 244 | 245 | .card_erro { 246 | display: none; 247 | background-color: #fff; 248 | color: black; 249 | width: 230px; 250 | position: fixed; 251 | border-radius: 4px; 252 | border: #ED145B 3px solid; 253 | padding: 10px; 254 | margin-right: 10%; 255 | } 256 | 257 | .card_erro #mensagem_erro{ 258 | font-weight: 500; 259 | font-size: 20px; 260 | } 261 | 262 | .formulario .tipo_campo { 263 | font-size: 20px; 264 | font-weight: 600 !important; 265 | } 266 | 267 | .formulario { 268 | display: flex; 269 | flex-direction: column; 270 | } 271 | 272 | input { 273 | margin-bottom: 10px; 274 | border: 2px solid #32b9cd; 275 | padding: 10px; 276 | text-align: center; 277 | border-radius: 10px; 278 | } 279 | 280 | .btn { 281 | font-family: "Barlow", sans-serif; 282 | border: 0; 283 | border-radius: 5px; 284 | font-weight: 600; 285 | font-size: 18px; 286 | padding: 10px 15px; 287 | color: white; 288 | background-color: #ED145B; 289 | width: 120px; 290 | align-self: center; 291 | margin-top: 5px; 292 | } 293 | 294 | .loading-div { 295 | width: 50px; 296 | margin: auto; 297 | display: none; 298 | } 299 | 300 | .loading-div img { 301 | height: 50px; 302 | width: 50px; 303 | } 304 | 305 | /* SIMULADOR */ 306 | 307 | .simulador { 308 | color: white; 309 | } 310 | 311 | .simulador .container { 312 | flex-direction: column; 313 | overflow: scroll; 314 | height: var(--tamanho-simulador); 315 | } 316 | 317 | /* ALERTA */ 318 | 319 | #alerta { 320 | position: absolute; 321 | right: 0; 322 | bottom: 0; 323 | } 324 | 325 | .mensagem-alarme { 326 | background-color: white; 327 | border-radius: 5px; 328 | width: 300px; 329 | height: 80px; 330 | margin: 10px; 331 | padding: 10px 0; 332 | display: flex; 333 | justify-content: space-evenly; 334 | align-items: center; 335 | } 336 | 337 | .mensagem-alarme h3 { 338 | font-size: 14px; 339 | margin: 0; 340 | } 341 | 342 | .mensagem-alarme .informacao { 343 | width: 66%; 344 | } 345 | 346 | .alarme-sino { 347 | width: 48px; 348 | height: 48px; 349 | animation-name: bell; 350 | animation-duration: 4s; 351 | background-image: url('https://cdn-icons-png.flaticon.com/512/1157/1157000.png'); 352 | background-size: cover; 353 | animation-iteration-count: infinite; 354 | } 355 | 356 | @keyframes bell { 357 | 0% {transform: rotate(25deg)} 358 | 25% {transform: rotate(-25deg)} 359 | 50% {transform: rotate(25deg)} 360 | 75% {transform: rotate(-25deg)} 361 | 100% {transform: rotate(25deg)} 362 | } -------------------------------------------------------------------------------- /public/dashboard/cards.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Tempo Real 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 |

AquaTech

30 | 31 |
32 |

Olá, usuário!

33 |
34 | 35 |
36 |

Aquários

37 |
38 | 39 | 44 | 45 | 50 | 51 |
52 |

Sair

53 |
54 | 55 |
56 | 57 |
58 |
59 |
60 |
61 |

62 | Legenda - Parâmetros para Alertas 63 |

64 |
65 |
66 |

Perigo

67 |

<=5°C

68 |
69 |
70 |

Alerta

71 |

<=10°C

72 |
73 |
74 |

Ideal

75 |

20°C

76 |
77 |
78 |

Alerta

79 |

>=22°C

80 |
81 |
82 |

Perigo

83 |

>=23°C

84 |
85 |
86 |
87 | 88 |
89 | 90 |
91 | 92 |
93 | 94 |
95 | 96 | 97 | 98 | 119 | 120 | -------------------------------------------------------------------------------- /public/dashboard/dashboard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Dashboards 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 |

AquaTech

36 | 37 |
38 |

Olá, usuário!

39 |
40 | 41 | 46 | 47 |
48 | 49 |

Gráficos

50 | 51 |
52 | 53 | 58 | 59 |
60 |

Sair

61 |
62 | 63 |
64 | 65 |
66 |
67 |
68 | 69 |
70 | 71 |
72 |
73 |
74 |
75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /public/dashboard/edicao-aviso.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Página Inicial 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 |
29 | 30 |

AquaTech

31 | 32 |
33 |

Olá, usuário!

34 |
35 | 36 | 41 | 42 | 47 | 48 | 53 | 54 |
55 |

Sair

56 |
57 | 58 |
59 | 60 |
61 | 62 |
63 |
64 |

Editar um aviso

65 |
66 | 71 | 77 | 83 |
84 | 89 |
90 | 91 |
92 | 93 |
94 |
95 |
96 |
97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /public/dashboard/mural.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Avisos 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 | 29 |

AquaTech

30 | 31 |
32 |

Olá, usuário!

33 |
34 | 35 | 40 | 41 | 46 | 47 |
48 |

Mural de Avisos

49 |
50 | 51 |
52 |

Sair

53 |
54 | 55 |
56 | 57 |
58 | 59 | 60 |
61 |
62 |
63 |
64 |

Publicar um aviso

65 |
66 |
67 | 72 |
73 |
74 | 79 |
80 |
81 | 82 |
83 |
84 |

Mural de Avisos

85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 251 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Página Inicial 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |

AquaTech

22 | 37 |
38 |
39 | 40 | 45 | 46 |
47 |
48 |
49 |
50 | 51 |

Missão

52 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et, quas cupiditate asperiores provident magnam 53 | vitae illum iusto fugiat atque deleniti nulla sed iure suscipit, laborum, aliquid accusantium cum dicta 54 | minima.

55 |
56 |
57 | 58 |

Visão

59 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et, quas cupiditate asperiores provident magnam 60 | vitae illum iusto fugiat atque deleniti nulla sed iure suscipit, laborum, aliquid accusantium cum dicta 61 | minima.

62 |
63 |
64 | 65 |

Valores

66 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Et, quas cupiditate asperiores provident magnam 67 | vitae illum iusto fugiat atque deleniti nulla sed iure suscipit, laborum, aliquid accusantium cum dicta 68 | minima.

69 |
70 |
71 |
72 |
73 | 74 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /public/js/alerta.js: -------------------------------------------------------------------------------- 1 | var alertas = []; 2 | 3 | function obterdados(idAquario) { 4 | fetch(`/medidas/tempo-real/${idAquario}`) 5 | .then(resposta => { 6 | if (resposta.status == 200) { 7 | resposta.json().then(resposta => { 8 | 9 | console.log(`Dados recebidos: ${JSON.stringify(resposta)}`); 10 | 11 | alertar(resposta, idAquario); 12 | }); 13 | } else { 14 | console.error(`Nenhum dado encontrado para o id ${idAquario} ou erro na API`); 15 | } 16 | }) 17 | .catch(function (error) { 18 | console.error(`Erro na obtenção dos dados do aquario p/ gráfico: ${error.message}`); 19 | }); 20 | 21 | } 22 | 23 | function alertar(resposta, idAquario) { 24 | var temp = resposta[0].temperatura; 25 | 26 | var grauDeAviso = ''; 27 | 28 | var limites = { 29 | muito_quente: 23, 30 | quente: 22, 31 | ideal: 20, 32 | frio: 10, 33 | muito_frio: 5 34 | }; 35 | 36 | var classe_temperatura = 'cor-alerta'; 37 | 38 | if (temp >= limites.muito_quente) { 39 | classe_temperatura = 'cor-alerta perigo-quente'; 40 | grauDeAviso = 'perigo quente' 41 | grauDeAvisoCor = 'cor-alerta perigo-quente' 42 | exibirAlerta(temp, idAquario, grauDeAviso, grauDeAvisoCor) 43 | } 44 | else if (temp < limites.muito_quente && temp >= limites.quente) { 45 | classe_temperatura = 'cor-alerta alerta-quente'; 46 | grauDeAviso = 'alerta quente' 47 | grauDeAvisoCor = 'cor-alerta alerta-quente' 48 | exibirAlerta(temp, idAquario, grauDeAviso, grauDeAvisoCor) 49 | } 50 | else if (temp < limites.quente && temp > limites.frio) { 51 | classe_temperatura = 'cor-alerta ideal'; 52 | removerAlerta(idAquario); 53 | } 54 | else if (temp <= limites.frio && temp > limites.muito_frio) { 55 | classe_temperatura = 'cor-alerta alerta-frio'; 56 | grauDeAviso = 'alerta frio' 57 | grauDeAvisoCor = 'cor-alerta alerta-frio' 58 | exibirAlerta(temp, idAquario, grauDeAviso, grauDeAvisoCor) 59 | } 60 | else if (temp <= limites.muito_frio) { 61 | classe_temperatura = 'cor-alerta perigo-frio'; 62 | grauDeAviso = 'perigo frio' 63 | grauDeAvisoCor = 'cor-alerta perigo-frio' 64 | exibirAlerta(temp, idAquario, grauDeAviso, grauDeAvisoCor) 65 | } 66 | 67 | var card; 68 | 69 | if (document.getElementById(`temp_aquario_${idAquario}`) != null) { 70 | document.getElementById(`temp_aquario_${idAquario}`).innerHTML = temp + "°C"; 71 | } 72 | 73 | if (document.getElementById(`card_${idAquario}`)) { 74 | card = document.getElementById(`card_${idAquario}`) 75 | card.className = classe_temperatura; 76 | } 77 | } 78 | 79 | function exibirAlerta(temp, idAquario, grauDeAviso, grauDeAvisoCor) { 80 | var indice = alertas.findIndex(item => item.idAquario == idAquario); 81 | 82 | if (indice >= 0) { 83 | alertas[indice] = { idAquario, temp, grauDeAviso, grauDeAvisoCor } 84 | } else { 85 | alertas.push({ idAquario, temp, grauDeAviso, grauDeAvisoCor }); 86 | } 87 | 88 | exibirCards(); 89 | } 90 | 91 | function removerAlerta(idAquario) { 92 | alertas = alertas.filter(item => item.idAquario != idAquario); 93 | exibirCards(); 94 | } 95 | 96 | function exibirCards() { 97 | alerta.innerHTML = ''; 98 | 99 | for (var i = 0; i < alertas.length; i++) { 100 | var mensagem = alertas[i]; 101 | alerta.innerHTML += transformarEmDiv(mensagem); 102 | } 103 | } 104 | 105 | function transformarEmDiv({ idAquario, temp, grauDeAviso, grauDeAvisoCor }) { 106 | 107 | var descricao = JSON.parse(sessionStorage.AQUARIOS).find(item => item.id == idAquario).descricao; 108 | return ` 109 |
110 |
111 |
112 |

${descricao} está em estado de ${grauDeAviso}!

113 | Temperatura capturada: ${temp}°C. 114 |
115 |
116 |
117 | `; 118 | } 119 | 120 | function atualizacaoPeriodica() { 121 | JSON.parse(sessionStorage.AQUARIOS).forEach(item => { 122 | obterdados(item.id) 123 | }); 124 | setTimeout(atualizacaoPeriodica, 5000); 125 | } 126 | -------------------------------------------------------------------------------- /public/js/sessao.js: -------------------------------------------------------------------------------- 1 | // sessão 2 | function validarSessao() { 3 | var email = sessionStorage.EMAIL_USUARIO; 4 | var nome = sessionStorage.NOME_USUARIO; 5 | 6 | var b_usuario = document.getElementById("b_usuario"); 7 | 8 | if (email != null && nome != null) { 9 | b_usuario.innerHTML = nome; 10 | } else { 11 | window.location = "../login.html"; 12 | } 13 | } 14 | 15 | function limparSessao() { 16 | sessionStorage.clear(); 17 | window.location = "../login.html"; 18 | } 19 | 20 | // carregamento (loading) 21 | function aguardar() { 22 | var divAguardar = document.getElementById("div_aguardar"); 23 | divAguardar.style.display = "flex"; 24 | } 25 | 26 | function finalizarAguardar(texto) { 27 | var divAguardar = document.getElementById("div_aguardar"); 28 | divAguardar.style.display = "none"; 29 | 30 | var divErrosLogin = document.getElementById("div_erros_login"); 31 | if (texto) { 32 | divErrosLogin.style.display = "flex"; 33 | divErrosLogin.innerHTML = texto; 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /public/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Login 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 |

AquaTech

25 | 40 |
41 |
42 | 43 | 44 |
45 |
46 |
47 | 48 |
49 |
50 |
51 | 71 |
72 |
73 | 74 | 75 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /public/simulador.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AquaTech | Simulador 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 |

AquaTech

24 | 37 |
38 |
39 | 40 | 41 | 42 |
43 |
44 |

Simulador

45 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium tempora architecto sint fugit 46 | dolorum? Ipsum laborum magnam similique labore, voluptate amet reprehenderit rem ab blanditiis quisquam 47 | laboriosam eaque alias. Reiciendis. Lorem ipsum, dolor sit amet consectetur adipisicing elit. 48 | Accusantium tempora architecto sint fugit dolorum? Ipsum laborum magnam similique labore, voluptate amet 49 | reprehenderit rem ab blanditiis quisquam laboriosam eaque alias. Reiciendis.

50 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium tempora architecto sint fugit 51 | dolorum? Ipsum laborum magnam similique labore, voluptate amet reprehenderit rem ab blanditiis quisquam 52 | laboriosam eaque alias. Reiciendis. Lorem ipsum, dolor sit amet consectetur adipisicing elit. 53 | Accusantium tempora architecto sint fugit dolorum? Ipsum laborum magnam similique labore, voluptate amet 54 | reprehenderit rem ab blanditiis quisquam laboriosam eaque alias. Reiciendis.

55 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium tempora architecto sint fugit 56 | dolorum? Ipsum laborum magnam similique labore, voluptate amet reprehenderit rem ab blanditiis quisquam 57 | laboriosam eaque alias. Reiciendis. Lorem ipsum, dolor sit amet consectetur adipisicing elit. 58 | Accusantium tempora architecto sint fugit dolorum? Ipsum laborum magnam similique labore, voluptate amet 59 | reprehenderit rem ab blanditiis quisquam laboriosam eaque alias. Reiciendis.

60 |

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Accusantium tempora architecto sint fugit 61 | dolorum? Ipsum laborum magnam similique labore, voluptate amet reprehenderit rem ab blanditiis quisquam 62 | laboriosam eaque alias. Reiciendis. Lorem ipsum, dolor sit amet consectetur adipisicing elit. 63 | Accusantium tempora architecto sint fugit dolorum? Ipsum laborum magnam similique labore, voluptate amet 64 | reprehenderit rem ab blanditiis quisquam laboriosam eaque alias. Reiciendis.

65 | 66 |
67 |
68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/controllers/aquarioController.js: -------------------------------------------------------------------------------- 1 | var aquarioModel = require("../models/aquarioModel"); 2 | 3 | function buscarAquariosPorEmpresa(req, res) { 4 | var idUsuario = req.params.idUsuario; 5 | 6 | aquarioModel.buscarAquariosPorEmpresa(idUsuario).then((resultado) => { 7 | if (resultado.length > 0) { 8 | res.status(200).json(resultado); 9 | } else { 10 | res.status(204).json([]); 11 | } 12 | }).catch(function (erro) { 13 | console.log(erro); 14 | console.log("Houve um erro ao buscar os aquarios: ", erro.sqlMessage); 15 | res.status(500).json(erro.sqlMessage); 16 | }); 17 | } 18 | 19 | 20 | function cadastrar(req, res) { 21 | var descricao = req.body.descricao; 22 | var idUsuario = req.body.idUsuario; 23 | 24 | if (descricao == undefined) { 25 | res.status(400).send("descricao está undefined!"); 26 | } else if (idUsuario == undefined) { 27 | res.status(400).send("idUsuario está undefined!"); 28 | } else { 29 | 30 | 31 | aquarioModel.cadastrar(descricao, idUsuario) 32 | .then((resultado) => { 33 | res.status(201).json(resultado); 34 | } 35 | ).catch((erro) => { 36 | console.log(erro); 37 | console.log( 38 | "\nHouve um erro ao realizar o cadastro! Erro: ", 39 | erro.sqlMessage 40 | ); 41 | res.status(500).json(erro.sqlMessage); 42 | }); 43 | } 44 | } 45 | 46 | module.exports = { 47 | buscarAquariosPorEmpresa, 48 | cadastrar 49 | } -------------------------------------------------------------------------------- /src/controllers/avisoController.js: -------------------------------------------------------------------------------- 1 | var avisoModel = require("../models/avisoModel"); 2 | 3 | function listar(req, res) { 4 | avisoModel.listar().then(function (resultado) { 5 | if (resultado.length > 0) { 6 | res.status(200).json(resultado); 7 | } else { 8 | res.status(204).send("Nenhum resultado encontrado!") 9 | } 10 | }).catch(function (erro) { 11 | console.log(erro); 12 | console.log("Houve um erro ao buscar os avisos: ", erro.sqlMessage); 13 | res.status(500).json(erro.sqlMessage); 14 | }); 15 | } 16 | 17 | function listarPorUsuario(req, res) { 18 | var idUsuario = req.params.idUsuario; 19 | 20 | avisoModel.listarPorUsuario(idUsuario) 21 | .then( 22 | function (resultado) { 23 | if (resultado.length > 0) { 24 | res.status(200).json(resultado); 25 | } else { 26 | res.status(204).send("Nenhum resultado encontrado!"); 27 | } 28 | } 29 | ) 30 | .catch( 31 | function (erro) { 32 | console.log(erro); 33 | console.log( 34 | "Houve um erro ao buscar os avisos: ", 35 | erro.sqlMessage 36 | ); 37 | res.status(500).json(erro.sqlMessage); 38 | } 39 | ); 40 | } 41 | 42 | function pesquisarDescricao(req, res) { 43 | var descricao = req.params.descricao; 44 | 45 | avisoModel.pesquisarDescricao(descricao) 46 | .then( 47 | function (resultado) { 48 | if (resultado.length > 0) { 49 | res.status(200).json(resultado); 50 | } else { 51 | res.status(204).send("Nenhum resultado encontrado!"); 52 | } 53 | } 54 | ).catch( 55 | function (erro) { 56 | console.log(erro); 57 | console.log("Houve um erro ao buscar os avisos: ", erro.sqlMessage); 58 | res.status(500).json(erro.sqlMessage); 59 | } 60 | ); 61 | } 62 | 63 | function publicar(req, res) { 64 | var titulo = req.body.titulo; 65 | var descricao = req.body.descricao; 66 | var idUsuario = req.params.idUsuario; 67 | 68 | if (titulo == undefined) { 69 | res.status(400).send("O título está indefinido!"); 70 | } else if (descricao == undefined) { 71 | res.status(400).send("A descrição está indefinido!"); 72 | } else if (idUsuario == undefined) { 73 | res.status(403).send("O id do usuário está indefinido!"); 74 | } else { 75 | avisoModel.publicar(titulo, descricao, idUsuario) 76 | .then( 77 | function (resultado) { 78 | res.json(resultado); 79 | } 80 | ) 81 | .catch( 82 | function (erro) { 83 | console.log(erro); 84 | console.log("Houve um erro ao realizar o post: ", erro.sqlMessage); 85 | res.status(500).json(erro.sqlMessage); 86 | } 87 | ); 88 | } 89 | } 90 | 91 | function editar(req, res) { 92 | var novaDescricao = req.body.descricao; 93 | var idAviso = req.params.idAviso; 94 | 95 | avisoModel.editar(novaDescricao, idAviso) 96 | .then( 97 | function (resultado) { 98 | res.json(resultado); 99 | } 100 | ) 101 | .catch( 102 | function (erro) { 103 | console.log(erro); 104 | console.log("Houve um erro ao realizar o post: ", erro.sqlMessage); 105 | res.status(500).json(erro.sqlMessage); 106 | } 107 | ); 108 | 109 | } 110 | 111 | function deletar(req, res) { 112 | var idAviso = req.params.idAviso; 113 | 114 | avisoModel.deletar(idAviso) 115 | .then( 116 | function (resultado) { 117 | res.json(resultado); 118 | } 119 | ) 120 | .catch( 121 | function (erro) { 122 | console.log(erro); 123 | console.log("Houve um erro ao deletar o post: ", erro.sqlMessage); 124 | res.status(500).json(erro.sqlMessage); 125 | } 126 | ); 127 | } 128 | 129 | module.exports = { 130 | listar, 131 | listarPorUsuario, 132 | pesquisarDescricao, 133 | publicar, 134 | editar, 135 | deletar 136 | } -------------------------------------------------------------------------------- /src/controllers/empresaController.js: -------------------------------------------------------------------------------- 1 | var empresaModel = require("../models/empresaModel"); 2 | 3 | function buscarPorCnpj(req, res) { 4 | var cnpj = req.query.cnpj; 5 | 6 | empresaModel.buscarPorCnpj(cnpj).then((resultado) => { 7 | res.status(200).json(resultado); 8 | }); 9 | } 10 | 11 | function listar(req, res) { 12 | empresaModel.listar().then((resultado) => { 13 | res.status(200).json(resultado); 14 | }); 15 | } 16 | 17 | function buscarPorId(req, res) { 18 | var id = req.params.id; 19 | 20 | empresaModel.buscarPorId(id).then((resultado) => { 21 | res.status(200).json(resultado); 22 | }); 23 | } 24 | 25 | function cadastrar(req, res) { 26 | var cnpj = req.body.cnpj; 27 | var razaoSocial = req.body.razaoSocial; 28 | 29 | empresaModel.buscarPorCnpj(cnpj).then((resultado) => { 30 | if (resultado.length > 0) { 31 | res 32 | .status(401) 33 | .json({ mensagem: `a empresa com o cnpj ${cnpj} já existe` }); 34 | } else { 35 | empresaModel.cadastrar(razaoSocial, cnpj).then((resultado) => { 36 | res.status(201).json(resultado); 37 | }); 38 | } 39 | }); 40 | } 41 | 42 | module.exports = { 43 | buscarPorCnpj, 44 | buscarPorId, 45 | cadastrar, 46 | listar, 47 | }; 48 | -------------------------------------------------------------------------------- /src/controllers/medidaController.js: -------------------------------------------------------------------------------- 1 | var medidaModel = require("../models/medidaModel"); 2 | 3 | function buscarUltimasMedidas(req, res) { 4 | 5 | const limite_linhas = 7; 6 | 7 | var idAquario = req.params.idAquario; 8 | 9 | console.log(`Recuperando as ultimas ${limite_linhas} medidas`); 10 | 11 | medidaModel.buscarUltimasMedidas(idAquario, limite_linhas).then(function (resultado) { 12 | if (resultado.length > 0) { 13 | res.status(200).json(resultado); 14 | } else { 15 | res.status(204).send("Nenhum resultado encontrado!") 16 | } 17 | }).catch(function (erro) { 18 | console.log(erro); 19 | console.log("Houve um erro ao buscar as ultimas medidas.", erro.sqlMessage); 20 | res.status(500).json(erro.sqlMessage); 21 | }); 22 | } 23 | 24 | 25 | function buscarMedidasEmTempoReal(req, res) { 26 | 27 | var idAquario = req.params.idAquario; 28 | 29 | console.log(`Recuperando medidas em tempo real`); 30 | 31 | medidaModel.buscarMedidasEmTempoReal(idAquario).then(function (resultado) { 32 | if (resultado.length > 0) { 33 | res.status(200).json(resultado); 34 | } else { 35 | res.status(204).send("Nenhum resultado encontrado!") 36 | } 37 | }).catch(function (erro) { 38 | console.log(erro); 39 | console.log("Houve um erro ao buscar as ultimas medidas.", erro.sqlMessage); 40 | res.status(500).json(erro.sqlMessage); 41 | }); 42 | } 43 | 44 | module.exports = { 45 | buscarUltimasMedidas, 46 | buscarMedidasEmTempoReal 47 | 48 | } -------------------------------------------------------------------------------- /src/controllers/usuarioController.js: -------------------------------------------------------------------------------- 1 | var usuarioModel = require("../models/usuarioModel"); 2 | var aquarioModel = require("../models/aquarioModel"); 3 | 4 | function autenticar(req, res) { 5 | var email = req.body.emailServer; 6 | var senha = req.body.senhaServer; 7 | 8 | if (email == undefined) { 9 | res.status(400).send("Seu email está undefined!"); 10 | } else if (senha == undefined) { 11 | res.status(400).send("Sua senha está indefinida!"); 12 | } else { 13 | 14 | usuarioModel.autenticar(email, senha) 15 | .then( 16 | function (resultadoAutenticar) { 17 | console.log(`\nResultados encontrados: ${resultadoAutenticar.length}`); 18 | console.log(`Resultados: ${JSON.stringify(resultadoAutenticar)}`); // transforma JSON em String 19 | 20 | if (resultadoAutenticar.length == 1) { 21 | console.log(resultadoAutenticar); 22 | 23 | aquarioModel.buscarAquariosPorEmpresa(resultadoAutenticar[0].empresaId) 24 | .then((resultadoAquarios) => { 25 | if (resultadoAquarios.length > 0) { 26 | res.json({ 27 | id: resultadoAutenticar[0].id, 28 | email: resultadoAutenticar[0].email, 29 | nome: resultadoAutenticar[0].nome, 30 | senha: resultadoAutenticar[0].senha, 31 | aquarios: resultadoAquarios 32 | }); 33 | } else { 34 | res.status(204).json({ aquarios: [] }); 35 | } 36 | }) 37 | } else if (resultadoAutenticar.length == 0) { 38 | res.status(403).send("Email e/ou senha inválido(s)"); 39 | } else { 40 | res.status(403).send("Mais de um usuário com o mesmo login e senha!"); 41 | } 42 | } 43 | ).catch( 44 | function (erro) { 45 | console.log(erro); 46 | console.log("\nHouve um erro ao realizar o login! Erro: ", erro.sqlMessage); 47 | res.status(500).json(erro.sqlMessage); 48 | } 49 | ); 50 | } 51 | 52 | } 53 | 54 | function cadastrar(req, res) { 55 | // Crie uma variável que vá recuperar os valores do arquivo cadastro.html 56 | var nome = req.body.nomeServer; 57 | var email = req.body.emailServer; 58 | var senha = req.body.senhaServer; 59 | var fkEmpresa = req.body.idEmpresaVincularServer; 60 | 61 | // Faça as validações dos valores 62 | if (nome == undefined) { 63 | res.status(400).send("Seu nome está undefined!"); 64 | } else if (email == undefined) { 65 | res.status(400).send("Seu email está undefined!"); 66 | } else if (senha == undefined) { 67 | res.status(400).send("Sua senha está undefined!"); 68 | } else if (fkEmpresa == undefined) { 69 | res.status(400).send("Sua empresa a vincular está undefined!"); 70 | } else { 71 | 72 | // Passe os valores como parâmetro e vá para o arquivo usuarioModel.js 73 | usuarioModel.cadastrar(nome, email, senha, fkEmpresa) 74 | .then( 75 | function (resultado) { 76 | res.json(resultado); 77 | } 78 | ).catch( 79 | function (erro) { 80 | console.log(erro); 81 | console.log( 82 | "\nHouve um erro ao realizar o cadastro! Erro: ", 83 | erro.sqlMessage 84 | ); 85 | res.status(500).json(erro.sqlMessage); 86 | } 87 | ); 88 | } 89 | } 90 | 91 | module.exports = { 92 | autenticar, 93 | cadastrar 94 | } -------------------------------------------------------------------------------- /src/database/config.js: -------------------------------------------------------------------------------- 1 | var mysql = require("mysql2"); 2 | 3 | // CONEXÃO DO BANCO MYSQL SERVER 4 | var mySqlConfig = { 5 | host: process.env.DB_HOST, 6 | database: process.env.DB_DATABASE, 7 | user: process.env.DB_USER, 8 | password: process.env.DB_PASSWORD, 9 | port: process.env.DB_PORT 10 | }; 11 | 12 | function executar(instrucao) { 13 | 14 | if (process.env.AMBIENTE_PROCESSO !== "producao" && process.env.AMBIENTE_PROCESSO !== "desenvolvimento") { 15 | console.log("\nO AMBIENTE (produção OU desenvolvimento) NÃO FOI DEFINIDO EM .env OU dev.env OU app.js\n"); 16 | return Promise.reject("AMBIENTE NÃO CONFIGURADO EM .env"); 17 | } 18 | 19 | return new Promise(function (resolve, reject) { 20 | var conexao = mysql.createConnection(mySqlConfig); 21 | conexao.connect(); 22 | conexao.query(instrucao, function (erro, resultados) { 23 | conexao.end(); 24 | if (erro) { 25 | reject(erro); 26 | } 27 | console.log(resultados); 28 | resolve(resultados); 29 | }); 30 | conexao.on('error', function (erro) { 31 | return ("ERRO NO MySQL SERVER: ", erro.sqlMessage); 32 | }); 33 | }); 34 | } 35 | 36 | module.exports = { 37 | executar 38 | }; -------------------------------------------------------------------------------- /src/database/script-tabelas.sql: -------------------------------------------------------------------------------- 1 | -- Arquivo de apoio, caso você queira criar tabelas como as aqui criadas para a API funcionar. 2 | -- Você precisa executar os comandos no banco de dados para criar as tabelas, 3 | -- ter este arquivo aqui não significa que a tabela em seu BD estará como abaixo! 4 | 5 | /* 6 | comandos para mysql server 7 | */ 8 | 9 | CREATE DATABASE aquatech; 10 | 11 | USE aquatech; 12 | 13 | CREATE TABLE empresa ( 14 | id INT PRIMARY KEY AUTO_INCREMENT, 15 | razao_social VARCHAR(50), 16 | cnpj CHAR(14), 17 | codigo_ativacao VARCHAR(50) 18 | ); 19 | 20 | CREATE TABLE usuario ( 21 | id INT PRIMARY KEY AUTO_INCREMENT, 22 | nome VARCHAR(50), 23 | email VARCHAR(50), 24 | senha VARCHAR(50), 25 | fk_empresa INT, 26 | FOREIGN KEY (fk_empresa) REFERENCES empresa(id) 27 | ); 28 | 29 | CREATE TABLE aviso ( 30 | id INT PRIMARY KEY AUTO_INCREMENT, 31 | titulo VARCHAR(100), 32 | descricao VARCHAR(150), 33 | fk_usuario INT, 34 | FOREIGN KEY (fk_usuario) REFERENCES usuario(id) 35 | ); 36 | 37 | create table aquario ( 38 | /* em nossa regra de negócio, um aquario tem apenas um sensor */ 39 | id INT PRIMARY KEY AUTO_INCREMENT, 40 | descricao VARCHAR(300), 41 | fk_empresa INT, 42 | FOREIGN KEY (fk_empresa) REFERENCES empresa(id) 43 | ); 44 | 45 | /* esta tabela deve estar de acordo com o que está em INSERT de sua API do arduino - dat-acqu-ino */ 46 | 47 | create table medida ( 48 | id INT PRIMARY KEY AUTO_INCREMENT, 49 | dht11_umidade DECIMAL, 50 | dht11_temperatura DECIMAL, 51 | luminosidade DECIMAL, 52 | lm35_temperatura DECIMAL, 53 | chave TINYINT, 54 | momento DATETIME, 55 | fk_aquario INT, 56 | FOREIGN KEY (fk_aquario) REFERENCES aquario(id) 57 | ); 58 | 59 | insert into empresa (razao_social, codigo_ativacao) values ('Empresa 1', 'ED145B'); 60 | insert into empresa (razao_social, codigo_ativacao) values ('Empresa 2', 'A1B2C3'); 61 | insert into aquario (descricao, fk_empresa) values ('Aquário de Estrela-do-mar', 1); 62 | insert into aquario (descricao, fk_empresa) values ('Aquário de Peixe-dourado', 2); -------------------------------------------------------------------------------- /src/models/aquarioModel.js: -------------------------------------------------------------------------------- 1 | var database = require("../database/config"); 2 | 3 | function buscarAquariosPorEmpresa(empresaId) { 4 | 5 | var instrucaoSql = `SELECT * FROM aquario a WHERE fk_empresa = ${empresaId}`; 6 | 7 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 8 | return database.executar(instrucaoSql); 9 | } 10 | 11 | function cadastrar(empresaId, descricao) { 12 | 13 | var instrucaoSql = `INSERT INTO (descricao, fk_empresa) aquario VALUES (${descricao}, ${empresaId})`; 14 | 15 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 16 | return database.executar(instrucaoSql); 17 | } 18 | 19 | 20 | module.exports = { 21 | buscarAquariosPorEmpresa, 22 | cadastrar 23 | } 24 | -------------------------------------------------------------------------------- /src/models/avisoModel.js: -------------------------------------------------------------------------------- 1 | var database = require("../database/config"); 2 | 3 | function listar() { 4 | console.log("ACESSEI O AVISO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function listar()"); 5 | var instrucaoSql = ` 6 | SELECT 7 | a.id AS idAviso, 8 | a.titulo, 9 | a.descricao, 10 | a.fk_usuario, 11 | u.id AS idUsuario, 12 | u.nome, 13 | u.email, 14 | u.senha 15 | FROM aviso a 16 | INNER JOIN usuario u 17 | ON a.fk_usuario = u.id; 18 | `; 19 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 20 | return database.executar(instrucaoSql); 21 | } 22 | 23 | function pesquisarDescricao(texto) { 24 | console.log("ACESSEI O AVISO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function pesquisarDescricao()"); 25 | var instrucaoSql = ` 26 | SELECT 27 | a.id AS idAviso, 28 | a.titulo, 29 | a.descricao, 30 | a.fk_usuario, 31 | u.id AS idUsuario, 32 | u.nome, 33 | u.email, 34 | u.senha 35 | FROM aviso a 36 | INNER JOIN usuario u 37 | ON a.fk_usuario = u.id 38 | WHERE a.descricao LIKE '${texto}'; 39 | `; 40 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 41 | return database.executar(instrucaoSql); 42 | } 43 | 44 | function listarPorUsuario(idUsuario) { 45 | console.log("ACESSEI O AVISO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function listarPorUsuario()"); 46 | var instrucaoSql = ` 47 | SELECT 48 | a.id AS idAviso, 49 | a.titulo, 50 | a.descricao, 51 | a.fk_usuario, 52 | u.id AS idUsuario, 53 | u.nome, 54 | u.email, 55 | u.senha 56 | FROM aviso a 57 | INNER JOIN usuario u 58 | ON a.fk_usuario = u.id 59 | WHERE u.id = ${idUsuario}; 60 | `; 61 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 62 | return database.executar(instrucaoSql); 63 | } 64 | 65 | function publicar(titulo, descricao, idUsuario) { 66 | console.log("ACESSEI O AVISO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function publicar(): ", titulo, descricao, idUsuario); 67 | var instrucaoSql = ` 68 | INSERT INTO aviso (titulo, descricao, fk_usuario) VALUES ('${titulo}', '${descricao}', ${idUsuario}); 69 | `; 70 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 71 | return database.executar(instrucaoSql); 72 | } 73 | 74 | function editar(novaDescricao, idAviso) { 75 | console.log("ACESSEI O AVISO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function editar(): ", novaDescricao, idAviso); 76 | var instrucaoSql = ` 77 | UPDATE aviso SET descricao = '${novaDescricao}' WHERE id = ${idAviso}; 78 | `; 79 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 80 | return database.executar(instrucaoSql); 81 | } 82 | 83 | function deletar(idAviso) { 84 | console.log("ACESSEI O AVISO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function deletar():", idAviso); 85 | var instrucaoSql = ` 86 | DELETE FROM aviso WHERE id = ${idAviso}; 87 | `; 88 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 89 | return database.executar(instrucaoSql); 90 | } 91 | 92 | module.exports = { 93 | listar, 94 | listarPorUsuario, 95 | pesquisarDescricao, 96 | publicar, 97 | editar, 98 | deletar 99 | } 100 | -------------------------------------------------------------------------------- /src/models/empresaModel.js: -------------------------------------------------------------------------------- 1 | var database = require("../database/config"); 2 | 3 | function buscarPorId(id) { 4 | var instrucaoSql = `SELECT * FROM empresa WHERE id = '${id}'`; 5 | 6 | return database.executar(instrucaoSql); 7 | } 8 | 9 | function listar() { 10 | var instrucaoSql = `SELECT id, razao_social, cnpj, codigo_ativacao FROM empresa`; 11 | 12 | return database.executar(instrucaoSql); 13 | } 14 | 15 | function buscarPorCnpj(cnpj) { 16 | var instrucaoSql = `SELECT * FROM empresa WHERE cnpj = '${cnpj}'`; 17 | 18 | return database.executar(instrucaoSql); 19 | } 20 | 21 | function cadastrar(razaoSocial, cnpj) { 22 | var instrucaoSql = `INSERT INTO empresa (razao_social, cnpj) VALUES ('${razaoSocial}', '${cnpj}')`; 23 | 24 | return database.executar(instrucaoSql); 25 | } 26 | 27 | module.exports = { buscarPorCnpj, buscarPorId, cadastrar, listar }; 28 | -------------------------------------------------------------------------------- /src/models/medidaModel.js: -------------------------------------------------------------------------------- 1 | var database = require("../database/config"); 2 | 3 | function buscarUltimasMedidas(idAquario, limite_linhas) { 4 | 5 | var instrucaoSql = `SELECT 6 | dht11_temperatura as temperatura, 7 | dht11_umidade as umidade, 8 | momento, 9 | DATE_FORMAT(momento,'%H:%i:%s') as momento_grafico 10 | FROM medida 11 | WHERE fk_aquario = ${idAquario} 12 | ORDER BY id DESC LIMIT ${limite_linhas}`; 13 | 14 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 15 | return database.executar(instrucaoSql); 16 | } 17 | 18 | function buscarMedidasEmTempoReal(idAquario) { 19 | 20 | var instrucaoSql = `SELECT 21 | dht11_temperatura as temperatura, 22 | dht11_umidade as umidade, 23 | DATE_FORMAT(momento,'%H:%i:%s') as momento_grafico, 24 | fk_aquario 25 | FROM medida WHERE fk_aquario = ${idAquario} 26 | ORDER BY id DESC LIMIT 1`; 27 | 28 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 29 | return database.executar(instrucaoSql); 30 | } 31 | 32 | module.exports = { 33 | buscarUltimasMedidas, 34 | buscarMedidasEmTempoReal 35 | } 36 | -------------------------------------------------------------------------------- /src/models/usuarioModel.js: -------------------------------------------------------------------------------- 1 | var database = require("../database/config") 2 | 3 | function autenticar(email, senha) { 4 | console.log("ACESSEI O USUARIO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function entrar(): ", email, senha) 5 | var instrucaoSql = ` 6 | SELECT id, nome, email, fk_empresa as empresaId FROM usuario WHERE email = '${email}' AND senha = '${senha}'; 7 | `; 8 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 9 | return database.executar(instrucaoSql); 10 | } 11 | 12 | // Coloque os mesmos parâmetros aqui. Vá para a var instrucaoSql 13 | function cadastrar(nome, email, senha, fkEmpresa) { 14 | console.log("ACESSEI O USUARIO MODEL \n \n\t\t >> Se aqui der erro de 'Error: connect ECONNREFUSED',\n \t\t >> verifique suas credenciais de acesso ao banco\n \t\t >> e se o servidor de seu BD está rodando corretamente. \n\n function cadastrar():", nome, email, senha, fkEmpresa); 15 | 16 | // Insira exatamente a query do banco aqui, lembrando da nomenclatura exata nos valores 17 | // e na ordem de inserção dos dados. 18 | var instrucaoSql = ` 19 | INSERT INTO usuario (nome, email, senha, fk_empresa) VALUES ('${nome}', '${email}', '${senha}', '${fkEmpresa}'); 20 | `; 21 | console.log("Executando a instrução SQL: \n" + instrucaoSql); 22 | return database.executar(instrucaoSql); 23 | } 24 | 25 | module.exports = { 26 | autenticar, 27 | cadastrar 28 | }; -------------------------------------------------------------------------------- /src/routes/aquarios.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | var aquarioController = require("../controllers/aquarioController"); 5 | 6 | router.get("/:empresaId", function (req, res) { 7 | aquarioController.buscarAquariosPorEmpresa(req, res); 8 | }); 9 | 10 | router.post("/cadastrar", function (req, res) { 11 | aquarioController.cadastrar(req, res); 12 | }) 13 | 14 | module.exports = router; -------------------------------------------------------------------------------- /src/routes/avisos.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | var avisoController = require("../controllers/avisoController"); 5 | 6 | router.get("/listar", function (req, res) { 7 | avisoController.listar(req, res); 8 | }); 9 | 10 | router.get("/listar/:idUsuario", function (req, res) { 11 | avisoController.listarPorUsuario(req, res); 12 | }); 13 | 14 | router.get("/pesquisar/:descricao", function (req, res) { 15 | avisoController.pesquisarDescricao(req, res); 16 | }); 17 | 18 | router.post("/publicar/:idUsuario", function (req, res) { 19 | avisoController.publicar(req, res); 20 | }); 21 | 22 | router.put("/editar/:idAviso", function (req, res) { 23 | avisoController.editar(req, res); 24 | }); 25 | 26 | router.delete("/deletar/:idAviso", function (req, res) { 27 | avisoController.deletar(req, res); 28 | }); 29 | 30 | module.exports = router; -------------------------------------------------------------------------------- /src/routes/empresas.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | var empresaController = require("../controllers/empresaController"); 5 | 6 | //Recebendo os dados do html e direcionando para a função cadastrar de usuarioController.js 7 | router.post("/cadastrar", function (req, res) { 8 | empresaController.cadastrar(req, res); 9 | }) 10 | 11 | router.get("/buscar", function (req, res) { 12 | empresaController.buscarPorCnpj(req, res); 13 | }); 14 | 15 | router.get("/buscar/:id", function (req, res) { 16 | empresaController.buscarPorId(req, res); 17 | }); 18 | 19 | router.get("/listar", function (req, res) { 20 | empresaController.listar(req, res); 21 | }); 22 | 23 | module.exports = router; -------------------------------------------------------------------------------- /src/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | router.get("/", function (req, res) { 5 | res.render("index"); 6 | }); 7 | 8 | module.exports = router; -------------------------------------------------------------------------------- /src/routes/medidas.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | var medidaController = require("../controllers/medidaController"); 5 | 6 | router.get("/ultimas/:idAquario", function (req, res) { 7 | medidaController.buscarUltimasMedidas(req, res); 8 | }); 9 | 10 | router.get("/tempo-real/:idAquario", function (req, res) { 11 | medidaController.buscarMedidasEmTempoReal(req, res); 12 | }) 13 | 14 | module.exports = router; -------------------------------------------------------------------------------- /src/routes/usuarios.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | var router = express.Router(); 3 | 4 | var usuarioController = require("../controllers/usuarioController"); 5 | 6 | //Recebendo os dados do html e direcionando para a função cadastrar de usuarioController.js 7 | router.post("/cadastrar", function (req, res) { 8 | usuarioController.cadastrar(req, res); 9 | }) 10 | 11 | router.post("/autenticar", function (req, res) { 12 | usuarioController.autenticar(req, res); 13 | }); 14 | 15 | module.exports = router; --------------------------------------------------------------------------------