commit bcf1a6d218bc22426c722f0fc49617022474b278 Author: Anderson Valadares Pinto Date: Wed Nov 11 16:26:38 2026 -0300 DBE S04: cadastro e listagem de instrumentos musicais diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93f5bdb --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +.env +npm-debug.log* +*.log +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7bc5bc6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Anderson Valadares Pinto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cca2632 --- /dev/null +++ b/README.md @@ -0,0 +1,149 @@ +# DBE-S04 - Cadastro e Listagem de Instrumentos Musicais + +**Aluno:** Anderson Valadares Pinto (20251PL.TSIAD0018) [SLS] + +Aplicação web desenvolvida para a disciplina de **Desenvolvimento Back-End (DBE)** - Semana 04. O projeto demonstra o cadastro e a listagem de instrumentos musicais em uma loja, utilizando **Node.js**, **Express**, **EJS**, **MongoDB** (com Mongoose) e estilização com **Bootstrap 5**. + +--- + +## 🛠️ Tecnologias Utilizadas + +- **Node.js**: Ambiente de execução JavaScript no servidor com suporte a **ES Modules** (`"type": "module"`). +- **Express.js**: Framework minimalista para criação de servidores HTTP e roteamento dinâmico. +- **EJS (Embedded JavaScript)**: Mecanismo de templates para renderização dinâmica no lado do servidor (SSR). +- **MongoDB + Mongoose**: Banco de dados orientado a documentos e modelagem dos instrumentos. +- **Bootstrap 5 & Bootstrap Icons (CDN)**: Framework CSS responsivo e ícones para uma interface moderna e acessível. + +--- + +## 🎸 Instrumentos de Teste + +O script `seed.js` cadastra seis instrumentos, atendendo às orientações da atividade: + +| Nome | Fabricante | Preço | Tipo | +|---|---|---|---| +| Guitarra Elétrica Stratocaster | Fender | R$ 5.490,00 | Cordas | +| Guitarra Acústica Folk | Yamaha | R$ 2.190,00 | Cordas | +| Baixo Elétrico SR300 | Ibanez | R$ 3.890,00 | Cordas | +| Bateria Acústica Roadshow | Pearl | R$ 7.290,00 | Percussão | +| Teclado Digital Juno-DS61 | Roland | R$ 4.590,00 | Teclas | +| Saxofone Alto YAS-280 | Yamaha | R$ 6.290,00 | Sopro | + +Há três instrumentos do tipo **Cordas**, preços diferentes e nomes que permitem testar uma pesquisa por "Guitarra", "Yamaha" ou "Elétrica" posteriormente. + +--- + +## 📌 Rotas e Endpoints + +| Método | Rota | Descrição | +|---|---|---| +| `GET` | `/` | Redireciona para a listagem de instrumentos. | +| `GET` | `/instrumentos` | Lista todos os instrumentos cadastrados, com nome, fabricante, tipo e preço. | +| `GET` | `/instrumentos/add` | Exibe o formulário de cadastro de um novo instrumento. | +| `POST` | `/instrumentos` | Recebe os dados do formulário, grava no MongoDB e exibe a confirmação. | + +### Exemplos de URLs para Testes: +- `http://localhost:3000/instrumentos` — Listagem completa do estoque +- `http://localhost:3000/instrumentos/add` — Formulário de cadastro +- `http://localhost:3000/naoexiste` — Resposta de página não encontrada (404) + +--- + +## 📂 Estrutura do Projeto + +``` +DBE-S04/ +├── models/ +│ └── Instrumento.js # Schema e validações do instrumento +├── routes/ +│ └── instrumento.js # Rotas de cadastro e listagem +├── views/ +│ ├── instrumento/ +│ │ ├── add.ejs # Formulário de cadastro +│ │ ├── addok.ejs # Confirmação do cadastro +│ │ └── lst.ejs # Listagem tabular com loop EJS +│ └── erro.ejs # Páginas de erro 404 e 500 +├── .gitignore +├── app.js # Servidor Express, EJS e conexão com o MongoDB +├── seed.js # Popula o banco com instrumentos de teste +├── package.json # Configurações do projeto e dependências +└── README.md # Documentação do projeto +``` + +--- + +## 🚀 Como Executar o Projeto Localmente + +Pré-requisitos: **Node.js 18+** e **MongoDB** escutando em `127.0.0.1:27017`. + +1. **Clone o repositório:** + ```bash + git clone https://gitea.tsiad.com.br/anderson/DBE-S04.git + cd DBE-S04 + ``` + +2. **Instale as dependências:** + ```bash + npm install + ``` + +3. **Popule o banco com os instrumentos de teste (opcional):** + ```bash + npm run seed + ``` + +4. **Inicie a aplicação:** + - Modo padrão: + ```bash + npm start + ``` + - Modo de desenvolvimento (watch mode): + ```bash + npm run dev + ``` + +5. **Acesse no navegador:** + [http://localhost:3000/instrumentos](http://localhost:3000/instrumentos) + +--- + +## ⚙️ Configuração + +As variáveis de ambiente são opcionais: + +| Variável | Padrão | +|---|---| +| `PORT` | `3000` | +| `MONGODB_URI` | `mongodb://127.0.0.1:27017/loja_instrumentos` | + +Exemplo: + +```bash +MONGODB_URI="mongodb://127.0.0.1:27017/loja_instrumentos" PORT=3000 npm start +``` + +--- + +## 🗃️ Modelo `Instrumento` + +| Campo | Tipo | Regras | +|---|---|---| +| `nome` | String | obrigatório, até 120 caracteres | +| `fabricante` | String | obrigatório, até 120 caracteres | +| `preco` | Number | obrigatório, maior ou igual a zero | +| `tipo` | String | obrigatório, um dos tipos da lista | + +Tipos aceitos: Cordas, Percussão, Teclas, Sopro, Áudio e Acessórios. + +--- + +## 📸 Telas + +![Listagem de instrumentos](docs/listagem.png) + +![Formulário de cadastro](docs/cadastro.png) + +![Confirmação do cadastro](docs/confirmacao.png) + +A listagem também funciona em telas pequenas (a tabela rola na horizontal): +[docs/listagem-mobile.png](docs/listagem-mobile.png). diff --git a/app.js b/app.js new file mode 100644 index 0000000..039ccba --- /dev/null +++ b/app.js @@ -0,0 +1,68 @@ +// Anderson Valadares Pinto (20251PL.TSIAD0018) [SLS] + +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import express from 'express'; +import mongoose from 'mongoose'; + +import instrumentoRoutes from './routes/instrumento.js'; + +// Configuração para resolução de caminhos com ES Modules +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const app = express(); +const PORT = Number(process.env.PORT) || 3000; +const MONGODB_URI = + process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/loja_instrumentos'; + +// Configuração do mecanismo de visualização EJS +app.set('view engine', 'ejs'); +app.set('views', path.join(__dirname, 'views')); + +app.use(express.urlencoded({ extended: true })); + +// Funções de formatação disponíveis em todos os templates. +app.locals.formatarPreco = (valor) => + new Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL', + }).format(Number(valor) || 0); + +app.use('/', instrumentoRoutes); + +// Página não encontrada. +app.use((req, res) => { + res.status(404).render('erro', { + titulo: 'Página Não Encontrada', + codigo: 404, + mensagem: 'O endereço que você tentou abrir não existe.', + }); +}); + +// Qualquer erro inesperado cai aqui, em vez de derrubar o servidor. +app.use((erro, req, res, next) => { + console.error(erro); + res.status(500).render('erro', { + titulo: 'Erro Interno', + codigo: 500, + mensagem: 'Algo deu errado ao processar a solicitação. Tente novamente.', + }); +}); + +async function iniciar() { + await mongoose.connect(MONGODB_URI); + console.log(`Conectado ao MongoDB em ${MONGODB_URI}`); + + app.listen(PORT, () => { + console.log( + `Servidor rodando com sucesso na porta ${PORT}: http://localhost:${PORT}/instrumentos` + ); + }); +} + +iniciar().catch((erro) => { + console.error('Não foi possível iniciar a aplicação:', erro.message); + process.exit(1); +}); diff --git a/docs/cadastro.png b/docs/cadastro.png new file mode 100644 index 0000000..c592ac9 Binary files /dev/null and b/docs/cadastro.png differ diff --git a/docs/confirmacao.png b/docs/confirmacao.png new file mode 100644 index 0000000..e8dbd85 Binary files /dev/null and b/docs/confirmacao.png differ diff --git a/docs/listagem-mobile.png b/docs/listagem-mobile.png new file mode 100644 index 0000000..c959498 Binary files /dev/null and b/docs/listagem-mobile.png differ diff --git a/docs/listagem.png b/docs/listagem.png new file mode 100644 index 0000000..f879234 Binary files /dev/null and b/docs/listagem.png differ diff --git a/models/Instrumento.js b/models/Instrumento.js new file mode 100644 index 0000000..ea2bb18 --- /dev/null +++ b/models/Instrumento.js @@ -0,0 +1,52 @@ +// Anderson Valadares Pinto (20251PL.TSIAD0018) [SLS] + +import mongoose from 'mongoose'; + +// Tipos aceitos no formulário. A lista também alimenta o + > + + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ Use ponto para os centavos — por exemplo, 1499.90. +
+
+
+ +
+ + + Cancelar + +
+ + + + + + + + + + + + + diff --git a/views/instrumento/addok.ejs b/views/instrumento/addok.ejs new file mode 100644 index 0000000..a47f4d4 --- /dev/null +++ b/views/instrumento/addok.ejs @@ -0,0 +1,123 @@ + + + + + + + <%= titulo %> | Loja de Instrumentos + + + + + + + + + + + +
+
+
+
+
+ + Cadastro realizado + + Ficha do Instrumento +
+
+
+ +
+

<%= titulo %>

+

+ <%= instrumento.nome %> já está no estoque da loja. +

+ +
+
+ + Nome: + + <%= instrumento.nome %> +
+
+ + Fabricante: + + <%= instrumento.fabricante %> +
+
+ + Tipo: + + + <%= instrumento.tipo %> + +
+
+ + Preço: + + <%= formatarPreco(instrumento.preco) %> +
+
+ + +
+
+
+
+
+ + + + + + + diff --git a/views/instrumento/lst.ejs b/views/instrumento/lst.ejs new file mode 100644 index 0000000..f49a78d --- /dev/null +++ b/views/instrumento/lst.ejs @@ -0,0 +1,139 @@ + + + + + + + <%= titulo %> | Loja de Instrumentos + + + + + + + + + + + +
+
+
+

+ <%= titulo %> +

+

+ Estoque da loja cadastrado no MongoDB. +

+
+ + Cadastrar Instrumento + +
+ + +
+
+ + + + + + + + + + + + <% if (instrumentos && instrumentos.length > 0) { %> + <% for (let i = 0; i < instrumentos.length; i++) { %> + <% const instrumento = instrumentos[i]; %> + + + + + + + + <% } %> + <% } else { %> + + + + <% } %> + +
#NomeFabricanteTipoPreço
+ + <%= i + 1 %> + + + <%= instrumento.nome %> + + <%= instrumento.fabricante %> + + + <%= instrumento.tipo %> + + + <%= formatarPreco(instrumento.preco) %> +
+
+ +

Nenhum instrumento cadastrado no estoque no momento.

+ + Cadastrar o primeiro instrumento + +
+
+
+
+ +

+ Quer incluir outro item? + Cadastrar novo instrumento +

+
+ + + + + + +