142 lines
6.7 KiB
PHP
142 lines
6.7 KiB
PHP
|
|
<?php
|
||
|
|
require_once 'config.php';
|
||
|
|
|
||
|
|
// Access variables from config.php
|
||
|
|
$api_url = $api_config['certificates_url'];
|
||
|
|
$refresh_interval = $api_config['refresh_interval']; // default or custom? config says 30s, file had 60s. config.php has 'refresh_interval' => 30000. Let's use config.
|
||
|
|
|
||
|
|
$timezone_abbr = date('T');
|
||
|
|
$timezone_offset = date('P');
|
||
|
|
?>
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>OpenVPN Certificate Statistics</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">
|
||
|
|
<link href="css/style.css?v=<?php echo time(); ?>" rel="stylesheet">
|
||
|
|
<script src="js/utils.js?v=<?php echo time(); ?>"></script>
|
||
|
|
</head>
|
||
|
|
|
||
|
|
<body>
|
||
|
|
<div class="main-content-wrapper">
|
||
|
|
<div class="container">
|
||
|
|
<div class="header">
|
||
|
|
<div class="d-flex justify-content-between align-items-flex-start">
|
||
|
|
<div class="header-title-container">
|
||
|
|
<h1 class="h3 mb-1">OpenVPN Certificate Statistics</h1>
|
||
|
|
<p class="text-muted mb-0 header-description">Certificate validity and expiration monitoring</p>
|
||
|
|
</div>
|
||
|
|
<div class="d-flex align-items-center flex-wrap gap-2">
|
||
|
|
<a href="index.php" class="btn-nav">
|
||
|
|
<i class="fas fa-list me-2"></i>Clients
|
||
|
|
</a>
|
||
|
|
<a href="certificates.php" class="btn-nav active">
|
||
|
|
<i class="fas fa-certificate me-2"></i>Certificates
|
||
|
|
</a>
|
||
|
|
<a href="dashboard.php" class="btn-nav">
|
||
|
|
<i class="fas fa-chart-pie me-2"></i>Analytics
|
||
|
|
</a>
|
||
|
|
<span class="header-badge" id="certCount">0 certificates</span>
|
||
|
|
<span class="header-timezone">
|
||
|
|
<i class="fas fa-globe me-1 text-muted"></i><?php echo $timezone_abbr; ?>
|
||
|
|
</span>
|
||
|
|
<button class="btn-header" onclick="toggleTheme()" title="Toggle Theme">
|
||
|
|
<i class="fas fa-moon" id="themeIcon"></i>
|
||
|
|
</button>
|
||
|
|
<button class="btn-header" onclick="fetchData()" title="Refresh">
|
||
|
|
<i class="fas fa-sync-alt" id="refreshIcon"></i>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="stats-info" id="statsInfo">
|
||
|
|
<div class="stat-item">
|
||
|
|
<div class="stat-value" id="totalCertificates">0</div>
|
||
|
|
<div class="stat-label">Total Certificates</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-item">
|
||
|
|
<div class="stat-value" id="activeCertificates">0</div>
|
||
|
|
<div class="stat-label">Active Certificates</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-item">
|
||
|
|
<div class="stat-value" id="expiringSoon">0</div>
|
||
|
|
<div class="stat-label">Expiring in 30 days</div>
|
||
|
|
</div>
|
||
|
|
<div class="stat-item">
|
||
|
|
<div class="stat-value" id="expiredCertificates">0</div>
|
||
|
|
<div class="stat-label">Expired Certificates</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-3">
|
||
|
|
<div class="d-flex gap-3 align-items-center flex-wrap">
|
||
|
|
<div class="input-group input-group-sm" style="width: 250px;">
|
||
|
|
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||
|
|
<input type="text" id="searchInput" class="form-control" placeholder="Search by client name..."
|
||
|
|
oninput="filterCertificates()">
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="form-check form-switch">
|
||
|
|
<input class="form-check-input" type="checkbox" id="hideExpired"
|
||
|
|
onchange="toggleExpiredCertificates()">
|
||
|
|
<label class="form-check-label user-select-none text-muted" for="hideExpired">Hide Expired
|
||
|
|
Certificates</label>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Certificates List Card -->
|
||
|
|
<div class="card" id="certificatesCard">
|
||
|
|
<div class="card-header d-flex justify-content-between align-items-center bg-transparent border-bottom">
|
||
|
|
<span><i class="fas fa-certificate me-2"></i>Certificates List</span>
|
||
|
|
<div>
|
||
|
|
<span class="status-badge status-valid me-1" id="activeCountBadge"><i
|
||
|
|
class="fas fa-check-circle me-1"></i><span id="activeCount">0</span>
|
||
|
|
Active</span>
|
||
|
|
<span class="status-badge status-expired" id="expiredCountBadge"><i
|
||
|
|
class="fas fa-times-circle me-1"></i><span id="expiredCount">0</span>
|
||
|
|
Expired</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="table-responsive">
|
||
|
|
<table class="table table-hover mb-0">
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th>Client Name</th>
|
||
|
|
<th>Validity Not After</th>
|
||
|
|
<th>Days Remaining</th>
|
||
|
|
<th>Status</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody id="certificatesTable">
|
||
|
|
<tr>
|
||
|
|
<td colspan="4" class="text-center py-4">
|
||
|
|
<div class="spinner-border spinner-border-sm text-primary" role="status">
|
||
|
|
<span class="visually-hidden">Loading...</span>
|
||
|
|
</div>
|
||
|
|
<p class="mt-2 mb-0">Loading certificates...</p>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="js/utils.js"></script>
|
||
|
|
<script>
|
||
|
|
window.AppConfig = {
|
||
|
|
apiUrl: '<?php echo $api_url; ?>',
|
||
|
|
refreshTime: <?php echo $refresh_interval; ?>
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
<script src="js/pages/certificates.js?v=<?php echo time(); ?>"></script>
|
||
|
|
</body>
|
||
|
|
|
||
|
|
</html>
|