/home/ejrndhmu/siapusaha.com/catalog.php
<?php
require_once 'includes/config.php';
require_once 'includes/functions.php';
// Ambil username reseller dari URL parameter
$resellerUsername = isset($_GET['reseller']) ? trim($_GET['reseller']) : '';
if (empty($resellerUsername)) {
header('Location: 404.php');
exit;
}
// Dapatkan informasi reseller
$resellerInfo = getResellerInfo($resellerUsername, true);
if (!$resellerInfo) {
header('Location: 404.php');
exit;
}
// Dapatkan paket-paket aktif reseller
$packages = getPublicResellerPackages($resellerInfo['id']);
// Filter dan pencarian
$searchQuery = isset($_GET['search']) ? trim($_GET['search']) : '';
$priceFilter = isset($_GET['price']) ? $_GET['price'] : '';
$durationFilter = isset($_GET['duration']) ? $_GET['duration'] : '';
// Terapkan filter
if (!empty($searchQuery) || !empty($priceFilter) || !empty($durationFilter)) {
$filteredPackages = [];
foreach ($packages as $package) {
$matchSearch = true;
$matchPrice = true;
$matchDuration = true;
// Filter pencarian
if (!empty($searchQuery)) {
$searchLower = strtolower($searchQuery);
$matchSearch = (
strpos(strtolower($package['name']), $searchLower) !== false ||
strpos(strtolower($package['description']), $searchLower) !== false ||
strpos(strtolower($package['features']), $searchLower) !== false
);
}
// Filter harga
if (!empty($priceFilter)) {
switch ($priceFilter) {
case 'under_100k':
$matchPrice = $package['price'] < 100000;
break;
case '100k_500k':
$matchPrice = $package['price'] >= 100000 && $package['price'] <= 500000;
break;
case '500k_1m':
$matchPrice = $package['price'] > 500000 && $package['price'] <= 1000000;
break;
case 'over_1m':
$matchPrice = $package['price'] > 1000000;
break;
}
}
// Filter durasi
if (!empty($durationFilter)) {
switch ($durationFilter) {
case 'daily':
$matchDuration = $package['duration_days'] < 30;
break;
case 'monthly':
$matchDuration = $package['duration_days'] >= 30 && $package['duration_days'] < 365;
break;
case 'yearly':
$matchDuration = $package['duration_days'] >= 365;
break;
}
}
if ($matchSearch && $matchPrice && $matchDuration) {
$filteredPackages[] = $package;
}
}
$packages = $filteredPackages;
}
// Fungsi untuk format harga
function formatPrice($price) {
return 'Rp ' . number_format($price, 0, ',', '.');
}
// Fungsi untuk format durasi
function formatDuration($days) {
if ($days >= 365) {
$years = floor($days / 365);
return $years . ' Tahun';
} elseif ($days >= 30) {
$months = floor($days / 30);
return $months . ' Bulan';
} else {
return $days . ' Hari';
}
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Katalog Paket - <?php echo htmlspecialchars($resellerInfo['full_name'] ?: $resellerInfo['username']); ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
:root {
--primary-color: #2563eb;
--secondary-color: #64748b;
--success-color: #059669;
--gradient-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
min-height: 100vh;
}
.hero-section {
background: var(--gradient-bg);
color: white;
padding: 4rem 0 2rem;
margin-bottom: 3rem;
}
.hero-content {
text-align: center;
}
.hero-title {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 1rem;
}
.hero-subtitle {
font-size: 1.2rem;
opacity: 0.9;
margin-bottom: 2rem;
}
.package-card {
background: white;
border-radius: 16px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
overflow: hidden;
height: 100%;
border: 1px solid #e2e8f0;
}
.package-card:hover {
transform: translateY(-8px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}
.package-banner {
width: 100%;
height: 200px;
object-fit: cover;
background: var(--gradient-bg);
}
.package-banner-placeholder {
height: 200px;
background: var(--gradient-bg);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 3rem;
}
.package-content {
padding: 1.5rem;
}
.package-name {
font-size: 1.4rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 0.5rem;
}
.package-description {
color: var(--secondary-color);
margin-bottom: 1rem;
line-height: 1.6;
}
.package-price {
font-size: 2rem;
font-weight: 800;
color: var(--primary-color);
margin-bottom: 0.5rem;
}
.package-duration {
color: var(--secondary-color);
font-size: 0.9rem;
margin-bottom: 1.5rem;
}
.features-list {
list-style: none;
padding: 0;
margin-bottom: 2rem;
}
.features-list li {
padding: 0.5rem 0;
color: #475569;
display: flex;
align-items: center;
}
.features-list li i {
color: var(--success-color);
margin-right: 0.75rem;
font-size: 0.9rem;
}
.checkout-btn {
background: var(--primary-color);
color: white;
border: none;
padding: 0.875rem 2rem;
border-radius: 12px;
font-weight: 600;
font-size: 1rem;
transition: all 0.3s ease;
width: 100%;
text-decoration: none;
display: inline-block;
text-align: center;
}
.checkout-btn:hover {
background: #1d4ed8;
transform: translateY(-2px);
color: white;
}
.no-packages {
text-align: center;
padding: 4rem 2rem;
color: var(--secondary-color);
}
.no-packages i {
font-size: 4rem;
margin-bottom: 1rem;
opacity: 0.5;
}
.search-filter-section {
max-width: 900px;
margin: 0 auto;
}
.search-filter-section .form-control,
.search-filter-section .form-select {
border-radius: 12px;
border: 2px solid rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
}
.search-filter-section .form-control:focus,
.search-filter-section .form-select:focus {
border-color: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.25);
background: white;
}
.search-filter-section .input-group-text {
border-radius: 12px 0 0 12px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-right: none;
background: rgba(255, 255, 255, 0.9);
}
.search-filter-section .btn {
border-radius: 12px;
font-weight: 600;
}
.results-info {
background: rgba(255, 255, 255, 0.9);
border-radius: 12px;
padding: 1rem;
margin-bottom: 2rem;
backdrop-filter: blur(10px);
}
@media (max-width: 768px) {
.hero-title {
font-size: 2rem;
}
.hero-subtitle {
font-size: 1rem;
}
.package-content {
padding: 1rem;
}
.search-filter-section {
padding: 0 1rem;
}
.search-filter-section .row {
margin: 0;
}
.search-filter-section .col-md-4,
.search-filter-section .col-md-3,
.search-filter-section .col-md-2 {
padding: 0 0.5rem;
margin-bottom: 0.75rem;
}
.search-filter-section .form-control,
.search-filter-section .form-select {
font-size: 0.9rem;
padding: 0.5rem 0.75rem;
}
.search-filter-section .input-group-text {
padding: 0.5rem 0.75rem;
}
.search-filter-section .btn {
font-size: 0.85rem;
padding: 0.5rem 1rem;
}
.search-filter-section .d-flex {
flex-direction: row;
gap: 0.5rem;
}
.search-filter-section .btn.flex-fill {
flex: 1;
}
.results-info .d-flex {
flex-direction: column;
gap: 1rem;
text-align: center;
}
}
.mobile-filter-toggle {
display: none;
}
/* Collapse filters into accordion on very small screens */
@media (max-width: 576px) {
.mobile-filter-toggle {
display: block !important;
width: 100%;
margin-bottom: 1rem;
}
.mobile-filter-content {
display: none;
}
.mobile-filter-content.show {
display: block;
}
.search-filter-section .col-md-4,
.search-filter-section .col-md-3,
.search-filter-section .col-md-2 {
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
}
}
</style>
</head>
<body>
<!-- Hero Section -->
<div class="hero-section">
<div class="container">
<div class="hero-content">
<h1 class="hero-title">
<i class="fas fa-store me-3"></i>
Katalog Paket Berlangganan
</h1>
<p class="hero-subtitle">
Pilih paket terbaik dari <strong><?php echo htmlspecialchars($resellerInfo['full_name'] ?: $resellerInfo['username']); ?></strong>
</p>
<!-- Search and Filter Form -->
<div class="search-filter-section mt-4">
<!-- Mobile Filter Toggle Button -->
<button type="button" class="btn btn-outline-light mobile-filter-toggle" onclick="toggleMobileFilter()">
<i class="fas fa-filter me-2"></i>
Filter & Pencarian
<i class="fas fa-chevron-down ms-2" id="toggle-icon"></i>
</button>
<form method="GET" class="row g-3 justify-content-center mobile-filter-content">
<input type="hidden" name="reseller" value="<?php echo htmlspecialchars($resellerUsername); ?>">
<!-- Search Input -->
<div class="col-md-4">
<div class="input-group">
<span class="input-group-text bg-white border-end-0">
<i class="fas fa-search text-muted"></i>
</span>
<input type="text"
name="search"
class="form-control border-start-0"
placeholder="Cari paket..."
value="<?php echo htmlspecialchars($searchQuery); ?>">
</div>
</div>
<!-- Price Filter -->
<div class="col-md-3">
<select name="price" class="form-select">
<option value="">Semua Harga</option>
<option value="under_100k" <?php echo $priceFilter === 'under_100k' ? 'selected' : ''; ?>>< Rp 100.000</option>
<option value="100k_500k" <?php echo $priceFilter === '100k_500k' ? 'selected' : ''; ?>>Rp 100.000 - 500.000</option>
<option value="500k_1m" <?php echo $priceFilter === '500k_1m' ? 'selected' : ''; ?>>Rp 500.000 - 1.000.000</option>
<option value="over_1m" <?php echo $priceFilter === 'over_1m' ? 'selected' : ''; ?>>> Rp 1.000.000</option>
</select>
</div>
<!-- Duration Filter -->
<div class="col-md-3">
<select name="duration" class="form-select">
<option value="">Semua Durasi</option>
<option value="daily" <?php echo $durationFilter === 'daily' ? 'selected' : ''; ?>>Harian</option>
<option value="monthly" <?php echo $durationFilter === 'monthly' ? 'selected' : ''; ?>>Bulanan</option>
<option value="yearly" <?php echo $durationFilter === 'yearly' ? 'selected' : ''; ?>>Tahunan</option>
</select>
</div>
<!-- Filter Buttons -->
<div class="col-md-2">
<div class="d-flex gap-2">
<button type="submit" class="btn btn-light flex-fill">
<i class="fas fa-filter me-1"></i>
Filter
</button>
<a href="catalog.php?reseller=<?php echo htmlspecialchars($resellerUsername); ?>"
class="btn btn-outline-light">
<i class="fas fa-times"></i>
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Packages Section -->
<div class="container mb-5">
<!-- Results Info -->
<?php if (!empty($searchQuery) || !empty($priceFilter) || !empty($durationFilter)): ?>
<div class="results-info">
<div class="d-flex justify-content-between align-items-center">
<div>
<h5 class="mb-1">
<i class="fas fa-search me-2"></i>
Hasil Pencarian
</h5>
<p class="mb-0 text-muted">
Ditemukan <?php echo count($packages); ?> paket
<?php if (!empty($searchQuery)): ?>
untuk "<strong><?php echo htmlspecialchars($searchQuery); ?></strong>"
<?php endif; ?>
</p>
</div>
<a href="catalog.php?reseller=<?php echo htmlspecialchars($resellerUsername); ?>"
class="btn btn-outline-primary btn-sm">
<i class="fas fa-times me-1"></i>
Reset Filter
</a>
</div>
</div>
<?php endif; ?>
<?php if (empty($packages)): ?>
<div class="no-packages">
<i class="fas fa-box-open"></i>
<?php if (!empty($searchQuery) || !empty($priceFilter) || !empty($durationFilter)): ?>
<h3>Tidak Ada Paket Ditemukan</h3>
<p>Tidak ada paket yang sesuai dengan kriteria pencarian Anda.</p>
<a href="catalog.php?reseller=<?php echo htmlspecialchars($resellerUsername); ?>"
class="btn btn-primary mt-3">
<i class="fas fa-arrow-left me-2"></i>
Lihat Semua Paket
</a>
<?php else: ?>
<h3>Belum Ada Paket Tersedia</h3>
<p>Reseller ini belum memiliki paket berlangganan yang aktif.</p>
<?php endif; ?>
</div>
<?php else: ?>
<div class="row g-4">
<?php foreach ($packages as $package): ?>
<?php
$features = json_decode($package['features'], true) ?: [];
?>
<div class="col-lg-4 col-md-6">
<div class="package-card">
<!-- Banner -->
<?php if (!empty($package['banner_url'])): ?>
<img src="<?php echo htmlspecialchars($package['banner_url']); ?>"
alt="<?php echo htmlspecialchars($package['name']); ?>"
class="package-banner">
<?php else: ?>
<div class="package-banner-placeholder">
<i class="fas fa-gift"></i>
</div>
<?php endif; ?>
<!-- Content -->
<div class="package-content">
<h3 class="package-name"><?php echo htmlspecialchars($package['name']); ?></h3>
<?php if (!empty($package['description'])): ?>
<p class="package-description"><?php echo htmlspecialchars($package['description']); ?></p>
<?php endif; ?>
<div class="package-price"><?php echo formatPrice($package['price']); ?></div>
<div class="package-duration">
<i class="fas fa-clock me-1"></i>
Masa Aktif: <?php echo formatDuration($package['duration_days']); ?>
</div>
<?php if (!empty($features)): ?>
<ul class="features-list">
<?php foreach ($features as $feature): ?>
<li>
<i class="fas fa-check-circle"></i>
<?php echo htmlspecialchars($feature); ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<a href="package_checkout.php?id=<?php echo $package['id']; ?>"
class="checkout-btn">
<i class="fas fa-shopping-cart me-2"></i>
Pesan Sekarang
</a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<!-- Footer -->
<footer class="bg-dark text-light py-4 mt-5">
<div class="container text-center">
<p class="mb-0">
<i class="fas fa-copyright me-1"></i>
<?php echo date('Y'); ?> - Katalog Paket <?php echo htmlspecialchars($resellerInfo['full_name'] ?: $resellerInfo['username']); ?>
</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
function toggleMobileFilter() {
const filterContent = document.querySelector('.mobile-filter-content');
const toggleIcon = document.getElementById('toggle-icon');
if (filterContent.classList.contains('show')) {
filterContent.classList.remove('show');
toggleIcon.classList.remove('fa-chevron-up');
toggleIcon.classList.add('fa-chevron-down');
} else {
filterContent.classList.add('show');
toggleIcon.classList.remove('fa-chevron-down');
toggleIcon.classList.add('fa-chevron-up');
}
}
// Auto-show filter if there are active filters
document.addEventListener('DOMContentLoaded', function() {
const urlParams = new URLSearchParams(window.location.search);
const hasFilters = urlParams.get('search') || urlParams.get('price') || urlParams.get('duration');
if (hasFilters && window.innerWidth <= 576) {
const filterContent = document.querySelector('.mobile-filter-content');
const toggleIcon = document.getElementById('toggle-icon');
filterContent.classList.add('show');
toggleIcon.classList.remove('fa-chevron-down');
toggleIcon.classList.add('fa-chevron-up');
}
});
</script>
</body>
</html>