0% acharam este documento útil (0 voto)
3 visualizações22 páginas

Controle Validade

O documento é um script PHP que gerencia um sistema de controle de validade de produtos, incluindo funcionalidades de login, cadastro, edição e exclusão de categorias e itens. Ele implementa proteção contra CSRF, validações de entrada e manipulação de erros, além de permitir a filtragem e paginação de itens. O front-end utiliza HTML e JavaScript para interações dinâmicas, como exibição de modais e pesquisa.

Enviado por

a.alessanio
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
3 visualizações22 páginas

Controle Validade

O documento é um script PHP que gerencia um sistema de controle de validade de produtos, incluindo funcionalidades de login, cadastro, edição e exclusão de categorias e itens. Ele implementa proteção contra CSRF, validações de entrada e manipulação de erros, além de permitir a filtragem e paginação de itens. O front-end utiliza HTML e JavaScript para interações dinâmicas, como exibição de modais e pesquisa.

Enviado por

a.alessanio
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

<?

php

include '[Link]';

session_start();

// Verificar se o usuário está logado

if (!isset($_SESSION['usuario_id'])) {

header('Location: [Link]');

exit;

// Verificar conexão com o banco de dados

if (!$pdo) {

die("Erro: Falha na conexão com o banco de dados.");

// Função para gerar token CSRF

function gerarTokenCSRF() {

if (empty($_SESSION['csrf_token'])) {

$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

return $_SESSION['csrf_token'];

// Validar token CSRF

function validarTokenCSRF($token) {

if (!isset($_SESSION['csrf_token']) || $token !== $_SESSION['csrf_token']) {

die("Erro: Token CSRF inválido.");

}
}

// Carregar categorias do banco de dados

try {

$stmt = $pdo->query("SELECT * FROM categorias ORDER BY nome ASC");

$categorias = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (PDOException $e) {

error_log("Erro ao carregar categorias: " . $e->getMessage());

$categorias = [];

$_SESSION['mensagem'] = "Erro ao carregar categorias. Tente novamente.";

$_SESSION['tipo_mensagem'] = 'erro';

// Cadastro de nova categoria

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['nova_categoria']))


{

try {

validarTokenCSRF($_POST['csrf_token']);

$nome_categoria = filter_input(INPUT_POST, 'nova_categoria',


FILTER_SANITIZE_STRING);

if (empty($nome_categoria) || strlen($nome_categoria) > 50) {

throw new Exception("O nome da categoria é obrigatório e deve ter no


máximo 50 caracteres.");

$stmt = $pdo->prepare("INSERT INTO categorias (nome) VALUES (:nome)");

$stmt->execute(['nome' => $nome_categoria]);


$_SESSION['mensagem'] = "Categoria cadastrada com sucesso!";

$_SESSION['tipo_mensagem'] = 'sucesso';

header('Location: controle_validade.php');

exit;

} catch (Exception $e) {

error_log("Erro ao cadastrar categoria: " . $e->getMessage());

$_SESSION['mensagem'] = "Erro ao cadastrar categoria. Tente novamente.";

$_SESSION['tipo_mensagem'] = 'erro';

header('Location: controle_validade.php');

exit;

// Carregar item para edição

$item_editar = null;

if (isset($_GET['editar_id']) && !empty($_GET['editar_id'])) {

$id = filter_input(INPUT_GET, 'editar_id', FILTER_VALIDATE_INT);

if (!$id) {

$_SESSION['mensagem'] = "Erro: ID inválido.";

$_SESSION['tipo_mensagem'] = 'erro';

header('Location: controle_validade.php');

exit;

try {

$stmt = $pdo->prepare("SELECT * FROM controle_validade WHERE id = :id");

$stmt->execute(['id' => $id]);

$item_editar = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$item_editar) {

$_SESSION['mensagem'] = "Erro: Item não encontrado.";

$_SESSION['tipo_mensagem'] = 'erro';

header('Location: controle_validade.php');

exit;

} catch (PDOException $e) {

error_log("Erro ao carregar item para edição: " . $e->getMessage());

$_SESSION['mensagem'] = "Erro ao carregar item. Tente novamente.";

$_SESSION['tipo_mensagem'] = 'erro';

header('Location: controle_validade.php');

exit;

// Cadastro ou edição de itens

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['produto'])) {

try {

validarTokenCSRF($_POST['csrf_token']);

$id = filter_input(INPUT_POST, 'editar_id', FILTER_VALIDATE_INT, ['options' =>


['default' => null]]);

$produto = trim(filter_input(INPUT_POST, 'produto',


FILTER_SANITIZE_STRING));

$categoria_id = filter_input(INPUT_POST, 'categoria_id', FILTER_VALIDATE_INT);

$quantidade = filter_input(INPUT_POST, 'quantidade', FILTER_VALIDATE_INT);

$data_vencimento = filter_input(INPUT_POST, 'data_vencimento',


FILTER_SANITIZE_STRING);
if (empty($produto) || strlen($produto) > 100) {

throw new Exception("O nome do produto é obrigatório e deve ter no máximo


100 caracteres.");

if (!$categoria_id || $quantidade <= 0 || empty($data_vencimento) ||


!preg_match('/^\d{4}-\d{2}-\d{2}$/', $data_vencimento)) {

throw new Exception("Todos os campos são obrigatórios e devem estar no


formato correto (Data: AAAA-MM-DD).");

$stmt = $pdo->prepare("SELECT COUNT(*) FROM categorias WHERE id = :id");

$stmt->execute(['id' => $categoria_id]);

if ($stmt->fetchColumn() == 0) {

throw new Exception("Categoria inválida.");

if ($id) {

$stmt = $pdo->prepare("

UPDATE controle_validade

SET produto = :produto, categoria_id = :categoria_id, quantidade =


:quantidade, data_vencimento = :data_vencimento

WHERE id = :id

");

$stmt->execute([

'produto' => $produto,

'categoria_id' => $categoria_id,

'quantidade' => $quantidade,

'data_vencimento' => $data_vencimento,

'id' => $id


]);

$_SESSION['mensagem'] = "Item atualizado com sucesso!";

} else {

$stmt = $pdo->prepare("

INSERT INTO controle_validade (produto, categoria_id, quantidade,


data_vencimento)

VALUES (:produto, :categoria_id, :quantidade, :data_vencimento)

");

$stmt->execute([

'produto' => $produto,

'categoria_id' => $categoria_id,

'quantidade' => $quantidade,

'data_vencimento' => $data_vencimento

]);

$_SESSION['mensagem'] = "Item cadastrado com sucesso!";

$_SESSION['tipo_mensagem'] = 'sucesso';

header('Location: controle_validade.php');

exit;

} catch (Exception $e) {

error_log("Erro ao salvar item: " . $e->getMessage());

$_SESSION['mensagem'] = "Erro ao salvar item: " . $e->getMessage();

$_SESSION['tipo_mensagem'] = 'erro';

header('Location: controle_validade.php');

exit;

}
// Excluir um item

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['excluir_id'])) {

try {

validarTokenCSRF($_POST['csrf_token']);

$id = filter_input(INPUT_POST, 'excluir_id', FILTER_VALIDATE_INT);

if (!$id) {

throw new Exception("ID inválido.");

$stmt = $pdo->prepare("DELETE FROM controle_validade WHERE id = :id");

$stmt->execute(['id' => $id]);

$_SESSION['mensagem'] = "Item excluído com sucesso!";

$_SESSION['tipo_mensagem'] = 'sucesso';

header('Location: controle_validade.php?page=' . (isset($_GET['page']) ?


$_GET['page'] : 1));

exit;

} catch (Exception $e) {

error_log("Erro ao excluir item: " . $e->getMessage());

$_SESSION['mensagem'] = "Erro ao excluir item. Tente novamente.";

$_SESSION['tipo_mensagem'] = 'erro';

header('Location: controle_validade.php?page=' . (isset($_GET['page']) ?


$_GET['page'] : 1));

exit;

// Configuração da paginação
$itens_por_pagina = 30;

$page = isset($_GET['page']) && is_numeric($_GET['page']) ? (int)$_GET['page'] : 1;

$offset = ($page - 1) * $itens_por_pagina;

// Filtros de busca

$categoria_filtro = isset($_GET['categoria']) ? (int)$_GET['categoria'] : '';

$data_inicio = isset($_GET['data_inicio']) ? $_GET['data_inicio'] : '';

$data_fim = isset($_GET['data_fim']) ? $_GET['data_fim'] : '';

$produto_filtro = isset($_GET['produto']) ? trim($_GET['produto']) : '';

$status_filtro = isset($_GET['status']) ? $_GET['status'] : '';

// Contar total de itens com filtros

try {

$sql = "SELECT COUNT(*) AS total FROM controle_validade cv JOIN categorias c


ON cv.categoria_id = [Link] WHERE 1=1";

$params = [];

if ($categoria_filtro) {

$sql .= " AND cv.categoria_id = :categoria";

$params[':categoria'] = $categoria_filtro;

if ($data_inicio) {

$sql .= " AND cv.data_vencimento >= :data_inicio";

$params[':data_inicio'] = $data_inicio;

if ($data_fim) {

$sql .= " AND cv.data_vencimento <= :data_fim";

$params[':data_fim'] = $data_fim;
}

if ($produto_filtro) {

$sql .= " AND [Link] LIKE :produto";

$params[':produto'] = "%$produto_filtro%";

if ($status_filtro) {

if ($status_filtro === 'vencido') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) < 0";

} elseif ($status_filtro === 'avencer') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) BETWEEN 0 AND


30";

} elseif ($status_filtro === 'alerta') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) BETWEEN 31 AND


60";

} elseif ($status_filtro === 'ok') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) > 60";

$stmt = $pdo->prepare($sql);

$stmt->execute($params);

$total_itens = $stmt->fetchColumn();

$total_paginas = ceil($total_itens / $itens_por_pagina);

} catch (PDOException $e) {

error_log("Erro ao contar itens: " . $e->getMessage());

$total_itens = 0;

$total_paginas = 1;

}
// Consulta para listar os itens com filtros e paginação

try {

$sql = "

SELECT [Link], [Link], [Link] AS categoria, [Link],


cv.data_vencimento,

DATEDIFF(cv.data_vencimento, CURDATE()) AS dias_restantes

FROM controle_validade cv

JOIN categorias c ON cv.categoria_id = [Link]

WHERE 1=1";

$params = [];

if ($categoria_filtro) {

$sql .= " AND cv.categoria_id = :categoria";

$params[':categoria'] = $categoria_filtro;

if ($data_inicio) {

$sql .= " AND cv.data_vencimento >= :data_inicio";

$params[':data_inicio'] = $data_inicio;

if ($data_fim) {

$sql .= " AND cv.data_vencimento <= :data_fim";

$params[':data_fim'] = $data_fim;

if ($produto_filtro) {

$sql .= " AND [Link] LIKE :produto";

$params[':produto'] = "%$produto_filtro%";

if ($status_filtro) {
if ($status_filtro === 'vencido') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) < 0";

} elseif ($status_filtro === 'avencer') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) BETWEEN 0 AND


30";

} elseif ($status_filtro === 'alerta') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) BETWEEN 31 AND


60";

} elseif ($status_filtro === 'ok') {

$sql .= " AND DATEDIFF(cv.data_vencimento, CURDATE()) > 60";

$sql .= " ORDER BY cv.data_vencimento ASC LIMIT :limit OFFSET :offset";

$stmt = $pdo->prepare($sql);

foreach ($params as $key => $value) {

$stmt->bindValue($key, $value);

$stmt->bindValue(':limit', $itens_por_pagina, PDO::PARAM_INT);

$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);

$stmt->execute();

$itens = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (PDOException $e) {

error_log("Erro ao listar itens: " . $e->getMessage());

$itens = [];

$_SESSION['mensagem'] = "Erro ao carregar itens. Tente novamente.";

$_SESSION['tipo_mensagem'] = 'erro';

?>
<!DOCTYPE html>

<html lang="pt-br">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Controle de Validade</title>

<script src="[Link]

<link rel="stylesheet"
href="[Link]
free/css/[Link]">

<style>

/* Estilo para o modal */

.modal {

display: none;

position: fixed;

top: 0;

left: 0;

width: 100%;

height: 100%;

background-color: rgba(0, 0, 0, 0.5);

z-index: 1000;

justify-content: center;

align-items: center;

.modal-content {

background-color: white;

padding: 20px;

border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);

text-align: center;

max-width: 400px;

width: 100%;

.[Link] {

display: flex;

</style>

<script>

function abrirPesquisa() {

let url = 'controle_validade_popup.php?';

let params = new URLSearchParams();

let categoria = [Link]('categoria_filtro').value;

let data_inicio = [Link]('data_inicio').value;

let data_fim = [Link]('data_fim').value;

let produto = [Link]('produto_filtro').value;

let status = [Link]('status_filtro').value;

if (categoria) [Link]('categoria', categoria);

if (data_inicio) [Link]('data_inicio', data_inicio);

if (data_fim) [Link]('data_fim', data_fim);

if (produto) [Link]('produto', produto);

if (status) [Link]('status', status);

[Link](url + [Link](), 'popup',


'width=800,height=600,scrollbars=yes');
}

// Função para mostrar o modal

function showModal(message, type) {

const modal = [Link]('modal');

const modalMessage = [Link]('modal-message');

const modalClass = type === 'sucesso' ? 'bg-green-100 text-green-700' : 'bg-


red-100 text-red-700';

[Link] = message;

[Link] = `p-4 rounded-lg ${modalClass}`;

[Link]('show');

// Função para fechar o modal

function closeModal() {

const modal = [Link]('modal');

[Link]('show');

</script>

</head>

<body class="bg-gray-300">

<div class="container mx-auto p-6">

<h1 class="text-3xl font-bold text-gray-800 mb-6">Controle de Validade</h1>

<!-- Botão Voltar -->

<div class="mb-4">

<a href="[Link]" class="text-blue-600 hover:underline"><i class="fas fa-


arrow-left"></i> Voltar à Página Inicial</a>
</div>

<!-- Modal para mensagens -->

<div id="modal" class="modal">

<div class="modal-content">

<div id="modal-message" class="p-4 rounded-lg"></div>

<button onclick="closeModal()" class="mt-4 bg-blue-600 text-white p-2


rounded-lg hover:bg-blue-700">OK</button>

</div>

</div>

<!-- Formulário de Cadastro de Categoria e Filtros de Busca lado a lado -->

<div class="flex flex-col md:flex-row gap-4 mb-8">

<!-- Card de Cadastro de Categoria -->

<div class="bg-white p-4 rounded-lg shadow-md w-full md:w-1/4">

<h2 class="text-lg font-semibold mb-2">Nova Categoria</h2>

<form method="POST" class="flex flex-col gap-2">

<input type="hidden" name="csrf_token" value="<?= gerarTokenCSRF();


?>">

<input type="text" name="nova_categoria" class="w-full p-2 border


rounded-lg" placeholder="Nome" required maxlength="50">

<button type="submit" class="bg-green-600 text-white p-2 rounded-lg


hover:bg-green-700">Cadastrar</button>

</form>

</div>

<!-- Card de Filtros de Busca -->

<div class="bg-white p-4 rounded-lg shadow-md w-full md:w-3/4">

<h2 class="text-lg font-semibold mb-2">Filtros de Busca</h2>


<form id="filtro_form" onsubmit="[Link]();
abrirPesquisa();">

<div class="grid grid-cols-1 md:grid-cols-5 gap-4">

<div class="md:col-span-1">

<label for="categoria_filtro" class="block text-sm font-medium text-


gray-700">Categoria</label>

<select id="categoria_filtro" name="categoria" class="mt-1 w-full p-2


border rounded-lg">

<option value="">Todas</option>

<?php foreach ($categorias as $categoria): ?>

<option value="<?= $categoria['id'] ?>" <?= $categoria_filtro ==


$categoria['id'] ? 'selected' : '' ?>>

<?= htmlspecialchars($categoria['nome']) ?>

</option>

<?php endforeach; ?>

</select>

</div>

<div class="md:col-span-1">

<label for="data_inicio" class="block text-sm font-medium text-gray-


700">Data Início</label>

<input type="date" id="data_inicio" name="data_inicio" value="<?=


$data_inicio ?>" class="mt-1 w-full p-2 border rounded-lg">

</div>

<div class="md:col-span-1">

<label for="data_fim" class="block text-sm font-medium text-gray-


700">Data Fim</label>

<input type="date" id="data_fim" name="data_fim" value="<?=


$data_fim ?>" class="mt-1 w-full p-2 border rounded-lg">

</div>

<div class="md:col-span-1">
<label for="produto_filtro" class="block text-sm font-medium text-
gray-700">Produto</label>

<input type="text" id="produto_filtro" name="produto" value="<?=


htmlspecialchars($produto_filtro) ?>" class="mt-1 w-full p-2 border rounded-lg"
placeholder="Digite o nome">

</div>

<div class="md:col-span-1">

<label for="status_filtro" class="block text-sm font-medium text-


gray-700">Status</label>

<select id="status_filtro" name="status" class="mt-1 w-full p-2


border rounded-lg">

<option value="">Todos</option>

<option value="vencido" <?= $status_filtro === 'vencido' ?


'selected' : '' ?>>Vencido</option>

<option value="avencer" <?= $status_filtro === 'avencer' ?


'selected' : '' ?>>À vencer</option>

<option value="alerta" <?= $status_filtro === 'alerta' ? 'selected' : ''


?>>Alerta</option>

<option value="ok" <?= $status_filtro === 'ok' ? 'selected' : ''


?>>OK</option>

</select>

<button type="submit" class="mt-2 w-full bg-blue-600 text-white p-2


rounded-lg hover:bg-blue-700">Pesquisar</button>

</div>

</div>

</form>

</div>

</div>

<!-- Formulário de Cadastro/Edição de Item -->

<form method="POST" class="bg-white p-6 rounded-lg shadow-md mb-8">


<input type="hidden" name="csrf_token" value="<?= gerarTokenCSRF(); ?>">

<input type="hidden" name="editar_id" value="<?= $item_editar['id'] ?? ''


?>">

<h2 class="text-xl font-semibold mb-4"><?= $item_editar ? 'Editar Item' :


'Cadastrar Novo Item' ?></h2>

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">

<div>

<label for="produto" class="block text-sm font-medium text-gray-


700">Produto</label>

<input type="text" id="produto" name="produto" value="<?=


$item_editar['produto'] ?? '' ?>" class="mt-1 w-full p-2 border rounded-lg"
required>

</div>

<div>

<label for="categoria_id" class="block text-sm font-medium text-gray-


700">Categoria</label>

<select id="categoria_id" name="categoria_id" class="mt-1 w-full p-2


border rounded-lg" required>

<option value="">-- Selecione uma categoria --</option>

<?php foreach ($categorias as $categoria): ?>

<option value="<?= $categoria['id'] ?>" <?= $item_editar &&


$item_editar['categoria_id'] == $categoria['id'] ? 'selected' : '' ?>>

<?= htmlspecialchars($categoria['nome']) ?>

</option>

<?php endforeach; ?>

</select>

</div>

<div>

<label for="quantidade" class="block text-sm font-medium text-gray-


700">Quantidade</label>
<input type="number" id="quantidade" name="quantidade" min="1"
value="<?= $item_editar['quantidade'] ?? '' ?>" class="mt-1 w-full p-2 border
rounded-lg" required>

</div>

<div>

<label for="data_vencimento" class="block text-sm font-medium text-


gray-700">Data de Vencimento</label>

<input type="date" id="data_vencimento" name="data_vencimento"


value="<?= $item_editar['data_vencimento'] ?? '' ?>" class="mt-1 w-full p-2 border
rounded-lg" required>

</div>

</div>

<button type="submit" class="mt-4 bg-blue-600 text-white p-2 rounded-lg


hover:bg-blue-700"><?= $item_editar ? 'Salvar Alterações' : 'Cadastrar'
?></button>

</form>

<!-- Lista de Itens Cadastrados -->

<h2 class="text-2xl font-semibold text-gray-800 mb-4">Itens


Cadastrados</h2>

<div class="bg-white rounded-lg shadow-md overflow-x-auto">

<table class="w-full">

<thead class="bg-gray-200">

<tr>

<th class="p-3 text-left">Produto</th>

<th class="p-3 text-left">Categoria</th>

<th class="p-3 text-left">Quantidade</th>

<th class="p-3 text-left">Data de Vencimento</th>

<th class="p-3 text-left">Dias Restantes</th>

<th class="p-3 text-left">Status</th>

<th class="p-3 text-left">Ações</th>


</tr>

</thead>

<tbody>

<?php if (empty($itens)): ?>

<tr><td colspan="7" class="p-3 text-center">Nenhum item


cadastrado.</td></tr>

<?php else: ?>

<?php foreach ($itens as $item): ?>

<tr class="border-t <?= $item['dias_restantes'] < 0 ? 'bg-red-100' :


($item['dias_restantes'] <= 30 ? 'bg-red-50' : ($item['dias_restantes'] <= 60 ? 'bg-
yellow-100' : 'bg-green-50')) ?>">

<td class="p-3"><?= htmlspecialchars($item['produto']) ?></td>

<td class="p-3"><?= htmlspecialchars($item['categoria']) ?></td>

<td class="p-3"><?= htmlspecialchars($item['quantidade'])


?></td>

<td class="p-3"><?= date('d/m/Y',


strtotime($item['data_vencimento'])) ?></td>

<td class="p-3"><?= $item['dias_restantes'] ?> dias</td>

<td class="p-3">

<?php if ($item['dias_restantes'] < 0): ?>

<span class="text-red-600 font-bold">Vencido</span>

<?php elseif ($item['dias_restantes'] <= 30): ?>

<span class="text-red-500 font-bold">À vencer</span>

<?php elseif ($item['dias_restantes'] <= 60): ?>

<span class="text-yellow-600 font-bold">Alerta</span>

<?php else: ?>

<span class="text-green-600 font-bold">OK</span>

<?php endif; ?>

</td>

<td class="p-3">
<a href="?editar_id=<?= $item['id'] ?>&page=<?= $page ?>"
class="text-blue-600 hover:underline mr-2"><i class="fas fa-edit"></i> Editar</a>

<form method="POST" class="inline" onsubmit="return


confirm('Tem certeza que deseja excluir este item?')">

<input type="hidden" name="csrf_token" value="<?=


gerarTokenCSRF(); ?>">

<input type="hidden" name="excluir_id" value="<?= $item['id']


?>">

<button type="submit" class="text-red-600 hover:underline"><i


class="fas fa-trash"></i> Excluir</button>

</form>

</td>

</tr>

<?php endforeach; ?>

<?php endif; ?>

</tbody>

</table>

</div>

<!-- Paginação -->

<?php if ($total_paginas > 1): ?>

<div class="mt-4 flex justify-center space-x-2">

<?php if ($page > 1): ?>

<a href="?page=<?= $page - 1 ?>&categoria=<?= $categoria_filtro


?>&data_inicio=<?= $data_inicio ?>&data_fim=<?= $data_fim ?>&produto=<?=
$produto_filtro ?>&status=<?= $status_filtro ?>" class="px-4 py-2 bg-gray-200 text-
gray-700 rounded-lg hover:bg-gray-300">Anterior</a>

<?php endif; ?>

<?php for ($i = 1; $i <= $total_paginas; $i++): ?>

<a href="?page=<?= $i ?>&categoria=<?= $categoria_filtro


?>&data_inicio=<?= $data_inicio ?>&data_fim=<?= $data_fim ?>&produto=<?=
$produto_filtro ?>&status=<?= $status_filtro ?>" class="px-4 py-2 <?= $i == $page ?
'bg-blue-600 text-white' : 'bg-gray-200 text-gray-700' ?> rounded-lg hover:bg-gray-
300"><?= $i ?></a>

<?php endfor; ?>

<?php if ($page < $total_paginas): ?>

<a href="?page=<?= $page + 1 ?>&categoria=<?= $categoria_filtro


?>&data_inicio=<?= $data_inicio ?>&data_fim=<?= $data_fim ?>&produto=<?=
$produto_filtro ?>&status=<?= $status_filtro ?>" class="px-4 py-2 bg-gray-200 text-
gray-700 rounded-lg hover:bg-gray-300">Próximo</a>

<?php endif; ?>

</div>

<?php endif; ?>

</div>

<!-- Script para exibir o modal -->

<script>

<?php if (isset($_SESSION['mensagem'])): ?>

showModal("<?= htmlspecialchars($_SESSION['mensagem']) ?>", "<?=


$_SESSION['tipo_mensagem'] ?>");

<?php unset($_SESSION['mensagem'], $_SESSION['tipo_mensagem']); ?>

<?php endif; ?>

</script>

</body>

</html>

Você também pode gostar