Initial commit

This commit is contained in:
2025-08-22 00:00:43 -03:00
commit a20f36a624
11 changed files with 1225 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
# bairrao

39
banco.sql Normal file
View File

@@ -0,0 +1,39 @@
CREATE TABLE times (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(100),
pontos INT,
jogos INT,
vitorias INT,
empates INT,
derrotas INT,
gols_pro INT,
gols_contra INT,
saldo_gols INT,
aproveitamento INT,
ultimos_jogos VARCHAR(20)
);
INSERT INTO times (nome, pontos, jogos, vitorias, empates, derrotas, gols_pro, gols_contra, saldo_gols, aproveitamento, ultimos_jogos) VALUES
('Palmeiras', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Flamengo', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Fluminense', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Bragantino', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Ceará', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Corinthians', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Cruzeiro', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Vasco', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('Juventude', 0, 0, 0, 0, 0, 0, 0, 0, 0, ''),
('São Paulo', 0, 0, 0, 0, 0, 0, 0, 0, 0, '');
CREATE TABLE IF NOT EXISTS historico_jogos (
id INT AUTO_INCREMENT PRIMARY KEY,
time_casa VARCHAR(100) NOT NULL,
time_visitante VARCHAR(100) NOT NULL,
gols_casa INT,
gols_visitante INT,
data_jogo TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
rodada INT NOT NULL,
CONSTRAINT check_different_teams CHECK (time_casa != time_visitante),
INDEX idx_rodada (rodada),
INDEX idx_data_jogo (data_jogo)
);

103
cadastro.php Normal file
View File

@@ -0,0 +1,103 @@
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Cadastrar Novo Jogo</title>
<link rel="stylesheet" href="estilo.css">
</head>
<body>
<?php
include 'controller.php';
?>
<h1>Cadastrar Novo Jogo</h1>
<div class="cadastro-container">
<?php if (isset($_GET['error'])): ?>
<div class="error-message">
<?php
if ($_GET['error'] == 1) echo "O time da casa e visitante não podem ser iguais!";
if ($_GET['error'] == 2) echo "Senha incorreta!";
if ($_GET['error'] == 4) echo "Data inválida!";
if ($_GET['error'] == 5) echo "Todos os campos são obrigatórios!";
if ($_GET['error'] == 6) echo "Rodada deve ser um número positivo!";
if ($_GET['error'] == 7 && isset($_GET['detail'])) echo htmlspecialchars(urldecode($_GET['detail']));
?>
</div>
<?php endif; ?>
<?php if (isset($_GET['success'])): ?>
<div class="success-message">
<?php if ($_GET['success'] == 2) echo "Jogo cadastrado com sucesso!"; ?>
</div>
<?php endif; ?>
<form action="controller.php?action=save_next" method="post">
<div class="jogo-container">
<select name="time_casa" class="time-select" required>
<option value="">Selecione o time da casa</option>
<?php
$sql = "SELECT nome FROM times ORDER BY nome";
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
echo "<option value='{$row['nome']}'>{$row['nome']}</option>";
}
?>
</select>
<span class="vs-text">X</span>
<select name="time_visitante" class="time-select" required>
<option value="">Selecione o time visitante</option>
<?php
$sql = "SELECT nome FROM times ORDER BY nome";
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
echo "<option value='{$row['nome']}'>{$row['nome']}</option>";
}
?>
</select>
</div>
<div class="senha-rodada-container">
<div class="form-group">
<label for="rodada">Rodada:</label>
<input type="number" name="rodada" min="1" required class="gols-input">
</div>
<div class="form-group">
<label for="data_jogo">Data e Hora do Jogo:</label>
<input type="datetime-local" name="data_jogo" required>
</div>
<div class="form-group">
<label for="senha">Senha de Administração:</label>
<div class="password-container">
<input type="password" name="senha" class="password-input" required>
</div>
</div>
<div class="btn-lancar-container">
<button type="submit" class="btn-lancar">Cadastrar Jogo</button>
</div>
</div>
</form>
</div>
<div class="voltar-link-container">
<a href="index.php?view=tabela" class="voltar-link">Voltar para a Tabela</a>
</div>
<script>
// Validação para evitar times iguais
document.querySelector('form').addEventListener('submit', function(e) {
const timeCasa = document.querySelector('select[name="time_casa"]').value;
const timeVisitante = document.querySelector('select[name="time_visitante"]').value;
if (timeCasa && timeVisitante && timeCasa === timeVisitante) {
e.preventDefault();
alert('O time da casa e o visitante não podem ser iguais!');
}
});
</script>
</body>
</html>

240
controller.php Normal file
View File

@@ -0,0 +1,240 @@
<?php
$conn = new mysqli("localhost", "root", "", "tabela");
if ($conn->connect_error) {
die("Conexão falhou: " . $conn->connect_error);
}
// Definir senha de administração
define('ADMIN_PASSWORD', 'senha123');
function verificarSenha() {
if (!isset($_POST['senha']) || $_POST['senha'] !== ADMIN_PASSWORD) {
header("Location: index.php?view=tabela&error=2");
exit();
}
}
function displayTeams($conn) {
$ordenar_por = isset($_GET['ordenar']) ? $conn->real_escape_string($_GET['ordenar']) : 'pontos';
$ordem = isset($_GET['ordem']) && $_GET['ordem'] === 'asc' ? 'ASC' : 'DESC';
$busca = isset($_GET['busca']) ? $conn->real_escape_string($_GET['busca']) : '';
$filtro = $busca ? "WHERE nome LIKE '%$busca%'" : '';
$sql = "SELECT * FROM times $filtro ORDER BY $ordenar_por $ordem, saldo_gols DESC, gols_pro DESC";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$pos = 1;
while ($row = $result->fetch_assoc()) {
$nome_time = $row['nome'];
$nome_arquivo = preg_replace('/[^a-zA-Z0-9]/', '', strtolower(iconv('UTF-8', 'ASCII//TRANSLIT', $nome_time)));
$caminho_escudo = "escudos/$nome_arquivo.png";
if (!file_exists($caminho_escudo)) {
$caminho_escudo = "escudos/escudo-generico.png";
}
echo "<tr>";
echo "<td>{$pos}</td>";
echo "<td><div style='display: flex; align-items: center; justify-content: center; gap: 10px;'>";
echo "<img src='{$caminho_escudo}' class='escudo' alt='{$row['nome']}'>";
echo $row['nome'];
echo "</div></td>";
echo "<td>{$row['pontos']}</td>";
echo "<td>{$row['jogos']}</td>";
echo "<td>{$row['vitorias']}</td>";
echo "<td>{$row['empates']}</td>";
echo "<td>{$row['derrotas']}</td>";
echo "<td>{$row['gols_pro']}</td>";
echo "<td>{$row['gols_contra']}</td>";
echo "<td>{$row['saldo_gols']}</td>";
echo "<td>{$row['aproveitamento']}</td>";
echo "<td class='ultimos-jogos'>";
foreach (explode(",", $row['ultimos_jogos']) as $res) {
if ($res) echo "<span class='$res'></span>";
}
echo "</td></tr>";
$pos++;
}
} else {
echo "<tr><td colspan='12'>Nenhum dado encontrado.</td></tr>";
}
}
function displayGames($conn, $rodada) {
$sql = "SELECT * FROM historico_jogos WHERE rodada = $rodada ORDER BY data_jogo";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$data = new DateTime($row['data_jogo']);
$diaSemana = $data->format('l');
$diaSemana = str_replace(
['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
$diaSemana
);
// Obter caminhos dos escudos
$nome_casa = preg_replace('/[^a-zA-Z0-9]/', '', strtolower(iconv('UTF-8', 'ASCII//TRANSLIT', $row['time_casa'])));
$nome_visitante = preg_replace('/[^a-zA-Z0-9]/', '', strtolower(iconv('UTF-8', 'ASCII//TRANSLIT', $row['time_visitante'])));
$escudo_casa = file_exists("escudos/$nome_casa.png") ? "escudos/$nome_casa.png" : "escudos/escudo-generico.png";
$escudo_visitante = file_exists("escudos/$nome_visitante.png") ? "escudos/$nome_visitante.png" : "escudos/escudo-generico.png";
echo "<div class='jogo-item'>";
echo "<div class='jogo-rodada'>Rodada {$row['rodada']}</div>";
echo "<div class='jogo-times'>";
echo "<div class='time-com-escudo'><img src='$escudo_casa' class='escudo-jogo' alt='{$row['time_casa']}'> {$row['time_casa']}</div>";
if ($row['gols_casa'] !== null && $row['gols_visitante'] !== null) {
echo "<div class='jogo-placar'>";
echo "<span>{$row['gols_casa']}</span>";
echo "<span>X</span>";
echo "<span>{$row['gols_visitante']}</span>";
echo "</div>";
} else {
echo "<div class='jogo-placar'><span>X</span></div>";
}
echo "<div class='time-com-escudo'><img src='$escudo_visitante' class='escudo-jogo' alt='{$row['time_visitante']}'> {$row['time_visitante']}</div>";
echo "</div>";
echo "<div class='jogo-info'>";
echo "<span>{$data->format('d/m')} - {$diaSemana}</span>";
echo "<span>{$data->format('H:i')}</span>";
echo "</div>";
echo "</div>";
}
} else {
echo "<p>Nenhum jogo cadastrado para a rodada $rodada.</p>";
}
}
function saveGameResult($conn) {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'save') {
verificarSenha();
$jogo_id = (int)$_POST['jogo_id'];
$gols_casa = (int)$_POST['gols_casa'];
$gols_visitante = (int)$_POST['gols_visitante'];
// Verificar se o jogo existe
$sql = "SELECT time_casa, time_visitante, rodada FROM historico_jogos WHERE id = $jogo_id AND gols_casa IS NULL AND gols_visitante IS NULL";
$result = $conn->query($sql);
if ($result->num_rows === 0) {
header("Location: lancar.php?error=3");
exit();
}
$jogo = $result->fetch_assoc();
$time_casa = $conn->real_escape_string($jogo['time_casa']);
$time_visitante = $conn->real_escape_string($jogo['time_visitante']);
$rodada = (int)$jogo['rodada'];
// Atualizar o jogo com os resultados
$sql_update = "UPDATE historico_jogos SET gols_casa = $gols_casa, gols_visitante = $gols_visitante WHERE id = $jogo_id";
if (!$conn->query($sql_update)) {
die("Erro ao registrar resultado: " . $conn->error);
}
// Função para atualizar estatísticas
function atualizarEstatisticas($conn, $time, $gols_pro, $gols_contra, $resultado) {
$pontos = 0;
$vitorias = 0;
$empates = 0;
$derrotas = 0;
switch ($resultado) {
case 'v':
$pontos = 3;
$vitorias = 1;
break;
case 'e':
$pontos = 1;
$empates = 1;
break;
case 'd':
$derrotas = 1;
break;
}
$sql = "UPDATE times SET
pontos = pontos + $pontos,
jogos = jogos + 1,
vitorias = vitorias + $vitorias,
empates = empates + $empates,
derrotas = derrotas + $derrotas,
gols_pro = gols_pro + $gols_pro,
gols_contra = gols_contra + $gols_contra,
saldo_gols = saldo_gols + ($gols_pro - $gols_contra),
ultimos_jogos = CONCAT('$resultado,', IFNULL(ultimos_jogos, ''))
WHERE nome = '$time'";
if (!$conn->query($sql)) {
die("Erro ao atualizar estatísticas do time $time: " . $conn->error);
}
}
// Atualizar estatísticas com base no resultado
if ($gols_casa > $gols_visitante) {
atualizarEstatisticas($conn, $time_casa, $gols_casa, $gols_visitante, 'v');
atualizarEstatisticas($conn, $time_visitante, $gols_visitante, $gols_casa, 'd');
} elseif ($gols_casa == $gols_visitante) {
atualizarEstatisticas($conn, $time_casa, $gols_casa, $gols_visitante, 'e');
atualizarEstatisticas($conn, $time_visitante, $gols_visitante, $gols_casa, 'e');
} else {
atualizarEstatisticas($conn, $time_casa, $gols_casa, $gols_visitante, 'd');
atualizarEstatisticas($conn, $time_visitante, $gols_visitante, $gols_casa, 'v');
}
// Atualizar aproveitamento
$conn->query("UPDATE times SET aproveitamento = ROUND((pontos / (jogos * 3)) * 100) WHERE jogos > 0");
header("Location: lancar.php?success=1");
exit();
}
}
function saveNextGame($conn) {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'save_next') {
verificarSenha();
// Verifica se todos os campos necessários foram enviados
if (!isset($_POST['time_casa']) || !isset($_POST['time_visitante']) || !isset($_POST['rodada']) || !isset($_POST['data_jogo'])) {
header("Location: cadastro.php?error=5");
exit();
}
$time_casa = $conn->real_escape_string($_POST['time_casa']);
$time_visitante = $conn->real_escape_string($_POST['time_visitante']);
$rodada = (int)$_POST['rodada'];
$data_jogo = $conn->real_escape_string($_POST['data_jogo']);
// Validações
if ($time_casa === $time_visitante) {
header("Location: cadastro.php?error=1");
exit();
}
if ($rodada < 1) {
header("Location: cadastro.php?error=6");
exit();
}
if (!strtotime($data_jogo)) {
header("Location: cadastro.php?error=4");
exit();
}
// Formata a data para o formato MySQL
$data_formatada = date('Y-m-d H:i:s', strtotime($data_jogo));
$sql = "INSERT INTO historico_jogos (time_casa, time_visitante, rodada, data_jogo)
VALUES ('$time_casa', '$time_visitante', $rodada, '$data_formatada')";
if ($conn->query($sql)) {
header("Location: cadastro.php?success=2");
} else {
// Adiciona mensagem de erro mais detalhada
$error_msg = urlencode("Erro ao cadastrar jogo: " . $conn->error);
header("Location: cadastro.php?error=7&detail=" . $error_msg);
}
exit();
}
}
// Handle game result saving
saveGameResult($conn);
// Handle next game saving
saveNextGame($conn);
?>

BIN
escudos/cruzeiro.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 KiB

BIN
escudos/escudo-generico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

632
estilo.css Normal file
View File

@@ -0,0 +1,632 @@
/* Estilos gerais do sistema (mantidos inalterados) */
body {
font-family: 'Arial', sans-serif;
background: #f5f5f5;
padding: 20px;
color: #333;
}
h1 {
text-align: center;
color: #006341;
margin-bottom: 20px;
font-size: 2.2em;
}
.tabela-wrapper {
overflow-x: auto;
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 15px;
margin-top: 20px;
}
table {
border-collapse: collapse;
width: 100%;
background: #fff;
}
th, td {
padding: 12px 15px;
text-align: center;
border-bottom: 1px solid #e0e0e0;
}
th {
background: #006341;
color: white;
font-weight: 600;
text-transform: uppercase;
font-size: 0.85em;
letter-spacing: 0.5px;
}
th a {
color: white;
text-decoration: none;
display: block;
padding: 5px;
}
th a:hover {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 3px;
}
tr:hover {
background-color: #f9f9f9;
}
form {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
input[type="text"], input[type="number"] {
padding: 10px 15px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
button[type="submit"] {
padding: 10px 20px;
background-color: #006341;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
button[type="submit"]:hover {
background-color: #004d33;
}
.ultimos-jogos {
display: flex;
justify-content: center;
gap: 5px;
}
.ultimos-jogos span {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
}
.v { background: #2ecc71; }
.e { background: #95a5a6; }
.d { background: #e74c3c; }
td:nth-child(2) {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.escudo {
width: 24px;
height: 24px;
object-fit: contain;
}
tr:first-child {
background-color: #e8f5e9;
}
tr:first-child:hover {
background-color: #d0e9d1;
}
.container {
display: flex;
gap: 20px;
margin-top: 20px;
}
.tabela-section {
flex: 2;
}
.jogos-section {
flex: 1;
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 15px;
}
.jogos-tabs {
display: flex;
margin-bottom: 15px;
border-bottom: 1px solid #ddd;
}
.jogos-tab {
padding: 10px 15px;
cursor: pointer;
background: #f5f5f5;
border: 1px solid #ddd;
border-bottom: none;
margin-right: 5px;
border-radius: 5px 5px 0 0;
}
.jogos-tab.active {
background: #006341;
color: white;
border-color: #006341;
}
.jogo-item {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
flex-direction: column;
}
.jogo-times {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
}
.jogo-placar {
display: flex;
align-items: center;
gap: 10px;
}
.jogo-placar span {
font-weight: bold;
font-size: 1.1em;
}
.jogo-info {
display: flex;
justify-content: space-between;
font-size: 0.9em;
color: #666;
}
.jogo-rodada {
font-weight: bold;
margin-bottom: 10px;
color: #006341;
}
/* Design atualizado para a seção de cadastro */
.cadastro-container {
max-width: 800px;
margin: 50px auto;
background: #ffffff;
border-radius: 16px;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
padding: 40px;
position: relative;
overflow: hidden;
}
.cadastro-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 8px;
background: linear-gradient(90deg, #006341, #00a86b);
}
/* Grupo 1: Lançar Resultado - Cadastrar Próximo Jogo */
.cadastro-tabs-container {
margin-bottom: 40px;
padding-bottom: 20px;
border-bottom: 1px solid #e9ecef;
}
.cadastro-tabs {
display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap;
}
.cadastro-tab {
padding: 12px 30px;
cursor: pointer;
background: #f1f3f5;
border-radius: 30px;
font-weight: 700;
font-size: 1.1em;
color: #2d3436;
transition: all 0.3s ease;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.cadastro-tab:hover {
background: #dfe6e9;
transform: translateY(-2px);
}
.cadastro-tab.active {
background: #006341;
color: #ffffff;
box-shadow: 0 6px 16px rgba(0, 99, 65, 0.3);
}
.cadastro-content {
display: none;
animation: slideIn 0.4s ease;
}
.cadastro-content.active {
display: block;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Grupo 2: jogo-container */
.jogo-container {
display: flex;
align-items: center;
justify-content: center;
gap: 25px;
margin: 30px; /* Increased bottom margin for spacing */
flex-wrap: wrap;
background: #f8f9fa;
padding: 25px;
border-radius: 12px;
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05);
border: 1px solid #e9ecef;
}
.time-select {
width: 280px;
padding: 14px 20px;
border: 1px solid #ced4da;
border-radius: 8px;
font-size: 1.05em;
background: #ffffff;
appearance: none;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="%232d3436" d="M7 10l5 5 5-5z"/></svg>');
background-repeat: no-repeat;
background-position: right 15px center;
transition: all 0.3s ease;
}
.time-select:focus {
outline: none;
border-color: #00a86b;
box-shadow: 0 0 12px rgba(0, 168, 107, 0.2);
}
.gols-input {
width: 90px;
padding: 14px;
border: 2px solid #00a86b;
border-radius: 8px;
text-align: center;
font-size: 1.2em;
font-weight: 700;
color: #2d3436;
background: #ffffff;
transition: all 0.3s ease;
}
.gols-input:focus {
outline: none;
box-shadow: 0 0 12px rgba(0, 168, 107, 0.2);
}
.vs-text {
font-size: 2em;
font-weight: 900;
color: #00a86b;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* Grupo 3: Senha e Rodada (including the button) */
.senha-rodada-container {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 20px;
margin: 0;
padding: 20px;
background: #f8f9fa;
border-radius: 12px;
border: 1px solid #e9ecef;
flex-wrap: wrap;
}
.form-group {
flex: 1;
min-width: 200px;
margin-bottom: 0;
}
.form-group label {
display: block;
margin-bottom: 12px;
font-weight: 700;
font-size: 1.1em;
color: #2d3436;
letter-spacing: 0.5px;
}
.password-container {
max-width: 350px;
width: 100%;
padding: 0;
background: transparent;
border: none;
transition: transform 0.3s ease;
}
.password-container:hover {
transform: scale(1.02);
}
.password-input {
width: 80%;
padding: 10px 15px;
border: 1px solid #ced4da;
border-radius: 6px;
font-size: 0.95em;
background: #ffffff;
color: #636e72;
transition: all 0.3s ease;
}
.password-input:focus {
outline: none;
border-color: #00a86b;
box-shadow: 0 0 8px rgba(0, 168, 107, 0.2);
}
.password-container label {
font-size: 0.9em;
font-weight: 600;
color: #636e72;
margin-bottom: 8px;
}
input[type="datetime-local"] {
padding: 14px 20px;
border: 1px solid #ced4da;
border-radius: 8px;
font-size: 1.05em;
width: 100%;
max-width: 350px;
margin: 0 auto;
display: block;
background: #ffffff;
transition: all 0.3s ease;
}
input[type="datetime-local"]:focus {
outline: none;
border-color: #00a86b;
box-shadow: 0 0 12px rgba(0, 168, 107, 0.2);
}
/* Grupo 4: Botão de Lançar resultado (inside senha-rodada-container) */
.btn-lancar-container {
min-width: 200px;
text-align: right;
}
.btn-lancar {
background: linear-gradient(45deg, #006341, #00a86b);
color: #ffffff;
padding: 12px 40px;
border: none;
border-radius: 30px;
cursor: pointer;
font-size: 1.1em;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
box-shadow: 0 6px 16px rgba(0, 99, 65, 0.3);
transition: all 0.3s ease;
}
.btn-lancar:hover {
background: linear-gradient(45deg, #004d33, #008555);
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(0, 99, 65, 0.4);
}
/* Grupo 5: Link de voltar para a tabela (now outside cadastro-container) */
.voltar-link-container {
text-align: center;
margin: 40px 0;
padding-top: 20px;
}
.voltar-link {
display: inline-block;
color: #00a86b;
text-decoration: none;
font-weight: 700;
font-size: 1.1em;
transition: all 0.3s ease;
}
.voltar-link:hover {
color: #006341;
text-decoration: underline;
transform: translateY(-2px);
}
.error-message {
color: #ff4757;
text-align: center;
margin: 25px 0;
padding: 15px;
background: #fff0f1;
border-radius: 8px;
font-weight: 600;
box-shadow: 0 2px 8px rgba(255, 71, 87, 0.1);
}
.success-message {
color: #00a86b;
text-align: center;
margin: 25px 0;
padding: 15px;
background: #e7f7ef;
border-radius: 8px;
font-weight: 600;
box-shadow: 0 2px 8px rgba(0, 168, 107, 0.1);
}
/* Estilos para responsividade */
@media (max-width: 1200px) {
.container {
flex-direction: column;
}
}
@media (max-width: 768px) {
th, td {
padding: 8px 10px;
font-size: 0.9em;
}
.cadastro-container {
margin: 20px;
padding: 20px;
}
.cadastro-tab {
padding: 10px 20px;
font-size: 1em;
}
.jogo-container {
flex-direction: column;
gap: 20px;
padding: 15px;
margin-bottom: 30px;
}
.time-select {
width: 100%;
}
.gols-input {
width: 100px;
}
.btn-lancar {
padding: 12px 30px;
font-size: 1em;
}
.password-container {
max-width: 100%;
padding: 0;
}
.senha-rodada-container {
flex-direction: column;
align-items: center;
gap: 15px;
}
.btn-lancar-container {
text-align: center;
width: 100%;
}
}
/* Estilos para escudos na seção de jogos */
.time-com-escudo {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.95em;
}
.escudo-jogo {
width: 20px;
height: 20px;
object-fit: contain;
}
/* Estilos para navegação por rodada */
.jogos-nav {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
}
.nav-arrow {
background: #006341;
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
font-size: 1.2em;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s;
}
.nav-arrow:hover {
background: #004d33;
}
.rodada-atual {
font-size: 1.3em;
font-weight: 700;
color: #006341;
}
.jogos-nav {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
}
.nav-arrow {
background: #006341;
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
font-size: 1.2em;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s;
}
.nav-arrow:hover {
background: #004d33;
}
.nav-arrow:disabled {
background: #95a5a6;
cursor: not-allowed;
}
.rodada-atual {
font-size: 1.3em;
font-weight: 700;
color: #006341;
min-width: 120px;
text-align: center;
}

112
index.php Normal file
View File

@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Tabela Brasileirão</title>
<link rel="stylesheet" href="estilo.css">
</head>
<body>
<?php
include 'controller.php';
$view = isset($_GET['view']) ? $_GET['view'] : 'tabela';
?>
<h1>Tabela Brasileirão</h1>
<?php if ($view === 'tabela'): ?>
<form method="GET">
<input type="text" name="busca" placeholder="Buscar time..." value="<?= htmlspecialchars($_GET['busca'] ?? '') ?>">
<input type="hidden" name="view" value="tabela">
<button type="submit">Buscar</button>
</form>
<div class="container">
<div class="tabela-section">
<div class="tabela-wrapper">
<table id="tabela">
<thead>
<tr>
<th>#</th>
<th>Time</th>
<th><a href="?view=tabela&ordenar=pontos">P</a></th>
<th><a href="?view=tabela&ordenar=jogos">J</a></th>
<th><a href="?view=tabela&ordenar=vitorias">V</a></th>
<th><a href="?view=tabela&ordenar=empates">E</a></th>
<th><a href="?view=tabela&ordenar=derrotas">D</a></th>
<th><a href="?view=tabela&ordenar=gols_pro">GP</a></th>
<th><a href="?view=tabela&ordenar=gols_contra">GC</a></th>
<th><a href="?view=tabela&ordenar=saldo_gols">SG</a></th>
<th><a href="?view=tabela&ordenar=aproveitamento">%</a></th>
<th>Últ. Jogos</th>
</tr>
</thead>
<tbody>
<?php displayTeams($conn); ?>
</tbody>
</table>
</div>
<div class="voltar-link-container">
<a href="lancar.php" class="voltar-link">Lançar Resultado de Jogo</a>
<a href="cadastro.php" class="voltar-link">Cadastrar Novo Jogo</a>
</div>
</div>
<div class="jogos-section">
<?php
$rodada_atual = 1; // Valor padrão
// Busca a última rodada com jogos cadastrados (com ou sem resultados)
$sql = "SELECT MAX(rodada) as ultima_rodada FROM historico_jogos";
$result = $conn->query($sql);
$ultima_rodada = 1;
if ($result && $result->num_rows > 0) {
$row = $result->fetch_assoc();
if (!empty($row['ultima_rodada'])) {
$ultima_rodada = $row['ultima_rodada'];
$rodada_atual = $ultima_rodada;
}
}
// Se houver parâmetro rodada na URL, usa ele
if (isset($_GET['rodada'])) {
$rodada_atual = (int)$_GET['rodada'];
if ($rodada_atual < 1) $rodada_atual = 1;
if ($rodada_atual > $ultima_rodada) $rodada_atual = $ultima_rodada;
}
?>
<div class="jogos-nav">
<button class="nav-arrow" onclick="mudarRodada(-1)" <?php echo $rodada_atual <= 1 ? 'disabled' : ''; ?>>&lt;</button>
<div class="rodada-atual">Rodada <span id="rodada-numero"><?= $rodada_atual ?>ª</span></div>
<button class="nav-arrow" onclick="mudarRodada(1)" <?php echo $rodada_atual >= $ultima_rodada ? 'disabled' : ''; ?>>&gt;</button>
</div>
<div id="jogos-rodada">
<?php displayGames($conn, $rodada_atual); ?>
</div>
</div>
</div>
<script>
function mudarRodada(delta) {
const urlParams = new URLSearchParams(window.location.search);
let rodadaAtual = parseInt(urlParams.get('rodada')) || <?php echo $rodada_atual; ?>;
let novaRodada = rodadaAtual + delta;
if (novaRodada < 1) novaRodada = 1;
if (novaRodada > <?php echo $ultima_rodada; ?>) novaRodada = <?php echo $ultima_rodada; ?>;
// Mantém outros parâmetros da URL (como busca)
urlParams.set('rodada', novaRodada);
urlParams.set('view', 'tabela');
// Verifica se há parâmetro de busca para manter
const busca = urlParams.get('busca');
if (busca) {
urlParams.set('busca', busca);
}
window.location.href = '?' + urlParams.toString();
}
</script>
<?php endif; ?>
</body>
</html>

86
lancar.php Normal file
View File

@@ -0,0 +1,86 @@
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Lançar Resultado de Jogo</title>
<link rel="stylesheet" href="estilo.css">
</head>
<body>
<?php
include 'controller.php';
?>
<h1>Lançar Resultado de Jogo</h1>
<div class="cadastro-container">
<?php if (isset($_GET['error'])): ?>
<div class="error-message">
<?php
if ($_GET['error'] == 2) echo "Senha incorreta!";
if ($_GET['error'] == 3) echo "Jogo inválido ou já possui resultado!";
if ($_GET['error'] == 5) echo "Todos os campos são obrigatórios!";
?>
</div>
<?php endif; ?>
<?php if (isset($_GET['success'])): ?>
<div class="success-message">
<?php
if ($_GET['success'] == 1) echo "Resultado cadastrado com sucesso!";
?>
</div>
<?php endif; ?>
<div id="form-resultado" class="cadastro-content active">
<form action="controller.php?action=save" method="post">
<div class="jogo-container">
<select name="jogo_id" class="time-select" required onchange="updateGameDetails(this)">
<option value="">Selecione um jogo cadastrado</option>
<?php
$sql = "SELECT id, time_casa, time_visitante, rodada FROM historico_jogos WHERE gols_casa IS NULL AND gols_visitante IS NULL ORDER BY rodada, data_jogo";
$result = $conn->query($sql);
while ($row = $result->fetch_assoc()) {
echo "<option value='{$row['id']}' data-casa='{$row['time_casa']}' data-visitante='{$row['time_visitante']}' data-rodada='{$row['rodada']}'>{$row['time_casa']} x {$row['time_visitante']} (Rodada {$row['rodada']})</option>";
}
?>
</select>
<input type="number" name="gols_casa" class="gols-input" min="0" value="0" required>
<span class="vs-text">X</span>
<input type="number" name="gols_visitante" class="gols-input" min="0" value="0" required>
<div id="game-details" style="font-size: 0.9em; color: #666;"></div>
</div>
<div class="senha-rodada-container">
<div class="form-group">
<label for="senha">Senha de Administração:</label>
<div class="password-container">
<input type="password" name="senha" class="password-input" required>
</div>
</div>
<div class="btn-lancar-container">
<button type="submit" class="btn-lancar">Lançar Resultado</button>
</div>
</div>
</form>
</div>
</div>
<div class="voltar-link-container">
<a href="index.php?view=tabela" class="voltar-link">Voltar para a Tabela</a>
</div>
<script>
function updateGameDetails(select) {
const selectedOption = select.options[select.selectedIndex];
const casa = selectedOption.getAttribute('data-casa');
const visitante = selectedOption.getAttribute('data-visitante');
const rodada = selectedOption.getAttribute('data-rodada');
const detailsDiv = document.getElementById('game-details');
if (casa && visitante && rodada) {
detailsDiv.innerText = `Jogo: ${casa} x ${visitante} (Rodada ${rodada})`;
} else {
detailsDiv.innerText = '';
}
}
</script>
</body>
</html>

9
script.js Normal file
View File

@@ -0,0 +1,9 @@
function mostrarJogos(tipo) {
document.getElementById('jogos-passados').style.display = 'none';
document.getElementById('jogos-atuais').style.display = 'none';
document.getElementById('jogos-futuros').style.display = 'none';
document.getElementById('jogos-' + tipo).style.display = 'block';
const tabs = document.querySelectorAll('.jogos-tab');
tabs.forEach(tab => tab.classList.remove('active'));
event.currentTarget.classList.add('active');
}