Upload files to "system/plugin/ui"

Signed-off-by: nestict <icttechnest@gmail.com>
This commit is contained in:
nestict 2025-05-24 12:36:52 +02:00
parent f5ec9276bd
commit 21a5212120
4 changed files with 589 additions and 0 deletions

BIN
system/plugin/ui/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,162 @@
{include file="sections/header.tpl"}
<style>
/* Styles for overall layout and responsiveness */
body {
background-color: #f8f9fa;
font-family: 'Arial', sans-serif;
}
.container {
margin-top: 20px;
background-color: #d8dfe5;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
padding: 20px;
max-width: 98%;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
/* Styles for table and pagination */
.table {
width: 100%;
margin-bottom: 1rem;
background-color: #fff;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.table th {
vertical-align: middle;
border-color: #dee2e6;
background-color: #343a40;
color: #fff;
}
.table td {
vertical-align: middle;
border-color: #dee2e6;
}
.table-striped tbody tr:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.05);
}
.table-hover tbody tr:hover {
background-color: rgba(0, 0, 0, 0.075);
color: #333;
font-weight: bold;
transition: background-color 0.3s, color 0.3s;
}
.pagination .page-item .page-link {
color: #007bff;
background-color: #fff;
border: 1px solid #dee2e6;
margin: 0 2px;
padding: 6px 12px;
transition: background-color 0.3s, color 0.3s;
}
.pagination .page-item .page-link:hover {
background-color: #e9ecef;
color: #0056b3;
}
.pagination .page-item.active .page-link {
z-index: 1;
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
.dataTables_wrapper .dataTables_paginate .paginate_button {
display: inline-block;
padding: 5px 10px;
margin-right: 5px;
border: 1px solid #ccc;
background-color: #fff;
color: #333;
cursor: pointer;
}
</style>
{if isset($message)}
<div class="alert alert-{if $notify_t == 's'}success{else}danger{/if}">
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
<div>{$message}</div>
</div>
{/if}
<div class="col-md-14">
<!-- LINE CHART -->
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">{Lang::T('Payment History')}</h3>
<div class="box-tools pull-right">
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-refresh"></i>
</button>
<a href="{$app_url}/pages/mpesa-webhook.html" class="btn bg-teal btn-sm"><i class="fa fa-file"></i>
</a>
</div>
</div>
<div class="box-body">
<div class="container">
<div class="table-responsive">
<table class="table table-bordered table-striped" id="payments-table">
<thead>
<tr>
<th>{Lang::T('Customer Name')}</th>
<th>{Lang::T('Transaction Type')}</th>
<th>{Lang::T('Transaction Time')}</th>
<th>{Lang::T('Amount Paid')}</th>
<th>{Lang::T('Package Name')}</th>
<th>{Lang::T('Package Price')}</th>
<th>{Lang::T('Status')}</th>
<th>{Lang::T('Bill Ref Number')}</th>
<th>{Lang::T('Company Balance')}</th>
<th>{Lang::T('Date')}</th>
</tr>
</thead>
<tbody>
{foreach $payments as $payment}
<tr>
<td><a href="{$app_url}/index.php?_route=customers/view/{$payment.CustomerID}">{$payment.FirstName}</a></td>
<td>{$payment.TransactionType}</td>
<td>{$payment.TransTime}</td>
<td>{$payment.TransAmount}</td>
<td>{$payment.PackageName}</td>
<td>{$payment.PackagePrice}</td>
<td><span
class="label {if $payment.TransactionStatus == Completed}label-success {elseif $payment.TransactionStatus == Pending}label-warning {/if}">{$payment.TransactionStatus}</span>
</td>
<td>{$payment.BillRefNumber}</td>
<td>{$payment.OrgAccountBalance}</td>
<td>{$payment.CreatedAt}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<script>
var $j = jQuery.noConflict();
$j(document).ready(function () {
$j('#payments-table').DataTable({
"pagingType": "full_numbers"
});
});
</script>
{include file="sections/footer.tpl"}

View File

@ -0,0 +1,234 @@
{include file="sections/header.tpl"}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<style>
.styled-form-group {
margin-bottom: 20px;
}
.styled-btn {
color: #28a745;
border: 1px solid #28a745;
background-color: #fff;
padding: 10px 20px;
font-size: 16px;
text-align: center;
text-decoration: none;
display: inline-block;
transition: all 0.3s ease;
}
.styled-btn:hover {
background-color: #28a745;
color: #fff;
}
.styled-small-text {
color: blue;
margin-top: 10px;
display: block;
font-size: 14px;
}
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
/* Hidden checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* Slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border-radius: 50%;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
</style>
{if isset($message)}
<div class="alert alert-{if $notify_t == 's'}success{else}danger{/if}">
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span>
</button>
<div>{$message}</div>
</div>
{/if}
<form class="form-horizontal" method="post" role="form" action="{$_url}plugin/c2b_settings">
<div class="row">
<div class="col-sm-12 col-md-12">
<div class="panel panel-primary panel-hovered panel-stacked mb30">
<div class="panel-heading">{Lang::T('M-Pesa C2B Payment Gateway')}</div>
<div class="panel-body">
<div class="form-group col-6">
<label class="col-md-3 control-label">{Lang::T('M-Pesa C2B Environment')}</label>
<div class="col-md-6">
<select class="form-control" name="mpesa_c2b_env" id="mpesa_c2b_env">
<option value="sandbox" {if $_c['mpesa_c2b_env']=='sandbox' }selected{/if}>
{Lang::T('SandBox or
Testing')}</option>
<option value="live" {if $_c['mpesa_c2b_env']=='live' }selected{/if}>{Lang::T('Live or
Production')}
</option>
</select>
<small class="form-text text-muted">
<font color="red"><b>{Lang::T('Sandbox')}</b></font> {Lang::T('is for testing purpose,
please switch to')} <font color="green"><b>{Lang::T('Live')}</b></font> {Lang::T('in
production.')}
</small>
</div>
</div>
<div class="form-group col-6">
<label class="col-md-3 control-label">M-Pesa C2B Consumer Key</label>
<div class="col-md-6">
<input type="text" class="form-control" id="mpesa_c2b_consumer_key"
name="mpesa_c2b_consumer_key" placeholder="xxxxxxxxxxxxxxxxx"
value="{$_c['mpesa_c2b_consumer_key']}">
<small class="form-text text-muted"><a href="https://developer.safaricom.co.ke/MyApps"
target="_blank">https://developer.safaricom.co.ke/MyApps</a></small>
</div>
</div>
<div class="form-group col-6">
<label class="col-md-3 control-label">M-Pesa C2B Consumer Secret</label>
<div class="col-md-6">
<input type="password" class="form-control" id="mpesa_c2b_consumer_secret"
name="mpesa_c2b_consumer_secret" placeholder="xxxxxxxxxxxxxxxxx"
value="{$_c['mpesa_c2b_consumer_secret']}">
</div>
</div>
<div class="form-group col-6">
<label class="col-md-3 control-label">M-Pesa C2B Business Shortcode</label>
<div class="col-md-6">
<input type="text" class="form-control" id="mpesa_c2b_business_code"
name="mpesa_c2b_business_code" placeholder="xxxxxxx" maxlength="7"
value="{$_c['mpesa_c2b_business_code']}">
</div>
</div>
<div class="form-group col-6">
<label class="col-md-3 control-label">M-Pesa C2B Version</label>
<div class="col-md-6">
<select class="form-control" name="mpesa_c2b_api">
<option value="v1" {if $_c['mpesa_c2b_api']=='v1' }selected{/if}>v1</option>
<option value="v2" {if $_c['mpesa_c2b_api']=='v2' }selected{/if}>v2</option>
</select>
<small class="form-text text-muted">Select the version of the API you want to
use.</small>
</div>
</div>
<div class="form-group col-6">
<label class="col-md-3 control-label">Bill Ref Number Type</label>
<div class="col-md-6">
<select class="form-control" name="mpesa_c2b_bill_ref">
<option value="phone" {if $_c['mpesa_c2b_bill_ref']=='phone' }selected{/if}>Phone Number</option>
<option value="username" {if $_c['mpesa_c2b_bill_ref']=='username' }selected{/if}>Username</option>
<option value="id" {if $_c['mpesa_c2b_bill_ref']=='id' }selected{/if}>Account ID</option>
</select>
<small class="form-text text-muted">How will the system identify your customers. BillRefNumber must be a unique identity</small>
</div>
</div>
<div class="form-group col-6">
<label class="col-md-3 control-label">{Lang::T('Accept Insufficient Fee')}</label>
<div class="col-md-6">
<label class="switch">
<input type="checkbox" id="mpesa_c2b_low_fee" value="1"
name="mpesa_c2b_low_fee" {if $_c['mpesa_c2b_low_fee']==1}checked{/if}>
<span class="slider"></span>
</label>
</div>
</div>
{if $_c['c2b_registered'] && $_c['mpesa_c2b_env']!='sandbox'}
<div class="form-group col-12 styled-form-group">
<label class="col-md-3 control-label">Register C2B URL</label>
<div class="col-md-6">
<button class="btn styled-btn">URLs Already Registered</button>
</div>
</div>
{else}
<div class="form-group col-12 styled-form-group">
<label class="col-md-3 control-label">Register C2B URL</label>
<div class="col-md-6">
<a href="{$_url}plugin/c2b_registerUrl" class="btn styled-btn">Click to Register Mpesa
C2B URL</a>
<small class="form-text text-muted styled-small-text">Click only after you have saved
the changes.</small>
</div>
</div>
{/if}
<div class="form-group col-6">
<div class="col-lg-offset-3 col-lg-10">
<button class="btn btn-primary waves-effect waves-light" name="save" value="save"
type="submit">Save Changes</button>
</div>
</div>
<div class="bs-callout bs-callout-info" id="callout-navbar-role">
<h4><b>Accept Insufficient Fee</b>:</h4>
<p> If Enable the money customer sent will be convert to customer balance, but if disabled the system will reject it. <br> It requires Validation URL</p>
<h4><b>Note</b>:</h4>
<p> Before click on Register URL <br>
Make sure you have fill the required fields <br>
</p>
</div>
</div>
</div>
</div>
</div>
</form>
<script>
$(document).ready(function () {
toggleTillNumberInput();
$('#mpesa_c2b_transaction').on('change', function () {
toggleTillNumberInput();
});
function toggleTillNumberInput() {
if ($('#mpesa_c2b_transaction').val() === 'BuyGoods') {
$('#tillNumberContainer').show();
} else {
$('#tillNumberContainer').hide();
}
}
});
</script>
{include file="sections/footer.tpl"}

View File

@ -0,0 +1,193 @@
{include file="sections/header.tpl"}
<section class="content-header">
<h1>
<div class="btn-group">
<button type="button" class="btn btn-success">
Captive Portal Settings
</button>
<button
type="button"
class="btn btn-success dropdown-toggle"
data-toggle="dropdown"
>
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="{$_url}plugin/captive_portal_settings">{Lang::T('General Settings')}</a></li>
<li>
<a href="{$_url}plugin/captive_portal_slider"
>{Lang::T('Manage Sliders')}</a
>
</li>
<li><a href="#">{Lang::T('Manage Advertisements')}</a></li>
<li><a href="#">{Lang::T('Manage Authorizations')}</a></li>
<li><a href="#">{Lang::T('Reports')}</a></li>
<li class="divider"></li>
<li>
<a
href="{$_url}plugin/captive_portal_login"
target="”_blank”"
>Preview Member Landing Page</a
>
</li>
<li>
<a
href="{$_url}plugin/captive_portal_download_login"
target="”_blank”"
> Download Login Page </a
>
</li>
</ul>
</div>
</h1>
<ol class="breadcrumb">
<li>
<a href="{$_url}plugin/captive_portal_overview"><i class="fa fa-dashboard"></i> Captive Portal</a>
</li>
<li class="active"> General Settings</li>
</ol>
</section>
<section class="content">
<div class="table-responsive">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active">
<a href="#tab_1" data-toggle="tab">{Lang::T('General Settings')}</a>
</li>
<li>
<a href="#tab_2" data-toggle="tab">{Lang::T('Customization')}</a>
</li>
<li>
<a href="#tab_3" data-toggle="tab">{Lang::T('Slider Settings')}</a>
</li>
<li>
<a href="#tab_4" data-toggle="tab">{Lang::T('Advertisement Settings')}</a>
</li>
<li>
<a href="#tab_5" data-toggle="tab">{Lang::T('Trial Authorization Settings')}</a>
</li>
<li>
<a href="#tab_6" data-toggle="tab">{Lang::T('Pages Settings')}</a>
</li>
</ul>
<div class="tab-content">
<div style="overflow-x:auto;" class="tab-pane active" id="tab_1">
<div class="box-body no-padding" id="">
<form method="POST" action="" enctype="multipart/form-data">
<div class="box-body">
<div class="form-group">
<label for="">Hotspot Page Title</label>
<input type="text" class="form-control" name="title" id="title" value="{$settings.hotspot_title}" required>
<small class="form-text text-muted">Hotspot Title will be display on Login Page Head Tag</small>
</div>
<div class="form-group">
<label for="">Hotspot Name</label>
<input type="text" class="form-control" name="name" id="name" value="{$settings.hotspot_name}" required>
<small class="form-text text-muted">Hotspot Name will be display on Login Page Nav Bar if Logo is not available</small>
</div>
<div class="form-group">
<label for="favicon">Favicon</label>
<input type="file" class="form-control" name="favicon" id="favicon" accept="image/x-icon, image/png, image/jpeg, image/gif" onchange="previewImage('favicon', 'favicon-preview')">
<small class="form-text text-muted">Favicon will be display on Login Page browser tab, its placed in head section</small>
<br>
<img id="favicon-preview" src="{$settings.favicon}" alt="Favicon Preview" style="max-width: 32px; max-height: 32px;">
</div>
<div class="form-group">
<label for="logo">Logo</label>
<input type="file" class="form-control" name="logo" id="logo" accept="image/png, image/jpeg, image/svg+xml" onchange="previewImage('logo', 'logo-preview')">
<small class="form-text text-muted">Logo will be display on Login Page Nav Bar section</small>
<br>
<img id="logo-preview" src="{$settings.logo}" alt="Logo Preview" style="max-width: 200px; max-height: 200px;">
</div>
<div class="form-group">
<label class="">{Lang::T('Allow Free Trial')}</label>
<div class="form-group">
<select name="trial" id="trial" class="form-control">
<option value="no" {if {$settings.hotspot_trial}=='no' }selected="selected" {/if}>No
</option>
<option value="yes" {if {$settings.hotspot_trial}=='yes' }selected="selected" {/if}>Yes
</option>
</select>
<small class="form-text text-muted"><ul>
<li>Choose No if you dont want to allow Free Trial </li>
<li>Make sure you enable free trial in Mikrotik Router</li>
<li>free trial button won't display
on captive portal preview, but will work if you connect from hotspot</li>
</ul></small>
</div>
</div>
<div class="form-group">
<label class="">{Lang::T('Allow Member Login')}</label>
<div class="form-group">
<select name="member" id="member" class="form-control">
<option value="no" {if {$settings.hotspot_member}=='no' }selected="selected" {/if}>No
</option>
<option value="yes" {if {$settings.hotspot_member}=='yes' }selected="selected" {/if}>Yes
</option>
</select>
<small class="form-text text-muted">Choose No If you want to disable Member Login</small>
</div>
</div>
</div>
<div class="box-footer">
<a href="{$_url}plugin/captive_portal_overview" class="btn btn-default">Cancel</a>
<button type="submit" class="btn btn-info pull-right">Save Changes</button>
</div>
</form>
</div>
</div>
<!-- /.tab-pane -->
<div class="tab-pane" style="overflow-x:auto;" id="tab_2">
<div class="box-body no-padding" id="">
This feature will be available on Pro Version
</div>
</div>
<!-- /.tab-pane -->
<div style="overflow-x:auto;" class="tab-pane" id="tab_3">
<div class="box-body no-padding" id="">
This feature will be available on Pro Version
</div>
</div>
<div style="overflow-x:auto;" class="tab-pane" id="tab_4">
<div class="box-body no-padding" id="">
This feature will be available on Pro Version
</div>
</div>
<div style="overflow-x:auto;" class="tab-pane" id="tab_5">
<div class="box-body no-padding" id="">
This feature will be available on Pro Version
</div>
</div>
<div style="overflow-x:auto;" class="tab-pane" id="tab_6">
<div class="box-body no-padding" id="">
This feature will be available on Pro Version
</div>
</div>
</div>
</div>
<div>
<pre><b>USAGE:</b>
<br>Upload your sliders in Slider Setting
<br>Go General Settings and setup as per your requirements
<br>Then download your the login.html by clicking on download login page
<br>Then upload the downloaded login.html file to your mikrotik router
<br>Make sure you add your webiste URL in mikrotik hotspot wall garden
<br>If your website is https i will suggest you to add certificate to your router
</pre>
</div>
</section>
<script>
window.addEventListener('DOMContentLoaded', function() {
var portalLink = "https://github.com/focuslinkstech";
$('#version').html('Captive Portal Plugin by: <a href="' + portalLink + '">Focuslinks Tech</a>');
});
</script>
{include file="sections/footer.tpl"}