271 lines
12 KiB
PHP
271 lines
12 KiB
PHP
{{-- My Subscription Page --}}
|
|
<div class="card" id="main-card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">My Subscription</h3>
|
|
</div>
|
|
<div class="card-body">
|
|
|
|
{{-- Current Subscription Status --}}
|
|
<div id="subscription-status-section">
|
|
<div id="subscription-loading" class="text-center" style="padding: 20px;">
|
|
<i class="fas fa-spinner fa-spin fa-2x"></i>
|
|
</div>
|
|
|
|
{{-- Active subscription panel (shown when subscribed) --}}
|
|
<div id="subscription-active-panel" style="display:none;">
|
|
<div class="info-box mb-3">
|
|
<span class="info-box-icon bg-success"><i class="fas fa-check-circle"></i></span>
|
|
<div class="info-box-content">
|
|
<span class="info-box-text">Active Plan</span>
|
|
<span class="info-box-number" id="sub-plan-name">—</span>
|
|
<div class="progress"><div class="progress-bar bg-success" id="sub-progress-bar"></div></div>
|
|
<span class="progress-description">
|
|
Expires: <strong id="sub-expires-at">—</strong>
|
|
(<span id="sub-days-remaining">—</span> days left)
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Expiry action badge --}}
|
|
<div id="sub-expiry-action-notice" class="alert" style="display:none;"></div>
|
|
|
|
<button class="btn btn-outline-primary btn-sm" onclick="SubPage_loadPlans()">
|
|
<i class="fas fa-redo"></i> Renew / Upgrade
|
|
</button>
|
|
</div>
|
|
|
|
{{-- No subscription panel --}}
|
|
<div id="subscription-none-panel" style="display:none;">
|
|
<div class="alert alert-warning">
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
You do not have an active subscription.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr>
|
|
|
|
{{-- Wallet Balance --}}
|
|
<div class="row mb-3">
|
|
<div class="col-6">
|
|
<div class="small-box bg-info">
|
|
<div class="inner">
|
|
<h4 id="sub-wallet-balance">₱0.00</h4>
|
|
<p>Wallet Balance</p>
|
|
</div>
|
|
<div class="icon"><i class="fas fa-wallet"></i></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Available Plans --}}
|
|
<h5>Available Plans</h5>
|
|
<div id="subscription-plans-loading" class="text-center" style="padding: 10px; display:none;">
|
|
<i class="fas fa-spinner fa-spin"></i> Loading plans...
|
|
</div>
|
|
<div id="subscription-plans-container" class="row" style="display:none;"></div>
|
|
|
|
<hr>
|
|
|
|
{{-- Invoice History --}}
|
|
<h5>Invoice History</h5>
|
|
<div id="subscription-invoices-loading" class="text-center" style="padding:10px; display:none;">
|
|
<i class="fas fa-spinner fa-spin"></i> Loading invoices...
|
|
</div>
|
|
<div id="subscription-invoices-container">
|
|
<table class="table table-sm table-striped" id="subscription-invoices-table" style="display:none;">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Plan</th>
|
|
<th>Amount</th>
|
|
<th>Method</th>
|
|
<th>Status</th>
|
|
<th>Reference</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="subscription-invoices-body"></tbody>
|
|
</table>
|
|
<div id="subscription-invoices-empty" class="text-muted" style="display:none;">No invoices yet.</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
|
|
// ── Bootstrap ────────────────────────────────────────────────────────
|
|
SubPage_loadStatus();
|
|
SubPage_loadInvoices();
|
|
|
|
// ── Load current subscription ────────────────────────────────────────
|
|
function SubPage_loadStatus() {
|
|
$.get('/subscription/my', function (data) {
|
|
$('#subscription-loading').hide();
|
|
|
|
const balance = parseFloat(data.balance || 0);
|
|
$('#sub-wallet-balance').text('₱' + balance.toFixed(2));
|
|
|
|
if (data.has_subscription && data.subscription) {
|
|
const sub = data.subscription;
|
|
const plan = sub.plan || {};
|
|
|
|
$('#sub-plan-name').text(plan.name || '—');
|
|
$('#sub-expires-at').text(sub.expires_at ? sub.expires_at.substring(0, 10) : '—');
|
|
$('#sub-days-remaining').text(sub.days_remaining ?? '—');
|
|
|
|
const pct = plan.duration_days
|
|
? Math.max(0, Math.min(100, Math.round((sub.days_remaining / plan.duration_days) * 100)))
|
|
: 0;
|
|
$('#sub-progress-bar').css('width', pct + '%');
|
|
|
|
// Expiry action notice
|
|
const notices = {
|
|
'restrict': { cls: 'alert-danger', msg: '<i class="fas fa-lock"></i> When your subscription expires, access to protected features will be restricted until you renew.' },
|
|
'warn': { cls: 'alert-warning', msg: '<i class="fas fa-bell"></i> You will receive a warning when your subscription expires.' },
|
|
'auto_deduct': { cls: 'alert-info', msg: '<i class="fas fa-sync"></i> Your subscription will automatically renew by deducting from your wallet balance.' },
|
|
};
|
|
const notice = notices[plan.expiry_action];
|
|
if (notice) {
|
|
$('#sub-expiry-action-notice')
|
|
.addClass(notice.cls)
|
|
.html(notice.msg)
|
|
.show();
|
|
}
|
|
|
|
$('#subscription-active-panel').show();
|
|
} else {
|
|
$('#subscription-none-panel').show();
|
|
SubPage_loadPlans();
|
|
}
|
|
}).fail(function () {
|
|
$('#subscription-loading').html('<span class="text-danger">Failed to load subscription status.</span>');
|
|
});
|
|
}
|
|
|
|
// ── Load available plans ─────────────────────────────────────────────
|
|
window.SubPage_loadPlans = function () {
|
|
$('#subscription-plans-loading').show();
|
|
$('#subscription-plans-container').hide().empty();
|
|
|
|
$.get('/subscription/plans', function (plans) {
|
|
$('#subscription-plans-loading').hide();
|
|
|
|
if (!plans || plans.length === 0) {
|
|
$('#subscription-plans-container').html('<p class="text-muted">No plans available.</p>').show();
|
|
return;
|
|
}
|
|
|
|
const balance = parseFloat($('#sub-wallet-balance').text().replace('₱', '')) || 0;
|
|
|
|
plans.forEach(function (plan) {
|
|
const canAfford = balance >= parseFloat(plan.price);
|
|
const card = `
|
|
<div class="col-md-4 mb-3">
|
|
<div class="card card-outline card-primary">
|
|
<div class="card-header text-center">
|
|
<h5 class="card-title">${escHtml(plan.name)}</h5>
|
|
</div>
|
|
<div class="card-body text-center">
|
|
<h3>₱${parseFloat(plan.price).toFixed(2)}</h3>
|
|
<p class="text-muted">${parseInt(plan.duration_days)} days</p>
|
|
<p class="small">${escHtml(plan.description || '')}</p>
|
|
${SubPage_expiryBadge(plan.expiry_action)}
|
|
<button
|
|
class="btn btn-primary btn-block mt-2"
|
|
${canAfford ? '' : 'disabled title="Insufficient balance"'}
|
|
onclick="SubPage_confirmPay('${escHtml(plan.hashkey)}', '${escHtml(plan.name)}', ${parseFloat(plan.price)})">
|
|
${canAfford ? '<i class="fas fa-wallet"></i> Pay with Wallet' : '<i class="fas fa-lock"></i> Insufficient Balance'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>`;
|
|
$('#subscription-plans-container').append(card);
|
|
});
|
|
|
|
$('#subscription-plans-container').show();
|
|
}).fail(function () {
|
|
$('#subscription-plans-loading').html('<span class="text-danger">Failed to load plans.</span>');
|
|
});
|
|
};
|
|
|
|
function SubPage_expiryBadge(action) {
|
|
const badges = {
|
|
'restrict': '<span class="badge badge-danger">Restricts on expiry</span>',
|
|
'warn': '<span class="badge badge-warning">Warning on expiry</span>',
|
|
'auto_deduct': '<span class="badge badge-info">Auto-renews on expiry</span>',
|
|
};
|
|
return badges[action] || '';
|
|
}
|
|
|
|
// ── Confirm + pay ────────────────────────────────────────────────────
|
|
window.SubPage_confirmPay = function (planHashkey, planName, price) {
|
|
const balance = parseFloat($('#sub-wallet-balance').text().replace('₱', '')) || 0;
|
|
|
|
ModalQuickDismiss(
|
|
'Confirm Payment',
|
|
`Pay <strong>₱${price.toFixed(2)}</strong> for <strong>${escHtml(planName)}</strong>?<br>
|
|
<small class="text-muted">Your wallet balance: ₱${balance.toFixed(2)}</small>`,
|
|
function () { SubPage_doWalletPay(planHashkey); }
|
|
);
|
|
};
|
|
|
|
function SubPage_doWalletPay(planHashkey) {
|
|
$.post('/subscription/pay/wallet', { plan_hashkey: planHashkey }, function (data) {
|
|
if (data && data.success) {
|
|
ModalQuickDismiss('Payment Successful', 'Your subscription is now active. Refreshing...');
|
|
setTimeout(function () { location.reload(); }, 1500);
|
|
} else {
|
|
ModalQuickDismiss('Payment Failed', typeof data === 'string' ? data : 'An error occurred.');
|
|
}
|
|
}).fail(function (xhr) {
|
|
ModalQuickDismiss('Payment Failed', xhr.responseJSON || xhr.responseText || 'An error occurred.');
|
|
});
|
|
}
|
|
|
|
// ── Load invoice history ─────────────────────────────────────────────
|
|
function SubPage_loadInvoices() {
|
|
$('#subscription-invoices-loading').show();
|
|
|
|
$.get('/subscription/invoices', function (invoices) {
|
|
$('#subscription-invoices-loading').hide();
|
|
|
|
if (!invoices || invoices.length === 0) {
|
|
$('#subscription-invoices-empty').show();
|
|
return;
|
|
}
|
|
|
|
invoices.forEach(function (inv) {
|
|
const statusBadge = {
|
|
'paid': '<span class="badge badge-success">Paid</span>',
|
|
'pending': '<span class="badge badge-warning">Pending</span>',
|
|
'failed': '<span class="badge badge-danger">Failed</span>',
|
|
}[inv.status] || inv.status;
|
|
|
|
const row = `<tr>
|
|
<td>${inv.created_at ? inv.created_at.substring(0, 10) : '—'}</td>
|
|
<td>${escHtml(inv.plan_name || '—')}</td>
|
|
<td>₱${parseFloat(inv.amount).toFixed(2)}</td>
|
|
<td>${escHtml(inv.payment_method)}</td>
|
|
<td>${statusBadge}</td>
|
|
<td>${escHtml(inv.payment_reference || '—')}</td>
|
|
</tr>`;
|
|
$('#subscription-invoices-body').append(row);
|
|
});
|
|
|
|
$('#subscription-invoices-table').show();
|
|
}).fail(function () {
|
|
$('#subscription-invoices-loading').html('<span class="text-danger">Failed to load invoices.</span>');
|
|
});
|
|
}
|
|
|
|
function escHtml(str) {
|
|
const d = document.createElement('div');
|
|
d.appendChild(document.createTextNode(str ?? ''));
|
|
return d.innerHTML;
|
|
}
|
|
|
|
})();
|
|
</script>
|