MINI
C:
/
xampp
/
htdocs
/
monitor
/
Upload File:
files >> C:/xampp/htdocs/monitor/index.php
<?php session_start(); // Koneksi Database $servername = "localhost"; $username = "root"; $password = ""; $dbname = "card_monitoring"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Buat Database dan Tabel Jika Tidak Ada $sql = "CREATE DATABASE IF NOT EXISTS $dbname"; $conn->query($sql); $conn->select_db($dbname); $sql = "CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )"; $conn->query($sql); $sql = "CREATE TABLE IF NOT EXISTS cards ( id INT AUTO_INCREMENT PRIMARY KEY, card_number VARCHAR(50) NOT NULL, card_type ENUM('keluar', 'dibayar') NOT NULL, amount DECIMAL(10,2) DEFAULT 0, transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, status ENUM('active', 'inactive') DEFAULT 'active', user_id INT, FOREIGN KEY (user_id) REFERENCES users(id) )"; $conn->query($sql); // Default admin user $adminCheck = $conn->query("SELECT * FROM users WHERE username='admin'"); if ($adminCheck->num_rows == 0) { $hashed_password = password_hash('admin123', PASSWORD_DEFAULT); $conn->query("INSERT INTO users (username, password) VALUES ('admin', '$hashed_password')"); } // Login Function if (isset($_POST['login'])) { $username = $_POST['username']; $password = $_POST['password']; $stmt = $conn->prepare("SELECT * FROM users WHERE username = ?"); $stmt->bind_param("s", $username); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows == 1) { $user = $result->fetch_assoc(); if (password_verify($password, $user['password'])) { $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; header("Location: {$_SERVER['PHP_SELF']}"); } else { $login_error = "Username atau password salah!"; } } else { $login_error = "Username tidak ditemukan!"; } } // Logout Function if (isset($_GET['logout'])) { session_destroy(); header("Location: {$_SERVER['PHP_SELF']}"); } // Add User Function if (isset($_POST['add_user']) && isset($_SESSION['user_id'])) { $new_username = $_POST['new_username']; $new_password = password_hash($_POST['new_password'], PASSWORD_DEFAULT); $stmt = $conn->prepare("INSERT INTO users (username, password) VALUES (?, ?)"); $stmt->bind_param("ss", $new_username, $new_password); $stmt->execute(); } // Edit Card Function if (isset($_POST['edit_card']) && isset($_SESSION['user_id'])) { $card_id = $_POST['card_id']; $card_number = $_POST['card_number']; $card_type = $_POST['card_type']; $amount = ($card_type == 'keluar') ? 0 : $_POST['amount']; // Check if card exists as 'keluar' before allowing change to 'dibayar' if ($card_type == 'dibayar') { $check_out = $conn->prepare("SELECT id FROM cards WHERE card_number = ? AND card_type = 'keluar'"); $check_out->bind_param("s", $card_number); $check_out->execute(); $check_out->store_result(); if ($check_out->num_rows == 0) { $_SESSION['error'] = "Kartu harus keluar terlebih dahulu sebelum bisa dibayar"; header("Location: {$_SERVER['PHP_SELF']}"); exit; } } $stmt = $conn->prepare("UPDATE cards SET card_number=?, card_type=?, amount=? WHERE id=?"); $stmt->bind_param("ssdi", $card_number, $card_type, $amount, $card_id); $stmt->execute(); } // Delete Card Function if (isset($_GET['delete_card']) && isset($_SESSION['user_id'])) { $card_id = $_GET['delete_card']; $stmt = $conn->prepare("DELETE FROM cards WHERE id=?"); $stmt->bind_param("i", $card_id); $stmt->execute(); header("Location: {$_SERVER['PHP_SELF']}"); } // Add Card Function if ((isset($_POST['add_card']) || isset($_POST['autoSubmit'])) && isset($_SESSION['user_id'])) { $card_number = $_POST['card_number']; $card_type = $_POST['card_type']; $amount = ($card_type == 'keluar') ? 0 : $_POST['amount']; $user_id = $_SESSION['user_id']; // Check if card exists as 'keluar' before allowing 'dibayar' if ($card_type == 'dibayar') { $check_out = $conn->prepare("SELECT id FROM cards WHERE card_number = ? AND card_type = 'keluar'"); $check_out->bind_param("s", $card_number); $check_out->execute(); $check_out->store_result(); if ($check_out->num_rows == 0) { $_SESSION['error'] = "Kartu harus keluar terlebih dahulu sebelum bisa dibayar"; header("Location: {$_SERVER['PHP_SELF']}"); exit; } } // Check if card already exists with same type $check = $conn->prepare("SELECT id FROM cards WHERE card_number = ? AND card_type = ?"); $check->bind_param("ss", $card_number, $card_type); $check->execute(); $check->store_result(); if ($check->num_rows > 0) { $_SESSION['error'] = "Kartu dengan nomor ini sudah ".($card_type == 'keluar' ? 'keluar' : 'dibayar'); } else { $stmt = $conn->prepare("INSERT INTO cards (card_number, card_type, amount, user_id) VALUES (?, ?, ?, ?)"); $stmt->bind_param("ssdi", $card_number, $card_type, $amount, $user_id); $stmt->execute(); } } // Get Cards Data and Statistics $cards = array(); $keluarCount = 0; $bayarCount = 0; if (isset($_SESSION['user_id'])) { $result = $conn->query("SELECT * FROM cards ORDER BY transaction_date DESC"); $stats = $conn->query("SELECT SUM(card_type = 'keluar') as keluar_count, SUM(card_type = 'dibayar') as bayar_count, COUNT(*) as total_count FROM cards"); $statsData = $stats->fetch_assoc(); $keluarCount = $statsData['keluar_count']; $bayarCount = $statsData['bayar_count']; $totalCount = $statsData['total_count']; $keluarPercent = $totalCount > 0 ? round(($keluarCount/$totalCount)*100) : 0; $bayarPercent = $totalCount > 0 ? round(($bayarCount/$totalCount)*100) : 0; while ($row = $result->fetch_assoc()) { $cards[] = $row; } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Card Monitoring System</title> <script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <script src="https://unpkg.com/html5-qrcode"></script> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> <!-- TCPDF library --> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script> <style> .card-keluar { border-left: 4px solid #ef4444; } .card-dibayar { border-left: 4px solid #10b981; } .blink { animation: blink 1s infinite; } @keyframes blink { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } </style> </head> <body class="bg-gray-100"> <?php if (!isset($_SESSION['user_id'])): ?> <!-- Login Form --> <div class="min-h-screen flex items-center justify-center"> <div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-md"> <div class="text-center mb-8"> <h1 class="text-2xl font-bold text-gray-800">Card Monitoring System</h1> <p class="text-gray-600">Silakan login untuk melanjutkan</p> </div> <?php if (isset($login_error)): ?> <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> <?php echo $login_error; ?> </div> <?php endif; ?> <form method="POST"> <div class="mb-4"> <label for="username" class="block text-gray-700 text-sm font-bold mb-2">Username</label> <input type="text" id="username" name="username" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500" required> </div> <div class="mb-6"> <label for="password" class="block text-gray-700 text-sm font-bold mb-2">Password</label> <input type="password" id="password" name="password" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500" required> </div> <button type="submit" name="login" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"> Login </button> </form> <div class="text-center mt-4"> <img src="https://storage.googleapis.com/workspace-0f70711f-8b4e-4d94-86f1-2a93ccde5887/image/4dfa8425-5e64-4035-a04a-dbe8151059c7.png" alt="Illustration of credit cards with digital security shield surrounding them" class="mx-auto mt-6"> </div> </div> </div> <?php else: ?> <!-- Dashboard --> <div class="min-h-screen"> <!-- Header --> <header class="bg-white shadow"> <div class="max-w-7xl mx-auto px-4 py-4 sm:px-6 lg:px-8 flex justify-between items-center"> <h1 class="text-xl font-bold text-gray-900"> <i class="fas fa-credit-card mr-2"></i> Card Monitoring System </h1> <div class="flex items-center space-x-4"> <button onclick="document.getElementById('userModal').classList.remove('hidden')" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg text-sm"> <i class="fas fa-user-plus mr-1"></i> Add User </button> <span class="text-gray-700">Welcome, <?php echo $_SESSION['username']; ?></span> <a href="?logout=1" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg text-sm"> <i class="fas fa-sign-out-alt mr-1"></i> Logout </a> </div> </div> </header> <!-- Main Content --> <main class="max-w-7xl mx-auto px-4 py-6 sm:px-6 lg:px-8"> <!-- Stats Cards --> <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8"> <div class="bg-white rounded-lg shadow p-6"> <div class="flex items-center"> <div class="p-3 rounded-full bg-red-100 text-red-600 mr-4"> <i class="fas fa-arrow-up text-lg"></i> </div> <div> <p class="text-sm font-medium text-gray-500">Keluar</p> <p class="text-2xl font-semibold text-gray-800"> <?php $result = $conn->query("SELECT COUNT(*) as total FROM cards WHERE card_type='keluar'"); echo $result->fetch_assoc()['total']; ?> </p> </div> </div> </div> <div class="bg-white rounded-lg shadow p-6"> <div class="flex items-center"> <div class="p-3 rounded-full bg-green-100 text-green-600 mr-4"> <i class="fas fa-arrow-down text-lg"></i> </div> <div> <p class="text-sm font-medium text-gray-500">Dibayar</p> <p class="text-2xl font-semibold text-gray-800"> <?php $result = $conn->query("SELECT COUNT(*) as total FROM cards WHERE card_type='dibayar'"); echo $result->fetch_assoc()['total']; ?> </p> </div> </div> </div> <div class="bg-white rounded-lg shadow p-6"> <div class="flex items-center"> <div class="p-3 rounded-full bg-blue-100 text-blue-600 mr-4"> <i class="fas fa-money-bill-wave text-lg"></i> </div> <div> <p class="text-sm font-medium text-gray-500">Total Amount</p> <p class="text-2xl font-semibold text-gray-800"> <?php $result = $conn->query("SELECT SUM(amount) as total FROM cards"); echo 'Rp ' . number_format($result->fetch_assoc()['total'] ?? 0, 2); ?> </p> </div> </div> </div> </div> <!-- Add Card Form --> <div class="bg-white rounded-lg shadow p-6 mb-8"> <h2 class="text-lg font-semibold text-gray-800 mb-4">Tambah Kartu</h2> <?php if (isset($_SESSION['error'])): ?> <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> <?php echo $_SESSION['error']; unset($_SESSION['error']); ?> </div> <?php endif; ?> <?php if (isset($_SESSION['error'])): ?> <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> <?php echo $_SESSION['error']; unset($_SESSION['error']); ?> </div> <?php endif; ?> <form method="POST"> <div class="grid grid-cols-1 md:grid-cols-4 gap-4"> <div> <label class="block text-sm font-medium text-gray-700 mb-1">Nomor Kartu <button type="button" onclick="startScanner()" class="ml-2 text-blue-600 hover:text-blue-800 text-sm font-normal"> <i class="fas fa-qrcode"></i> Scan QR </button> </label> <input type="text" name="card_number" id="cardNumberInput" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" required> <div id="scanner-container" class="hidden mt-2"></div> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-1">Tipe Kartu</label> <select name="card_type" id="cardTypeInput" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" required> <option value="">Pilih Tipe</option> <option value="keluar">Keluar</option> <option value="dibayar">Dibayar</option> </select> </div> <div> <label class="block text-sm font-medium text-gray-700 mb-1">Amount</label> <select name="amount" id="amountInput" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" required> <option value="">Pilih Nominal</option> <option value="100000">Rp 100,000</option> <option value="500000">Rp 500,000</option> </select> <script> document.getElementById('cardTypeInput').addEventListener('change', function() { const amountInput = document.getElementById('amountInput'); if (this.value === 'keluar') { amountInput.value = '0'; amountInput.disabled = true; amountInput.classList.add('bg-gray-100'); } else { amountInput.value = ''; amountInput.disabled = false; amountInput.classList.remove('bg-gray-100'); } }); </script> </div> <div class="flex items-end"> <button type="submit" name="add_card" class="w-full bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md text-sm font-medium focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> Tambah Kartu </button> <input type="hidden" id="autoSubmit" name="add_card" value="1"> </div> </div> </form> </div> <!-- Report Controls --> <div class="bg-white rounded-lg shadow p-4 mb-6 flex justify-between items-center"> <div class="flex space-x-4"> <select id="reportPeriod" class="border border-gray-300 rounded px-3 py-2"> <option value="daily">Harian</option> <option value="monthly">Bulanan</option> </select> <input type="date" id="reportDate" class="border border-gray-300 rounded px-3 py-2"> <button id="generateReport" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded"> Generate Report </button> </div> <button id="exportPdf" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded"> <i class="fas fa-file-pdf mr-2"></i> Export PDF </button> </div> <!-- Cards Table --> <div class="bg-white rounded-lg shadow overflow-hidden"> <div class="px-6 py-4 border-b border-gray-200"> <div class="flex justify-between items-center"> <h3 class="text-lg font-medium text-gray-900">Monitoring Kartu</h3> <div class="relative"> <input type="text" placeholder="Search..." id="searchInput" class="pl-8 pr-4 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> <i class="fas fa-search text-gray-400"></i> </div> </div> </div> </div> <div class="overflow-x-auto"> <table class="min-w-full divide-y divide-gray-200"> <thead class="bg-gray-50"> <tr> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">No</th> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Nomor Kartu</th> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tipe</th> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tanggal</th> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th> <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th> </tr> </thead> <tbody class="bg-white divide-y divide-gray-200"> <?php foreach ($cards as $index => $card): ?> <tr class="<?php echo $card['card_type'] === 'keluar' ? 'card-keluar' : 'card-dibayar'; ?> <?php echo $index < 5 ? 'blink' : ''; ?>"> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?php echo $index + 1; ?></td> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"><?php echo $card['card_number']; ?></td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> <span class="<?php echo $card['card_type'] === 'keluar' ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800'; ?> px-2 py-1 rounded-full text-xs"> <?php echo ucfirst($card['card_type']); ?> </span> </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">Rp <?php echo number_format($card['amount'], 2); ?></td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?php echo date('d M Y H:i', strtotime($card['transaction_date'])); ?></td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> <span class="<?php echo $card['status'] === 'active' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'; ?> px-2 py-1 rounded-full text-xs"> <?php echo ucfirst($card['status']); ?> </span> </td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> <button onclick="openEditModal(<?php echo $card['id']; ?>)" class="text-blue-600 hover:text-blue-900 mr-3"> <i class="fas fa-edit"></i> </button> <button onclick="confirmDelete(<?php echo $card['id']; ?>)" class="text-red-600 hover:text-red-900"> <i class="fas fa-trash"></i> </button> </td> </tr> <?php endforeach; ?> <?php if (empty($cards)): ?> <tr> <td colspan="6" class="px-6 py-4 text-center text-sm text-gray-500">Belum ada data kartu</td> </tr> <?php endif; ?> </tbody> </table> </div> </div> <!-- Users Table --> <div class="bg-white rounded-lg shadow overflow-hidden mt-8"> <div class="px-6 py-4 border-b border-gray-200"> <h3 class="text-lg font-medium text-gray-900">User Management</h3> </div> <div class="overflow-x-auto"> <table class="min-w-full divide-y divide-gray-200"> <thead class="bg-gray-50"> <tr> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">ID</th> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Username</th> <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Created At</th> </tr> </thead> <tbody class="bg-white divide-y divide-gray-200"> <?php $users = $conn->query("SELECT * FROM users ORDER BY created_at DESC"); while($user = $users->fetch_assoc()): ?> <tr> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?= $user['id'] ?></td> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"><?= $user['username'] ?></td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"><?= date('d M Y', strtotime($user['created_at'])) ?></td> </tr> <?php endwhile; ?> </tbody> </table> </div> </div> <!-- Summary Chart --> <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6"> <div class="bg-white rounded-lg shadow p-6"> <h3 class="text-lg font-medium text-gray-800 mb-4">Summary by Type</h3> <div class="flex justify-between mb-2"> <span class="font-medium">Keluar:</span> <span><?php echo $keluarPercent; ?>% (<?php echo $keluarCount; ?>)</span> </div> <div class="w-full bg-gray-200 rounded-full h-2.5"> <div class="bg-red-600 h-2.5 rounded-full" style="width: <?php echo $keluarPercent; ?>%"></div> </div> <div class="flex justify-between mt-4 mb-2"> <span class="font-medium">Dibayar:</span> <span><?php echo $bayarPercent; ?>% (<?php echo $bayarCount; ?>)</span> </div> <div class="w-full bg-gray-200 rounded-full h-2.5"> <div class="bg-green-600 h-2.5 rounded-full" style="width: <?php echo $bayarPercent; ?>%"></div> </div> </div> <?php if($totalCount > 0): ?> <div class="bg-white rounded-lg shadow p-6"> <h3 class="text-lg font-medium text-gray-800 mb-4">Latest Transactions</h3> <img src="https://storage.googleapis.com/workspace-0f70711f-8b4e-4d94-86f1-2a93ccde5887/image/e5562dcd-daff-45e5-82f3-0246d957d3f7.png" alt="Line chart showing transaction trends over time" class="w-full h-auto"> </div> <?php endif; ?> </div> </main> </div> <?php endif; ?> <script> document.getElementById('searchInput').addEventListener('input', function() { const searchValue = this.value.toLowerCase(); const rows = document.querySelectorAll('tbody tr'); rows.forEach(row => { const text = row.textContent.toLowerCase(); row.style.display = text.includes(searchValue) ? '' : 'none'; }); }); </script> <!-- User Modal --> <div id="userModal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full"> <div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white"> <div class="mt-3 text-center"> <h3 class="text-lg leading-6 font-medium text-gray-900">Add New User</h3> <div class="mt-2 px-7 py-3"> <form method="POST"> <div class="mb-4"> <label class="block text-gray-700 text-sm font-bold mb-2">Username</label> <input type="text" name="new_username" class="w-full px-3 py-2 border rounded" required> </div> <div class="mb-4"> <label class="block text-gray-700 text-sm font-bold mb-2">Password</label> <input type="password" name="new_password" class="w-full px-3 py-2 border rounded" required> </div> <div class="flex space-x-4"> <button type="submit" name="add_user" class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"> Create User </button> <button type="button" onclick="document.getElementById('userModal').classList.add('hidden')" class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"> Cancel </button> </div> </form> </div> </div> </div> </div> <!-- Edit Card Modal --> <div id="editModal" class="hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full"> <div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white"> <div class="mt-3 text-center"> <h3 class="text-lg leading-6 font-medium text-gray-900">Edit Card</h3> <div class="mt-2 px-7 py-3"> <form id="editForm" method="POST"> <input type="hidden" name="card_id" id="editCardId"> <div class="mb-4"> <label class="block text-gray-700 text-sm font-bold mb-2">Nomor Kartu</label> <input type="text" name="card_number" id="editCardNumber" class="w-full px-3 py-2 border rounded" required> </div> <div class="mb-4"> <label class="block text-gray-700 text-sm font-bold mb-2">Tipe Kartu</label> <select name="card_type" id="editCardType" class="w-full px-3 py-2 border rounded" required> <option value="keluar">Keluar</option> <option value="dibayar">Dibayar</option> </select> </div> <div class="mb-4"> <label class="block text-gray-700 text-sm font-bold mb-2">Amount</label> <select name="amount" id="editAmount" class="w-full px-3 py-2 border rounded" required> <option value="100000">Rp 100,000</option> <option value="500000">Rp 500,000</option> </select> </div> <div class="flex space-x-4"> <button type="submit" name="edit_card" class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"> Save Changes </button> <button type="button" onclick="document.getElementById('editModal').classList.add('hidden')" class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"> Cancel </button> </div> </form> </div> </div> </div> </div> <script> function startScanner() { const scannerContainer = document.getElementById('scanner-container'); scannerContainer.classList.remove('hidden'); const html5QrCode = new Html5Qrcode("scanner-container"); html5QrCode.start( { facingMode: "environment" }, { fps: 10, qrbox: { width: 250, height: 250 } }, (qrCodeMessage) => { // On scan success document.getElementById('cardNumberInput').value = qrCodeMessage; document.getElementById('cardTypeInput').value = 'keluar'; // Auto set to "keluar" html5QrCode.stop().then(() => { scannerContainer.classList.add('hidden'); // Auto-submit the form document.querySelector('form[method="POST"]').submit(); }).catch(err => console.log(err)); }, (errorMessage) => { // Parse error, ignore } ).catch(err => { console.error("Scanner error:", err); alert("Error starting scanner: " + err); }); } function openEditModal(cardId) { // In real implementation, this would fetch card data via AJAX document.getElementById('editCardId').value = cardId; document.getElementById('editModal').classList.remove('hidden'); } function confirmDelete(cardId) { if(confirm('Are you sure you want to delete this card?')) { // In real implementation, this would submit a delete request window.location.href = `?delete_card=${cardId}`; } } </script> <script> document.getElementById('exportPdf').addEventListener('click', function() { const element = document.createElement('div'); element.innerHTML = ` <h1 class="text-2xl font-bold mb-4">Laporan Transaksi Kartu</h1> <p class="mb-2">Periode: ${document.getElementById('reportPeriod').value === 'daily' ? 'Harian' : 'Bulanan'}</p> <p class="mb-4">Tanggal: ${document.getElementById('reportDate').value}</p> ${document.querySelector('.bg-white.rounded-lg.shadow.overflow-hidden').outerHTML} `; const opt = { margin: 10, filename: 'laporan-kartu.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' } }; html2pdf().from(element).set(opt).save(); }); // Set default date to today document.getElementById('reportDate').valueAsDate = new Date(); </script> </body> </html>
Copyright ©2021 || Defacer Indonesia