Auto commit: 2025-10-06T00:57:03.276Z

This commit is contained in:
Flatlogic Bot 2025-10-06 00:57:03 +00:00
parent 8dd1b311f8
commit 3d8da9a26a
9 changed files with 1011 additions and 3 deletions

View File

@ -1,8 +1,113 @@
/* Custom CSS for Si-Apon */ /* Add your custom styles here */
.alert {
padding: 1rem;
margin-bottom: 1rem;
border-radius: 0.5rem;
border: 1px solid transparent;
}
.alert-danger {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
.alert-success {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
/* Login & Register Page */
.login-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f4f4f4;
}
.login-box {
background: #fff;
padding: 2.5rem;
border-radius: 0.5rem;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
width: 100%;
max-width: 420px;
}
.login-header {
text-align: center;
margin-bottom: 2rem;
}
.login-header h2 {
margin: 0;
font-size: 1.8rem;
color: #264653;
}
.login-header p {
color: #6c757d;
}
.logo-link {
text-decoration: none;
}
.login-form .form-group {
margin-bottom: 1.5rem;
}
.login-form label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
color: #264653;
}
.login-form input {
width: 100%;
padding: 0.75rem;
border: 1px solid #ccc;
border-radius: 0.25rem;
}
.btn-login {
width: 100%;
padding: 0.85rem;
border: none;
border-radius: 0.25rem;
background-color: #2A9D8F;
color: white;
font-size: 1.1rem;
cursor: pointer;
transition: background-color 0.3s;
}
.btn-login:hover {
background-color: #248a7e;
}
.login-footer {
text-align: center;
margin-top: 1.5rem;
}
.login-footer p {
margin: 0.5rem 0;
color: #6c757d;
}
.login-footer a {
color: #2A9D8F;
text-decoration: none;
}
.login-footer a:hover {
text-decoration: underline;
}
body { body {
font-family: 'Lato', sans-serif; font-family: 'Lato', sans-serif;
color: #264653; color: #264653;
background-color: #F4F4F4; background-color: #F4F4F4;
margin: 0;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -36,6 +141,9 @@ h1, h2, h3, h4, h5, h6 {
border-color: #2A9D8F; border-color: #2A9D8F;
padding: 10px 20px; padding: 10px 20px;
border-radius: 0.5rem; border-radius: 0.5rem;
color: white;
text-decoration: none;
display: inline-block;
} }
.btn-secondary { .btn-secondary {
@ -50,7 +158,239 @@ section {
} }
.card { .card {
background: #fff;
padding: 2rem;
border: none; border: none;
border-radius: 0.5rem; border-radius: 0.5rem;
box-shadow: 0 4px 8px rgba(0,0,0,0.1); box-shadow: 0 4px 8px rgba(0,0,0,0.05);
margin-bottom: 2rem;
}
/* Dashboard Layout */
.dashboard-wrapper {
display: flex;
min-height: 100vh;
}
.sidebar {
width: 260px;
background: #264653;
color: #fff;
display: flex;
flex-direction: column;
}
.sidebar-header {
padding: 1.5rem;
text-align: center;
border-bottom: 1px solid #3a5e6c;
}
.sidebar-header h3 {
margin: 0;
color: #fff;
}
.sidebar-header a {
text-decoration: none;
}
.sidebar-nav {
flex-grow: 1;
padding-top: 1rem;
}
.sidebar-nav a {
display: block;
padding: 1rem 1.5rem;
color: #e0e0e0;
text-decoration: none;
transition: background 0.3s, color 0.3s;
}
.sidebar-nav a:hover, .sidebar-nav a.active {
background: #2A9D8F;
color: #fff;
}
.sidebar-footer {
padding: 1.5rem;
border-top: 1px solid #3a5e6c;
}
.sidebar-footer a {
display: block;
text-align: center;
color: #e0e0e0;
text-decoration: none;
}
.main-content {
flex-grow: 1;
background: #f4f4f4;
}
.main-header {
background: #fff;
padding: 1rem 2rem;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
}
.content-area {
padding: 2rem;
}
/* Dashboard Table */
.table-responsive {
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
thead {
background-color: #f8f9fa;
}
th, td {
padding: 0.9rem 1rem;
text-align: left;
border-bottom: 1px solid #dee2e6;
}
tbody tr:hover {
background-color: #f1f1f1;
}
/* Badges */
.badge {
padding: 0.3em 0.6em;
border-radius: 0.25rem;
font-size: 0.85em;
font-weight: 700;
color: #fff;
}
.role-admin {
background-color: #d9534f;
}
.role-petugas-pajak {
background-color: #f0ad4e;
}
.role-wajib-pajak {
background-color: #5bc0de;
}
/* Status Badges */
.status-pending {
background-color: #f0ad4e; /* Orange */
}
.status-approved {
background-color: #5cb85c; /* Green */
}
.status-rejected {
background-color: #d9534f; /* Red */
}
/* Form Card for Lapor Pajak */
.form-card {
max-width: 800px;
margin: 0 auto;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: .5rem;
font-weight: bold;
}
.form-group input,
.form-group select {
width: 100%;
padding: .75rem;
border: 1px solid #ccc;
border-radius: .25rem;
box-sizing: border-box; /* Add this */
}
.period-group {
display: flex;
gap: 1rem;
}
.period-group select {
flex: 1;
}
.btn-block {
width: 100%;
}
/* Dashboard card header */
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 1px solid #eee;
}
.card-header h3 {
margin: 0;
}
/* General Dashboard Container */
.dashboard-container {
display: flex;
min-height: 100vh;
}
.logo {
text-decoration: none;
color: #fff;
font-family: 'Merriweather', serif;
font-size: 1.5rem;
}
.user-info {
display: flex;
align-items: center;
gap: 1rem;
}
/* Action Buttons in Tables */
.actions {
white-space: nowrap;
}
.actions .btn {
margin-right: 0.5rem;
}
.btn-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
border-radius: 0.2rem;
}
.btn-success {
background-color: #5cb85c;
border-color: #5cb85c;
color: white;
}
.btn-danger {
background-color: #d9534f;
border-color: #d9534f;
color: white;
} }

197
dashboard.php Normal file
View File

@ -0,0 +1,197 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}
$user_id = $_SESSION['user_id'];
$userName = $_SESSION['user_name'] ?? 'Pengguna';
$userRole = $_SESSION['user_role'] ?? 'Tidak Dikenal';
$pdo = db();
$users = [];
$tax_reports = [];
// Fetch data based on user role
if ($userRole === 'Super Administrator') {
$stmt = $pdo->query("SELECT id, name, email, role, created_at FROM users ORDER BY created_at DESC");
$users = $stmt->fetchAll();
} elseif ($userRole === 'Wajib Pajak') {
$stmt = $pdo->prepare("SELECT * FROM tax_reports WHERE user_id = :user_id ORDER BY created_at DESC");
$stmt->execute([':user_id' => $user_id]);
$tax_reports = $stmt->fetchAll();
} elseif ($userRole === 'Petugas Pajak') {
$stmt = $pdo->query("SELECT tr.*, u.name AS taxpayer_name FROM tax_reports tr JOIN users u ON tr.user_id = u.id ORDER BY tr.created_at DESC");
$tax_reports = $stmt->fetchAll();
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - Si-Apon</title>
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="dashboard-container">
<aside class="sidebar">
<div class="sidebar-header">
<a href="index.php" class="logo">Si-Apon</a>
</div>
<nav class="sidebar-nav">
<a href="dashboard.php" class="active">Dashboard</a>
<?php if ($userRole === 'Wajib Pajak'): ?>
<a href="lapor-pajak.php">Lapor Pajak</a>
<?php endif; ?>
<?php if ($userRole === 'Petugas Pajak'): ?>
<a href="dashboard.php" class="active">Verifikasi Laporan</a>
<?php endif; ?>
<?php if ($userRole === 'Super Administrator'): ?>
<a href="#">Manajemen Pengguna</a>
<?php endif; ?>
</nav>
<div class="sidebar-footer">
<a href="logout.php">Logout</a>
</div>
</aside>
<main class="main-content">
<header class="main-header">
<h1>Selamat Datang, <?php echo htmlspecialchars($userName); ?>!</h1>
<div class="user-info">
<span class="role-badge role-<?php echo strtolower(str_replace(' ', '-', $userRole)); ?>"><?php echo htmlspecialchars($userRole); ?></span>
</div>
</header>
<section class="content-section">
<?php if ($userRole === 'Super Administrator'): ?>
<div class="card">
<div class="card-header">
<h3>Manajemen Pengguna</h3>
</div>
<div class="card-body">
<div class="table-responsive">
<table>
<thead>
<tr>
<th>Nama</th>
<th>Email</th>
<th>Peran</th>
<th>Tanggal Terdaftar</th>
</tr>
</thead>
<tbody>
<?php if (empty($users)): ?>
<tr><td colspan="4">Tidak ada pengguna untuk ditampilkan.</td></tr>
<?php else: ?>
<?php foreach ($users as $user): ?>
<tr>
<td><?php echo htmlspecialchars($user['name']); ?></td>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td><span class="badge role-<?php echo strtolower(str_replace(' ', '-', htmlspecialchars($user['role']))); ?>"><?php echo htmlspecialchars($user['role']); ?></span></td>
<td><?php echo date("d M Y", strtotime($user['created_at'])); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php elseif ($userRole === 'Petugas Pajak'): ?>
<div class="card">
<div class="card-header">
<h3>Verifikasi Laporan Pajak</h3>
</div>
<div class="card-body">
<div class="table-responsive">
<table>
<thead>
<tr>
<th>Wajib Pajak</th>
<th>Tanggal Lapor</th>
<th>Jenis Pajak</th>
<th>Total Pajak</th>
<th>Status</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
<?php if (empty($tax_reports)):
?>
<tr><td colspan="6" style="text-align: center;">Tidak ada laporan untuk diverifikasi.</td></tr>
<?php else: ?>
<?php foreach ($tax_reports as $report): ?>
<tr>
<td><?php echo htmlspecialchars($report['taxpayer_name']); ?></td>
<td><?php echo date("d M Y", strtotime($report['created_at'])); ?></td>
<td><?php echo htmlspecialchars($report['tax_type']); ?></td>
<td>Rp <?php echo number_format($report['tax_amount'], 2, ',', '.'); ?></td>
<td><span class="badge status-<?php echo strtolower(htmlspecialchars($report['status'])); ?>"><?php echo htmlspecialchars($report['status']); ?></span></td>
<td class="actions">
<?php if ($report['status'] === 'Pending'): ?>
<a href="verifikasi-laporan.php?id=<?php echo $report['id']; ?>&action=approve" class="btn btn-success btn-sm">Setuju</a>
<a href="verifikasi-laporan.php?id=<?php echo $report['id']; ?>&action=reject" class="btn btn-danger btn-sm">Tolak</a>
<?php else: ?>
-
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php elseif ($userRole === 'Wajib Pajak'): ?>
<div class="card">
<div class="card-header">
<h3>Riwayat Laporan Pajak Anda</h3>
<a href="lapor-pajak.php" class="btn btn-primary">Lapor Pajak Baru</a>
</div>
<div class="card-body">
<div class="table-responsive">
<table>
<thead>
<tr>
<th>Jenis Pajak</th>
<th>Periode</th>
<th>Omzet Kotor</th>
<th>Total Pajak</th>
<th>Status</th>
<th>Tanggal Lapor</th>
</tr>
</thead>
<tbody>
<?php if (empty($tax_reports)): ?>
<tr><td colspan="6" style="text-align: center;">Anda belum memiliki riwayat laporan.</td></tr>
<?php else: ?>
<?php foreach ($tax_reports as $report): ?>
<tr>
<td><?php echo htmlspecialchars($report['tax_type']); ?></td>
<td><?php echo date('F', mktime(0, 0, 0, $report['period_month'], 10)) . ' ' . $report['period_year']; ?></td>
<td>Rp <?php echo number_format($report['gross_revenue'], 2, ',', '.'); ?></td>
<td>Rp <?php echo number_format($report['tax_amount'], 2, ',', '.'); ?></td>
<td><span class="badge status-<?php echo strtolower(htmlspecialchars($report['status'])); ?>"><?php echo htmlspecialchars($report['status']); ?></span></td>
<td><?php echo date("d M Y", strtotime($report['created_at'])); ?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php endif; ?>
</section>
</main>
</div>
</body>
</html>

86
db/setup.php Normal file
View File

@ -0,0 +1,86 @@
<?php
require_once 'config.php';
try {
$pdo = db();
// Create users table
$sql_users = "
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role ENUM('Wajib Pajak', 'Petugas Pajak', 'Pimpinan', 'Super Administrator') NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=INNODB;
";
$pdo->exec($sql_users);
echo "Table 'users' created successfully (if it didn't exist).<br>";
// Inser dummy users
$users = [
[
'name' => 'Admin',
'email' => 'admin@sarmikab.go.id',
'password' => password_hash('admin123', PASSWORD_DEFAULT),
'role' => 'Super Administrator'
],
[
'name' => 'Petugas Pajak',
'email' => 'petugas@sarmikab.go.id',
'password' => password_hash('petugas123', PASSWORD_DEFAULT),
'role' => 'Petugas Pajak'
],
[
'name' => 'Wajib Pajak Contoh',
'email' => 'wajibpajak@example.com',
'password' => password_hash('wajibpajak123', PASSWORD_DEFAULT),
'role' => 'Wajib Pajak'
],
[
'name' => 'Pimpinan',
'email' => 'pimpinan@sarmikab.go.id',
'password' => password_hash('pimpinan123', PASSWORD_DEFAULT),
'role' => 'Pimpinan'
]
];
$stmt = $pdo->prepare("INSERT INTO users (name, email, password, role) VALUES (:name, :email, :password, :role)");
foreach ($users as $user) {
// Check if user exists
$check_stmt = $pdo->prepare("SELECT id FROM users WHERE email = :email");
$check_stmt->execute(['email' => $user['email']]);
if ($check_stmt->fetch()) {
echo "User with email {$user['email']} already exists. Skipping.<br>";
} else {
$stmt->execute($user);
echo "User with email {$user['email']} inserted successfully.<br>";
}
}
// Create tax_reports table
$sql_tax_reports = "
CREATE TABLE IF NOT EXISTS tax_reports (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
tax_type VARCHAR(100) NOT NULL,
period_month INT NOT NULL,
period_year INT NOT NULL,
gross_revenue DECIMAL(15, 2) NOT NULL,
tax_amount DECIMAL(15, 2) NOT NULL,
status ENUM('pending', 'approved', 'rejected') NOT NULL DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=INNODB;
";
$pdo->exec($sql_tax_reports);
echo "Table 'tax_reports' created successfully (if it didn't exist).<br>";
echo "<hr>Database setup complete!";
} catch (PDOException $e) {
die("DB ERROR: " . $e->getMessage());
}

View File

@ -33,7 +33,7 @@
<li class="nav-item"><a class="nav-link" href="#about">Tentang</a></li> <li class="nav-item"><a class="nav-link" href="#about">Tentang</a></li>
<li class="nav-item"><a class="nav-link" href="#taxes">Pajak & Retribusi</a></li> <li class="nav-item"><a class="nav-link" href="#taxes">Pajak & Retribusi</a></li>
<li class="nav-item"><a class="nav-link" href="#contact">Kontak</a></li> <li class="nav-item"><a class="nav-link" href="#contact">Kontak</a></li>
<li class="nav-item"><a class="btn btn-primary ms-lg-3" href="#">Login</a></li> <a href="login.php" class="btn btn-primary">Login</a>
</ul> </ul>
</div> </div>
</div> </div>

145
lapor-pajak.php Normal file
View File

@ -0,0 +1,145 @@
<?php
session_start();
require_once 'db/config.php';
// Pastikan pengguna sudah login dan merupakan Wajib Pajak
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'Wajib Pajak') {
header("Location: login.php");
exit;
}
$user_id = $_SESSION['user_id'];
$notification = '';
$error = '';
// Daftar jenis pajak yang tersedia
$tax_types = [
'Pajak Hotel',
'Pajak Restoran',
'Pajak Hiburan',
'Pajak Reklame',
'Pajak Parkir',
'Pajak Air Tanah'
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$tax_type = $_POST['tax_type'] ?? '';
$period_month = $_POST['period_month'] ?? '';
$period_year = $_POST['period_year'] ?? '';
$gross_revenue = $_POST['gross_revenue'] ?? '';
// Validasi sederhana
if (empty($tax_type) || empty($period_month) || empty($period_year) || empty($gross_revenue)) {
$error = 'Semua field wajib diisi.';
} elseif (!is_numeric($gross_revenue) || $gross_revenue < 0) {
$error = 'Omzet kotor harus berupa angka positif.';
} else {
try {
// Asumsi tarif pajak 10% untuk semua jenis
$tax_rate = 0.10;
$tax_amount = (float)$gross_revenue * $tax_rate;
$pdo = db();
$stmt = $pdo->prepare(
"INSERT INTO tax_reports (user_id, tax_type, period_month, period_year, gross_revenue, tax_amount)
VALUES (:user_id, :tax_type, :period_month, :period_year, :gross_revenue, :tax_amount)"
);
$stmt->execute([
':user_id' => $user_id,
':tax_type' => $tax_type,
':period_month' => $period_month,
':period_year' => $period_year,
':gross_revenue' => $gross_revenue,
':tax_amount' => $tax_amount
]);
$notification = 'Laporan pajak Anda telah berhasil diserahkan. Tarif pajak yang dikenakan adalah 10%.';
} catch (PDOException $e) {
$error = "Gagal menyimpan laporan: " . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lapor Pajak - Si-Apon</title>
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
<div class="dashboard-container">
<aside class="sidebar">
<div class="sidebar-header">
<a href="index.php" class="logo">Si-Apon</a>
</div>
<nav class="sidebar-nav">
<a href="dashboard.php">Dashboard</a>
<a href="lapor-pajak.php" class="active">Lapor Pajak</a>
<a href="logout.php">Logout</a>
</nav>
</aside>
<main class="main-content">
<header class="main-header">
<h1>Formulir Pelaporan Pajak</h1>
<div class="user-info">
<span><?php echo htmlspecialchars($_SESSION['user_name']); ?></span>
<span class="role-badge"><?php echo htmlspecialchars($_SESSION['user_role']); ?></span>
</div>
</header>
<section class="content-section">
<div class="card form-card">
<div class="card-body">
<?php if ($notification): ?>
<div class="alert alert-success"><?php echo $notification; ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<form action="lapor-pajak.php" method="POST">
<div class="form-group">
<label for="tax_type">Jenis Pajak</label>
<select id="tax_type" name="tax_type" required>
<option value="" disabled selected>-- Pilih Jenis Pajak --</option>
<?php foreach ($tax_types as $type): ?>
<option value="<?php echo htmlspecialchars($type); ?>"><?php echo htmlspecialchars($type); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="period_month">Periode Pajak</label>
<div class="period-group">
<select id="period_month" name="period_month" required>
<option value="" disabled selected>Bulan</option>
<?php for ($i = 1; $i <= 12; $i++): ?>
<option value="<?php echo $i; ?>"><?php echo date('F', mktime(0, 0, 0, $i, 10)); ?></option>
<?php endfor; ?>
</select>
<select id="period_year" name="period_year" required>
<option value="" disabled selected>Tahun</option>
<?php for ($i = date('Y'); $i >= date('Y') - 5; $i--): ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php endfor; ?>
</select>
</div>
</div>
<div class="form-group">
<label for="gross_revenue">Total Omzet Kotor (Rupiah)</label>
<input type="number" id="gross_revenue" name="gross_revenue" placeholder="Contoh: 5000000" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">Kirim Laporan</button>
</div>
</form>
</div>
</div>
</section>
</main>
</div>
</body>
</html>

96
login.php Normal file
View File

@ -0,0 +1,96 @@
<?php
session_start();
require_once 'db/config.php';
$error_message = '';
$success_message = '';
// Check for success message from registration
if (isset($_SESSION['success_message'])) {
$success_message = $_SESSION['success_message'];
unset($_SESSION['success_message']);
}
// Redirect if already logged in
if (isset($_SESSION['user_id'])) {
header("Location: dashboard.php");
exit();
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($email) || empty($password)) {
$error_message = "Email dan password tidak boleh kosong.";
} else {
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
// Password is correct, start session
$_SESSION['user_id'] = $user['id'];
$_SESSION['user_name'] = $user['name'];
$_SESSION['user_role'] = $user['role'];
header("Location: dashboard.php");
exit();
} else {
$error_message = "Email atau password salah.";
}
} catch (PDOException $e) {
$error_message = "Terjadi kesalahan koneksi database.";
// For development: error_log($e->getMessage());
}
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Si-Apon</title>
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="login-container">
<div class="login-box">
<div class="login-header">
<a href="index.php" class="logo-link"><h2>Si-Apon</h2></a>
<p>Silakan masuk untuk melanjutkan.</p>
</div>
<?php if (!empty($error_message)): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error_message); ?></div>
<?php endif; ?>
<?php if (!empty($success_message)): ?>
<div class="alert alert-success"><?php echo htmlspecialchars($success_message); ?></div>
<?php endif; ?>
<form action="login.php" method="post" class="login-form">
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<button type="submit" class="btn-login">Login</button>
</div>
</form>
<div class="login-footer">
<p>Belum punya akun? <a href="register.php">Daftar di sini</a></p>
<p><a href="#">Lupa Password?</a></p>
</div>
</div>
</div>
</body>
</html>

22
logout.php Normal file
View File

@ -0,0 +1,22 @@
<?php
session_start();
// Unset all of the session variables.
$_SESSION = array();
// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// Finally, destroy the session.
session_destroy();
// Redirect to login page
header("Location: login.php");
exit();

92
register.php Normal file
View File

@ -0,0 +1,92 @@
<?php
session_start();
require_once 'db/config.php';
$error = '';
$success = '';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$name = trim($_POST['name']);
$email = trim($_POST['email']);
$password = trim($_POST['password']);
$role = 'Wajib Pajak'; // Default role for new registrations
if (empty($name) || empty($email) || empty($password)) {
$error = 'Semua field harus diisi.';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Format email tidak valid.';
} else {
try {
$pdo = db();
// Check if email already exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
$stmt->execute([$email]);
if ($stmt->fetch()) {
$error = 'Email sudah terdaftar.';
} else {
// Hash the password
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
// Insert new user
$stmt = $pdo->prepare("INSERT INTO users (name, email, password, role) VALUES (?, ?, ?, ?)");
if ($stmt->execute([$name, $email, $hashed_password, $role])) {
$_SESSION['success_message'] = "Registrasi berhasil! Silakan login.";
header("Location: login.php");
exit;
} else {
$error = 'Terjadi kesalahan. Gagal mendaftar.';
}
}
} catch (PDOException $e) {
// In production, you should log this error instead of showing it to the user.
$error = "Database error: " . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registrasi - Si-Apon</title>
<link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<div class="login-container">
<div class="login-box">
<div class="login-header">
<h2>Registrasi Akun</h2>
<p>Buat akun baru untuk memulai.</p>
</div>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<form action="register.php" method="post" class="login-form">
<div class="form-group">
<label for="name">Nama Lengkap</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<button type="submit" class="btn-login">Daftar</button>
</div>
</form>
<div class="login-footer">
<p>Sudah punya akun? <a href="login.php">Login di sini</a></p>
</div>
</div>
</div>
</body>
</html>

30
verifikasi-laporan.php Normal file
View File

@ -0,0 +1,30 @@
<?php
session_start();
require_once 'db/config.php';
// Proteksi halaman: hanya untuk Petugas Pajak
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'Petugas Pajak') {
header("Location: login.php");
exit();
}
$report_id = $_GET['id'] ?? null;
$action = $_GET['action'] ?? null;
if ($report_id && ($action === 'approve' || $action === 'reject')) {
$new_status = ($action === 'approve') ? 'Approved' : 'Rejected';
try {
$pdo = db();
$stmt = $pdo->prepare("UPDATE tax_reports SET status = :status WHERE id = :id");
$stmt->execute([':status' => $new_status, ':id' => $report_id]);
} catch (PDOException $e) {
// Sebaiknya log error ini di production
die("Database error: " . $e->getMessage());
}
}
// Redirect kembali ke dashboard
header("Location: dashboard.php");
exit();
?>