Upload files to "ui/ui"

Signed-off-by: nestict <icttechnest@gmail.com>
This commit is contained in:
nestict 2025-05-24 12:11:28 +02:00
parent 04693a88e5
commit fdadc713af
5 changed files with 1295 additions and 0 deletions

215
ui/ui/customers-add.tpl Normal file
View File

@ -0,0 +1,215 @@
{include file="sections/header.tpl"}
{assign var="icmcode" value="ICM{rand(000000,999999)}"}
{assign var="itcode" value="IT{rand(500,999)}"}
<div class="container-fluid">
<form class="form-horizontal" method="post" role="form" action="{$_url}customers/add-post">
<div class="row">
<div class="col-md-12">
<div class="card card-primary card-hovered card-stacked mb30">
<div class="card-header" style="display: grid; align-content: center; justify-content: center;">
<h5 class="card-title">{Lang::T('Add New Contact')}</h5></div>
<div class="card-body">
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Full Name')}</label>
<div class="col-md-9">
<input type="text" required class="form-control" id="fullname" name="fullname">
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Username')}</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-user"></i></span>
<input type="text" class="form-control" name="username" value="{$icmcode}" id="username" required
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Account')}</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-user"></i></span>
<input type="text" class="form-control" name="account" value="{$itcode}" id="account" required>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Email')}</label>
<div class="col-md-9">
<input type="email" class="form-control" id="email" name="email" value="icom@net.com">
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Phone Number')}</label>
<div class="col-md-9">
<div class="input-group">
{if $_c['country_code_phone']!= ''}
<span class="input-group-text" id="basic-addon1">+</span>
{else}
<span class="input-group-text" id="basic-addon1"><i
class="glyphicon glyphicon-phone-alt"></i></span>
{/if}
<input type="text" class="form-control" name="phonenumber" value="254"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Password')}</label>
<div class="col-md-9">
<input type="password" class="form-control" autocomplete="off" required id="password"
value="{$icmcode}" name="password" onmouseleave="this.type = 'password'"
onmouseenter="this.type = 'text'">
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('PPPOE Password')}</label>
<div class="col-md-9">
<input type="password" class="form-control" id="pppoe_password" name="pppoe_password"
value="{$icmcode}" onmouseleave="this.type = 'password'"
onmouseenter="this.type = 'text'">
<span class="help-block">
{Lang::T('User Cannot change this, only admin. if it Empty it will use user password')}
</span>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Area')}</label>
<div class="col-md-9">
<textarea name="address" id="address" class="form-control"></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Service Type')}</label>
<div class="col-md-9">
<select class="form-select" style="height: 52px; background-color: white;" id="service_type" name="service_type">
<option value="Hotspot">Hotspot</option>
<option value="PPPoE">PPPoE</option>
<option value="Static">Static</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Account Type')}</label>
<div class="col-md-9">
<select class="form-select" style="height: 52px; background-color: white;" id="account_type" name="account_type">
<option value="Personal">Personal
</option>
<option value="Business">Business</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Coordinates')}</label>
<div class="col-md-9">
<input name="coordinates" id="coordinates" class="form-control" value=""
placeholder="6.465422, 3.406448">
<div id="map" style="width: '100%'; height: 200px; min-height: 150px;"></div>
</div>
</div>
<div class="col-md-12">
<div class="card kanbanPreview-bx">
<div class="card-body">
<div class="sub-card">
<div class="card-header">
<h5 class="">{Lang::T('Attributes')}</div>
<div class="card-body" style="border: none;">
<!-- Customers Attributes add start -->
<div id="custom-fields-container">
</div>
<!-- Customers Attributes add end -->
</div>
<div class="card-footer">
<button class="btn btn-success btn-block" type="button"
id="add-custom-field">{Lang::T('Add')}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<center>
<button class="btn btn-primary" type="submit">
{Lang::T('Save Changes')}
</button>
<br><a href="{$_url}customers/list" class="btn btn-link">{Lang::T('Cancel')}</a>
</center>
</form>
{literal}
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
var customFieldsContainer = document.getElementById('custom-fields-container');
var addCustomFieldButton = document.getElementById('add-custom-field');
addCustomFieldButton.addEventListener('click', function() {
var fieldIndex = customFieldsContainer.children.length;
var newField = document.createElement('div');
newField.className = 'form-group row';
newField.innerHTML = `
<div class="col-md-4">
<input type="text" class="form-control" name="custom_field_name[]" placeholder="Name">
</div>
<div class="col-md-6">
<input type="text" class="form-control" name="custom_field_value[]" placeholder="Value">
</div>
<div class="col-md-2">
<button type="button" class="remove-custom-field btn btn-danger btn-sm">-</button>
</div>
`;
customFieldsContainer.appendChild(newField);
});
customFieldsContainer.addEventListener('click', function(event) {
if (event.target.classList.contains('remove-custom-field')) {
var fieldContainer = event.target.parentNode.parentNode;
fieldContainer.parentNode.removeChild(fieldContainer);
}
});
});
</script>
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
<script>
function getLocation() {
if (window.location.protocol == "https:" && navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
setupMap(51.505, -0.09);
}
}
function showPosition(position) {
setupMap(position.coords.latitude, position.coords.longitude);
}
function setupMap(lat, lon) {
var map = L.map('map').setView([lat, lon], 13);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 20
}).addTo(map);
var marker = L.marker([lat, lon]).addTo(map);
map.on('click', function(e){
var coord = e.latlng;
var lat = coord.lat;
var lng = coord.lng;
var newLatLng = new L.LatLng(lat, lng);
marker.setLatLng(newLatLng);
$('#coordinates').val(lat + ',' + lng);
});
}
window.onload = function() {
getLocation();
}
</script>
{/literal}
</div>
{include file="sections/footer.tpl"}

254
ui/ui/customers-edit.tpl Normal file
View File

@ -0,0 +1,254 @@
{include file="sections/header.tpl"}
<div class="container-fluid">
<form class="form-horizontal" method="post" role="form" action="{$_url}customers/edit-post">
<div class="row">
<div class="col-md-12">
<div class="card card-primary card-hovered card-stacked mb30">
<div class="card-header" style="display: grid; align-content: center; justify-content: center;">
<h5 class="card-title">{Lang::T('Edit Contact')}</h5>
</div>
<div class="card-body">
<input type="hidden" name="id" value="{$d['id']}">
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Full Name')}</label>
<div class="col-md-9">
<input type="text" class="form-control" id="fullname" name="fullname"
value="{$d['fullname']}">
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Username')}</label>
<div class="col-md-9">
<div class="input-group mb-3">
{if $_c['country_code_phone']!= ''}
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-user"></i></span>
{else}
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-user"></i></span>
{/if}
<input type="text" class="form-control" name="username" value="{$d['username']}"
required placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']} {Lang::T('Phone Number')}{else}{Lang::T('Username')}{/if}">
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Account')}</label>
<div class="col-md-9">
<div class="input-group mb-3">
{if $_c['country_code_phone']!= ''}
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-user"></i></span>
{else}
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-user"></i></span>
{/if}
<input type="text" class="form-control" name="username" value="{$d['account']}"
required>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Email')}</label>
<div class="col-md-9">
<input type="email" class="form-control" id="email" name="email" value="{$d['email']}">
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Phone Number')}</label>
<div class="col-md-9">
<div class="input-group">
{if $_c['country_code_phone']!= ''}
<span class="input-group-text" id="basic-addon1">+</span>
{else}
<span class="input-group-text" id="basic-addon1"><i
class="fa fa-phone-alt"></i></span>
{/if}
<input type="text" class="form-control" name="phonenumber" value="{$d['phonenumber']}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Password')}</label>
<div class="col-md-9">
<input type="password" autocomplete="off" class="form-control" id="password" name="password"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
value="{$d['password']}">
<span class="help-block">{Lang::T('Keep Blank to do not change Password')}</span>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('PPPOE Password')}</label>
<div class="col-md-9">
<input type="password" autocomplete="off" class="form-control" id="pppoe_password"
name="pppoe_password" value="{$d['pppoe_password']}"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'">
<span class="help-block">
{Lang::T('User Cannot change this, only admin. if it Empty it will use user password')}
</span>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Area')}</label>
<div class="col-md-9">
<textarea name="address" id="address" class="form-control">{$d['address']}</textarea>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Service Type')}</label>
<div class="col-md-9">
<select class="form-select" style="height: 52px; background-color: white;" id="service_type" name="service_type">
<option value="Hotspot" {if $d['service_type'] eq 'Hotspot' }selected{/if}>Hotspot
</option>
<option value="PPPoE" {if $d['service_type'] eq 'PPPoE' }selected{/if}>PPPoE</option>
<option value="Static" {if $d['service_type'] eq 'Static' }selected{/if}>Static</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Account Type')}</label>
<div class="col-md-9">
<select class="form-select" style="height: 52px; background-color: white;" id="account_type" name="account_type">
<option value="Personal" {if $d['account_type'] eq 'Personal' }selected{/if}>Personal
</option>
<option value="Business" {if $d['account_type'] eq 'Business' }selected{/if}>Business
</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 control-label">{Lang::T('Coordinates')}</label>
<div class="col-md-9">
<input name="coordinates" id="coordinates" class="form-control" value="{$d['coordinates']}"
placeholder="6.465422, 3.406448">
<div id="map" style="width: '100%'; height: 200px; min-height: 150px;"></div>
</div>
</div>
<div class="col-md-12">
<div class="card kanbanPreview-bx">
<div class="card-body">
<div class="sub-card">
<div class="card-header">
<h5>{Lang::T('Attributes')}</h5></div>
<div class="card-body">
<!--Customers Attributes edit start -->
{if $customFields}
{foreach $customFields as $customField}
<div class="form-group row">
<label class="col-md-4 control-label"
for="{$customField.field_name}">{$customField.field_name}</label>
<div class="col-md-6">
<input class="form-control" type="text" name="custom_fields[{$customField.field_name}]"
id="{$customField.field_name}" value="{$customField.field_value}">
</div>
<label class="col-md-2">
<input type="checkbox" name="delete_custom_fields[]" value="{$customField.field_name}">
Delete
</label>
</div>
{/foreach}
{/if}
<!--Customers Attributes edit end -->
<!-- Customers Attributes add start -->
<div id="custom-fields-container">
</div>
<!-- Customers Attributes add end -->
</div>
<div class="card-footer">
<button class="btn btn-success btn-block" type="button"
id="add-custom-field">{Lang::T('Add')}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<center>
<button class="btn btn-primary" type="submit">
{Lang::T('Save Changes')}
</button>
<br><a href="{$_url}customers/list" class="btn btn-link">{Lang::T('Cancel')}</a>
</center>
</form>
{literal}
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
var customFieldsContainer = document.getElementById('custom-fields-container');
var addCustomFieldButton = document.getElementById('add-custom-field');
addCustomFieldButton.addEventListener('click', function() {
var fieldIndex = customFieldsContainer.children.length;
var newField = document.createElement('div');
newField.className = 'form-group row';
newField.innerHTML = `
<div class="col-md-4">
<input type="text" class="form-control" name="custom_field_name[]" placeholder="Name">
</div>
<div class="col-md-6">
<input type="text" class="form-control" name="custom_field_value[]" placeholder="Value">
</div>
<div class="col-md-2">
<button type="button" class="remove-custom-field btn btn-danger btn-sm">-</button>
</div>
`;
customFieldsContainer.appendChild(newField);
});
customFieldsContainer.addEventListener('click', function(event) {
if (event.target.classList.contains('remove-custom-field')) {
var fieldContainer = event.target.parentNode.parentNode;
fieldContainer.parentNode.removeChild(fieldContainer);
}
});
});
</script>
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
<script>
function getLocation() {
if (window.location.protocol == "https:" && navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
setupMap(51.505, -0.09);
}
}
function showPosition(position) {
setupMap(position.coords.latitude, position.coords.longitude);
}
function setupMap(lat, lon) {
var map = L.map('map').setView([lat, lon], 13);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 20
}).addTo(map);
var marker = L.marker([lat, lon]).addTo(map);
map.on('click', function(e) {
var coord = e.latlng;
var lat = coord.lat;
var lng = coord.lng;
var newLatLng = new L.LatLng(lat, lng);
marker.setLatLng(newLatLng);
$('#coordinates').val(lat + ',' + lng);
});
}
window.onload = function() {
{/literal}{if $d['coordinates']}
setupMap({$d['coordinates']});
{else}
getLocation();
{/if}{literal}
}
</script>
{/literal}
</div>
{include file="sections/footer.tpl"}

64
ui/ui/customers-map.tpl Normal file
View File

@ -0,0 +1,64 @@
{include file="sections/header.tpl"}
<div class="container-fluid">
<!-- Map container div -->
<div class="card">
<div id="map" class="well card-body" style="width: '100%'; height: 78vh; margin: 20px auto"></div>
</div>
{literal}
<script>
function getLocation() {
if (window.location.protocol == "https:" && navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
setupMap(51.505, -0.09);
}
}
function showPosition(position) {
setupMap(position.coords.latitude, position.coords.longitude);
}
function setupMap(lat, lon) {
var map = L.map('map').setView([lat, lon], 13);
var group = L.featureGroup().addTo(map);
var customers = {/literal}{$customers|json_encode}{literal};
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 20
}).addTo(map);
customers.forEach(function(customer) {
var name = customer.id;
var name = customer.name;
var info = customer.info;
var direction = customer.direction;
var coordinates = customer.coordinates;
var balance = customer.balance;
var address = customer.address;
// Create a popup for the marker
var popupContent = "<strong>Name</strong>: " + name + "<br>" +
"<strong>Info</strong>: " + info + "<br>" +
"<strong>Balance</strong>: " + balance + "<br>" +
"<strong>Address</strong>: " + address + "<br>" +
"<a href='{/literal}{$_url}{literal}customers/view/"+ customer.id +"'>More Info</a> &bull; " +
"<a href='https://www.google.com/maps/dir//" + direction + "' target='maps'>Get Direction</a><br>";
// Add marker to map
var marker = L.marker(JSON.parse(coordinates)).addTo(group);
marker.bindTooltip(name, { permanent: true }).bindPopup(popupContent);
});
map.fitBounds(group.getBounds());
}
window.onload = function() {
getLocation();
}
</script>
{/literal}
</div>
{include file="sections/footer.tpl"}

263
ui/ui/customers-view.tpl Normal file
View File

@ -0,0 +1,263 @@
{include file="sections/header.tpl"}
<div class="container-fluid">
<div class="row">
<div class="col-sm-4 col-md-4">
<div class="card card-primary">
<div class="card-body card-profile">
<img class="user-img img-responsive img-circle"
src="https://robohash.org/{$d['id']}?set=set3&size=100x100&bgset=bg1"
onerror="this.src='{$UPLOAD_PATH}/user.default.jpg'" alt="avatar">
<h3 class="profile-username text-center">{$d['fullname']}</h3>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{Lang::T('Username')}</b> <span class="pull-right">{$d['username']}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Phone Number')}</b> <span class="pull-right">{$d['phonenumber']}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Email')}</b> <span class="pull-right">{$d['email']}</span>
</li>
</ul>
<!--<p class="text-muted">{Lang::nl2br($d['address'])}</p>-->
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
<b>{Lang::T('Password')}</b> <input type="password" value="{$d['password']}"
style=" border: 0px; text-align: right;" class="pull-right"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
onclick="this.select()">
</li>
{if $d['pppoe_password'] != ''}
<li class="list-group-item">
<b>PPPOE {Lang::T('Password')}</b> <input type="password" value="{$d['pppoe_password']}"
style=" border: 0px; text-align: right;" class="pull-right"
onmouseleave="this.type = 'password'" onmouseenter="this.type = 'text'"
onclick="this.select()">
</li>
{/if}
<!--Customers Attributes view start -->
{if $customFields}
{foreach $customFields as $customField}
<li class="list-group-item">
<b>{$customField.field_name}</b> <span class="pull-right">
{if strpos($customField.field_value, ':0') === false}
{$customField.field_value}
{else}
<b>{Lang::T('Paid')}</b>
{/if}
</span>
</li>
{/foreach}
{/if}
<!--Customers Attributes view end -->
<li class="list-group-item">
<b>{Lang::T('Service Type')}</b> <span class="pull-right">{Lang::T($d['service_type'])}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Account')}</b> <span class="pull-right">{Lang::T($d['account'])}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Account Type')}</b> <span class="pull-right">{Lang::T($d['account_type'])}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Balance')}</b> <span class="pull-right">{Lang::moneyFormat($d['balance'])}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Auto Renewal')}</b> <span class="pull-right">{if
$d['auto_renewal']}yes{else}no
{/if}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Created On')}</b> <span
class="pull-right">{Lang::dateTimeFormat($d['created_at'])}</span>
</li>
<li class="list-group-item">
<b>{Lang::T('Last Login')}</b> <span
class="pull-right">{Lang::dateTimeFormat($d['last_login'])}</span>
</li>
{if $d['coordinates']}
<li class="list-group-item">
<b>{Lang::T('Coordinates')}</b> <span class="pull-right">
<i class="glyphicon glyphicon-road"></i> <a style="color: black;"
href="https://www.google.com/maps/dir//{$d['coordinates']}/" target="_blank">Get
Directions</a>
</span>
<div id="map" style="width: '100%'; height: 100px;"></div>
</li>
{/if}
</ul>
<div class="row">
<div class="col-xs-4 mb-3">
<a href="{$_url}customers/delete/{$d['id']}" id="{$d['id']}"
class="btn btn-danger btn-block btn-sm"
onclick="return confirm('{Lang::T('Delete')}?')"><span class="fa fa-trash"></span></a>
</div>
<div class="col-xs-8">
<a href="{$_url}customers/edit/{$d['id']}"
class="btn btn-warning btn-sm btn-block">{Lang::T('Edit')}</a>
</div>
</div>
</div>
</div>
{foreach $packages as $package}
<div class="card card-{if $package['status']=='on'}success{else}danger{/if}">
<div class="card-body card-profile">
<h4 class="text-center">{$package['type']} - {$package['namebp']}</h4>
<ul class="list-group list-group-unbordered">
<li class="list-group-item">
{Lang::T('Active')} <span class="pull-right">{if
$package['status']=='on'}yes{else}no
{/if}</span>
</li>
<li class="list-group-item">
{Lang::T('Type')} <span class="pull-right">
{if $package['prepaid'] eq yes}Prepaid{else}<b>Postpaid</b>{/if}</span>
</li>
<li class="list-group-item">
{Lang::T('Created On')} <span
class="pull-right">{Lang::dateAndTimeFormat($package['recharged_on'],$package['recharged_time'])}</span>
</li>
<li class="list-group-item">
{Lang::T('Expires On')} <span class="pull-right">{Lang::dateAndTimeFormat($package['expiration'],
$package['time'])}</span>
</li>
<li class="list-group-item">
{$package['routers']} <span class="pull-right">{$package['method']}</span>
</li>
</ul>
<div class="row">
<div class="col-xs-4">
<a href="{$_url}customers/deactivate/{$d['id']}/{$package['plan_id']}" id="{$d['id']}"
class="btn btn-danger btn-block btn-sm"
onclick="return confirm('This will deactivate Customer Plan, and make it expired')">{Lang::T('Deactivate')}</a>
</div>
<div class="col-xs-8">
<a href="{$_url}customers/recharge/{$d['id']}/{$package['plan_id']}"
class="btn btn-success btn-sm btn-block">{Lang::T('Recharge')}</a>
</div>
</div>
</div>
</div>
{/foreach}
<div class="row">
<div class="col-xs-4">
<a href="{$_url}customers/list" class="btn btn-primary btn-sm btn-block">{Lang::T('Back')}</a>
</div>
<div class="col-xs-4">
<a href="{$_url}customers/sync/{$d['id']}"
onclick="return confirm('This will sync Customer to Mikrotik?')"
class="btn btn-info btn-sm btn-block">{Lang::T('Sync')}</a>
</div>
<div class="col-xs-4">
<a href="{$_url}message/send/{$d['id']}" class="btn btn-success btn-sm btn-block">{Lang::T('Send
Message')}</a>
</div>
</div>
</div>
<div class="col-sm-8 col-md-8">
<div class="card">
<div class="card-body">
<ul class="nav nav-tabs">
<li role="presentation" {if $v=='order' }class="nav-item" {/if}><a class="nav-link active"
href="{$_url}customers/view/{$d['id']}/order">30 {Lang::T('Order History')}</a></li>
<li role="presentation" {if $v=='activation' }class="nav-item" {/if}><a class="nav-link active"
href="{$_url}customers/view/{$d['id']}/activation">30 {Lang::T('Activation History')}</a></li>
</ul>
<div class="table-responsive" style="background-color: white;">
<table id="datatable" class="table table-bordered table-striped">
{if Lang::arrayCount($activation)}
<thead>
<tr>
<th>{Lang::T('Invoice')}</th>
<th>{Lang::T('Username')}</th>
<th>{Lang::T('Plan Name')}</th>
<th>{Lang::T('Plan Price')}</th>
<th>{Lang::T('Type')}</th>
<th>{Lang::T('Created On')}</th>
<th>{Lang::T('Expires On')}</th>
<th>{Lang::T('Method')}</th>
</tr>
</thead>
<tbody>
{foreach $activation as $ds}
<tr onclick="window.location.href = '{$_url}plan/view/{$ds['id']}'" style="cursor:pointer;">
<td>{$ds['invoice']}</td>
<td>{$ds['username']}</td>
<td>{$ds['plan_name']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td>{$ds['type']}</td>
<td class="text-success">{Lang::dateAndTimeFormat($ds['recharged_on'],$ds['recharged_time'])}
</td>
<td class="text-danger">{Lang::dateAndTimeFormat($ds['expiration'],$ds['time'])}</td>
<td>{$ds['method']}</td>
</tr>
{/foreach}
</tbody>
{/if}
{if Lang::arrayCount($order)}
<thead>
<tr>
<th>{Lang::T('Plan Name')}</th>
<th>{Lang::T('Gateway')}</th>
<th>{Lang::T('Routers')}</th>
<th>{Lang::T('Type')}</th>
<th>{Lang::T('Plan Price')}</th>
<th>{Lang::T('Created On')}</th>
<th>{Lang::T('Expires On')}</th>
<th>{Lang::T('Date Done')}</th>
<th>{Lang::T('Method')}</th>
</tr>
</thead>
<tbody>
{foreach $order as $ds}
<tr>
<td>{$ds['plan_name']}</td>
<td>{$ds['gateway']}</td>
<td>{$ds['routers']}</td>
<td>{$ds['payment_channel']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
<td class="text-primary">{Lang::dateTimeFormat($ds['created_date'])}</td>
<td class="text-danger">{Lang::dateTimeFormat($ds['expired_date'])}</td>
<td class="text-success">{if $ds['status']!=1}{Lang::dateTimeFormat($ds['paid_date'])}{/if}</td>
<td>{if $ds['status']==1}{Lang::T('UNPAID')}
{elseif $ds['status']==2}{Lang::T('PAID')}
{elseif $ds['status']==3}{$_L['FAILED']}
{elseif $ds['status']==4}{Lang::T('CANCELED')}
{elseif $ds['status']==5}{Lang::T('UNKNOWN')}
{/if}</td>
</tr>
{/foreach}
</tbody>
{/if}
</table>
</div>
{include file="pagination.tpl"}
</div>
</div>
</div>
</div>
{if $d['coordinates']}
{literal}
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
<script>
function setupMap(lat, lon) {
var map = L.map('map').setView([lat, lon], 17);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_all/{z}/{x}/{y}.png', {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 20
}).addTo(map);
var marker = L.marker([lat, lon]).addTo(map);
}
window.onload = function() {
{/literal}setupMap({$d['coordinates']});{literal}
}
</script>
{/literal}
{/if}
</div>
{include file="sections/footer.tpl"}

499
ui/ui/dashboard.tpl Normal file
View File

@ -0,0 +1,499 @@
{include file="sections/header.tpl"}
<div class="container-fluid">
<style>
.icon i{
font-size: 36px;
}
</style>
<div class="row">
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-secondary card-border" style="background:#3444d5 !important;"></div>
<div class="card-body box-style">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class=" num-text text-black font-w200 fs-48">{$_c['currency_code']}{number_format($iday,0,$_c['dec_point'],$_c['thousands_sep'])}</h4>
<p class="fs-14">{Lang::T('Income Today')}</p>
</div>
<div class="icon" style="color: #864AD1;">
<i class="fas fa-dollar-sign"></i>
</div>
</div>
<div class="">
<a href="{$_url}reports/by-date" class="small-box-footer" style="color: #fc5130;">{Lang::T('View Reports')} <i
class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-warning card-border"></div>
<div class="card-body">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class="num-text text-black font-w200 fs-48">{$_c['currency_code']}{number_format($imonth,0,$_c['dec_point'],$_c['thousands_sep'])}</h4>
<p class="fs-14">{Lang::T('Income This Month')}</p>
</div>
<!--<div class="icon" style="color: #FFB930;">
<i class="fa fa-chart-bar"></i>
</div>-->
</div>
<div class="">
<a href="{$_url}reports/by-period" class="small-box-footer" style="color: #fc5130;">{Lang::T('View Reports')} <i
class="fa fa-arrow-circle-right"></i></a>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-success card-border"></div>
<div class="card-body box-style">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class="num-text text-black font-w200 fs-48">{$u_act}/{$u_all}</h4>
<p class="fs-14">{Lang::T('Users Active')}</p>
</div>
<div class="icon" style="color: #20F174;">
<i class="fa fa-users"></i>
</div>
</div>
<div class="">
<a href="{$_url}plan/list" class="small-box-footer" style="color: #fc5130;">{Lang::T('View All')} <i
class="fa fa-arrow-circle-right"></i></a>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-info card-border"></div>
<div class="card-body box-style">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class="num-text text-black font-w200 fs-48">{$c_all}</h4>
<p class="fs-14">{Lang::T('Total Users')}</p>
</div>
<div class="icon" style="color: #3ECDFF;">
<i class="fa fa-users"></i>
</div>
</div>
<div class="" >
<a href="{$_url}customers/list" class="small-box-footer" style="color: #fc5130;">{Lang::T('View All')} <i
class="fa fa-arrow-circle-right"></i></a>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-secondary card-border" style="background:#3444d5 !important;"></div>
<div class="card-body box-style">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class=" num-text text-black font-w200 fs-48" id="total-online-users"></h4>
<p class="fs-14">{Lang::T('Online Users')}</p>
</div>
<div class="icon" style="color: #864AD1;">
<i class="fas fa-users"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-warning card-border"></div>
<div class="card-body">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class="num-text text-black font-w200 fs-48" id="total_data"></h4>
<p class="fs-14">{Lang::T('Data Usage')}</p>
</div>
<div class="icon" style="color: #FFB930;">
<i class="fas fa-signal"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-success card-border"></div>
<div class="card-body box-style">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class="num-text text-black font-w200 fs-48" id="online-hotspot-users"></h4>
<p class="fs-14">{Lang::T('Online Hotspot Users')}</p>
</div>
<div class="icon" style="color: #20F174;">
<i class="fas fa-wifi"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-xxl-3 col-lg-6 col-sm-6">
<div class="card card-bd">
<div class="bg-info card-border"></div>
<div class="card-body box-style">
<div class="media align-items-center col">
<div class="inner media-body me-3">
<h4 class="num-text text-black font-w200 fs-48" id="online-pppoe-users"></h4>
<p class="fs-14">{Lang::T('Online PPPoE Users')}</p>
</div>
<div class="icon" style="color: #3ECDFF;">
<i class="fas fa-network-wired"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<!-- solid sales graph -->
{if $_c['hide_mrc'] != 'yes'}
<div class="card">
<div class="card-header">
<i class="fa fa-th"></i>
<h3 class="card-title">{Lang::T('Monthly Customers')}</h3>
<div class="card-tools pull-right">
<a href="{$_url}dashboard&refresh" class="btn bg-teal btn-xsm"><i
class="fa fa-refresh"></i>
</a>
</div>
</div>
<!-- <div class="card-body text-center pb-0 px-2 pt-2">
<div id="widgetChart1" class="widgetChart1 dashboard-chart"></div>
</div> -->
<div class="card-body border-radius-none">
<canvas class="chart" id="chart" style="height: 200px;"></canvas>
</div>
</div>
{/if}
</div>
<div class="col-md-6">
<!-- solid sales graph -->
{if $_c['hide_tms'] != 'yes'}
<div class="card card-solid ">
<div class="card-header">
<i class="fa fa-inbox"></i>
<h3 class="card-title">{Lang::T('Total Monthly Sales')}</h3>
<div class="card-tools pull-right">
<a href="{$_url}dashboard&refresh" class="btn bg-teal btn-sm"><i
class="fa fa-refresh"></i>
</a>
</div>
</div>
<!-- <div class="card-body pb-0 px-2 pt-2">
<div id="chartTimeline" class="timeline-chart"></div>
</div> -->
<div class="card-body border-radius-none">
<canvas id="salesChart" class="monthly-project-chart" style="height: 200px;"></canvas>
</div>
</div>
{/if}
</div>
<div class="col-md-12">
{if $_c['hide_uet'] != 'yes'}
<div class="card card-warning card-hovered project-stats table-responsive">
<div class="card-header">
<h3 class="card-title">{Lang::T('Expired Users')}</h3></div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>{Lang::T('Fullname')}</th>
<th>{Lang::T('Username')}</th>
<th>{Lang::T('Account')}</th>
<th>{Lang::T('Created On')}</th>
<th>{Lang::T('Expires On')}</th>
<th>{Lang::T('Router')}</th>
<th>{Lang::T('Package')}</th>
<th>{Lang::T('Action')}</th>
</tr>
</thead>
<tbody>
{foreach $expire as $expired}
<tr>
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['fullname']}</a></td>
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['username']}</a></td>
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['account']}</a></td>
<td>{Lang::dateAndTimeFormat($expired['recharged_on'],$expired['recharged_time'])}
</td>
<td>{Lang::dateAndTimeFormat($expired['expiration'],$expired['time'])}
</td>
<td>{$expired['routers']}</td>
<td>{$expired['namebp']}</td>
<td>
<a href="{$_url}plan/recharge/{$expired['customer_id']}" id="{$expired['customer_id']}" style="margin: 0px;color:black;"
class="btn btn-warning btn-xs">{Lang::T('Recharge')}</a>
</td>
</tr>
</tbody>
{/foreach}
</table>
</div>
&nbsp; {include file="pagination.tpl"}
</div>
</div>
{/if}
</div>
<div class="col-md-6">
{if $_c['disable_voucher'] != 'yes' && $stocks['unused']>0 || $stocks['used']>0}
{if $_c['hide_vs'] != 'yes'}
<div class="card card-primary card-hovered project-stats">
<div class="card-header">Vouchers Stock</div>
<div class="table-responsive">
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>{Lang::T('Plan Name')}</th>
<th>unused</th>
<th>used</th>
</tr>
</thead>
<tbody>
{foreach $plans as $stok}
<tr>
<td>{$stok['name_plan']}</td>
<td>{$stok['unused']}</td>
<td>{$stok['used']}</td>
</tr>
</tbody>
{/foreach}
<tr>
<td>Total</td>
<td>{$stocks['unused']}</td>
<td>{$stocks['used']}</td>
</tr>
</table>
</div>
</div>
{/if}
{/if}
</div>
</div>
<div class="row">
<div class="col-md-6">
{if $_c['hide_aui'] != 'yes'}
<div class="card card-hovered activities">
<div class="card-header"><h3 class="card-title">{Lang::T('All Users Insights')}</h3></div>
<div class="card-body">
<canvas id="userRechargesChart" style="height: 600px;"></canvas>
</div>
</div>
{/if}
</div>
<div class="col-md-6">
{if $_c['hide_al'] != 'yes'}
<div class="card card-info card-hovered activities" style="height: 600px;">
<div class="card-header"><a class="card-title" href="{$_url}logs">{Lang::T('Activity Log')}</a></div>
<div class="card-body">
<div id="DZ_W_TimeLine" class="widget-timeline dz-scroll ps ps--active-y" style="height: 460px;">
<ul class="timeline">
{foreach $dlog as $dlogs}
<li class="primary">
<div class="timeline-badge primary"></div>
<div class="timeline-panel text-muted">
<span class="point"></span>
<span class="time small text-muted">{Lang::timeElapsed($dlogs['date'],true)}</span>
<p>{$dlogs['description']}</p>
</div>
</li>
{/foreach}
</ul>
</div>
</div>
</div>
{/if}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.1/dist/chart.min.js"></script>
<script type="text/javascript">
{if $_c['hide_mrc'] != 'yes'}
{literal}
document.addEventListener("DOMContentLoaded", function() {
var counts = JSON.parse('{/literal}{$monthlyRegistered|json_encode}{literal}');
var monthNames = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
var labels = [];
var data = [];
for (var i = 1; i <= 12; i++) {
var month = counts.find(count => count.date === i);
labels.push(month ? monthNames[i - 1] : monthNames[i - 1].substring(0, 3));
data.push(month ? month.count : 0);
}
var ctx = document.getElementById('chart').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Registered Members',
data: data,
backgroundColor: '#fc5130',
borderColor: '#fc5130',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: true,
grid: {
color: 'rgba(0, 0, 0, 0.1)'
}
}
}
}
});
});
{/literal}
{/if}
{if $_c['hide_tmc'] != 'yes'}
{literal}
document.addEventListener("DOMContentLoaded", function() {
var monthlySales = JSON.parse('{/literal}{$monthlySales|json_encode}{literal}');
var monthNames = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
var labels = [];
var data = [];
for (var i = 1; i <= 12; i++) {
var month = findMonthData(monthlySales, i);
labels.push(month ? monthNames[i - 1] : monthNames[i - 1].substring(0, 3));
data.push(month ? month.totalSales : 0);
}
var ctx = document.getElementById('salesChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
//type: 'radialBar',
data: {
labels: labels,
datasets: [{
label: 'Monthly Sales',
data: data,
backgroundColor: '#fc5130', // Customize the background color
borderColor: '#fc5130', // Customize the border color
borderWidth: 2
}]
},
options: {
responsive: true,
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: true,
grid: {
color: 'rgba(0, 0, 0, 0.1)'
}
}
}
}
});
});
function findMonthData(monthlySales, month) {
for (var i = 0; i < monthlySales.length; i++) {
if (monthlySales[i].month === month) {
return monthlySales[i];
}
}
return null;
}
{/literal}
{/if}
{if $_c['hide_aui'] != 'yes'}
{literal}
document.addEventListener("DOMContentLoaded", function() {
// Get the data from PHP and assign it to JavaScript variables
var u_act = '{/literal}{$u_act}{literal}';
var c_all = '{/literal}{$c_all}{literal}';
var u_all = '{/literal}{$u_all}{literal}';
//lets calculate the inactive users as reported
var expired = u_all - u_act;
var inactive = c_all - u_all;
// Create the chart data
var data = {
labels: ['Active Users', 'Expired Users', 'Inactive Users'],
datasets: [{
label: 'User Recharges',
data: [parseInt(u_act), parseInt(expired), parseInt(inactive)],
backgroundColor: ['rgba(4, 191, 13)', 'rgba(191, 35, 4)', 'rgba(0, 0, 255, 0.5'],
borderColor: ['rgba(0, 255, 0, 1)', 'rgba(255, 99, 132, 1)', 'rgba(0, 0, 255, 0.7'],
borderWidth: 1
}]
};
// Create chart options
var options = {
responsive: true,
aspectRatio: 1,
plugins: {
legend: {
position: 'bottom',
labels: {
boxWidth: 15
}
}
}
};
// Get the canvas element and create the chart
var ctx = document.getElementById('userRechargesChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'pie',
data: data,
options: options
});
});
{/literal}
{/if}
</script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url: "{$_url}onlineusers/summary", // Adjust this URL to your actual endpoint
type: 'GET',
dataType: 'json', // Ensure the expected response is JSON
success: function(data) {
console.log('Data fetched successfully:', data);
// Check if data is null or missing properties and set defaults to 0
$('#total-online-users').text(data.total_users || 0);
$('#online-hotspot-users').text(data.hotspot_users || 0);
$('#online-pppoe-users').text(data.ppp_users || 0);
$('#total_data').text(data.total_bytes || 0);
},
error: function(error) {
console.log('Error fetching data:', error);
// Set all values to 0 in case of an error
$('#total-online-users').text(0);
$('#online-hotspot-users').text(0);
$('#online-pppoe-users').text(0);
$('#total_data').text(0);
}
});
});
</script>
{include file="sections/footer.tpl"}