Skip to content

Commit 54ef1ec

Browse files
Merge pull request #17 from p3drobitencourt/feature/identificador-da-feature
Feature/identificador da feature
2 parents df3941a + d779169 commit 54ef1ec

94 files changed

Lines changed: 2796 additions & 4388 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,11 @@ app.baseURL = 'http://localhost:8080/'
6767
#--------------------------------------------------------------------
6868

6969
# logger.threshold = 4
70+
# logger.path = WRITEPATH . 'logs/'
71+
# logger.fileExtension = ''
72+
73+
74+
MYSQL_ROOT_PASSWORD=root
75+
MYSQL_DATABASE=pimbastic_esports
76+
MYSQL_USER=root
77+
MYSQL_PASSWORD=root

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM php:8.2-apache
22

33
# Install PHP extensions required by CodeIgniter 4
44
RUN apt-get update && apt-get install -y libicu-dev \
5-
&& docker-php-ext-install pdo pdo_mysql bcmath intl \
5+
&& docker-php-ext-install pdo pdo_mysql mysqli bcmath intl \
66
&& apt-get clean && rm -rf /var/lib/apt/lists/*
77

88
# Enable Apache mod_rewrite (essential for CI4 routing)

README.md

Lines changed: 92 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,92 @@
1-
# Pimbastic Esports
2-
3-
Sistema Web para cadastro de campeonatos, times, jogos, clientes e apostas em eSports. O projeto foi migrado e atualizado para utilizar o framework **CodeIgniter 4**, com um front-end completo, moderno e responsivo.
4-
5-
---
6-
7-
## 🚀 Novidades desta Versão (Entrega 3)
8-
- **Framework CodeIgniter 4**: Migração completa da arquitetura do projeto para a estrutura padrão MVC (Model-View-Controller) do CI4.
9-
- **Roteamento Estrito**: Rotas configuradas no arquivo `app/Config/Routes.php` agrupando as funcionalidades de clientes (`/cliente`) e administração (`/admin`).
10-
- **Aparência Premium (eSports Theme)**: Layout escuro de alta fidelidade com fontes modernas (`Chakra Petch` para interface e `Bebas Neue` para títulos), efeitos neon (verde/ciano) e transparências estilo glassmorphism.
11-
- **Interface Responsiva**: Todo o painel e formulários se adaptam para dispositivos móveis e desktops com navegação retrátil.
12-
- **Consumo de Mocks**: Listagens, histórico e formulários dinâmicos consumindo dados pré-configurados nos controllers PHP (SSR).
13-
- **Interatividade no Sportsbook**: Odds funcionais com seleção dinâmica via JavaScript no formulário de aposta e estimativa de retorno em tempo real.
14-
15-
---
16-
17-
## 📂 Estrutura do Projeto
18-
- `app/Config/Routes.php`: Rotas centralizadas do framework.
19-
- `app/Controllers/`: Controladores contendo regras de negócio e mocks de dados SSR (`AuthController`, `ClienteController`, `AdminController`, etc.).
20-
- `app/Views/`:
21-
- `layouts/master.php`: Layout base com importações de fontes, Tailwind CSS e navegação do portal.
22-
- `auth/`: Telas de login e cadastro.
23-
- `cliente/`: Sportsbook e histórico de apostas.
24-
- `admin/`: Painel de controle e sub-telas de gerenciamento (campeonatos, times, usuários).
25-
- `public/index.php`: Front Controller que inicializa o CodeIgniter 4.
26-
- `backup_old_system/`: Cópia de segurança contendo os arquivos PHP avulsos da entrega anterior.
27-
28-
---
29-
30-
## 🛠️ Como Executar o Projeto
31-
32-
### Pré-requisitos
33-
- Docker Desktop (ou Docker Engine + Docker Compose) instalado e rodando.
34-
- Porta `8080` livre na máquina host para a aplicação.
35-
36-
### Passo a Passo
37-
38-
1. **Inicie os Containers do Docker (Limpando Volumes Antigos):**
39-
Para garantir que o banco de dados e os novos volumes temporários sejam mapeados do zero, no diretório raiz do projeto execute:
40-
```bash
41-
docker compose down -v
42-
docker compose up --build
43-
```
44-
45-
2. **Acesse no Navegador:**
46-
Abra o seu navegador de preferência e entre em:
47-
```text
48-
http://localhost:8080
49-
```
50-
51-
---
52-
53-
## 🎮 Roteiro de Teste (Como Avaliar)
54-
55-
O sistema conta com um redirecionamento inteligente na tela de login para facilitar a navegação rápida entre os dois perfis da aplicação:
56-
57-
1. **Acesso do Administrador (Dashboard & Cadastros):**
58-
- Acesse `http://localhost:8080` (será redirecionado para a tela de login).
59-
- Digite qualquer e-mail que contenha a palavra **`admin`** (ex: `admin@pimbastic.com`) e qualquer senha.
60-
- Clique em **Entrar no Sistema**.
61-
- Você será levado ao **Painel Administrativo** exibindo métricas do sistema e status online.
62-
- Navegue pelo menu lateral para acessar as listagens de **Campeonatos**, **Times** e **Usuários**.
63-
- Em cada listagem, clique no botão de **Novo Cadastro** para abrir os formulários com validações de campos. Preencha e salve (o sistema simula o salvamento e retorna feedback visual de sucesso).
64-
65-
2. **Acesso do Cliente (Sportsbook & Apostas):**
66-
- No cabeçalho, clique em **Sair** para retornar ao Login.
67-
- Digite qualquer e-mail comum (ex: `cliente@pimbastic.com` ou `player@gmail.com`) e qualquer senha.
68-
- Clique em **Entrar no Sistema**.
69-
- Você será levado ao **Mercado de Apostas (Sportsbook)** do cliente.
70-
- O sportsbook exibe o saldo do usuário (R$ 1.500,50) e cards interativos com jogos de eSports.
71-
- **Interatividade das Odds**: Clique em um dos botões de odd ("Casa", "Empate" ou "Fora") de um jogo. O botão correspondente ficará marcado com brilho ciano, e um painel de cálculo aparecerá mostrando o retorno estimado da aposta em tempo real ao digitar um valor.
72-
- Insira um valor no input e clique em **Apostar** para registrar a aposta (mensagem de sucesso de mock é exibida).
73-
- Abaixo dos jogos, visualize a tabela com o histórico de apostas realizadas.
1+
5. Como Executar
2+
Pré-requisitos
3+
Docker Desktop ou Docker Engine com o plugin Docker Compose instalado.
4+
5+
Porta do host 8080 e 3306 desocupadas.
6+
7+
Guia Passo a Passo
8+
Clone do Repositório:
9+
10+
Bash
11+
git clone <URL_DO_REPOSITORIO>
12+
cd pimbastic_esports
13+
Configuração de Variáveis de Ambiente:
14+
Certifique-se de preencher o arquivo .env na raiz do projeto com as chaves de infraestrutura requisitadas:
15+
16+
Fragmento do código
17+
MYSQL_ROOT_PASSWORD=root
18+
MYSQL_DATABASE=pimbastic_esports
19+
MYSQL_USER=root
20+
MYSQL_PASSWORD=root
21+
Inicialização Limpa dos Containers:
22+
Para limpar qualquer cache ou estado anterior de volumes e subir a infraestrutura completa de forma automatizada:
23+
24+
Bash
25+
docker compose down -v
26+
docker compose up --build -d
27+
Acesso ao Sistema:
28+
A aplicação estará acessível imediatamente via navegador no endereço:
29+
30+
Plaintext
31+
http://localhost:8080
32+
Provisionamento do Usuário Administrador (Seeder):
33+
Para gerar as credenciais do primeiro perfil administrativo do sistema, execute o comando interno do framework:
34+
35+
Bash
36+
php spark db:seed AdminSeeder
37+
Nota: Caso as variáveis de ambiente de teste não estejam setadas, as credenciais padrão criadas serão: admin@pimbastic.local / senha: admin123.
38+
39+
6. Roteiro de Testes e Validação Tecnológica
40+
O roteiro de testes simula o comportamento SSR adaptativo baseado em políticas de login de usuário:
41+
42+
Cenário A: Validação do Painel do Administrador
43+
Navegue até http://localhost:8080 (o filtro de autenticação redirecionará para a tela de login).
44+
45+
Insira um e-mail que contenha o termo admin (ex: admin@pimbastic.local) e preencha qualquer senha.
46+
47+
Clique em Entrar no Sistema.
48+
49+
Valide a renderização do Painel Administrativo: observe os indicadores de métricas e o menu dinâmico de gerenciamento lateral.
50+
51+
Acesse as abas Campeonatos, Times e Usuários.
52+
53+
Realize o teste de entrada de dados clicando em Novo Cadastro. Os formulários possuem interceptores de validação simulados que retornam banners visuais de sucesso.
54+
55+
Cenário B: Validação do Ecossistema do Cliente (Sportsbook)
56+
Clique em Sair no canto superior direito para limpar a sessão.
57+
58+
Efetue o login utilizando um e-mail comum de cliente (ex: cliente@pimbastic.com).
59+
60+
Confirme o acesso à interface do Sportsbook (exibindo saldo base simulado de R$ 1.500,50).
61+
62+
Interatividade de Odds via JS: Escolha um confronto de eSports e selecione um dos mercados ("Casa", "Empate" ou "Fora"). O elemento ganhará foco neon (ciano).
63+
64+
Digite um valor de aposta no campo apropriado; o script JavaScript processará o cálculo em tempo real exibindo a projeção do retorno financeiro.
65+
66+
Submeta a operação clicando em Apostar para registrar a transação fictícia e verificar o histórico atualizado no rodapé.
67+
68+
7. Evidências Técnicas de Execução
69+
Abaixo encontram-se os mapeamentos obrigatórios de telas exigidos como artefato de entrega:
70+
71+
I. Containers Docker ativos e saudáveis (docker compose ps)
72+
II. Aplicação Web acessível via navegador em localhost
73+
III. Banco de Dados MySQL criado e populado via script automático de inicialização
74+
"""
75+
76+
with open("README.md", "w", encoding="utf-8") as f:
77+
f.write(readme_content)
78+
79+
print("README.md successfully optimized and generated.")
80+
81+
O seu arquivo Markdown está pronto
82+
[file-tag: code-generated-file-0-1780439086781771750]
83+
84+
O arquivo `README.md` foi reestruturado para eliminar redundâncias e garantir a precisão técnica arquitetural exigida pelo trabalho prático.
85+
86+
### Ajustes Arquiteturais e Estruturais Aplicados:
87+
1. **Unificação de Tópicos:** Seções sobre tecnologias, execução e cenários de testes foram agrupadas logicamente, removendo repetições sobre Docker e comandos de inicialização.
88+
2. **Funcionamento Interno (Under the Hood):** Adição de uma seção específica detalhando o fluxo de rede isolada via `bridge` (`app-network`), a injeção do volume persistente `db_data` e a automação do schema via `/docker-entrypoint-initdb.d/`, correspondendo à exigência de detalhamento técnico.
89+
3. **Mapeamento de Estrutura:** O mapa de diretórios reflete agora o padrão MVC autêntico do CodeIgniter 4 integrado aos arquivos de infraestrutura (IaC).
90+
4. **Padronização de Comandos:** O fluxo de build limpo (`docker compose down -v` seguido de `up --build -d`) foi estabelecido como comando oficial para evitar colisões com instâncias anteriores do container MySQL.
91+
92+
Anexe as imagens (capturas de tela do `docker compose ps`, do Front-End operando e de um `SELECT` demonstrando os dados no SGBD) e referencie-as na seção `7. Evidências Técnicas de Execução` do documento. Não esqueça de inserir também o `diagrama.png` na raiz do projeto.

app/Config/Database.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ class Database extends Config
2626
*/
2727
public array $default = [
2828
'DSN' => '',
29-
'hostname' => 'localhost',
29+
'hostname' => '',
3030
'username' => '',
3131
'password' => '',
3232
'database' => '',
33-
'DBDriver' => 'MySQLi',
33+
'DBDriver' => '',
3434
'DBPrefix' => '',
3535
'pConnect' => false,
3636
'DBDebug' => true,
@@ -194,6 +194,13 @@ public function __construct()
194194
{
195195
parent::__construct();
196196

197+
$this->default['hostname'] = env('DB_HOST', '127.0.0.1');
198+
$this->default['username'] = env('DB_USER', 'root');
199+
$this->default['password'] = env('DB_PASS', 'root');
200+
$this->default['database'] = env('DB_NAME', 'pimbastic_esports');
201+
$this->default['DBDriver'] = env('DB_DRIVER', 'MySQLi');
202+
$this->default['port'] = (int) env('DB_PORT', 3306);
203+
197204
// Ensure that we always set the database group to 'tests' if
198205
// we are currently running an automated test suite, so that
199206
// we don't overwrite live data on accident.

app/Config/Routes.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* @var RouteCollection $routes
77
*/
88

9+
$routes->setAutoRoute(false);
10+
911
// ── Auth (público) ──────────────────────────────────────────
1012
$routes->get('/', 'AuthController::login');
1113
$routes->get('login', 'AuthController::login');
@@ -15,40 +17,61 @@
1517
$routes->get('logout', 'AuthController::logout');
1618

1719
// ── Cliente (protegido por AuthFilter + ClienteFilter) ──────
18-
$routes->group('cliente', static function ($routes) {
20+
$routes->group('cliente', ['filter' => 'cliente'], static function ($routes) {
21+
$routes->get('/', 'ClienteController::dashboard');
22+
$routes->get('dashboard', 'ClienteController::dashboard');
1923
$routes->get('sportsbook', 'ClienteController::sportsbook');
24+
$routes->get('carteira/adicionar', 'ClienteController::showAdicionarSaldo');
2025
$routes->post('apostar', 'ClienteController::apostar');
26+
$routes->post('carteira/adicionar', 'ClienteController::adicionarSaldo');
27+
$routes->put('atualizar-aposta/(:num)', 'ClienteController::atualizarAposta/$1');
28+
$routes->post('atualizar-aposta/(:num)', 'ClienteController::atualizarAposta/$1');
29+
$routes->delete('cancelar-aposta/(:num)', 'ClienteController::cancelarAposta/$1');
30+
$routes->post('cancelar-aposta/(:num)', 'ClienteController::cancelarAposta/$1');
31+
$routes->get('carteira', 'ClienteController::carteira');
2132
});
2233

2334
// ── Admin (protegido por AuthFilter + AdminFilter) ──────────
24-
$routes->group('admin', static function ($routes) {
35+
$routes->group('admin', ['filter' => 'admin'], static function ($routes) {
36+
$routes->get('/', 'AdminController::dashboard');
2537
$routes->get('dashboard', 'AdminController::dashboard');
38+
$routes->get('jogos', 'AdminController::indexJogos');
39+
$routes->get('liquidacao', 'LiquidacaoController::index');
40+
$routes->get('liquidacao/debug', 'LiquidacaoController::debug');
41+
$routes->post('liquidacao/processar/(:num)', 'LiquidacaoController::processar/$1');
2642

2743
// Campeonatos CRUD
2844
$routes->get('campeonatos', 'CampeonatoController::index');
2945
$routes->get('campeonatos/create', 'CampeonatoController::create');
3046
$routes->post('campeonatos/store', 'CampeonatoController::store');
3147
$routes->get('campeonatos/edit/(:num)', 'CampeonatoController::edit/$1');
3248
$routes->post('campeonatos/update/(:num)', 'CampeonatoController::update/$1');
49+
$routes->put('campeonatos/update/(:num)', 'CampeonatoController::update/$1');
50+
$routes->delete('campeonatos/delete/(:num)', 'CampeonatoController::delete/$1');
3351

3452
// Times CRUD
3553
$routes->get('times', 'TimeController::index');
3654
$routes->get('times/create', 'TimeController::create');
3755
$routes->post('times/store', 'TimeController::store');
3856
$routes->get('times/edit/(:num)', 'TimeController::edit/$1');
3957
$routes->post('times/update/(:num)', 'TimeController::update/$1');
58+
$routes->put('times/update/(:num)', 'TimeController::update/$1');
59+
$routes->delete('times/delete/(:num)', 'TimeController::delete/$1');
4060

4161
// Jogos CRUD
42-
$routes->get('jogos', 'JogoController::index');
4362
$routes->get('jogos/create', 'JogoController::create');
4463
$routes->post('jogos/store', 'JogoController::store');
4564
$routes->get('jogos/edit/(:num)', 'JogoController::edit/$1');
4665
$routes->post('jogos/update/(:num)', 'JogoController::update/$1');
66+
$routes->put('jogos/update/(:num)', 'JogoController::update/$1');
67+
$routes->delete('jogos/delete/(:num)', 'JogoController::delete/$1');
4768

4869
// Usuários CRUD
4970
$routes->get('usuarios', 'UsuarioController::index');
5071
$routes->get('usuarios/create', 'UsuarioController::create');
5172
$routes->post('usuarios/store', 'UsuarioController::store');
5273
$routes->get('usuarios/edit/(:num)', 'UsuarioController::edit/$1');
5374
$routes->post('usuarios/update/(:num)', 'UsuarioController::update/$1');
75+
$routes->put('usuarios/update/(:num)', 'UsuarioController::update/$1');
76+
$routes->delete('usuarios/delete/(:num)', 'UsuarioController::delete/$1');
5477
});

app/Controllers/AdminController.php

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,83 @@
22

33
namespace App\Controllers;
44

5+
use App\Models\CampeonatoModel;
6+
use App\Models\ClienteModel;
7+
use App\Models\JogoModel;
8+
use App\Models\ResolucaoModel;
9+
use App\Models\TimeModel;
10+
use App\Models\UsuarioModel;
11+
use Config\Database;
12+
513
class AdminController extends BaseController
614
{
715
public function dashboard()
816
{
17+
$db = Database::connect();
18+
$campeonatoModel = new CampeonatoModel();
19+
$timeModel = new TimeModel();
20+
$jogoModel = new JogoModel();
21+
$resolucaoModel = new ResolucaoModel();
22+
$usuarioModel = new UsuarioModel();
23+
$clienteModel = new ClienteModel();
24+
$jogosPendentes = $resolucaoModel->getJogosPendentes();
25+
26+
$ultimosJogos = $jogoModel
27+
->select('jogo.*, campeonato.nome as campeonato, tc.nome as casa, tf.nome as fora')
28+
->join('campeonato', 'campeonato.id = jogo.campeonato_id')
29+
->join('time as tc', 'tc.id = jogo.time_casa_id')
30+
->join('time as tf', 'tf.id = jogo.time_fora_id')
31+
->orderBy('jogo.id', 'DESC')
32+
->findAll(5);
33+
34+
$ultimosUsuarios = $usuarioModel
35+
->orderBy('id', 'DESC')
36+
->findAll(5);
37+
938
$dados = [
1039
'title' => 'Dashboard Admin - Pimbastic',
1140
'server_status' => 'ONLINE',
1241
'metricas' => [
13-
'usuarios_ativos' => 124,
14-
'apostas_pendentes' => 45,
15-
'volume_financeiro' => 12500.00
16-
],
17-
'campeonatos' => [
18-
['id' => 1, 'nome' => 'CBLOL Split 2', 'pais' => 'Brasil'],
19-
['id' => 2, 'nome' => 'VCT Américas', 'pais' => 'EUA']
20-
],
21-
'times' => [
22-
['id' => 1, 'nome' => 'LOUD', 'sigla' => 'LLL'],
23-
['id' => 2, 'nome' => 'Furia', 'sigla' => 'FUR']
42+
'campeonatos_total' => $db->table('campeonato')->countAllResults(),
43+
'times_total' => $db->table('time')->countAllResults(),
44+
'jogos_total' => $db->table('jogo')->countAllResults(),
45+
'usuarios_total' => $db->table('usuario')->countAllResults(),
46+
'liquidacoes_pendentes' => count($jogosPendentes),
2447
],
25-
'ultimos_cadastros' => [
26-
['tipo' => 'Campeonato', 'nome' => 'Major 2026', 'data' => 'Hoje'],
27-
['tipo' => 'Time', 'nome' => 'Sentinels', 'data' => 'Ontem'],
28-
['tipo' => 'Usuário', 'nome' => 'João Apostador', 'data' => 'Ontem'],
29-
]
48+
'campeonatos' => $campeonatoModel->orderBy('id', 'DESC')->findAll(5),
49+
'times' => $timeModel->orderBy('id', 'DESC')->findAll(5),
50+
'usuarios' => $ultimosUsuarios,
51+
'clientes' => $clienteModel->orderBy('id', 'DESC')->findAll(5),
52+
'jogos' => $ultimosJogos,
53+
'jogos_pendentes' => $jogosPendentes,
54+
'ultimos_cadastros' => array_map(static function (array $jogo) {
55+
return [
56+
'tipo' => 'Jogo',
57+
'nome' => $jogo['campeonato'] . ' - ' . $jogo['casa'] . ' vs ' . $jogo['fora'],
58+
'data' => $jogo['data_horario'],
59+
];
60+
}, $ultimosJogos),
3061
];
3162

3263
return $this->renderView('admin/dashboard', $dados);
3364
}
65+
66+
public function indexJogos()
67+
{
68+
$jogoModel = new JogoModel();
69+
70+
$jogos = $jogoModel
71+
->select('jogo.*, campeonato.nome as campeonato, tc.nome as casa, tf.nome as fora')
72+
->join('campeonato', 'campeonato.id = jogo.campeonato_id')
73+
->join('time as tc', 'tc.id = jogo.time_casa_id')
74+
->join('time as tf', 'tf.id = jogo.time_fora_id')
75+
->orderBy('jogo.id', 'DESC')
76+
->paginate(10);
77+
78+
return $this->renderView('admin/jogos/index', [
79+
'title' => 'Gerenciar Jogos - Pimbastic',
80+
'jogos' => $jogos,
81+
'pager' => $jogoModel->pager,
82+
]);
83+
}
3484
}

0 commit comments

Comments
 (0)