- Updated session variables to use 'authorization' array instead of 'username' for user identification across multiple files. - Introduced a new function `getUserPermissions` to consolidate user permissions retrieval based on assigned roles. - Modified API calls to use the new authorization structure and updated endpoints to v2. - Enhanced language support by adding 'PL' to the list of supported languages. - Cleaned up redundant code and improved session management during user login and registration processes. - Added a new API endpoint for fetching user permissions based on user ID.
755 lines
27 KiB
PHP
755 lines
27 KiB
PHP
<?php
|
|
defined(page_security_key) or exit;
|
|
|
|
if (debug && debug_id == $_SESSION['authorization']['id']){
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
}
|
|
|
|
include_once './assets/functions.php';
|
|
include_once './settings/settings_redirector.php';
|
|
|
|
//SET ORIGIN FOR NAVIGATION
|
|
$prev_page = $_SESSION['prev_origin'] ?? '';
|
|
$page = $_SESSION['origin'] = 'licenses';
|
|
|
|
//Check if allowed
|
|
if (isAllowed($page,$_SESSION['authorization']['profile'],$_SESSION['authorization']['permission'],'R') === 0){
|
|
header('location: index.php');
|
|
exit;
|
|
}
|
|
//PAGE Security
|
|
$page_manage = 'licenses';
|
|
$update_allowed = isAllowed($page_manage ,$_SESSION['authorization']['profile'],$_SESSION['authorization']['permission'],'U');
|
|
$delete_allowed = isAllowed($page_manage ,$_SESSION['authorization']['profile'],$_SESSION['authorization']['permission'],'D');
|
|
$create_allowed = isAllowed($page_manage ,$_SESSION['authorization']['profile'],$_SESSION['authorization']['permission'],'C');
|
|
|
|
// Handle license status update
|
|
if ($update_allowed === 1 && isset($_POST['submit'])) {
|
|
$data = json_encode($_POST, JSON_UNESCAPED_UNICODE);
|
|
$responses = ioServer('/v2/products_software_licenses', $data);
|
|
if ($responses !== 'NOK'){
|
|
header('Location: index.php?page=licenses&success_msg=2');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Handle AJAX API requests
|
|
if (isset($_GET['action'])) {
|
|
$action = $_GET['action'];
|
|
|
|
// Suppress errors for API responses to avoid HTML output breaking JSON
|
|
error_reporting(0);
|
|
ini_set('display_errors', 0);
|
|
|
|
try {
|
|
// Licenses data
|
|
if ($action === 'licenses_data') {
|
|
// Filter out 'page', 'action', and cache busting timestamp from GET parameters
|
|
$filtered_params = $_GET;
|
|
unset($filtered_params['page']);
|
|
unset($filtered_params['action']);
|
|
unset($filtered_params['_t']);
|
|
|
|
$get_values = urlGETdetails($filtered_params) ?? '';
|
|
$api_url = '/v2/products_software_licenses/' . $get_values;
|
|
$response = ioServer($api_url, '');
|
|
header('Content-Type: application/json');
|
|
echo $response;
|
|
exit;
|
|
}
|
|
|
|
// Licenses totals
|
|
if ($action === 'licenses_totals') {
|
|
// Filter out 'page', 'action', and cache busting timestamp from GET parameters
|
|
$filtered_params = $_GET;
|
|
unset($filtered_params['page']);
|
|
unset($filtered_params['action']);
|
|
unset($filtered_params['_t']);
|
|
|
|
$get_values = urlGETdetails($filtered_params) ?? '';
|
|
$api_url = '/v2/products_software_licenses/' . $get_values . '&totals=';
|
|
$response = ioServer($api_url, '');
|
|
header('Content-Type: application/json');
|
|
echo $response;
|
|
exit;
|
|
}
|
|
|
|
// Software versions for dropdown
|
|
if ($action === 'software_versions') {
|
|
$api_url = '/v2/products_software_versions/list=&status=1';
|
|
$response = ioServer($api_url, '');
|
|
header('Content-Type: application/json');
|
|
echo $response;
|
|
exit;
|
|
}
|
|
|
|
// Handle license status update via AJAX
|
|
if ($action === 'update_license' && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if ($update_allowed === 1) {
|
|
$data = json_encode($_POST, JSON_UNESCAPED_UNICODE);
|
|
$response = ioServer('/v2/products_software_licenses', $data);
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['success' => ($response !== 'NOK'), 'response' => $response]);
|
|
} else {
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['success' => false, 'error' => 'Not allowed']);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['error' => 'Server error', 'message' => $e->getMessage()]);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
//GET PARAMETERS
|
|
$pagination_page = isset($_GET['p']) ? $_GET['p'] : 1;
|
|
$status = isset($_GET['status']) ? '&status='.$_GET['status'] : '';
|
|
$search = isset($_GET['search']) ? '&search='.$_GET['search'] : '';
|
|
|
|
// Determine the URL
|
|
$url = 'index.php?page=licenses'.$status.$search;
|
|
//GET Details from URL
|
|
$GET_VALUES = urlGETdetails($_GET) ?? '';
|
|
//CALL TO API
|
|
$api_url = '/v2/products_software_licenses/'.$GET_VALUES;
|
|
$responses = ioServer($api_url,'');
|
|
|
|
//Decode Payload
|
|
if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;}
|
|
|
|
//Return QueryTotal from API
|
|
$api_url = '/v2/products_software_licenses/'.$GET_VALUES.'&totals=';
|
|
$query_total = ioServer($api_url,'');
|
|
//Decode Payload
|
|
if (!empty($query_total)){$query_total = json_decode($query_total,);}else{$query_total = null;}
|
|
|
|
// Handle success messages
|
|
if (isset($_GET['success_msg'])) {
|
|
if ($_GET['success_msg'] == 1) {
|
|
$success_msg = 'Licenses created successfully!';
|
|
}
|
|
if ($_GET['success_msg'] == 2) {
|
|
$success_msg = 'License updated successfully!';
|
|
}
|
|
if ($_GET['success_msg'] == 3) {
|
|
$success_msg = 'License deleted successfully!';
|
|
}
|
|
}
|
|
|
|
// Get software versions for dropdown
|
|
$api_url = '/v2/products_software_versions/list=&status=1';
|
|
$software_versions = ioServer($api_url,'');
|
|
if (!empty($software_versions)){$software_versions = json_decode($software_versions);}else{$software_versions = null;}
|
|
|
|
template_header('Licenses', 'licenses','view');
|
|
$view = '
|
|
<div class="content-title">
|
|
<div class="title">
|
|
<i class="fa-solid fa-key"></i>
|
|
<div class="txt">
|
|
<h2>Software Licenses ('.$query_total.')</h2>
|
|
<p>Manage and create software licenses for devices</p>
|
|
</div>
|
|
</div>
|
|
<div class="title-actions">';
|
|
|
|
if ($create_allowed === 1){
|
|
$view .= '<button onclick="openBulkLicenseModal()" class="btn">+</button>';
|
|
}
|
|
|
|
$view .= '<button id="filter-toggle" class="btn alt" onclick="toggleFilters()">
|
|
<i class="fa-solid fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>';
|
|
|
|
if (isset($success_msg)){
|
|
$view .= ' <div class="msg success">
|
|
<i class="fas fa-check-circle"></i>
|
|
<p>'.$success_msg.'</p>
|
|
<i class="fas fa-times"></i>
|
|
</div>';
|
|
}
|
|
|
|
$view .= '
|
|
<div id="filter-panel" class="filter-panel" style="display: none;">
|
|
<div class="filter-content">
|
|
<form action="" method="get">
|
|
<input type="hidden" name="page" value="licenses">
|
|
<div class="filter-row">
|
|
<div class="filter-group">
|
|
<select name="status">
|
|
<option value="" disabled selected>Status</option>
|
|
<option value="0"'.($status==0?' selected':'').'>Inactive</option>
|
|
<option value="1"'.($status==1?' selected':'').'>Assigned</option>
|
|
<option value="2"'.($status==2?' selected':'').'>Expired</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="filter-group search-group">
|
|
<input type="text" name="search" placeholder="Search license key..." value="">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="filter-actions">
|
|
<button type="submit" class="btn"><i class="fas fa-level-down-alt fa-rotate-90"></i></button>
|
|
<a class="btn alt" href="index.php?page=licenses">Clear</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
$view .= '
|
|
<div class="content-block">
|
|
<div class="table">
|
|
<table class="sortable">
|
|
<thead>
|
|
<tr>
|
|
<th>License Key</th>
|
|
<th>Software Version</th>
|
|
<th>Status</th>
|
|
<th>Transaction ID</th>
|
|
<th>Starts At</th>
|
|
<th>Expires</th>
|
|
<th>Assigned To (Serial)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
';
|
|
|
|
if (empty($responses)){
|
|
|
|
$view .= '
|
|
<tr>
|
|
<td colspan="7" style="text-align:center;">No licenses found</td>
|
|
</tr>';
|
|
}
|
|
else {
|
|
foreach ($responses as $response){
|
|
// Check if license is expired based on timestamp
|
|
$actual_status = $response->status;
|
|
if (!empty($response->expires_at)) {
|
|
$expiry_time = strtotime($response->expires_at);
|
|
$current_time = time();
|
|
if ($current_time > $expiry_time) {
|
|
// License is expired - override status
|
|
$actual_status = 2;
|
|
}
|
|
}
|
|
|
|
// Status display based on actual status
|
|
$status_text = '';
|
|
if ($actual_status == 0) {
|
|
$status_text = 'Inactive';
|
|
} elseif ($actual_status == 1) {
|
|
$status_text = 'Assigned';
|
|
} elseif ($actual_status == 2) {
|
|
$status_text = 'Expired';
|
|
}
|
|
|
|
// Format dates
|
|
$starts_display = '-';
|
|
if (!empty($response->starts_at)) {
|
|
$starts_display = date('Y-m-d', strtotime($response->starts_at));
|
|
}
|
|
|
|
$expires_display = '-';
|
|
if (!empty($response->expires_at)) {
|
|
$expires_display = date('Y-m-d', strtotime($response->expires_at));
|
|
}
|
|
|
|
$view .= '
|
|
<tr style="cursor: pointer;" onclick="openLicenseModal('.htmlspecialchars(json_encode($response), ENT_QUOTES).')">
|
|
<td>'.$response->license_key.'</td>
|
|
<td>'.$response->version_name.'</td>
|
|
<td>'.$status_text.'</td>
|
|
<td>'.(isset($response->transaction_id) && strpos($response->transaction_id, 'SC') === 0 ? '<a href="index.php?page=order&txn_id='.$response->transaction_id.'" class="link-with-icon">'.$response->transaction_id.' <i class="fa-solid fa-up-right-from-square"></i></a>' : ($response->transaction_id ?? '-')).'</td>
|
|
<td>'.$starts_display.'</td>
|
|
<td>'.$expires_display.'</td>
|
|
<td>'.(isset($response->assigned_serial) ? '<a href="index.php?page=equipment&serialnumber='.$response->assigned_serial.'" class="link-with-icon">'.$response->assigned_serial.' <i class="fa-solid fa-up-right-from-square"></i></a>' : ($response->assigned_serial ?? '-')).'</td>
|
|
</tr>
|
|
';
|
|
}
|
|
}
|
|
$view .= '
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
';
|
|
|
|
$view.='<div class="pagination">';
|
|
if ($pagination_page > 1) {
|
|
$page = $pagination_page-1;
|
|
$view .= '<a href="'.$url.'&p=1">First</a>';
|
|
$view .= '<a href="'.$url.'&p='.$page.'">Prev</a>';
|
|
}
|
|
$totals = ceil($query_total / 50) == 0 ? 1 : ceil($query_total / 50);
|
|
$view .= '<span> Page '.$pagination_page.' of '.$totals.'</span>';
|
|
if ($pagination_page * 50 < $query_total){
|
|
$page = $pagination_page+1;
|
|
$view .= '<a href="'.$url.'&p='.$page.'">Next</a>';
|
|
$view .= '<a href="'.$url.'&p='.$totals.'">Last</a>';
|
|
|
|
}
|
|
$view .= '</div>';
|
|
|
|
|
|
|
|
// Bulk License Modal
|
|
$view .= '
|
|
<div id="bulkLicenseModal" class="modal" style="display: none;">
|
|
<div class="modal-content" style="max-width: 700px;">
|
|
<div class="modal-header">
|
|
<h3><i class="fa-solid fa-key"></i> Create Bulk Licenses</h3>
|
|
<button onclick="closeBulkLicenseModal()" class="close-btn">
|
|
<i class="fa-solid fa-times"></i>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="bulkLicenseForm">
|
|
<div class="form-group">
|
|
<label for="bulk_version_id">Software Version *</label>
|
|
<select id="bulk_version_id" name="version_id" required>
|
|
<option value="">Select software version...</option>';
|
|
|
|
if (!empty($software_versions)) {
|
|
foreach ($software_versions as $version) {
|
|
$view .= '<option value="'.$version->rowID.'">'.$version->name.' (v'.$version->version.')</option>';
|
|
}
|
|
}
|
|
|
|
$view .= '
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="bulk_serials">Serial Numbers *</label>
|
|
<textarea id="bulk_serials" name="serials" rows="8" placeholder="Paste serial numbers, one per line: SN001 SN002 SN003" required></textarea>
|
|
<small style="color: #666; display: block; margin-top: 5px;">Enter one serial number per line</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="bulk_transaction_id">Transaction ID *</label>
|
|
<input type="text" id="bulk_transaction_id" name="transaction_id" placeholder="e.g., PO-12345" required>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group half">
|
|
<label for="bulk_starts_at">Start Date</label>
|
|
<input type="date" id="bulk_starts_at" name="starts_at">
|
|
</div>
|
|
<div class="form-group half">
|
|
<label for="bulk_expires_at">Expiration Date</label>
|
|
<input type="date" id="bulk_expires_at" name="expires_at">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="button" onclick="closeBulkLicenseModal()" class="btn alt">Cancel</button>
|
|
<button type="submit" class="btn">Create Licenses</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>';
|
|
|
|
// License Details Modal
|
|
$view .= '
|
|
<div id="licenseDetailModal" class="modal" style="display: none;">
|
|
<div class="modal-content" style="max-width: 700px;">
|
|
<div class="modal-header">
|
|
<h3><i class="fa-solid fa-key"></i> License Details</h3>
|
|
<button onclick="closeLicenseDetailModal()" class="close-btn">
|
|
<i class="fa-solid fa-times"></i>
|
|
</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form action="" method="post" id="licenseDetailForm">
|
|
<div class="license-details-grid" style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-bottom: 25px;">
|
|
<div class="detail-group">
|
|
<label style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">License Key</label>
|
|
<div id="detail_license_key" style="padding: 10px 12px; background: #f8f9fa; border-radius: 4px; font-family: monospace; font-size: 14px; word-break: break-all;"></div>
|
|
</div>
|
|
|
|
<div class="detail-group">
|
|
<label style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">Software Version</label>
|
|
<div id="detail_version_name" style="padding: 10px 12px; background: #f8f9fa; border-radius: 4px; font-size: 14px;"></div>
|
|
</div>
|
|
|
|
<div class="detail-group">
|
|
<label style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">Status</label>
|
|
<div id="detail_status" style="padding: 10px 12px; background: #f8f9fa; border-radius: 4px; font-size: 14px;"></div>
|
|
</div>
|
|
|
|
<div class="detail-group">
|
|
<label style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">Transaction ID</label>
|
|
<div id="detail_transaction_id" style="padding: 10px 12px; background: #f8f9fa; border-radius: 4px; font-size: 14px;"></div>
|
|
</div>
|
|
|
|
<div class="detail-group">
|
|
<label for="detail_starts_at" style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">Starts At</label>
|
|
<input type="date" id="detail_starts_at" name="starts_at" style="width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
|
|
</div>
|
|
|
|
<div class="detail-group">
|
|
<label for="detail_expires_at" style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">Expires</label>
|
|
<input type="date" id="detail_expires_at" name="expires_at" style="width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
|
|
</div>
|
|
|
|
<div class="detail-group" style="grid-column: 1 / -1;">
|
|
<label style="display: block; margin-bottom: 5px; color: #666; font-size: 13px; font-weight: 500;">Assigned To (Serial)</label>
|
|
<div id="detail_assigned_serial" style="padding: 10px 12px; background: #f8f9fa; border-radius: 4px; font-size: 14px;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<input type="hidden" id="detail_rowID" name="rowID" value="">
|
|
<input type="hidden" name="status" value="0">
|
|
|
|
<div class="form-actions" style="border-top: 1px solid #e0e0e0; padding-top: 20px;">';
|
|
|
|
if ($update_allowed === 1) {
|
|
$view .= '
|
|
<button type="button" id="updateDatesBtn" class="btn" onclick="updateLicenseDates()">
|
|
<i class="fa-solid fa-save"></i>
|
|
</button>
|
|
<button type="submit" name="submit" id="setInactiveBtn" class="btn" style="background: #dc3545;" onclick="return confirm(\'Are you sure you want to set this license as inactive?\')">
|
|
<i class="fa-solid fa-ban"></i>
|
|
</button>';
|
|
}
|
|
|
|
$view .= '
|
|
<button type="button" onclick="closeLicenseDetailModal()" class="btn alt">Close</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>';
|
|
|
|
//OUTPUT
|
|
echo $view;
|
|
|
|
// Add JavaScript for modals and API calls
|
|
echo '
|
|
<script>
|
|
// Store current license data
|
|
let currentLicenseData = null;
|
|
|
|
// Modal functions
|
|
function openBulkLicenseModal() {
|
|
// Set default dates
|
|
const today = new Date().toISOString().split(\'T\')[0];
|
|
document.getElementById("bulk_starts_at").value = today;
|
|
document.getElementById("bulk_expires_at").value = "2099-12-31";
|
|
|
|
document.getElementById("bulkLicenseModal").style.display = "flex";
|
|
}
|
|
|
|
function closeBulkLicenseModal() {
|
|
document.getElementById("bulkLicenseModal").style.display = "none";
|
|
document.getElementById("bulkLicenseForm").reset();
|
|
// Reset date fields to defaults
|
|
const today = new Date().toISOString().split(\'T\')[0];
|
|
document.getElementById("bulk_starts_at").value = today;
|
|
document.getElementById("bulk_expires_at").value = "2099-12-31";
|
|
}
|
|
|
|
// License detail modal functions
|
|
function openLicenseModal(licenseData) {
|
|
currentLicenseData = licenseData;
|
|
|
|
// Calculate actual status (check expiry)
|
|
let actualStatus = licenseData.status;
|
|
if (licenseData.expires_at) {
|
|
const expiryTime = new Date(licenseData.expires_at).getTime();
|
|
const currentTime = new Date().getTime();
|
|
if (currentTime > expiryTime) {
|
|
actualStatus = 2;
|
|
}
|
|
}
|
|
|
|
// Status text and formatting
|
|
let statusText = "";
|
|
let statusClass = "";
|
|
if (actualStatus == 0) {
|
|
statusText = "Inactive";
|
|
statusClass = "id2";
|
|
} else if (actualStatus == 1) {
|
|
statusText = "Assigned";
|
|
} else if (actualStatus == 2) {
|
|
statusText = "Expired";
|
|
statusClass = "id2";
|
|
}
|
|
|
|
// Format dates for input fields (YYYY-MM-DD)
|
|
const startsValue = licenseData.starts_at ? licenseData.starts_at.split(\' \')[0] : "";
|
|
const expiresValue = licenseData.expires_at ? licenseData.expires_at.split(\' \')[0] : "";
|
|
|
|
// Populate modal fields
|
|
document.getElementById("detail_license_key").textContent = licenseData.license_key || "-";
|
|
document.getElementById("detail_version_name").textContent = licenseData.version_name || "-";
|
|
document.getElementById("detail_status").innerHTML = \'<span class="status \' + statusClass + \'">\' + statusText + \'</span>\';
|
|
document.getElementById("detail_transaction_id").textContent = licenseData.transaction_id || "-";
|
|
document.getElementById("detail_starts_at").value = startsValue;
|
|
document.getElementById("detail_expires_at").value = expiresValue;
|
|
document.getElementById("detail_assigned_serial").textContent = licenseData.assigned_serial || "-";
|
|
|
|
// Set hidden form field
|
|
document.getElementById("detail_rowID").value = licenseData.rowID || "";
|
|
|
|
// Show/hide inactive button based on current status
|
|
const inactiveBtn = document.getElementById("setInactiveBtn");
|
|
if (inactiveBtn) {
|
|
if (actualStatus == 0) {
|
|
inactiveBtn.style.display = "none";
|
|
} else {
|
|
inactiveBtn.style.display = "inline-block";
|
|
}
|
|
}
|
|
|
|
document.getElementById("licenseDetailModal").style.display = "flex";
|
|
}
|
|
|
|
function closeLicenseDetailModal() {
|
|
document.getElementById("licenseDetailModal").style.display = "none";
|
|
currentLicenseData = null;
|
|
}
|
|
|
|
// Close modal on background click
|
|
window.onclick = function(event) {
|
|
const bulkModal = document.getElementById("bulkLicenseModal");
|
|
const detailModal = document.getElementById("licenseDetailModal");
|
|
|
|
if (event.target == bulkModal) {
|
|
closeBulkLicenseModal();
|
|
}
|
|
if (event.target == detailModal) {
|
|
closeLicenseDetailModal();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Bulk license form submission
|
|
document.getElementById("bulkLicenseForm").addEventListener("submit", async function(e) {
|
|
e.preventDefault();
|
|
|
|
const serials = document.getElementById("bulk_serials").value
|
|
.split("\\n")
|
|
.map(s => s.trim())
|
|
.filter(s => s.length > 0);
|
|
|
|
if (serials.length === 0) {
|
|
alert("Please enter at least one serial number.");
|
|
return;
|
|
}
|
|
|
|
const formData = {
|
|
bulk: true,
|
|
version_id: document.getElementById("bulk_version_id").value,
|
|
serials: serials,
|
|
transaction_id: document.getElementById("bulk_transaction_id").value,
|
|
starts_at: document.getElementById("bulk_starts_at").value,
|
|
expires_at: document.getElementById("bulk_expires_at").value,
|
|
license_type: 1,
|
|
status: 1
|
|
};
|
|
|
|
try {
|
|
const response = await fetch("index.php?page=licenses&action=update_license", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
},
|
|
body: new URLSearchParams(formData)
|
|
});
|
|
|
|
const result = await response.json();
|
|
if (result.success) {
|
|
window.location.href = "index.php?page=licenses&success_msg=1";
|
|
} else {
|
|
alert("Error creating licenses: " + (result.error || "Please try again."));
|
|
}
|
|
} catch (error) {
|
|
console.error("Error:", error);
|
|
alert("Error creating licenses. Please try again.");
|
|
}
|
|
});
|
|
|
|
// Filter toggle function
|
|
function toggleFilters() {
|
|
const panel = document.getElementById("filter-panel");
|
|
if (panel.style.display === "none") {
|
|
panel.style.display = "block";
|
|
} else {
|
|
panel.style.display = "none";
|
|
}
|
|
}
|
|
|
|
// Update license dates function
|
|
async function updateLicenseDates() {
|
|
const rowID = document.getElementById("detail_rowID").value;
|
|
const starts_at = document.getElementById("detail_starts_at").value;
|
|
const expires_at = document.getElementById("detail_expires_at").value;
|
|
|
|
if (!rowID) {
|
|
alert("Invalid license ID");
|
|
return;
|
|
}
|
|
|
|
// Convert date to timestamp format (YYYY-MM-DD HH:MM:SS)
|
|
const starts_at_timestamp = starts_at ? starts_at + " 00:00:00" : "";
|
|
const expires_at_timestamp = expires_at ? expires_at + " 23:59:59" : "";
|
|
|
|
const formData = {
|
|
rowID: rowID,
|
|
starts_at: starts_at_timestamp,
|
|
expires_at: expires_at_timestamp
|
|
};
|
|
|
|
try {
|
|
const response = await fetch("index.php?page=licenses&action=update_license", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
},
|
|
body: new URLSearchParams(formData)
|
|
});
|
|
|
|
const result = await response.json();
|
|
if (result.success) {
|
|
window.location.href = "index.php?page=licenses&success_msg=2";
|
|
} else {
|
|
alert("Error updating license: " + (result.error || "Please try again."));
|
|
}
|
|
} catch (error) {
|
|
console.error("Error:", error);
|
|
alert("Error updating license. Please try again.");
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
/* Modal styles */
|
|
.modal {
|
|
display: none;
|
|
position: fixed;
|
|
z-index: 1000;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: auto;
|
|
background-color: rgba(0,0,0,0.5);
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.modal-content {
|
|
background-color: #fff;
|
|
margin: auto;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
width: 90%;
|
|
max-width: 600px;
|
|
}
|
|
|
|
.modal-header {
|
|
padding: 20px 25px;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
margin: 0;
|
|
color: #333;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.close-btn {
|
|
background: transparent;
|
|
border: none;
|
|
font-size: 24px;
|
|
cursor: pointer;
|
|
color: #666;
|
|
padding: 0;
|
|
width: 30px;
|
|
height: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.close-btn:hover {
|
|
color: #333;
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 25px;
|
|
}
|
|
|
|
.form-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.form-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
color: #333;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.form-group input[type="text"],
|
|
.form-group select,
|
|
.form-group textarea {
|
|
width: 100%;
|
|
padding: 10px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.form-group textarea {
|
|
resize: vertical;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.form-group input:focus,
|
|
.form-group select:focus,
|
|
.form-group textarea:focus {
|
|
outline: none;
|
|
border-color: #04AA6D;
|
|
}
|
|
|
|
.form-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
justify-content: flex-end;
|
|
margin-top: 25px;
|
|
}
|
|
|
|
.form-row {
|
|
display: flex;
|
|
gap: 15px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.form-group.half {
|
|
flex: 1;
|
|
margin-bottom: 0;
|
|
}
|
|
</style>
|
|
';
|
|
|
|
template_footer();
|
|
?>
|