feat: toggle fitur voucher (setting voucher_enabled) + gate route & sembunyikan link

This commit is contained in:
oxpoe committed 2026-10-12 22:20:48 +07:00
1 parent 8caae14cfd
commit 63994df1e4
4 files changed
+26 -4

No files matched your search

+2
View File
@@ -4732,6 +4732,8 @@ router.post('/settings', requireAdminSession, express.urlencoded({ extended: tru
const newSettings = { ...req.body };
if (newSettings.whatsapp_enabled === 'true') newSettings.whatsapp_enabled = true;
else if (newSettings.whatsapp_enabled === 'false') newSettings.whatsapp_enabled = false;
if (newSettings.voucher_enabled === 'true') newSettings.voucher_enabled = true;
else if (newSettings.voucher_enabled === 'false') newSettings.voucher_enabled = false;
if (newSettings.qris_static_enabled === 'true') newSettings.qris_static_enabled = true;
else if (newSettings.qris_static_enabled === 'false') newSettings.qris_static_enabled = false;
+6
View File
@@ -2,6 +2,7 @@ const express = require('express');
const router = express.Router();
const customerDevice = require('../services/customerDeviceService');
const { getSettingsWithCache, getNowLocal, getCurrentTimeInfo, getNowLocalISO, formatDateLocal, formatTimeLocal } = require('../config/settingsManager');
function voucherFeatureOn() { try { const s = getSettingsWithCache() || {}; const v = s.voucher_enabled; return !(v === false || v === 'false' || v === '0' || v === 0); } catch (e) { return true; } }
const noticeSvc = require('../services/serviceNoticeService');
const ssidChangeCooldown = new Map(); // key: customer id / loginId -> timestamp terakhir ubah SSID
const registrationService = require('../services/registrationService');
@@ -890,6 +891,7 @@ router.get('/check-billing', async (req, res) => {
let _voucherLastGoodProfiles = null;
router.get('/voucher', async (req, res) => {
if (!voucherFeatureOn()) return res.redirect('/customer/login?err=' + encodeURIComponent('Fitur voucher sedang dinonaktifkan'));
const settings = getSettingsWithCache();
const error = String(req.query.err || '').trim() || null;
const info = String(req.query.info || '').trim() || null;
@@ -1149,6 +1151,7 @@ router.get('/voucher', async (req, res) => {
});
router.get('/voucher/qris/:orderId', async (req, res) => {
if (!voucherFeatureOn()) return res.redirect('/customer/login?err=' + encodeURIComponent('Fitur voucher sedang dinonaktifkan'));
const settings = getSettingsWithCache();
const orderId = Number(req.params.orderId || 0);
const secret = settings.session_secret || 'rahasia-portal-pelanggan-default-ganti-ini';
@@ -1196,6 +1199,7 @@ router.get('/voucher/qris/:orderId', async (req, res) => {
});
// API endpoint untuk cek status voucher order (untuk auto-polling di halaman QRIS)
router.get('/voucher/status/:orderId', async (req, res) => {
if (!voucherFeatureOn()) return res.json({ success: false, status: 'disabled', message: 'Fitur voucher dinonaktifkan' });
const settings = getSettingsWithCache();
const orderId = Number(req.params.orderId || 0);
const secret = settings.session_secret || 'rahasia-portal-pelanggan-default-ganti-ini';
@@ -1224,6 +1228,7 @@ router.get('/voucher/status/:orderId', async (req, res) => {
router.post('/public/voucher/create-payment', async (req, res) => {
if (!voucherFeatureOn()) return res.status(403).json({ success: false, message: 'Fitur voucher dinonaktifkan' });
const settings = getSettingsWithCache();
const buyerPhone = normalizeBuyerPhone(req.body.buyer_phone);
@@ -3352,6 +3357,7 @@ router.post('/payment/proof/:invoiceId', uploadProof.single('proof'), async (req
});
router.post('/voucher/proof/:orderId', uploadProof.single('proof'), async (req, res) => {
if (!voucherFeatureOn()) return res.redirect('/customer/login?err=' + encodeURIComponent('Fitur voucher sedang dinonaktifkan'));
const settings = getSettingsWithCache();
const secret = settings.session_secret || 'rahasia-portal-pelanggan-default-ganti-ini';
const token = String(req.body && req.body.token ? req.body.token : '').trim();
+13
View File
@@ -432,6 +432,19 @@
</div>
</div>
<!-- Fitur Opsional -->
<div data-setcat="notif">
<h6 style="font-size:13px;color:var(--muted);margin-bottom:12px;text-transform:uppercase;letter-spacing:1px"><i class="bi bi-toggles"></i> Fitur Opsional</h6>
<div class="fg">
<label class="fl"><%= t('admin.set.voucher_enabled','Fitur Voucher (Beli Voucher Wi-Fi)') %></label>
<select class="fs" name="voucher_enabled">
<option value="true" <%= (settings.voucher_enabled === false || settings.voucher_enabled === 'false' || settings.voucher_enabled === '0' || settings.voucher_enabled === 0) ? '' : 'selected' %>><%= t('common.active','Aktif') %></option>
<option value="false" <%= (settings.voucher_enabled === false || settings.voucher_enabled === 'false' || settings.voucher_enabled === '0' || settings.voucher_enabled === 0) ? 'selected' : '' %>><%= t('common.inactive','Nonaktif') %></option>
</select>
<div style="font-size:10px; color:var(--muted); margin-top:4px">Nonaktifkan untuk menyembunyikan halaman Beli Voucher publik (mis. saat deploy).</div>
</div>
</div>
<!-- WhatsApp -->
<div data-setcat="notif">
<h6 style="font-size:13px;color:var(--muted);margin-bottom:12px;text-transform:uppercase;letter-spacing:1px"><i class="bi bi-whatsapp"></i> Integrasi WhatsApp</h6>
+5 -4
View File
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="<%= lang || 'id' %>" data-theme="dark">
<% const voucherOn = !(settings && (settings.voucher_enabled === false || settings.voucher_enabled === 'false' || settings.voucher_enabled === '0' || settings.voucher_enabled === 0)); %>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
@@ -41,7 +42,7 @@
<a href="#packages">Paket</a>
<a href="#features"><%= t('landing.nav.features','Keunggulan') %></a>
<a href="/customer/check-billing"><%= t('landing.hero.check','Cek Tagihan') %></a>
<a href="/customer/voucher"><%= t('login.voucher_nav','Voucher') %></a>
<% if (voucherOn) { %><a href="/customer/voucher"><%= t('login.voucher_nav','Voucher') %></a><% } %>
<% if (typeof settings !== 'undefined' && settings && settings.status_url) { %><a href="<%= settings.status_url %>" target="_blank" rel="noopener">Status</a><% } %>
</nav>
<div class="header-actions">
@@ -56,7 +57,7 @@
<a href="#packages" onclick="toggleMenu()"><%= t('landing.nav.packages_full','Paket & Harga') %></a>
<a href="#features" onclick="toggleMenu()"><%= t('landing.nav.features','Keunggulan') %></a>
<a href="/customer/check-billing" onclick="toggleMenu()"><i class="bi bi-receipt"></i> <%= t('landing.hero.check','Cek Tagihan') %></a>
<a href="/customer/voucher" onclick="toggleMenu()"><i class="bi bi-ticket-perforated"></i> <%= t('login.voucher_short','Beli Voucher') %></a>
<% if (voucherOn) { %><a href="/customer/voucher" onclick="toggleMenu()"><i class="bi bi-ticket-perforated"></i> <%= t('login.voucher_short','Beli Voucher') %></a><% } %>
<a href="/customer/register" onclick="toggleMenu()"><i class="bi bi-person-plus"></i> <%= t('login.register_new','Daftar Baru') %></a>
<% if (typeof settings !== 'undefined' && settings && settings.status_url) { %><a href="<%= settings.status_url %>" target="_blank" rel="noopener" onclick="toggleMenu()"><i class="bi bi-activity"></i> Status Server</a><% } %>
</div>
@@ -120,7 +121,7 @@
<div class="quick-tools">
<a href="/customer/check-billing" class="qtool"><i class="bi bi-receipt"></i> <%= t('landing.hero.check','Cek Tagihan') %></a>
<a href="/customer/voucher" class="qtool"><i class="bi bi-ticket-perforated"></i> <%= t('login.voucher_short','Beli Voucher') %></a>
<% if (voucherOn) { %><a href="/customer/voucher" class="qtool"><i class="bi bi-ticket-perforated"></i> <%= t('login.voucher_short','Beli Voucher') %></a><% } %>
</div>
<div class="auth-foot">
@@ -209,7 +210,7 @@
<h4>Portal</h4>
<div class="foot-links">
<a href="/customer/check-billing"><%= t('login.check_full','Cek & Bayar Tagihan') %></a>
<a href="/customer/voucher"><%= t('login.voucher','Beli Voucher Wi-Fi') %></a>
<% if (voucherOn) { %><a href="/customer/voucher"><%= t('login.voucher','Beli Voucher Wi-Fi') %></a><% } %>
<a href="/customer/register"><%= t('login.new_install','Pasang Baru') %></a>
<a href="/customer/dashboard"><%= t('login.dashboard','Dashboard Pelanggan') %></a>
</div>