home
/
u529748449
/
domains
/
borabilhete.com
/
public_html
/
admin
➕ New
📤 Upload
✎ Editing:
time.php
← Back
<?php // admin/time.php require_once __DIR__ . '/conexao.php'; require_once __DIR__ . '/auth.php'; error_reporting(E_ALL); ini_set('display_errors', 1); date_default_timezone_set('America/Sao_Paulo'); // Admin e Produtor podem acessar esta tela require_login(['admin','produtor']); $isAdmin = ($_SESSION['role'] ?? '') === 'admin'; $ownerId = (int)($_SESSION['produtor_id'] ?? 0); // produtor logado (ou admin) if ($ownerId <= 0) { http_response_code(403); exit('Sessão inválida.'); } // Papéis permitidos $ALLOWED_ROLES = $isAdmin ? ['admin','produtor','agente'] : ['agente']; // ===== Helpers ===== function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } function fetch_user(mysqli $conn, int $id): ?array { $st = $conn->prepare("SELECT id, nome, email, role, empresa_id, criado_em FROM produtores WHERE id=?"); $st->bind_param('i', $id); $st->execute(); $r = $st->get_result()->fetch_assoc(); $st->close(); return $r ?: null; } function count_admins(mysqli $conn): int { $res = $conn->query("SELECT COUNT(*) FROM produtores WHERE role='admin'"); [$n] = $res->fetch_row(); return (int)$n; } function email_exists(mysqli $conn, string $email, ?int $ignoreId = null): bool { if ($ignoreId) { $sql = "SELECT 1 FROM produtores WHERE email = ? AND id <> ? LIMIT 1"; $st = $conn->prepare($sql); $st->bind_param('si', $email, $ignoreId); } else { $sql = "SELECT 1 FROM produtores WHERE email = ? LIMIT 1"; $st = $conn->prepare($sql); $st->bind_param('s', $email); } $st->execute(); $has = (bool)$st->get_result()->fetch_row(); $st->close(); return $has; } // ===== Flash (PRG) ===== $flash = $_SESSION['flash_time'] ?? []; unset($_SESSION['flash_time']); function add_flash(string $type, string $msg){ $_SESSION['flash_time'][] = ['t'=>$type, 'm'=>$msg]; } // ===== CSRF ===== if (empty($_SESSION['csrf_time'])) { $_SESSION['csrf_time'] = bin2hex(random_bytes(16)); } $CSRF = $_SESSION['csrf_time']; // ===== POST (ações) ===== if ($_SERVER['REQUEST_METHOD']==='POST') { $okCsrf = isset($_POST['csrf']) && hash_equals($_SESSION['csrf_time'], (string)$_POST['csrf']); if (!$okCsrf) { add_flash('error','Falha de CSRF. Recarregue a página e tente novamente.'); header('Location: time.php'); exit; } $action = $_POST['action'] ?? ''; // --- Criar usuário --- if ($action === 'create') { $nome = trim($_POST['nome'] ?? ''); $email = trim($_POST['email'] ?? ''); $senha = (string)($_POST['senha'] ?? ''); $role = $isAdmin ? strtolower(trim($_POST['role'] ?? 'agente')) : 'agente'; // empresa_id: admin pode escolher (ou deixar vazio = NULL); produtor é forçado para o próprio ID if ($isAdmin) { $empresa_id = trim($_POST['empresa_id'] ?? ''); $empresa_id = ctype_digit($empresa_id) ? (int)$empresa_id : null; } else { $empresa_id = $ownerId; } if ($nome==='' || $email==='' || $senha==='') { add_flash('error','Preencha nome, e-mail e senha.'); header('Location: time.php'); exit; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { add_flash('error','E-mail inválido.'); header('Location: time.php'); exit; } if (!in_array($role, $ALLOWED_ROLES, true)) { add_flash('error','Papel inválido.'); header('Location: time.php'); exit; } if (email_exists($conn, $email, null)) { add_flash('error','Já existe um usuário com este e-mail.'); header('Location: time.php'); exit; } $hash = password_hash($senha, PASSWORD_DEFAULT); if ($empresa_id === null) { // empresa_id NULL $sql = "INSERT INTO produtores (nome, email, senha, role, empresa_id, criado_em) VALUES (?,?,?,?,NULL, NOW())"; $st = $conn->prepare($sql); $st->bind_param('ssss', $nome, $email, $hash, $role); $ok = $st->execute(); $st->close(); } else { $sql = "INSERT INTO produtores (nome, email, senha, role, empresa_id, criado_em) VALUES (?,?,?,?,?, NOW())"; $st = $conn->prepare($sql); $st->bind_param('ssssi', $nome, $email, $hash, $role, $empresa_id); $ok = $st->execute(); $st->close(); } if ($ok) add_flash('ok','Usuário criado com sucesso.'); else add_flash('error','Erro ao criar usuário: '.$conn->error); header('Location: time.php'); exit; } // --- Atualizar papel/empresa (apenas admin) --- if ($action === 'update_role') { if (!$isAdmin) { add_flash('error','Você não tem permissão para alterar papéis.'); header('Location: time.php'); exit; } $id = isset($_POST['id']) && ctype_digit($_POST['id']) ? (int)$_POST['id'] : 0; $role = strtolower(trim($_POST['role'] ?? '')); $empresa_id = trim($_POST['empresa_id'] ?? ''); $empresa_id = ctype_digit($empresa_id) ? (int)$empresa_id : null; if ($id<=0) { add_flash('error','ID inválido.'); header('Location: time.php'); exit; } if (!in_array($role, $ALLOWED_ROLES, true)) { add_flash('error','Papel inválido.'); header('Location: time.php'); exit; } $user = fetch_user($conn, $id); if (!$user) { add_flash('error','Usuário não encontrado.'); header('Location: time.php'); exit; } if ($user['role']==='admin' && $role!=='admin' && count_admins($conn) <= 1) { add_flash('error','Não é possível retirar o papel de admin do último administrador.'); header('Location: time.php'); exit; } if ($empresa_id === null) { $st = $conn->prepare("UPDATE produtores SET role=?, empresa_id=NULL WHERE id=?"); $st->bind_param('si', $role, $id); } else { $st = $conn->prepare("UPDATE produtores SET role=?, empresa_id=? WHERE id=?"); $st->bind_param('sii', $role, $empresa_id, $id); } $ok = $st->execute(); $st->close(); if ($ok) add_flash('ok','Papel atualizado com sucesso.'); else add_flash('error','Erro ao atualizar papel: '.$conn->error); header('Location: time.php'); exit; } // --- Redefinir senha (admin: qualquer; produtor: só dos seus agentes) --- if ($action === 'reset_password') { $id = isset($_POST['id']) && ctype_digit($_POST['id']) ? (int)$_POST['id'] : 0; $senha = (string)($_POST['senha'] ?? ''); if ($id<=0 || $senha==='') { add_flash('error','Informe o ID e a nova senha.'); header('Location: time.php'); exit; } if (!$isAdmin) { // Verifica se pertence ao produtor e é agente $stc = $conn->prepare("SELECT 1 FROM produtores WHERE id=? AND role='agente' AND empresa_id=? LIMIT 1"); $stc->bind_param('ii', $id, $ownerId); $stc->execute(); $okScope = (bool)$stc->get_result()->fetch_row(); $stc->close(); if (!$okScope) { add_flash('error','Você não tem permissão para alterar este usuário.'); header('Location: time.php'); exit; } } $hash = password_hash($senha, PASSWORD_DEFAULT); $st = $conn->prepare("UPDATE produtores SET senha=? WHERE id=?"); $st->bind_param('si', $hash, $id); $ok = $st->execute(); $st->close(); if ($ok) add_flash('ok','Senha redefinida com sucesso.'); else add_flash('error','Erro ao redefinir senha: '.$conn->error); header('Location: time.php'); exit; } // Desconhecido add_flash('error','Ação inválida.'); header('Location: time.php'); exit; } // ===== GET (lista) ===== $users = []; if ($isAdmin) { $sql = "SELECT id, nome, email, role, empresa_id, criado_em FROM produtores ORDER BY nome ASC"; $res = $conn->query($sql); } else { // Produtor enxerga apenas seus agentes $st = $conn->prepare("SELECT id, nome, email, role, empresa_id, criado_em FROM produtores WHERE role='agente' AND empresa_id=? ORDER BY nome ASC"); $st->bind_param('i', $ownerId); $st->execute(); $res = $st->get_result(); } while($row = $res->fetch_assoc()){ $users[] = $row; } if (!$isAdmin) { $st->close(); } ?> <!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <title>Time – Gestão de Usuários</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> <link rel="stylesheet" href="css/adminprodutor.css?v=2"> <link rel="stylesheet" href="../public/css/header.css"> <style> .container .grid-2-time { display: grid; grid-template-columns: 1fr 2fr; gap: 16px; } @media (max-width: 900px){ .container .grid-2-time { grid-template-columns: 1fr; } } .card form.inline { display:flex; align-items:center; gap:8px; flex-wrap:wrap; } .card form.inline .role-select{ min-width: 140px; } .card form.inline input[type="number"]{ width:120px; } .badge-role{ padding:2px 8px; border-radius:999px; font-size:12px; background:#eee; } .badge-role.admin{ background:#ffe1e1; color:#a30000; } .badge-role.produtor{ background:#e9f3ff; color:#004c97; } .badge-role.agente{ background:#e8ffe6; color:#086b00; } .table-users { width:100%; border-collapse: collapse; } .table-users th, .table-users td{ padding:10px 8px; border-bottom:1px solid #eee; vertical-align: middle; } .table-users th{ text-align:left; font-weight:600; color:#333; } .table-users td.actions{ white-space:nowrap; } .table-users small.muted{ color:#777; } .form-create .field{ display:flex; flex-direction:column; gap:6px; margin-bottom:10px; } .form-create .inline-2{ display:grid; grid-template-columns: 1fr 1fr; gap:10px; } @media (max-width: 640px){ .form-create .inline-2{ grid-template-columns: 1fr; } } .note{ font-size:12px; color:#666; margin-top:6px; } </style> </head> <body> <?php include __DIR__ . '/includes/header_admin.php'; ?> <div class="container"> <h1>Time</h1> <div class="top-actions"> <a class="btn" href="index.php"><i class="fa-solid fa-arrow-left"></i> Voltar ao painel</a> </div> <?php if(!empty($flash)): ?> <?php foreach($flash as $f): ?> <div class="alert <?= $f['t']==='ok'?'ok':'error' ?>"><?= h($f['m']) ?></div> <?php endforeach; ?> <?php endif; ?> <div class="grid-2-time"> <!-- Criar usuário --> <div class="card"> <h3><i class="fa-solid fa-user-plus"></i> Criar usuário</h3> <form class="form-create" method="post"> <input type="hidden" name="csrf" value="<?= h($CSRF) ?>"> <input type="hidden" name="action" value="create"> <div class="field"> <label>Nome</label> <input type="text" name="nome" required maxlength="120" placeholder="Nome completo"> </div> <div class="field"> <label>E-mail</label> <input type="email" name="email" required maxlength="180" placeholder="email@dominio.com"> </div> <div class="inline-2"> <div class="field"> <label>Senha</label> <input type="password" name="senha" required minlength="6" placeholder="Mínimo 6 caracteres"> </div> <?php if ($isAdmin): ?> <div class="field"> <label>Papel</label> <select name="role" required> <?php foreach($ALLOWED_ROLES as $r): ?> <option value="<?= h($r) ?>" <?= $r==='agente'?'selected':'' ?>> <?= ucfirst($r) ?> </option> <?php endforeach; ?> </select> </div> <?php else: ?> <div class="field"> <label>Papel</label> <input type="text" value="Agente" disabled> <input type="hidden" name="role" value="agente"> <div class="note">Produtores só podem criar agentes para validar ingressos.</div> </div> <?php endif; ?> </div> <?php if ($isAdmin): ?> <div class="field"> <label>Empresa ID (opcional, útil para agentes)</label> <input type="number" name="empresa_id" inputmode="numeric" placeholder="Ex.: 123"> <div class="note">Para vincular um agente a um produtor específico, informe o ID do produtor.</div> </div> <?php else: ?> <input type="hidden" name="empresa_id" value="<?= (int)$ownerId ?>"> <div class="note">O agente será automaticamente vinculado ao seu time (empresa_id = <?= (int)$ownerId ?>).</div> <?php endif; ?> <button class="submit" type="submit"> <i class="fa-solid fa-floppy-disk"></i> Criar usuário </button> </form> <p class="muted" style="margin-top:8px;"> Senhas são armazenadas com <code>password_hash()</code>. </p> </div> <!-- Lista e ações --> <div class="card"> <h3><i class="fa-solid fa-users"></i> Usuários</h3> <div class="table-scroll"> <table class="table-users"> <thead> <tr> <th>ID</th> <th>Nome / E-mail</th> <th>Papel</th> <th>Empresa ID</th> <th>Criado em</th> <th class="actions">Ações</th> </tr> </thead> <tbody> <?php if(!$users): ?> <tr><td colspan="6" class="muted">Nenhum usuário encontrado.</td></tr> <?php else: foreach($users as $u): ?> <tr> <td>#<?= (int)$u['id'] ?></td> <td> <div><strong><?= h($u['nome']) ?></strong></div> <small class="muted"><?= h($u['email']) ?></small> </td> <td><span class="badge-role <?= h($u['role']) ?>"><?= ucfirst(h($u['role'])) ?></span></td> <td><?= $u['empresa_id']!==null ? (int)$u['empresa_id'] : '<span class="muted">—</span>' ?></td> <td><small class="muted"><?= $u['criado_em'] ? date('d/m/Y H:i', strtotime($u['criado_em'])) : '—' ?></small></td> <td class="actions"> <?php if ($isAdmin): ?> <!-- Atualizar papel / empresa --> <form class="inline" method="post" style="margin-bottom:6px;"> <input type="hidden" name="csrf" value="<?= h($CSRF) ?>"> <input type="hidden" name="action" value="update_role"> <input type="hidden" name="id" value="<?= (int)$u['id'] ?>"> <select name="role" class="role-select"> <?php foreach($ALLOWED_ROLES as $r): ?> <option value="<?= h($r) ?>" <?= $u['role']===$r?'selected':'' ?>><?= ucfirst($r) ?></option> <?php endforeach; ?> </select> <input type="number" name="empresa_id" inputmode="numeric" placeholder="Empresa ID" value="<?= $u['empresa_id']!==null ? (int)$u['empresa_id'] : '' ?>"> <button class="btn" type="submit"><i class="fa-solid fa-rotate"></i> Atualizar</button> </form> <?php endif; ?> <!-- Resetar senha --> <form class="inline" method="post"> <input type="hidden" name="csrf" value="<?= h($CSRF) ?>"> <input type="hidden" name="action" value="reset_password"> <input type="hidden" name="id" value="<?= (int)$u['id'] ?>"> <input type="password" name="senha" placeholder="Nova senha" minlength="6" required> <button class="btn" type="submit"><i class="fa-solid fa-key"></i> Redefinir</button> </form> </td> </tr> <?php endforeach; endif; ?> </tbody> </table> </div> <?php if (!$isAdmin): ?> <p class="muted" style="margin-top:8px;"> Você está vendo apenas os <strong>agentes do seu time</strong>. Para criar novos, use o formulário ao lado. </p> <?php else: ?> <p class="muted" style="margin-top:8px;"> Observação: você não pode remover o papel de <strong>admin</strong> do último administrador do sistema. </p> <?php endif; ?> </div> </div> </div> </body> </html>
💾 Save Changes
Cancel
📤 Upload File
×
Select File
Upload
Cancel
➕ Create New
×
Type
📄 File
📁 Folder
Name
Create
Cancel
✎ Rename Item
×
Current Name
New Name
Rename
Cancel
🔐 Change Permissions
×
Target File
Permission (e.g., 0755, 0644)
0755
0644
0777
Apply
Cancel