O erro indica que a biblioteca jsPDF não está disponível no ambiente. Vou corrigir isso implementando uma solução que funciona sem dependências externas, usando a API nativa do navegador para gerar PDFs.
jsPDFbaixarTicketPDF() que abre uma nova janela com HTML formatado para impressãobaixarTicketPDFAlternativo() que usa Canvas APIEsta solução funciona em todos os navegadores modernos sem necessidade de bibliotecas externas, resolvendo o erro de importação do jsPDF.
Corrija a minha api//Codigo<?php// Cabeçalhos CORSheader('Content-Type: application/json');header('Access-Control-Allow-Origin: https://apilaguna.rf.gd/');header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');header('Access-Control-Allow-Headers: Content-Type');// Responde requisições preflightif ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { http_response_code(200); exit();}require 'config.php';$method = $_SERVER['REQUEST_METHOD'];$action = $_GET['action'] ?? '';switch ($action) { case 'login': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $email = $data['email'] ?? ''; $senha = $data['senha'] ?? ''; $stmt = $pdo->prepare('SELECT * FROM usuarios WHERE email = ?'); $stmt->execute([$email]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user && password_verify($senha, $user['senha'])) { unset($user['senha']); echo json_encode(['success' => true, 'usuario' => $user]); } else { echo json_encode(['success' => false, 'message' => 'Email ou senha incorretos']); } } break; case 'register': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $nome = $data['nome'] ?? ''; $email = $data['email'] ?? ''; $telefone = $data['telefone'] ?? ''; $senha = $data['senha'] ?? ''; $stmt = $pdo->prepare('SELECT COUNT(*) FROM usuarios WHERE email = ?'); $stmt->execute([$email]); if ($stmt->fetchColumn() > 0) { echo json_encode(['success' => false, 'message' => 'Email já cadastrado']); exit; } $senhaHash = password_hash($senha, PASSWORD_BCRYPT); $stmt = $pdo->prepare('INSERT INTO usuarios (nome, email, telefone, senha, data_cadastro, is_admin) VALUES (?, ?, ?, ?, CURDATE(), 0)'); $stmt->execute([$nome, $email, $telefone, $senhaHash]); $userId = $pdo->lastInsertId(); echo json_encode(['success' => true, 'user_id' => $userId]); } break; case 'get_precos': if ($method === 'GET') { $stmt = $pdo->query('SELECT tipo, preco_por_hora FROM quadras'); $precos = $stmt->fetchAll(PDO::FETCH_ASSOC); $formattedPrecos = ['areia' => 0, 'society' => 0]; foreach ($precos as $preco) { $formattedPrecos[$preco['tipo']] = $preco['preco_por_hora']; } echo json_encode($formattedPrecos); } break; case 'update_preco': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $tipo = $data['tipo'] ?? ''; $novoPreco = $data['preco'] ?? 0; $stmt = $pdo->prepare('SELECT id, preco_por_hora FROM quadras WHERE tipo = ?'); $stmt->execute([$tipo]); $quadra = $stmt->fetch(PDO::FETCH_ASSOC); if ($quadra) { $stmt = $pdo->prepare('UPDATE quadras SET preco_por_hora = ? WHERE id = ?'); $stmt->execute([$novoPreco, $quadra['id']]); $stmt = $pdo->prepare('INSERT INTO historico_precos (quadra_id, preco_antigo, preco_novo, data_alteracao) VALUES (?, ?, ?, NOW())'); $stmt->execute([$quadra['id'], $quadra['preco_por_hora'], $novoPreco]); echo json_encode(['success' => true]); } else { echo json_encode(['success' => false, 'message' => 'Quadra não encontrada']); } } break; case 'get_historico_precos': if ($method === 'GET') { $stmt = $pdo->query('SELECT h.*, q.tipo FROM historico_precos h JOIN quadras q ON h.quadra_id = q.id ORDER BY h.data_alteracao DESC'); $historico = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($historico); } break; case 'get_reservas': if ($method === 'GET') { $usuarioId = $_GET['usuario_id'] ?? null; $filtro = $_GET['filtro'] ?? 'todas'; $query = 'SELECT r.*, u.nome as cliente, q.tipo, t.numero_ticket, t.qr_code FROM reservas r JOIN usuarios u ON r.usuario_id = u.id JOIN quadras q ON r.quadra_id = q.id LEFT JOIN tickets t ON r.id = t.reserva_id'; $params = []; if ($usuarioId) { $query .= ' WHERE r.usuario_id = ?'; $params[] = $usuarioId; if ($filtro !== 'todas') { $query .= ' AND r.status = ?'; $params[] = $filtro; } } elseif ($filtro !== 'todas') { $query .= ' WHERE r.status = ?'; $params[] = $filtro; } $query .= ' ORDER BY r.data_criacao DESC'; $stmt = $pdo->prepare($query); $stmt->execute($params); $reservas = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($reservas); } break; case 'fazer_reserva': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $usuarioId = $data['usuario_id'] ?? 0; $tipo = $data['tipo'] ?? ''; $dataReserva = $data['data'] ?? ''; $horarios = $data['horarios'] ?? []; $valorTotal = $data['valor_total'] ?? 0; $stmt = $pdo->prepare('SELECT id, preco_por_hora FROM quadras WHERE tipo = ?'); $stmt->execute([$tipo]); $quadra = $stmt->fetch(PDO::FETCH_ASSOC); if (!$quadra) { echo json_encode(['success' => false, 'message' => 'Quadra não encontrada']); exit; } // Verificar conflitos de horário $stmt = $pdo->prepare('SELECT COUNT(*) FROM reservas WHERE quadra_id = ? AND data = ? AND horario = ? AND status != "cancelada"'); foreach ($horarios as $horario) { $stmt->execute([$quadra['id'], $dataReserva, $horario]); if ($stmt->fetchColumn() > 0) { echo json_encode(['success' => false, 'message' => "Horário $horario já reservado"]); exit; } } // Inserir reservas $reservaIds = []; $numeroTicket = 'TKT-' . time() . '-' . $usuarioId; foreach ($horarios as $horario) { $stmt = $pdo->prepare('INSERT INTO reservas (usuario_id, quadra_id, data, horario, valor_total, status, data_criacao) VALUES (?, ?, ?, ?, ?, "pendente", NOW())'); $stmt->execute([$usuarioId, $quadra['id'], $dataReserva, $horario, $valorTotal / count($horarios)]); $reservaId = $pdo->lastInsertId(); $reservaIds[] = $reservaId; // Gerar ticket para cada reserva $qrCode = 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=' . urlencode(json_encode([ 'ticketId' => $numeroTicket, 'reservaId' => $reservaId, 'usuarioId' => $usuarioId, 'tipo' => $tipo, 'data' => $dataReserva, 'horario' => $horario, 'valor' => $valorTotal / count($horarios) ])); $stmt = $pdo->prepare('INSERT INTO tickets (reserva_id, numero_ticket, qr_code, data_emissao) VALUES (?, ?, ?, NOW())'); $stmt->execute([$reservaId, $numeroTicket, $qrCode]); } echo json_encode([ 'success' => true, 'numero_ticket' => $numeroTicket, 'qr_code' => $qrCode, 'data' => $dataReserva, 'horarios' => $horarios, 'valor_total' => $valorTotal, 'reserva_ids' => $reservaIds ]); } break; case 'confirmar_pagamento': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $reservaIds = $data['reserva_ids'] ?? []; $stmt = $pdo->prepare('UPDATE reservas SET status = "confirmada" WHERE id = ?'); foreach ($reservaIds as $id) { $stmt->execute([$id]); } echo json_encode(['success' => true]); } break; case 'verificar_ticket': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $numeroTicket = $data['numero_ticket'] ?? ''; $stmt = $pdo->prepare('SELECT t.*, r.*, u.nome as cliente, q.tipo FROM tickets t JOIN reservas r ON t.reserva_id = r.id JOIN usuarios u ON r.usuario_id = u.id JOIN quadras q ON r.quadra_id = q.id WHERE t.numero_ticket = ?'); $stmt->execute([$numeroTicket]); $ticket = $stmt->fetch(PDO::FETCH_ASSOC); if ($ticket) { echo json_encode(['success' => true, 'ticket' => $ticket]); } else { echo json_encode(['success' => false, 'message' => 'Ticket não encontrado']); } } break; case 'confirmar_presenca': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $reservaId = $data['reserva_id'] ?? 0; $stmt = $pdo->prepare('UPDATE reservas SET status = "presente" WHERE id = ?'); $stmt->execute([$reservaId]); echo json_encode(['success' => true]); } break; case 'cancelar_reserva': if ($method === 'POST') { $data = json_decode(file_get_contents('php://input'), true); $reservaId = $data['reserva_id'] ?? 0; $stmt = $pdo->prepare('UPDATE reservas SET status = "cancelada" WHERE id = ?'); $stmt->execute([$reservaId]); echo json_encode(['success' => true]); } break; case 'get_clientes': if ($method === 'GET') { $search = $_GET['search'] ?? ''; $query = 'SELECT id, nome, email, telefone, data_cadastro, is_admin FROM usuarios WHERE is_admin = 0'; $params = []; if ($search) { $query .= ' AND (nome LIKE ? OR email LIKE ?)'; $params = ["%$search%", "%$search%"]; } $query .= ' ORDER BY nome'; $stmt = $pdo->prepare($query); $stmt->execute($params); $clientes = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($clientes); } break; default: echo json_encode(['error' => 'Ação inválida']); break;}?>
Vou corrigir sua API PHP com melhorias na estrutura, tratamento de erros e padronização das respostas:
jsonResponse() para padronizar todas as respostasvalidateRequired() para validar campos obrigatóriosfilter_var()trim()rowCount() para confirmar alteraçõesget_users como alias para get_clientesEsta versão corrigida é mais robusta, segura e fácil de manter, com melhor tratamento de erros e validações mais rigorosas.
laguna-beach.vercel.app/:1 Access to fetch at 'https://apilaguna.rf.gd/api.php?action=get_precos' from origin 'https://laguna-beach.vercel.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.