O que a tela principal faz
- Mostra filtros, botões e modais.
- Carrega a listagem inicial.
- Dispara chamadas AJAX para os arquivos internos.
- Atualiza a interface após salvar, buscar ou excluir.
Esta página mostra o esqueleto ideal de um módulo para manter o BarberBot consistente. O objetivo é ajudar o próximo desenvolvedor a saber quais arquivos criar, qual responsabilidade cada um tem e como organizar o fluxo.
No BarberBot, um módulo normalmente é composto por uma tela principal e uma subpasta com arquivos operacionais. A tela principal monta a interface e os arquivos internos executam as ações.
listar.php consulta e monta HTML.salvar.php insere ou atualiza dados.buscar.php carrega um registro específico.excluir.php remove um registro.Quando for criar ou reorganizar um módulo, este é o formato mais previsível para o BarberBot:
/public_html/sistema/painel/paginas/nome_modulo.php
/public_html/sistema/painel/paginas/nome_modulo/listar.php
/public_html/sistema/painel/paginas/nome_modulo/salvar.php
/public_html/sistema/painel/paginas/nome_modulo/buscar.php
/public_html/sistema/painel/paginas/nome_modulo/excluir.php
nome_modulo.php fica diretamente em /paginas e representa a tela.
A subpasta /nome_modulo concentra as operações que a tela chama por AJAX.
nome_modulo.phpArquivo de interface. Deve concentrar HTML da tela, filtros, modais, botões e chamadas AJAX.
listar.phpArquivo de listagem. Deve consultar o banco, aplicar filtros, montar a tabela e devolver HTML.
salvar.phpArquivo de persistência. Deve validar entradas e executar INSERT ou UPDATE.
buscar.phpArquivo de carregamento individual. Deve retornar dados de um registro para preencher formulário ou modal.
excluir.phpArquivo de remoção. Deve validar o ID, excluir com segurança e retornar status simples para a tela.
nome_modulo.phpEste arquivo deve ser a porta de entrada do módulo. Ele monta a tela, exibe o formulário e dispara as ações.
<?php
require_once("../../conexao.php");
$pag = 'nome_modulo';
?>
<div class="titulo-pagina">
<h2><?php echo ucfirst(str_replace('_', ' ', $pag)); ?></h2>
<button type="button" class="btn btn-primary" onclick="abrirModalCadastro()">Novo cadastro</button>
</div>
<div class="filtros-pagina">
<input type="text" id="busca" class="form-control" placeholder="Buscar...">
<button type="button" class="btn btn-secondary" onclick="listar()">Filtrar</button>
</div>
<div id="listar"></div>
<div class="modal fade" id="modalForm" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form id="form">
<div class="modal-header">
<h5 class="modal-title" id="tituloModal">Cadastrar registro</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" name="id" id="id">
<div class="row">
<div class="col-md-12">
<label>Nome</label>
<input type="text" class="form-control" name="nome" id="nome" required>
</div>
</div>
<small id="mensagem"></small>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Salvar</button>
</div>
</form>
</div>
</div>
</div>
<script>
function listar() {
var busca = $('#busca').val();
$.ajax({
url: 'paginas/' + 'nome_modulo' + '/listar.php',
method: 'POST',
data: { busca: busca },
dataType: 'html',
success: function(resposta) {
$('#listar').html(resposta);
}
});
}
function abrirModalCadastro() {
limparCampos();
$('#tituloModal').text('Cadastrar registro');
$('#modalForm').modal('show');
}
function limparCampos() {
$('#id').val('');
$('#nome').val('');
$('#mensagem').text('');
}
$('#form').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: 'paginas/' + 'nome_modulo' + '/salvar.php',
method: 'POST',
data: new FormData(this),
processData: false,
contentType: false,
success: function(resposta) {
if (resposta.trim() === 'Salvo com Sucesso') {
$('#modalForm').modal('hide');
listar();
} else {
$('#mensagem').text(resposta);
}
}
});
});
$(document).ready(function() {
listar();
});
</script>listar.phpResponsável por consultar, tratar lista vazia e retornar o HTML da tabela já pronto para a tela.
<?php
require_once("../../../conexao.php");
@session_start();
$busca = trim($_POST['busca'] ?? '');
$sql = "SELECT * FROM nome_tabela WHERE nome LIKE :busca ORDER BY id DESC";
$query = $pdo->prepare($sql);
$query->bindValue(':busca', '%' . $busca . '%');
$query->execute();
$res = $query->fetchAll(PDO::FETCH_ASSOC);
$total_reg = count($res);
if ($total_reg == 0) {
echo '<div class="alert alert-light border">Nenhum registro encontrado.</div>';
exit();
}
?>
<table class="table table-hover">
<thead>
<tr>
<th>Nome</th>
<th class="esc">Data</th>
<th width="120">Ações</th>
</tr>
</thead>
<tbody>
<?php foreach ($res as $item): ?>
<tr>
<td><?php echo htmlspecialchars($item['nome']); ?></td>
<td class="esc"><?php echo date('d/m/Y', strtotime($item['data_cad'])); ?></td>
<td>
<button type="button" class="btn btn-sm btn-outline-primary"
onclick="editar('<?php echo $item['id']; ?>')">Editar</button>
<button type="button" class="btn btn-sm btn-outline-danger"
onclick="excluir('<?php echo $item['id']; ?>')">Excluir</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>salvar.phpDeve centralizar validação mínima e persistência. O retorno deve ser simples para o AJAX interpretar.
<?php
require_once("../../../conexao.php");
@session_start();
$id = (int)($_POST['id'] ?? 0);
$nome = trim($_POST['nome'] ?? '');
if ($nome === '') {
echo 'Preencha o campo nome';
exit();
}
if ($id > 0) {
$query = $pdo->prepare("UPDATE nome_tabela SET nome = :nome WHERE id = :id");
$query->bindValue(':id', $id, PDO::PARAM_INT);
} else {
$query = $pdo->prepare("INSERT INTO nome_tabela SET nome = :nome, data_cad = curDate()");
}
$query->bindValue(':nome', $nome);
$query->execute();
echo 'Salvo com Sucesso';buscar.phpIndicado para edição em modal. O ideal é responder em JSON para preencher campos no JavaScript.
<?php
require_once("../../../conexao.php");
@session_start();
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
echo json_encode(['sucesso' => false, 'mensagem' => 'ID inválido']);
exit();
}
$query = $pdo->prepare("SELECT * FROM nome_tabela WHERE id = :id LIMIT 1");
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute();
$res = $query->fetch(PDO::FETCH_ASSOC);
if (!$res) {
echo json_encode(['sucesso' => false, 'mensagem' => 'Registro não encontrado']);
exit();
}
echo json_encode([
'sucesso' => true,
'dados' => [
'id' => $res['id'],
'nome' => $res['nome']
]
]);excluir.phpDeve ser objetivo: validar o ID, excluir o registro e retornar uma mensagem curta de sucesso ou erro.
<?php
require_once("../../../conexao.php");
@session_start();
$id = (int)($_POST['id'] ?? 0);
if ($id <= 0) {
echo 'ID inválido';
exit();
}
$query = $pdo->prepare("DELETE FROM nome_tabela WHERE id = :id");
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute();
echo 'Excluído com Sucesso';O módulo ideal do BarberBot segue um fluxo simples e previsível. Isso facilita depuração, manutenção e onboarding de novos devs.
nome_modulo.php
↓
listar.php
↓
conexao.php
↓
SELECT na tabela
↓
HTML volta para a tela
nome_modulo.php
↓
salvar.php
↓
conexao.php
↓
INSERT / UPDATE
↓
mensagem de retorno
↓
listar.php é chamado novamente
O padrão mais simples é: salvar, fechar modal, chamar listar() novamente.
Para buscar um registro e preencher formulário, JSON costuma ser melhor do que HTML.
/paginas.prepare e bindValue.htmlspecialchars quando necessário.