default widgets

This commit is contained in:
iBNu Maksum 2025-02-17 13:54:18 +07:00
parent 69a7d842e0
commit 4bb5361d4b
No known key found for this signature in database
GPG Key ID: 7FC82848810579E5
15 changed files with 338 additions and 235 deletions

View File

@ -33,13 +33,19 @@ if (date("d") >= $reset_day) {
}
$current_date = date('Y-m-d');
$ui->assign('start_date', $start_date);
$ui->assign('current_date', $current_date);
$widgets = ORM::for_table('tbl_widgets')->selects("enabled", 1)->order_by_asc("orders")->findArray();
$count = count($widgets);
for ($i = 0; $i < $count; $i++) {
try{
require_once $WIDGET_PATH . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php";
$widgets[$i]['content'] = (new $widgets[$i]['widget'])->getWidget($widgets[$i]);;
if(file_exists($WIDGET_PATH . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php")){
require_once $WIDGET_PATH . DIRECTORY_SEPARATOR . $widgets[$i]['widget'].".php";
$widgets[$i]['content'] = (new $widgets[$i]['widget'])->getWidget($widgets[$i]);
}else{
$widgets[$i]['content'] = "Widget not found";
}
} catch (Throwable $e) {
$widgets[$i]['content'] = $e->getMessage();
}
@ -47,139 +53,4 @@ for ($i = 0; $i < $count; $i++) {
$ui->assign('widgets', $widgets);
run_hook('view_dashboard'); #HOOK
$ui->display('admin/dashboard_widget.tpl');
die();
//activity log
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->find_many();
$ui->assign('dlog', $dlog);
$log = ORM::for_table('tbl_logs')->count();
$ui->assign('log', $log);
if ($config['hide_vs'] != 'yes') {
$cacheStocksfile = $CACHE_PATH . File::pathFixer('/VoucherStocks.temp');
$cachePlanfile = $CACHE_PATH . File::pathFixer('/VoucherPlans.temp');
//Cache for 5 minutes
if (file_exists($cacheStocksfile) && time() - filemtime($cacheStocksfile) < 600) {
$stocks = json_decode(file_get_contents($cacheStocksfile), true);
$plans = json_decode(file_get_contents($cachePlanfile), true);
} else {
// Count stock
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
$plans = array();
$stocks = array("used" => 0, "unused" => 0);
$n = 0;
foreach ($tmp as $plan) {
$unused = ORM::for_table('tbl_voucher')
->where('id_plan', $plan['id'])
->where('status', 0)->count();
$used = ORM::for_table('tbl_voucher')
->where('id_plan', $plan['id'])
->where('status', 1)->count();
if ($unused > 0 || $used > 0) {
$plans[$n]['name_plan'] = $plan['name_plan'];
$plans[$n]['unused'] = $unused;
$plans[$n]['used'] = $used;
$stocks["unused"] += $unused;
$stocks["used"] += $used;
$n++;
}
}
file_put_contents($cacheStocksfile, json_encode($stocks));
file_put_contents($cachePlanfile, json_encode($plans));
}
}
$cacheMRfile = File::pathFixer('/monthlyRegistered.temp');
//Cache for 1 hour
if (file_exists($cacheMRfile) && time() - filemtime($cacheMRfile) < 3600) {
$monthlyRegistered = json_decode(file_get_contents($cacheMRfile), true);
} else {
//Monthly Registered Customers
$result = ORM::for_table('tbl_customers')
->select_expr('MONTH(created_at)', 'month')
->select_expr('COUNT(*)', 'count')
->where_raw('YEAR(created_at) = YEAR(NOW())')
->group_by_expr('MONTH(created_at)')
->find_many();
$monthlyRegistered = [];
foreach ($result as $row) {
$monthlyRegistered[] = [
'date' => $row->month,
'count' => $row->count
];
}
file_put_contents($cacheMRfile, json_encode($monthlyRegistered));
}
$cacheMSfile = $CACHE_PATH . File::pathFixer('/monthlySales.temp');
//Cache for 12 hours
if (file_exists($cacheMSfile) && time() - filemtime($cacheMSfile) < 43200) {
$monthlySales = json_decode(file_get_contents($cacheMSfile), true);
} else {
// Query to retrieve monthly data
$results = ORM::for_table('tbl_transactions')
->select_expr('MONTH(recharged_on)', 'month')
->select_expr('SUM(price)', 'total')
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
->where_not_equal('method', 'Customer - Balance')
->where_not_equal('method', 'Recharge Balance - Administrator')
->group_by_expr('MONTH(recharged_on)')
->find_many();
// Create an array to hold the monthly sales data
$monthlySales = array();
// Iterate over the results and populate the array
foreach ($results as $result) {
$month = $result->month;
$totalSales = $result->total;
$monthlySales[$month] = array(
'month' => $month,
'totalSales' => $totalSales
);
}
// Fill in missing months with zero sales
for ($month = 1; $month <= 12; $month++) {
if (!isset($monthlySales[$month])) {
$monthlySales[$month] = array(
'month' => $month,
'totalSales' => 0
);
}
}
// Sort the array by month
ksort($monthlySales);
// Reindex the array
$monthlySales = array_values($monthlySales);
file_put_contents($cacheMSfile, json_encode($monthlySales));
}
if ($config['router_check']) {
$routeroffs = ORM::for_table('tbl_routers')->selects(['id', 'name', 'last_seen'])->where('status', 'Offline')->where('enabled', '1')->order_by_desc('name')->find_array();
$ui->assign('routeroffs', $routeroffs);
}
$timestampFile = "$UPLOAD_PATH/cron_last_run.txt";
if (file_exists($timestampFile)) {
$lastRunTime = file_get_contents($timestampFile);
$ui->assign('run_date', date('Y-m-d h:i:s A', $lastRunTime));
}
// Assign the monthly sales data to Smarty
$ui->assign('start_date', $start_date);
$ui->assign('current_date', $current_date);
$ui->assign('monthlySales', $monthlySales);
$ui->assign('xfooter', '');
$ui->assign('monthlyRegistered', $monthlyRegistered);
$ui->assign('stocks', $stocks);
$ui->assign('plans', $plans);
run_hook('view_dashboard'); #HOOK
$ui->display('admin/dashboard.tpl');
$ui->display('admin/dashboard_widget.tpl');

View File

@ -0,0 +1,15 @@
<?php
class activity_log
{
public function getWidget()
{
global $config, $ui, $current_date, $start_date;
$dlog = ORM::for_table('tbl_logs')->limit(5)->order_by_desc('id')->findArray();
$ui->assign('dlog', $dlog);
// $log = ORM::for_table('tbl_logs')->count();
// $ui->assign('log', $log);
return $ui->fetch('widget/activity_log.tpl');
}
}

View File

@ -0,0 +1,17 @@
<?php
class cron_monitor
{
public function getWidget()
{
global $UPLOAD_PATH,$ui;
$timestampFile = "$UPLOAD_PATH/cron_last_run.txt";
if (file_exists($timestampFile)) {
$lastRunTime = file_get_contents($timestampFile);
$ui->assign('run_date', date('Y-m-d h:i:s A', $lastRunTime));
}
return $ui->fetch('widget/cron_monitor.tpl');
}
}

View File

@ -0,0 +1,17 @@
<?php
class default_info_row
{
public function getWidget()
{
global $config,$ui;
if ($config['enable_balance'] == 'yes'){
$cb = ORM::for_table('tbl_customers')->whereGte('balance', 0)->sum('balance');
$ui->assign('cb', $cb);
}
return $ui->fetch('widget/default_info_row.tpl');
}
}

View File

@ -0,0 +1,28 @@
<?php
class graph_customers_insight
{
public function getWidget()
{
global $CACHE_PATH,$ui;
$u_act = ORM::for_table('tbl_user_recharges')->where('status', 'on')->count();
if (empty($u_act)) {
$u_act = '0';
}
$ui->assign('u_act', $u_act);
$u_all = ORM::for_table('tbl_user_recharges')->count();
if (empty($u_all)) {
$u_all = '0';
}
$ui->assign('u_all', $u_all);
$c_all = ORM::for_table('tbl_customers')->count();
if (empty($c_all)) {
$c_all = '0';
}
$ui->assign('c_all', $c_all);
return $ui->fetch('widget/graph_customers_insight.tpl');
}
}

View File

@ -0,0 +1,34 @@
<?php
class graph_monthly_registered_customers
{
public function getWidget()
{
global $CACHE_PATH,$ui;
$cacheMRfile = File::pathFixer('/monthlyRegistered.temp');
//Cache for 1 hour
if (file_exists($cacheMRfile) && time() - filemtime($cacheMRfile) < 3600) {
$monthlyRegistered = json_decode(file_get_contents($cacheMRfile), true);
} else {
//Monthly Registered Customers
$result = ORM::for_table('tbl_customers')
->select_expr('MONTH(created_at)', 'month')
->select_expr('COUNT(*)', 'count')
->where_raw('YEAR(created_at) = YEAR(NOW())')
->group_by_expr('MONTH(created_at)')
->find_many();
$monthlyRegistered = [];
foreach ($result as $row) {
$monthlyRegistered[] = [
'date' => $row->month,
'count' => $row->count
];
}
file_put_contents($cacheMRfile, json_encode($monthlyRegistered));
}
$ui->assign('monthlyRegistered', $monthlyRegistered);
return $ui->fetch('widget/graph_monthly_registered_customers.tpl');
}
}

View File

@ -0,0 +1,60 @@
<?php
class graph_monthly_sales
{
public function getWidget()
{
global $CACHE_PATH, $ui;
$cacheMSfile = $CACHE_PATH . File::pathFixer('/monthlySales.temp');
//Cache for 12 hours
if (file_exists($cacheMSfile) && time() - filemtime($cacheMSfile) < 43200) {
$monthlySales = json_decode(file_get_contents($cacheMSfile), true);
} else {
// Query to retrieve monthly data
$results = ORM::for_table('tbl_transactions')
->select_expr('MONTH(recharged_on)', 'month')
->select_expr('SUM(price)', 'total')
->where_raw("YEAR(recharged_on) = YEAR(CURRENT_DATE())") // Filter by the current year
->where_not_equal('method', 'Customer - Balance')
->where_not_equal('method', 'Recharge Balance - Administrator')
->group_by_expr('MONTH(recharged_on)')
->find_many();
// Create an array to hold the monthly sales data
$monthlySales = array();
// Iterate over the results and populate the array
foreach ($results as $result) {
$month = $result->month;
$totalSales = $result->total;
$monthlySales[$month] = array(
'month' => $month,
'totalSales' => $totalSales
);
}
// Fill in missing months with zero sales
for ($month = 1; $month <= 12; $month++) {
if (!isset($monthlySales[$month])) {
$monthlySales[$month] = array(
'month' => $month,
'totalSales' => 0
);
}
}
// Sort the array by month
ksort($monthlySales);
// Reindex the array
$monthlySales = array_values($monthlySales);
file_put_contents($cacheMSfile, json_encode($monthlySales));
}
$ui->assign('monthlySales', $monthlySales);
return $ui->fetch('widget/graph_monthly_sales.tpl');
}
}

View File

@ -0,0 +1,11 @@
<?php
class html_only
{
public function getWidget($data = null)
{
global $ui;
return $data['content'];
}
}

View File

@ -0,0 +1,16 @@
<?php
class mikrotik_cron_monitor
{
public function getWidget()
{
global $config,$ui;
if ($config['router_check']) {
$routeroffs = ORM::for_table('tbl_routers')->selects(['id', 'name', 'last_seen'])->where('status', 'Offline')->where('enabled', '1')->order_by_desc('name')->find_array();
$ui->assign('routeroffs', $routeroffs);
}
return $ui->fetch('widget/mikrotik_cron_monitor.tpl');
}
}

View File

@ -5,7 +5,7 @@ class top_widget
{
public function getWidget()
{
global $config, $ui, $current_date, $start_date;
global $ui, $current_date, $start_date;
$iday = ORM::for_table('tbl_transactions')
->where('recharged_on', $current_date)
@ -28,11 +28,6 @@ class top_widget
}
$ui->assign('imonth', $imonth);
if ($config['enable_balance'] == 'yes') {
$cb = ORM::for_table('tbl_customers')->whereGte('balance', 0)->sum('balance');
$ui->assign('cb', $cb);
}
$u_act = ORM::for_table('tbl_user_recharges')->where('status', 'on')->count();
if (empty($u_act)) {
$u_act = '0';

View File

@ -0,0 +1,43 @@
<?php
class voucher_stocks
{
public function getWidget()
{
global $CACHE_PATH,$ui;
$cacheStocksfile = $CACHE_PATH . File::pathFixer('/VoucherStocks.temp');
$cachePlanfile = $CACHE_PATH . File::pathFixer('/VoucherPlans.temp');
//Cache for 5 minutes
if (file_exists($cacheStocksfile) && time() - filemtime($cacheStocksfile) < 600) {
$stocks = json_decode(file_get_contents($cacheStocksfile), true);
$plans = json_decode(file_get_contents($cachePlanfile), true);
} else {
// Count stock
$tmp = $v = ORM::for_table('tbl_plans')->select('id')->select('name_plan')->find_many();
$plans = array();
$stocks = array("used" => 0, "unused" => 0);
$n = 0;
foreach ($tmp as $plan) {
$unused = ORM::for_table('tbl_voucher')
->where('id_plan', $plan['id'])
->where('status', 0)->count();
$used = ORM::for_table('tbl_voucher')
->where('id_plan', $plan['id'])
->where('status', 1)->count();
if ($unused > 0 || $used > 0) {
$plans[$n]['name_plan'] = $plan['name_plan'];
$plans[$n]['unused'] = $unused;
$plans[$n]['used'] = $used;
$stocks["unused"] += $unused;
$stocks["used"] += $used;
$n++;
}
}
file_put_contents($cacheStocksfile, json_encode($stocks));
file_put_contents($cachePlanfile, json_encode($plans));
}
$ui->assign('stocks', $stocks);
$ui->assign('plans', $plans);
return $ui->fetch('widget/voucher_stocks.tpl');
}
}

View File

@ -2,11 +2,11 @@
<div class="panel-heading"><a href="{Text::url('logs')}">{Lang::T('Activity Log')}</a></div>
<div class="panel-body">
<ul class="list-unstyled">
{foreach $dlog as $dlogs}
{foreach $dlog as $dl}
<li class="primary">
<span class="point"></span>
<span class="time small text-muted">{Lang::timeElapsed($dlogs['date'],true)}</span>
<p>{$dlogs['description']}</p>
<span class="time small text-muted">{Lang::timeElapsed($dl['date'],true)}</span>
<p>{$dl['description']}</p>
</li>
{/foreach}
</ul>

View File

@ -7,53 +7,51 @@
<script type="text/javascript">
{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;
if (inactive < 0) {
inactive = 0;
}
// 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
}]
};
{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;
if (inactive < 0) {
inactive = 0;
}
// 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
}
// 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
});
// 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}
});
{/literal}
</script>

View File

@ -18,56 +18,54 @@
<script type="text/javascript">
{if $_c['hide_mrc'] != 'yes'}
{literal}
document.addEventListener("DOMContentLoaded", function() {
var counts = JSON.parse('{/literal}{$monthlyRegistered|json_encode}{literal}');
{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 monthNames = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
var labels = [];
var data = [];
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);
}
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: 'rgba(0, 0, 255, 0.5)',
borderColor: 'rgba(0, 0, 255, 0.7)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: true,
grid: {
color: 'rgba(0, 0, 0, 0.1)'
}
var ctx = document.getElementById('chart').getContext('2d');
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Registered Members',
data: data,
backgroundColor: 'rgba(0, 0, 255, 0.5)',
borderColor: 'rgba(0, 0, 255, 0.7)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: true,
grid: {
color: 'rgba(0, 0, 0, 0.1)'
}
}
}
});
}
});
{/literal}
{/if}
});
{/literal}
</script>