Compare commits

...

23 Commits

Author SHA1 Message Date
8db3d6c679 update changelog 2024-02-23 14:44:37 +07:00
ddd7fb49fe Fix invoice 2024-02-23 14:40:47 +07:00
c6a203b1f0 Add Alert Page 2024-02-23 14:20:12 +07:00
6de63bed63 Integrate with PhpNuxBill Printer 2024-02-23 11:39:25 +07:00
9552a14de5 add button print 2024-02-22 18:37:28 +07:00
9d379b3fbd Phpnuxbill android printer support 2024-02-22 18:27:18 +07:00
4f3e5972b0 Merge pull request #112 from Focuslinkstech/Development
Update accounts.php
2024-02-22 11:45:29 +07:00
be65976310 link to settings when hide widget 2024-02-22 11:42:17 +07:00
8728af4332 Add Loading when click submit 2024-02-22 11:41:55 +07:00
07870d05ad Update accounts.php
Fix OTP not sending bug
2024-02-21 11:58:13 +01:00
cee6f8949c Merge branch 'Development' 2024-02-21 16:15:21 +07:00
3bdf44ddbe Merge pull request #111 from Focuslinkstech/Development
Bug Fix: OTP bugs
2024-02-21 16:13:26 +07:00
17c1675b4a Update accounts.php
fix lang function
2024-02-21 10:13:05 +01:00
54d1c4439d Bug Fix: OTP bugs
add phone number validation to prevent invalid phone number, phone number must be 10 digits up

fix issue with updating phone number without OTP
2024-02-21 10:02:31 +01:00
e710bd2862 Merge branch 'Development' 2024-02-21 14:38:09 +07:00
5309cb26db Delete Table Responsive, first Column Freeze 2024-02-21 14:37:44 +07:00
8072fe40eb change burst form 2024-02-21 14:11:19 +07:00
702f2b443c remove multiple spaces 2024-02-21 11:54:22 +07:00
a44190c1c2 delete meta table 2024-02-21 11:11:14 +07:00
3871b51f0f change position table customer field 2024-02-21 11:11:13 +07:00
d9a20f7213 Merge pull request #110 from Focuslinkstech/Development
Update: New Features "Miscellaneous"
2024-02-21 11:10:54 +07:00
a70b954981 Update: New Features "Miscellaneous"
[option] OTP is required when user want to change phone number.

admin can choose option in
 [Miscellaneous]
2024-02-21 00:15:36 +01:00
95e79439a2 delete meta table 2024-02-20 20:01:26 +07:00
45 changed files with 864 additions and 270 deletions

View File

@ -2,6 +2,25 @@
# CHANGELOG
## 2024.2.23
- Integrate with PhpNuxBill Printer
- Fix Invoice
- add admin ID in transaction
## 2024.2.22
- Add Loading when click submit
- link to settings when hide widget
## 2024.2.21
- Fix SQL Installer
- remove multiple space in language
- Change Phone Number require OTP by @Focuslinkstech
- Change burst Form
- Delete Table Responsive, first Column Freeze
## 2024.2.20
- Fix list admin

View File

@ -219,6 +219,23 @@ function sendWhatsapp($phone, $txt)
Message::sendWhatsapp($phone, $txt);
}
function _alert($text, $type = 'success', $url = "home")
{
global $ui;
if(!isset($ui)) return;
if(strlen($url)>4){
if(substr($url,0,4)!="http"){
$url = U.$url;
}
}else{
$url = U.$url;
}
$ui->assign('text', $text);
$ui->assign('type', $type);
$ui->assign('url', $url);
$ui->display('alert.tpl');
}
if(!isset($api_secret)){
$api_secret = $db_password;

View File

@ -181,16 +181,6 @@ CREATE TABLE `tb_languages` (
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
ALTER TABLE `tbl_voucher` ADD `generated_by` INT NOT NULL DEFAULT '0' COMMENT 'id admin' AFTER `status`;
ALTER TABLE `tbl_users` ADD `root` INT NOT NULL DEFAULT '0' COMMENT 'for sub account' AFTER `id`;
ALTER TABLE `tbl_users` CHANGE `user_type` `user_type` ENUM('SuperAdmin','Admin','Report','Agent','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
ALTER TABLE `tbl_users` CHANGE `password` `password` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
ALTER TABLE `tbl_users` ADD `phone` VARCHAR(32) NOT NULL DEFAULT '' AFTER `password`, ADD `email` VARCHAR(128) NOT NULL DEFAULT '' AFTER `phone`, ADD `city` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kota' AFTER `email`, ADD `subdistrict` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kecamatan' AFTER `city`, ADD `ward` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kelurahan' AFTER `subdistrict`;
ALTER TABLE `tbl_customers` ADD `created_by` INT NOT NULL DEFAULT '0' AFTER `auto_renewal`;
ALTER TABLE `tbl_plans` ADD `list_expired` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'address list' AFTER `pool_expired`;
ALTER TABLE `tbl_bandwidth` ADD `burst` VARCHAR(128) NOT NULL DEFAULT '' AFTER `rate_up_unit`;
ALTER TABLE `tbl_appconfig`
ADD PRIMARY KEY (`id`);
@ -200,9 +190,6 @@ ALTER TABLE `tbl_bandwidth`
ALTER TABLE `tbl_customers`
ADD PRIMARY KEY (`id`);
ALTER TABLE `tbl_customers_meta`
ADD PRIMARY KEY (`id`);
ALTER TABLE `tbl_logs`
ADD PRIMARY KEY (`id`);
@ -243,9 +230,6 @@ ALTER TABLE `tbl_bandwidth`
ALTER TABLE `tbl_customers`
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT;
ALTER TABLE `tbl_customers_meta`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `tbl_logs`
MODIFY `id` int(10) NOT NULL AUTO_INCREMENT;
@ -322,3 +306,14 @@ CREATE TABLE tbl_customers_fields (
field_value VARCHAR(255) NOT NULL,
FOREIGN KEY (customer_id) REFERENCES tbl_customers(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
ALTER TABLE `tbl_voucher` ADD `generated_by` INT NOT NULL DEFAULT '0' COMMENT 'id admin' AFTER `status`;
ALTER TABLE `tbl_users` ADD `root` INT NOT NULL DEFAULT '0' COMMENT 'for sub account' AFTER `id`;
ALTER TABLE `tbl_users` CHANGE `user_type` `user_type` ENUM('SuperAdmin','Admin','Report','Agent','Sales') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
ALTER TABLE `tbl_users` CHANGE `password` `password` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
ALTER TABLE `tbl_users` ADD `phone` VARCHAR(32) NOT NULL DEFAULT '' AFTER `password`, ADD `email` VARCHAR(128) NOT NULL DEFAULT '' AFTER `phone`, ADD `city` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kota' AFTER `email`, ADD `subdistrict` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kecamatan' AFTER `city`, ADD `ward` VARCHAR(64) NOT NULL DEFAULT '' COMMENT 'kelurahan' AFTER `subdistrict`;
ALTER TABLE `tbl_customers` ADD `created_by` INT NOT NULL DEFAULT '0' AFTER `auto_renewal`;
ALTER TABLE `tbl_plans` ADD `list_expired` VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'address list' AFTER `pool_expired`;
ALTER TABLE `tbl_bandwidth` ADD `burst` VARCHAR(128) NOT NULL DEFAULT '' AFTER `rate_up_unit`;
ALTER TABLE `tbl_transactions` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;
ALTER TABLE `tbl_user_recharges` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;

View File

@ -38,9 +38,10 @@ Class Admin{
}
}
public static function _info(){
$id = Admin::getID();
$d = ORM::for_table('tbl_users')->find_one($id);
return $d;
public static function _info($id = 0){
if(empty($id) && $id>0){
$id = Admin::getID();
}
return ORM::for_table('tbl_users')->find_one($id);
}
}

View File

@ -12,6 +12,7 @@ class Lang
{
global $_L, $lan_file, $config;
$_L = $_SESSION['Lang'];
$key = preg_replace('/\s+/', ' ', $key);
if (!empty($_L[$key])) {
return $_L[$key];
}

View File

@ -19,7 +19,7 @@ class Package
*/
public static function rechargeUser($id_customer, $router_name, $plan_id, $gateway, $channel)
{
global $_c;
global $config, $admin;
$date_now = date("Y-m-d H:i:s");
$date_only = date("Y-m-d");
$time_only = date("H:i:s");
@ -47,6 +47,9 @@ class Package
$t->method = "$gateway - $channel";
$t->routers = $router_name;
$t->type = "Balance";
if ($channel == 'Administrator') {
$t->admin_id = $admin['id'];
}
$t->save();
$balance_before = $c['balance'];
@ -54,9 +57,9 @@ class Package
$balance = $c['balance'] + $p['price'];
$textInvoice = Lang::getNotifText('invoice_balance');
$textInvoice = str_replace('[[company_name]]', $_c['CompanyName'], $textInvoice);
$textInvoice = str_replace('[[address]]', $_c['address'], $textInvoice);
$textInvoice = str_replace('[[phone]]', $_c['phone'], $textInvoice);
$textInvoice = str_replace('[[company_name]]', $config['CompanyName'], $textInvoice);
$textInvoice = str_replace('[[address]]', $config['address'], $textInvoice);
$textInvoice = str_replace('[[phone]]', $config['phone'], $textInvoice);
$textInvoice = str_replace('[[invoice]]', $inv, $textInvoice);
$textInvoice = str_replace('[[date]]', Lang::dateTimeFormat($date_now), $textInvoice);
$textInvoice = str_replace('[[payment_gateway]]', $gateway, $textInvoice);
@ -67,13 +70,13 @@ class Package
$textInvoice = str_replace('[[name]]', $c['fullname'], $textInvoice);
$textInvoice = str_replace('[[user_name]]', $c['username'], $textInvoice);
$textInvoice = str_replace('[[user_password]]', $c['password'], $textInvoice);
$textInvoice = str_replace('[[footer]]', $_c['note'], $textInvoice);
$textInvoice = str_replace('[[footer]]', $config['note'], $textInvoice);
$textInvoice = str_replace('[[balance_before]]', Lang::moneyFormat($balance_before), $textInvoice);
$textInvoice = str_replace('[[balance]]', Lang::moneyFormat($balance), $textInvoice);
if ($_c['user_notification_payment'] == 'sms') {
if ($config['user_notification_payment'] == 'sms') {
Message::sendSMS($c['phonenumber'], $textInvoice);
} else if ($_c['user_notification_payment'] == 'wa') {
} else if ($config['user_notification_payment'] == 'wa') {
Message::sendWhatsapp($c['phonenumber'], $textInvoice);
}
@ -127,7 +130,7 @@ class Package
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p, "$date_exp $time");
}else{
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
@ -146,6 +149,9 @@ class Package
$b->method = "$gateway - $channel";
$b->routers = $router_name;
$b->type = "Hotspot";
if ($channel == 'Administrator') {
$b->admin_id = $admin['id'];
}
$b->save();
// insert table transactions
@ -161,11 +167,14 @@ class Package
$t->method = "$gateway - $channel";
$t->routers = $router_name;
$t->type = "Hotspot";
if ($channel == 'Administrator') {
$t->admin_id = $admin['id'];
}
$t->save();
} else {
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p, "$date_exp $time");
}else{
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removeHotspotUser($client, $c['username']);
Mikrotik::removeHotspotActiveUser($client, $c['username']);
@ -185,6 +194,9 @@ class Package
$d->method = "$gateway - $channel";
$d->routers = $router_name;
$d->type = "Hotspot";
if ($channel == 'Administrator') {
$d->admin_id = $admin['id'];
}
$d->save();
// insert table transactions
@ -200,6 +212,9 @@ class Package
$t->method = "$gateway - $channel";
$t->routers = $router_name;
$t->type = "Hotspot";
if ($channel == 'Administrator') {
$t->admin_id = $admin['id'];
}
$t->save();
}
Message::sendTelegram("#u$c[username] #buy #Hotspot \n" . $p['name_plan'] .
@ -231,7 +246,7 @@ class Package
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p, "$date_exp $time");
}else{
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
@ -250,6 +265,9 @@ class Package
$b->method = "$gateway - $channel";
$b->routers = $router_name;
$b->type = "PPPOE";
if ($channel == 'Administrator') {
$b->admin_id = $admin['id'];
}
$b->save();
// insert table transactions
@ -265,11 +283,14 @@ class Package
$t->method = "$gateway - $channel";
$t->routers = $router_name;
$t->type = "PPPOE";
if ($channel == 'Administrator') {
$t->admin_id = $admin['id'];
}
$t->save();
} else {
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p, "$date_exp $time");
}else{
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::removePpoeUser($client, $c['username']);
Mikrotik::removePpoeActive($client, $c['username']);
@ -289,6 +310,9 @@ class Package
$d->method = "$gateway - $channel";
$d->routers = $router_name;
$d->type = "PPPOE";
if ($channel == 'Administrator') {
$d->admin_id = $admin['id'];
}
$d->save();
// insert table transactions
@ -303,6 +327,9 @@ class Package
$t->time = $time;
$t->method = "$gateway - $channel";
$t->routers = $router_name;
if ($channel == 'Administrator') {
$t->admin_id = $admin['id'];
}
$t->type = "PPPOE";
$t->save();
}
@ -322,9 +349,9 @@ class Package
$c = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
$p = ORM::for_table('tbl_plans')->where('id', $plan_id)->where('enabled', '1')->find_one();
$b = ORM::for_table('tbl_user_recharges')->find_one($from_id);
if($p['routers'] == $b['routers'] && $b['routers'] != 'radius'){
if ($p['routers'] == $b['routers'] && $b['routers'] != 'radius') {
$mikrotik = Mikrotik::info($p['routers']);
}else{
} else {
$mikrotik = Mikrotik::info($b['routers']);
}
// delete first
@ -358,21 +385,21 @@ class Package
}
}
// call the next mikrotik
if($p['routers'] != $b['routers'] && $p['routers'] != 'radius'){
if ($p['routers'] != $b['routers'] && $p['routers'] != 'radius') {
$mikrotik = Mikrotik::info($p['routers']);
}
if ($p['type'] == 'Hotspot') {
if ($b) {
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p, $b['expiration'].''.$b['time']);
}else{
Radius::customerAddPlan($c, $p, $b['expiration'] . '' . $b['time']);
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addHotspotUser($client, $p, $c);
}
} else {
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p, $b['expiration'].''.$b['time']);
}else{
Radius::customerAddPlan($c, $p, $b['expiration'] . '' . $b['time']);
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addHotspotUser($client, $p, $c);
}
@ -381,14 +408,14 @@ class Package
if ($b) {
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p);
}else{
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addPpoeUser($client, $p, $c);
}
} else {
if ($p['is_radius']) {
Radius::customerAddPlan($c, $p);
}else{
} else {
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
Mikrotik::addPpoeUser($client, $p, $c);
}
@ -401,4 +428,70 @@ class Package
{
return substr(str_shuffle(str_repeat('0123456789', $l)), 0, $l);
}
/**
* @param in tbl_transactions
* @param string $router_name router name for this package
* @param int $plan_id plan id for this package
* @param string $gateway payment gateway name
* @param string $channel channel payment gateway
* @return boolean
*/
public static function createInvoice($in)
{
global $config, $admin, $ui;
$date = Lang::dateAndTimeFormat($in['recharged_on'], $in['recharged_time']);
if ($admin['id'] != $in['admin_id'] && $in['admin_id'] > 0) {
$_admin = Admin::_info($in['admin_id']);
// if admin not deleted
if ($_admin) $admin = $_admin;
}
//print
$invoice = Lang::pad($config['CompanyName'], ' ', 2) . "\n";
$invoice .= Lang::pad($config['address'], ' ', 2) . "\n";
$invoice .= Lang::pad($config['phone'], ' ', 2) . "\n";
$invoice .= Lang::pad("", '=') . "\n";
$invoice .= Lang::pads("Invoice", $in['invoice'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Date'), $date, ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Sales'), $admin['fullname'], ' ') . "\n";
$invoice .= Lang::pad("", '=') . "\n";
$invoice .= Lang::pads(Lang::T('Type'), $in['type'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ') . "\n";
$invoice .= Lang::pad($in['method'], ' ', 2) . "\n";
$invoice .= Lang::pads(Lang::T('Username'), $in['username'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Password'), '**********', ' ') . "\n";
if ($in['type'] != 'Balance') {
$invoice .= Lang::pads(Lang::T('Created On'), Lang::dateAndTimeFormat($in['recharged_on'], $in['recharged_time']), ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Expires On'), Lang::dateAndTimeFormat($in['expiration'], $in['time']), ' ') . "\n";
}
$invoice .= Lang::pad("", '=') . "\n";
$invoice .= Lang::pad($config['note'], ' ', 2) . "\n";
$ui->assign('invoice', $invoice);
$config['printer_cols'] = 30;
//whatsapp
$invoice = Lang::pad($config['CompanyName'], ' ', 2) . "\n";
$invoice .= Lang::pad($config['address'], ' ', 2) . "\n";
$invoice .= Lang::pad($config['phone'], ' ', 2) . "\n";
$invoice .= Lang::pad("", '=') . "\n";
$invoice .= Lang::pads("Invoice", $in['invoice'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Date'), $date, ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Sales'), $admin['fullname'], ' ') . "\n";
$invoice .= Lang::pad("", '=') . "\n";
$invoice .= Lang::pads(Lang::T('Type'), $in['type'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ') . "\n";
$invoice .= Lang::pad($in['method'], ' ', 2) . "\n";
$invoice .= Lang::pads(Lang::T('Username'), $in['username'], ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Password'), '**********', ' ') . "\n";
if ($in['type'] != 'Balance') {
$invoice .= Lang::pads(Lang::T('Created On'), Lang::dateAndTimeFormat($in['recharged_on'], $in['recharged_time']), ' ') . "\n";
$invoice .= Lang::pads(Lang::T('Expires On'), Lang::dateAndTimeFormat($in['expiration'], $in['time']), ' ') . "\n";
}
$invoice .= Lang::pad("", '=') . "\n";
$invoice .= Lang::pad($config['note'], ' ', 2) . "\n";
$ui->assign('whatsapp', urlencode("```$invoice```"));
}
}

View File

@ -101,7 +101,6 @@ if (isset($_SESSION['notify'])) {
unset($_SESSION['ntype']);
}
// Routing Engine
$req = _get('_route');
$routes = explode('/', $req);

View File

@ -42,17 +42,17 @@ switch ($action) {
$c = ORM::for_table('tbl_user_recharges')->where('username', $user['username'])->find_one();
if ($c) {
$p = ORM::for_table('tbl_plans')->where('id', $c['plan_id'])->find_one();
if($p['is_radius']){
if($c['type'] == 'Hotspot' || ($c['type'] == 'PPPOE' && empty($d['pppoe_password']))){
if ($p['is_radius']) {
if ($c['type'] == 'Hotspot' || ($c['type'] == 'PPPOE' && empty($d['pppoe_password']))) {
Radius::customerUpsert($d, $p);
}
}else{
} else {
$mikrotik = Mikrotik::info($c['routers']);
$client = Mikrotik::getClient($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password']);
if ($c['type'] == 'Hotspot') {
Mikrotik::setHotspotUser($client, $c['username'], $npass);
Mikrotik::removeHotspotActiveUser($client, $user['username']);
} else if(empty($d['pppoe_password'])){
Mikrotik::setHotspotUser($client, $c['username'], $npass);
Mikrotik::removeHotspotActiveUser($client, $user['username']);
} else if (empty($d['pppoe_password'])) {
// only change when pppoe_password empty
Mikrotik::setPpoeUser($client, $c['username'], $npass);
Mikrotik::removePpoeActive($client, $user['username']);
@ -84,7 +84,7 @@ switch ($action) {
$ui->assign('d', $d);
$ui->display('user-profile.tpl');
} else {
r2(U . 'home', 'e', $_L['Account_Not_Found']);
r2(U . 'home', 'e', Lang::T('Account Not Found'));
}
break;
@ -122,6 +122,133 @@ switch ($action) {
}
break;
case 'phone-update':
$d = ORM::for_table('tbl_customers')->find_one($user['id']);
if ($d) {
//run_hook('customer_view_edit_profile'); #HOOK
$ui->assign('d', $d);
$ui->display('user-phone-update.tpl');
} else {
r2(U . 'home', 'e', Lang::T('Account Not Found'));
}
break;
case 'phone-update-otp':
$phone = _post('phone');
$username = $user['username'];
$otpPath = 'system/cache/sms/';
// Validate the phone number format
if (!preg_match('/^[0-9]{10,}$/', $phone)) {
r2(U . 'accounts/phone-update', 'e', Lang::T('Invalid phone number format'));
}
if (empty($config['sms_url'])) {
r2(U . 'accounts/phone-update', 'e', Lang::T('SMS server not Available, Please try again later'));
}
if (!empty($config['sms_url'])) {
if (!empty($phone)) {
$d = ORM::for_table('tbl_customers')->where('username', $username)->where('phonenumber', $phone)->find_one();
if ($d) {
r2(U . 'accounts/phone-update', 'e', Lang::T('You cannot use your current phone number'));
}
if (!file_exists($otpPath)) {
mkdir($otpPath);
touch($otpPath . 'index.html');
}
$otpFile = $otpPath . sha1($username . $db_password) . ".txt";
$phoneFile = $otpPath . sha1($username . $db_password) . "_phone.txt";
// expired 10 minutes
if (file_exists($otpFile) && time() - filemtime($otpFile) < 1200) {
r2(U . 'accounts/phone-update', 'e', Lang::T('Please wait ' . (1200 - (time() - filemtime($otpFile))) . ' seconds before sending another SMS'));
} else {
$otp = rand(100000, 999999);
file_put_contents($otpFile, $otp);
file_put_contents($phoneFile, $phone);
// send send OTP to user
if ($config['phone_otp_type'] === 'sms') {
Message::sendSMS($phone, $config['CompanyName'] . "\n Your Verification code is: $otp");
} elseif ($config['phone_otp_type'] === 'whatsapp') {
Message::sendWhatsapp($phone, $config['CompanyName'] . "\n Your Verification code is: $otp");
} elseif ($config['phone_otp_type'] === 'both') {
Message::sendSMS($phone, $config['CompanyName'] . "\n Your Verification code is: $otp");
Message::sendWhatsapp($phone, $config['CompanyName'] . "\n Your Verification code is: $otp");
}
//redirect after sending OTP
r2(U . 'accounts/phone-update', 'e', Lang::T('Verification code has been sent to your phone'));
}
}
}
break;
case 'phone-update-post':
$phone = _post('phone');
$otp_code = _post('otp');
$username = $user['username'];
$otpPath = 'system/cache/sms/';
// Validate the phone number format
if (!preg_match('/^[0-9]{10,}$/', $phone)) {
r2(U . 'accounts/phone-update', 'e', Lang::T('Invalid phone number format'));
exit();
}
if (!empty($config['sms_url'])) {
$otpFile = $otpPath . sha1($username . $db_password) . ".txt";
$phoneFile = $otpPath . sha1($username . $db_password) . "_phone.txt";
// Check if OTP file exists
if (!file_exists($otpFile)) {
r2(U . 'accounts/phone-update', 'e', Lang::T('Please request OTP first'));
exit();
}
// expired 10 minutes
if (time() - filemtime($otpFile) > 1200) {
unlink($otpFile);
unlink($phoneFile);
r2(U . 'accounts/phone-update', 'e', Lang::T('Verification code expired'));
exit();
} else {
$code = file_get_contents($otpFile);
// Check if OTP code matches
if ($code != $otp_code) {
r2(U . 'accounts/phone-update', 'e', Lang::T('Wrong Verification code'));
exit();
}
// Check if the phone number matches the one that requested the OTP
$savedPhone = file_get_contents($phoneFile);
if ($savedPhone !== $phone) {
r2(U . 'accounts/phone-update', 'e', Lang::T('The phone number does not match the one that requested the OTP'));
exit();
}
// OTP verification successful, delete OTP and phone number files
unlink($otpFile);
unlink($phoneFile);
}
} else {
r2(U . 'accounts/phone-update', 'e', Lang::T('SMS server not available'));
exit();
}
// Update the phone number in the database
$d = ORM::for_table('tbl_customers')->where('username', $username)->find_one();
if ($d) {
$d->phonenumber = Lang::phoneFormat($phone);
$d->save();
}
r2(U . 'accounts/profile', 's', Lang::T('Phone number updated successfully'));
break;
default:
$ui->display('a404.tpl');
}

View File

@ -26,19 +26,16 @@ switch ($do) {
$d->last_login = date('Y-m-d H:i:s');
$d->save();
_log($username . ' ' . Lang::T('Login Successful'), $d['user_type'], $d['id']);
r2(U . 'dashboard');
_alert(Lang::T('Login Successful'),'success', "dashboard");
} else {
_msglog('e', Lang::T('Invalid Username or Password'));
_log($username . ' ' . Lang::T('Failed Login'), $d['user_type']);
r2(U . 'admin');
_alert(Lang::T('Invalid Username or Password'),'danger', "admin");
}
} else {
_msglog('e', Lang::T('Invalid Username or Password'));
r2(U . 'admin');
_alert(Lang::T('Invalid Username or Password'),'danger', "admin");
}
} else {
_msglog('e', Lang::T('Invalid Username or Password'));
r2(U . 'admin');
_alert(Lang::T('Invalid Username or Password'),'danger', "admin");
}
break;

View File

@ -44,6 +44,7 @@ switch ($action) {
run_hook('view_edit_bandwith'); #HOOK
$d = ORM::for_table('tbl_bandwidth')->find_one($id);
if($d){
$ui->assign('burst',explode(" ", $d['burst']));
$ui->assign('d',$d);
$ui->display('bandwidth-edit.tpl');
}else{
@ -67,8 +68,19 @@ switch ($action) {
$rate_down_unit = _post('rate_down_unit');
$rate_up = _post('rate_up');
$rate_up_unit = _post('rate_up_unit');
$burst = _post('burst');
run_hook('add_bandwidth'); #HOOK
$isBurst = true;
$burst = "";
if(isset($_POST['burst'])){
foreach($_POST['burst'] as $b){
if(empty($b)){
$isBurst = false;
}
}
if($isBurst){
$burst = implode(' ', $_POST['burst']);
};
}
$msg = '';
if(Validator::Length($name,16,4) == false){
$msg .= 'Name should be between 5 to 15 characters'. '<br>';
@ -104,8 +116,19 @@ switch ($action) {
$rate_down_unit = _post('rate_down_unit');
$rate_up = _post('rate_up');
$rate_up_unit = _post('rate_up_unit');
$burst = _post('burst');
run_hook('edit_bandwidth'); #HOOK
run_hook('edit_bandwidth'); #HOOK
$isBurst = true;
$burst = "";
if(isset($_POST['burst'])){
foreach($_POST['burst'] as $b){
if(empty($b)){
$isBurst = false;
}
}
if($isBurst){
$burst = implode(' ', $_POST['burst']);
};
}
$msg = '';
if(Validator::Length($name,16,4) == false){
$msg .= 'Name should be between 5 to 15 characters'. '<br>';

View File

@ -26,7 +26,7 @@ switch ($do) {
$d->last_login = date('Y-m-d H:i:s');
$d->save();
_log($username . ' ' . Lang::T('Login Successful'), 'User', $d['id']);
r2(U . 'home');
_alert(Lang::T('Login Successful'),'success', "home");
} else {
_msglog('e', Lang::T('Invalid Username or Password'));
_log($username . ' ' . Lang::T('Failed Login'), 'User');
@ -64,6 +64,7 @@ switch ($do) {
r2(U . 'login', 'e', Lang::T('Voucher activation failed'));
}
} else {
_alert(Lang::T('Login Successful'),'success', "dashboard");
r2(U . 'login', 'e', Lang::T('Voucher activation failed') . '.');
}
}

View File

@ -9,4 +9,4 @@ if (session_status() == PHP_SESSION_NONE) session_start();
Admin::removeCookie();
User::removeCookie();
session_destroy();
header('location: index.php');
_alert(Lang::T('Logout Successful'),'warning', "login");

View File

@ -129,8 +129,7 @@ switch ($action) {
if (Package::rechargeUser($id_customer, $server, $plan, "Recharge", $admin['fullname'])) {
$c = ORM::for_table('tbl_customers')->where('id', $id_customer)->find_one();
$in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
$ui->assign('in', $in);
$ui->assign('date', date("Y-m-d H:i:s"));
Package::createInvoice($in);
$ui->display('invoice.tpl');
_log('[' . $admin['username'] . ']: ' . 'Recharge ' . $c['username'] . ' [' . $in['plan_name'] . '][' . Lang::moneyFormat($in['price']) . ']', $admin['user_type'], $admin['id']);
} else {
@ -143,9 +142,8 @@ switch ($action) {
case 'view':
$id = $routes['2'];
$d = ORM::for_table('tbl_transactions')->where('id', $id)->find_one();
$ui->assign('in', $d);
$in = ORM::for_table('tbl_transactions')->where('id', $id)->find_one();
$ui->assign('in', $in);
if (!empty($routes['3']) && $routes['3'] == 'send') {
$c = ORM::for_table('tbl_customers')->where('username', $d['username'])->find_one();
if ($c) {
@ -154,8 +152,8 @@ switch ($action) {
}
r2(U . 'prepaid/view/' . $id, 'd', "Customer not found");
}
Package::createInvoice($in);
$ui->assign('_title', 'View Invoice');
$ui->assign('date', Lang::dateAndTimeFormat($d['recharged_on'], $d['recharged_time']));
$ui->display('invoice.tpl');
break;
@ -163,6 +161,10 @@ switch ($action) {
case 'print':
$content = $_POST['content'];
if (!empty($content)) {
if ($_POST['nux'] == 'print') {
//header("Location: nux://print?text=".urlencode($content));
$ui->assign('nuxprint', "nux://print?text=" . urlencode($content));
}
$ui->assign('content', $content);
} else {
$id = _post('id');
@ -593,7 +595,7 @@ switch ($action) {
$content .= Lang::pad("", '=') . "\n";
$content .= Lang::pad($config['note'], ' ', 2) . "\n";
$ui->assign('_title', Lang::T('View'));
$ui->assign('wa', urlencode("```$content```"));
$ui->assign('whatsapp', urlencode("```$content```"));
$ui->display('voucher-view.tpl');
} else {
r2(U . 'prepaid/voucher/', 'e', Lang::T('Voucher Not Found'));
@ -632,8 +634,7 @@ switch ($action) {
$v1->user = $user['username'];
$v1->save();
$in = ORM::for_table('tbl_transactions')->where('username', $user['username'])->order_by_desc('id')->find_one();
$ui->assign('in', $in);
$ui->assign('date', date("Y-m-d H:i:s"));
Package::createInvoice($in);
$ui->display('invoice.tpl');
} else {
r2(U . 'prepaid/refill', 'e', "Failed to refill account");
@ -658,8 +659,7 @@ switch ($action) {
if (Package::rechargeUser($user, 'balance', $plan, "Deposit", $admin['fullname'])) {
$c = ORM::for_table('tbl_customers')->where('id', $user)->find_one();
$in = ORM::for_table('tbl_transactions')->where('username', $c['username'])->order_by_desc('id')->find_one();
$ui->assign('in', $in);
$ui->assign('date', date("Y-m-d H:i:s"));
Package::createInvoice($in);
$ui->display('invoice.tpl');
} else {
r2(U . 'prepaid/refill', 'e', "Failed to refill account");

View File

@ -427,5 +427,32 @@
"Code": "Code",
"Send_To_Customer": "Send To Customer",
"Prev": "Prev",
"Voucher_Not_Found": "Voucher Not Found"
"Voucher_Not_Found": "Voucher Not Found",
"Miscellaneous": "Miscellaneous",
"OTP_Required": "OTP Required",
"Change": "Change",
"Change_Phone_Number": "Change Phone Number",
"Current_Number": "Current Number",
"New_Number": "New Number",
"Input_your_phone_number": "Input your phone number",
"OTP": "OTP",
"Enter_OTP_that_was_sent_to_your_phone": "Enter OTP that was sent to your phone",
"Update": "Update",
"OTP_is_required_when_user_want_to_change_phone_number": "OTP is required when user want to change phone number",
"Rate": "Rate",
"Burst": "Burst",
"Editing_Bandwidth_will_not_automatically_update_the_plan__you_need_to_edit_the_plan_then_save_again": "Editing Bandwidth will not automatically update the plan, you need to edit the plan then save again",
"OTP_Method": "OTP Method",
"SMS": "SMS",
"WhatsApp": "WhatsApp",
"SMS_and_WhatsApp": "SMS and WhatsApp",
"The_method_which_OTP_will_be_sent_to_user": "The method which OTP will be sent to user",
"Report_Viewer": "Report Viewer",
"Super_Administrator": "Super Administrator",
"Send_To": "Send To",
"Resend": "Resend",
"Alert": "Alert",
"success": "success",
"Click_Here": "Click Here",
"danger": "danger"
}

View File

@ -65,5 +65,9 @@
],
"2024.2.20.1" : [
"DROP TABLE IF EXISTS `tbl_customers_meta`;"
],
"2024.2.23" : [
"ALTER TABLE `tbl_transactions` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;",
"ALTER TABLE `tbl_user_recharges` ADD `admin_id` INT NOT NULL DEFAULT '1' AFTER `type`;"
]
}

47
ui/ui/alert.tpl Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{ucwords(Lang::T($type))} - {$_c['CompanyName']}</title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
<meta http-equiv="refresh" content="3; url={$url}">
</head>
<body class="hold-transition lockscreen">
<div class="lockscreen-wrapper">
<div class="panel panel-{$type}">
<div class="panel-heading">{ucwords(Lang::T($type))}</div>
<div class="panel-body">
{$text}
</div>
<div class="panel-footer">
<a href="{$url}" id="button" class="btn btn-{$type} btn-block btn-block">{Lang::T('Click Here')} (3)</a>
</div>
</div>
<div class="lockscreen-footer text-center">
{$_c['CompanyName']}
</div>
</div>
<script>
var time = 3;
timer();
function timer() {
setTimeout(() => {
time--;
if (time > -1) {
document.getElementById("button").innerHTML = "{Lang::T('Click Here')} (" + time + ")";
timer();
}
}, 1000);
}
</script>
</body>
</html>

View File

@ -74,11 +74,11 @@
<label class="col-md-2 control-label">Theme</label>
<div class="col-md-6">
<select name="theme" id="theme" class="form-control">
<option value="default" {if $_c['theme'] eq 'default'}selected="selected" {/if}>Default
<option value="default" {if $_c['theme'] eq 'default' }selected="selected" {/if}>Default
</option>
{foreach $themes as $theme}
<option value="{$theme}" {if $_c['theme'] eq $theme}selected="selected" {/if}>
{Lang::ucWords($theme)}</option>
<option value="{$theme}" {if $_c['theme'] eq $theme}selected="selected" {/if}>
{Lang::ucWords($theme)}</option>
{/foreach}
</select>
</div>
@ -94,7 +94,7 @@
<p class="help-block col-md-4">edit at config.php</p>
</div>
</div>
<div class="panel-heading">
<div class="panel-heading" id="hide_dashboard_content">
<div class="btn-group pull-right">
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
@ -103,21 +103,21 @@
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-3 control-label"><input type="checkbox" name="hide_mrc" value="yes"
{if $_c['hide_mrc'] eq 'yes'}checked{/if}>
<label class="col-md-3 control-label"><input type="checkbox" name="hide_mrc" value="yes" {if
$_c['hide_mrc'] eq 'yes' }checked{/if}>
{Lang::T('Monthly Registered Customers')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_tms" value="yes"
{if $_c['hide_tms'] eq 'yes'}checked{/if}> {Lang::T('Total Monthly Sales')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_aui" value="yes"
{if $_c['hide_aui'] eq 'yes'}checked{/if}> {Lang::T('All Users Insights')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_al" value="yes"
{if $_c['hide_al'] eq 'yes'}checked{/if}> {Lang::T('Activity Log')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_uet" value="yes"
{if $_c['hide_uet'] eq 'yes'}checked{/if}> {Lang::T('User Expired, Today')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_vs" value="yes"
{if $_c['hide_vs'] eq 'yes'}checked{/if}> Vouchers Stock</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_pg" value="yes"
{if $_c['hide_pg'] eq 'yes'}checked{/if}> Payment Gateway</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_tms" value="yes" {if
$_c['hide_tms'] eq 'yes' }checked{/if}> {Lang::T('Total Monthly Sales')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_aui" value="yes" {if
$_c['hide_aui'] eq 'yes' }checked{/if}> {Lang::T('All Users Insights')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_al" value="yes" {if
$_c['hide_al'] eq 'yes' }checked{/if}> {Lang::T('Activity Log')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_uet" value="yes" {if
$_c['hide_uet'] eq 'yes' }checked{/if}> {Lang::T('User Expired, Today')}</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_vs" value="yes" {if
$_c['hide_vs'] eq 'yes' }checked{/if}> Vouchers Stock</label>
<label class="col-md-2 control-label"><input type="checkbox" name="hide_pg" value="yes" {if
$_c['hide_pg'] eq 'yes' }checked{/if}> Payment Gateway</label>
</div>
</div>
<div class="panel-heading">
@ -132,9 +132,9 @@
<label class="col-md-2 control-label">{Lang::T('Disable Voucher')}</label>
<div class="col-md-6">
<select name="disable_voucher" id="disable_voucher" class="form-control">
<option value="no" {if $_c['disable_voucher'] == 'no'}selected="selected" {/if}>No
<option value="no" {if $_c['disable_voucher']=='no' }selected="selected" {/if}>No
</option>
<option value="yes" {if $_c['disable_voucher'] == 'yes'}selected="selected" {/if}>Yes
<option value="yes" {if $_c['disable_voucher']=='yes' }selected="selected" {/if}>Yes
</option>
</select>
</div>
@ -144,12 +144,12 @@
<label class="col-md-2 control-label">{Lang::T('Voucher Format')}</label>
<div class="col-md-6">
<select name="voucher_format" id="voucher_format" class="form-control">
<option value="up" {if $_c['voucher_format'] == 'up'}selected="selected" {/if}>UPPERCASE
<option value="up" {if $_c['voucher_format']=='up' }selected="selected" {/if}>UPPERCASE
</option>
<option value="low" {if $_c['voucher_format'] == 'low'}selected="selected" {/if}>
<option value="low" {if $_c['voucher_format']=='low' }selected="selected" {/if}>
lowercase
</option>
<option value="rand" {if $_c['voucher_format'] == 'rand'}selected="selected" {/if}>
<option value="rand" {if $_c['voucher_format']=='rand' }selected="selected" {/if}>
RaNdoM
</option>
</select>
@ -157,31 +157,33 @@
<p class="help-block col-md-4">UPPERCASE lowercase RaNdoM</p>
</div>
{if $_c['disable_voucher'] != 'yes'}
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Disable Registration')}</label>
<div class="col-md-6">
<select name="disable_registration" id="disable_registration" class="form-control">
<option value="no" {if $_c['disable_registration'] == 'no'}selected="selected" {/if}>No
</option>
<option value="yes" {if $_c['disable_registration'] == 'yes'}selected="selected" {/if}>
Yes
</option>
</select>
</div>
<p class="help-block col-md-4">
{Lang::T('Customer just Login with Phone number and Voucher Code, Voucher will be password')}
</p>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Disable Registration')}</label>
<div class="col-md-6">
<select name="disable_registration" id="disable_registration" class="form-control">
<option value="no" {if $_c['disable_registration']=='no' }selected="selected" {/if}>No
</option>
<option value="yes" {if $_c['disable_registration']=='yes' }selected="selected" {/if}>
Yes
</option>
</select>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Redirect after Activation</label>
<div class="col-md-6">
<input type="text" class="form-control" id="voucher_redirect" name="voucher_redirect"
placeholder="https://192.168.88.1/status" value="{$voucher_redirect}">
</div>
<p class="help-block col-md-4">
{Lang::T('After Customer activate voucher or login, customer will be redirected to this url')}
</p>
<p class="help-block col-md-4">
{Lang::T('Customer just Login with Phone number and Voucher Code, Voucher will be
password')}
</p>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Redirect after Activation</label>
<div class="col-md-6">
<input type="text" class="form-control" id="voucher_redirect" name="voucher_redirect"
placeholder="https://192.168.88.1/status" value="{$voucher_redirect}">
</div>
<p class="help-block col-md-4">
{Lang::T('After Customer activate voucher or login, customer will be redirected to this
url')}
</p>
</div>
{/if}
</div>
<div class="panel-heading">
@ -223,9 +225,9 @@
<label class="col-md-2 control-label">{Lang::T('Enable System')}</label>
<div class="col-md-6">
<select name="enable_balance" id="enable_balance" class="form-control">
<option value="no" {if $_c['enable_balance'] == 'no'}selected="selected" {/if}>No
<option value="no" {if $_c['enable_balance']=='no' }selected="selected" {/if}>No
</option>
<option value="yes" {if $_c['enable_balance'] == 'yes'}selected="selected" {/if}>Yes
<option value="yes" {if $_c['enable_balance']=='yes' }selected="selected" {/if}>Yes
</option>
</select>
</div>
@ -235,10 +237,10 @@
<label class="col-md-2 control-label">{Lang::T('Allow Transfer')}</label>
<div class="col-md-6">
<select name="allow_balance_transfer" id="allow_balance_transfer" class="form-control">
<option value="no" {if $_c['allow_balance_transfer'] == 'no'}selected="selected" {/if}>
<option value="no" {if $_c['allow_balance_transfer']=='no' }selected="selected" {/if}>
No</option>
<option value="yes" {if $_c['allow_balance_transfer'] == 'yes'}selected="selected"
{/if}>Yes</option>
<option value="yes" {if $_c['allow_balance_transfer']=='yes' }selected="selected" {/if}>
Yes</option>
</select>
</div>
<p class="help-block col-md-4">{Lang::T('Allow balance transfer between customers')}</p>
@ -304,8 +306,8 @@
onchange="document.getElementById('sms_url').value = this.value">
<option value="">Select Router</option>
{foreach $r as $rs}
<option value="{$rs['name']}" {if $rs['name']==$_c['sms_url']}selected{/if}>
{$rs['name']}</option>
<option value="{$rs['name']}" {if $rs['name']==$_c['sms_url']}selected{/if}>
{$rs['name']}</option>
{/foreach}
</select>
</div>
@ -352,9 +354,9 @@
<select name="user_notification_expired" id="user_notification_expired"
class="form-control">
<option value="none">None</option>
<option value="wa" {if $_c['user_notification_expired'] == 'wa'}selected="selected"
<option value="wa" {if $_c['user_notification_expired']=='wa' }selected="selected"
{/if}>Whatsapp</option>
<option value="sms" {if $_c['user_notification_expired'] == 'sms'}selected="selected"
<option value="sms" {if $_c['user_notification_expired']=='sms' }selected="selected"
{/if}>SMS</option>
</select>
</div>
@ -366,9 +368,9 @@
<select name="user_notification_payment" id="user_notification_payment"
class="form-control">
<option value="none">None</option>
<option value="wa" {if $_c['user_notification_payment'] == 'wa'}selected="selected"
<option value="wa" {if $_c['user_notification_payment']=='wa' }selected="selected"
{/if}>Whatsapp</option>
<option value="sms" {if $_c['user_notification_payment'] == 'sms'}selected="selected"
<option value="sms" {if $_c['user_notification_payment']=='sms' }selected="selected"
{/if}>SMS</option>
</select>
</div>
@ -381,9 +383,9 @@
<select name="user_notification_reminder" id="user_notification_reminder"
class="form-control">
<option value="none">None</option>
<option value="wa" {if $_c['user_notification_reminder'] == 'wa'}selected="selected"
<option value="wa" {if $_c['user_notification_reminder']=='wa' }selected="selected"
{/if}>Whatsapp</option>
<option value="sms" {if $_c['user_notification_reminder'] == 'sms'}selected="selected"
<option value="sms" {if $_c['user_notification_reminder']=='sms' }selected="selected"
{/if}>SMS</option>
</select>
</div>
@ -452,6 +454,43 @@
</div>
</div>
</div>
<div class="panel-heading">
<div class="btn-group pull-right">
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button>
</div>
{Lang::T('Miscellaneous')}
</div>
<div class="panel-body">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('OTP Required')}</label>
<div class="col-md-6">
<select name="allow_phone_otp" id="allow_phone_otp" class="form-control">
<option value="no" {if $_c['allow_phone_otp']=='no' }selected="selected" {/if}>
No</option>
<option value="yes" {if $_c['allow_phone_otp']=='yes' }selected="selected" {/if}>Yes
</option>
</select>
</div>
<p class="help-block col-md-4">{Lang::T('OTP is required when user want to change phone
number')}</p>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('OTP Method')}</label>
<div class="col-md-6">
<select name="phone_otp_type" id="phone_otp_type" class="form-control">
<option value="sms" {if $_c['phone_otp_type']=='sms' }selected="selected" {/if}>
{Lang::T('SMS')}
<option value="whatsapp" {if $_c['phone_otp_type']=='whatsapp' }selected="selected"
{/if}> {Lang::T('WhatsApp')}
<option value="both" {if $_c['phone_otp_type']=='both' }selected="selected" {/if}>
{Lang::T('SMS and WhatsApp')}
</option>
</select>
</div>
<p class="help-block col-md-4">{Lang::T('The method which OTP will be sent to user')}</p>
</div>
</div>
{* <div class="panel-heading" id="envato">
<div class="btn-group pull-right">
<button class="btn btn-primary btn-xs" title="save" type="submit"><span
@ -484,8 +523,8 @@
<div class="panel-body">
<div class="form-group">
<button class="btn btn-success btn-block waves-effect waves-light"
type="submit">{Lang::T('Save Changes')}</button>
<button class="btn btn-success btn-block waves-effect waves-light" type="submit">{Lang::T('Save
Changes')}</button>
</div>
</div>
@ -511,14 +550,14 @@ add dst-host=*.{$_domain}</pre>
function testWa() {
var target = prompt("Phone number\nSave First before Test", "");
if (target != null) {
window.location.href = '{$_url}settings/app&testWa='+target;
window.location.href = '{$_url}settings/app&testWa=' + target;
}
}
function testSms() {
var target = prompt("Phone number\nSave First before Test", "");
if (target != null) {
window.location.href = '{$_url}settings/app&testSms='+target;
window.location.href = '{$_url}settings/app&testSms=' + target;
}
}

View File

@ -40,7 +40,31 @@
<div class="form-group">
<label class="col-md-2 control-label">Burst Limit</label>
<div class="col-md-6">
<input type="text" class="form-control" id="burst" name="burst" placeholder="[Burst/Limit] [Burst/Threshold] [Burst/Time] [Priority] [Limit/At]">
<input type="text" class="form-control" name="burst[]" placeholder="[Burst/Limit]">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Burst Threshold</label>
<div class="col-md-6">
<input type="text" class="form-control" name="burst[]" placeholder="[Burst/Threshold]">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Burst Time</label>
<div class="col-md-6">
<input type="text" class="form-control" name="burst[]" placeholder="[Burst/Time]">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Priority</label>
<div class="col-md-6">
<input type="number" class="form-control" name="burst[]" placeholder="[Priority]">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Limit At</label>
<div class="col-md-6">
<input type="text" class="form-control" name="burst[]" placeholder="[Limit/At]">
</div>
</div>
<div class="form-group">

View File

@ -43,11 +43,39 @@
</select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Burst Limit</label>
<div class="col-md-6">
<input type="text" class="form-control" id="burst" name="burst" value="{$d['burst']}" placeholder="[Burst/Limit] [Burst/Threshold] [Burst/Time] [Priority] [Limit/At]">
<input type="text" class="form-control" name="burst[]" placeholder="[Burst/Limit]" value="{$burst[0]}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Burst Threshold</label>
<div class="col-md-6">
<input type="text" class="form-control" name="burst[]" placeholder="[Burst/Threshold]" value="{$burst[1]}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Burst Time</label>
<div class="col-md-6">
<input type="text" class="form-control" name="burst[]" placeholder="[Burst/Time]" value="{$burst[2]}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Priority</label>
<div class="col-md-6">
<input type="number" class="form-control" name="burst[]" placeholder="[Priority]" value="{$burst[3]}">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Limit At</label>
<div class="col-md-6">
<input type="text" class="form-control" name="burst[]" placeholder="[Limit/At]" value="{$burst[4]}">
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<small>{Lang::T('Editing Bandwidth will not automatically update the plan, you need to edit the plan then save again')}</small>
</div>
</div>
<div class="form-group">

View File

@ -24,12 +24,12 @@
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<table class="table table-bordered table-condensed table-striped table_mobile">
<thead>
<tr>
<th>{Lang::T('Bandwidth Name')}</th>
<th>{Lang::T('Rate Download')}</th>
<th>{Lang::T('Rate Upload')}</th>
<th>{Lang::T('Rate')}</th>
<th>{Lang::T('Burst')}</th>
<th>{Lang::T('Manage')}</th>
</tr>
</thead>
@ -37,8 +37,8 @@
{foreach $d as $ds}
<tr>
<td>{$ds['name_bw']}</td>
<td>{$ds['rate_down']} {$ds['rate_down_unit']}</td>
<td>{$ds['rate_up']} {$ds['rate_up_unit']}</td>
<td>{$ds['rate_down']} {$ds['rate_down_unit']} / {$ds['rate_up']} {$ds['rate_up_unit']}</td>
<td>{$ds['burst']}</td>
<td>
<a href="{$_url}bandwidth/edit/{$ds['id']}" class="btn btn-sm btn-warning">{Lang::T('Edit')}</a>
<a href="{$_url}bandwidth/delete/{$ds['id']}" id="{$ds['id']}" class="btn btn-danger btn-sm" onclick="return confirm('{Lang::T('Delete')}?')" ><i class="glyphicon glyphicon-trash"></i></a>

View File

@ -32,7 +32,7 @@
class="ion ion-android-add"> </i> {Lang::T('Add New Contact')}</a>
</div>&nbsp;
</div>
<div class="table-responsive">
<div class="table-responsive table_mobile">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>

View File

@ -71,8 +71,8 @@
<div class="box-tools pull-right">
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
<button type="button" class="btn bg-teal btn-sm" data-widget="remove"><i class="fa fa-times"></i>
</button>
<a href="{$_url}settings/app#hide_dashboard_content" class="btn bg-teal btn-sm" ><i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="box-body border-radius-none">
@ -92,8 +92,8 @@
<div class="box-tools pull-right">
<button type="button" class="btn bg-teal btn-sm" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
<button type="button" class="btn bg-teal btn-sm" data-widget="remove"><i class="fa fa-times"></i>
</button>
<a href="{$_url}settings/app#hide_dashboard_content" class="btn bg-teal btn-sm" ><i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="box-body border-radius-none">
@ -108,7 +108,7 @@
<div class="panel panel-primary mb20 panel-hovered project-stats table-responsive">
<div class="panel-heading">Vouchers Stock</div>
<div class="table-responsive">
<table class="table">
<table class="table table-condensed">
<thead>
<tr>
<th>{Lang::T('Plan Name')}</th>
@ -139,20 +139,17 @@
<div class="panel panel-warning mb20 panel-hovered project-stats table-responsive">
<div class="panel-heading">{Lang::T('User Expired, Today')}</div>
<div class="table-responsive">
<table class="table">
<table class="table table-condensed">
<thead>
<tr>
<th>Id</th>
<th>{Lang::T('Username')}</th>
<th>{Lang::T('Created On')}</th>
<th>{Lang::T('Expires On')}</th>
</tr>
</thead>
<tbody>
{$no = 1}
{foreach $expire as $expired}
<tr>
<td>{$no++}</td>
<td><a href="{$_url}customers/viewu/{$expired['username']}">{$expired['username']}</a></td>
<td>{Lang::dateAndTimeFormat($expired['recharged_on'],$expired['recharged_time'])}
</td>

View File

@ -45,13 +45,14 @@
<th>{Lang::T('Routers')}</th>
<th>{Lang::T('Expired IP Pool')}</th>
<th>{Lang::T('Manage')}</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled"
{elseif $ds['allow_purchase'] != 'yes'}class="warning" title="Customer can't purchase" {/if}>
<td>{$ds['name_plan']}</td>
<td class="headcol">{$ds['name_plan']}</td>
<td>{$ds['typebp']}</td>
<td>{$ds['name_bw']}</td>
<td>{Lang::moneyFormat($ds['price'])}</td>
@ -75,6 +76,7 @@
onclick="return confirm('{Lang::T('Delete')}?')"
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
</td>
<td>{$ds['id']}</td>
</tr>
{/foreach}
</tbody>

View File

@ -15,47 +15,58 @@
</script>
</head>
<body topmargin="0" leftmargin="0" onload="printpage()">
<body topmargin="0" leftmargin="0" {if !$nuxprint} onload="printpage()" {/if}>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<table width="200">
<tr>
<td>
{if $content}<pre style="border-style: none; background-color: white;">{$content}</pre>{else}
<pre style="border-style: none; background-color: white;"><b>{Lang::pad($_c['CompanyName'],' ', 2)}</b>
{Lang::pad($_c['address'],' ', 2)}
{Lang::pad($_c['phone'],' ', 2)}
{Lang::pad("", '=')}
{Lang::pads("Invoice", $in['invoice'], ' ')}
{Lang::pads(Lang::T('Date'), $date, ' ')}
{Lang::pads(Lang::T('Sales'), $_admin['fullname'], ' ')}
{Lang::pad("", '=')}
{Lang::pads(Lang::T('Type'), $in['type'], ' ')}
{Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ')}
{Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ')}
{Lang::pad($in['method'], ' ', 2)}
{if $content}
<pre style="border-style: none; background-color: white;">{$content}</pre>{else}
<pre style="border-style: none; background-color: white;"><b>{Lang::pad($_c['CompanyName'],' ', 2)}</b>
{Lang::pad($_c['address'],' ', 2)}
{Lang::pad($_c['phone'],' ', 2)}
{Lang::pad("", '=')}
{Lang::pads("Invoice", $in['invoice'], ' ')}
{Lang::pads(Lang::T('Date'), $date, ' ')}
{Lang::pads(Lang::T('Sales'), $_admin['fullname'], ' ')}
{Lang::pad("", '=')}
{Lang::pads(Lang::T('Type'), $in['type'], ' ')}
{Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ')}
{Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ')}
{Lang::pad($in['method'], ' ', 2)}
{Lang::pads(Lang::T('Username'), $in['username'], ' ')}
{Lang::pads(Lang::T('Password'), '**********', ' ')}
{if $in['type'] != 'Balance'}
{Lang::pads(Lang::T('Created On'), Lang::dateAndTimeFormat($in['recharged_on'],$in['recharged_time']), ' ')}
{Lang::pads(Lang::T('Expires On'), Lang::dateAndTimeFormat($in['expiration'],$in['time']), ' ')}
{/if}
{Lang::pad("", '=')}
{Lang::pad($_c['note'],' ', 2)}</pre>
{/if}
{Lang::pads(Lang::T('Username'), $in['username'], ' ')}
{Lang::pads(Lang::T('Password'), '**********', ' ')}
{if $in['type'] != 'Balance'}
{Lang::pads(Lang::T('Created On'), Lang::dateAndTimeFormat($in['recharged_on'],$in['recharged_time']), ' ')}
{Lang::pads(Lang::T('Expires On'), Lang::dateAndTimeFormat($in['expiration'],$in['time']), ' ')}
{/if}
{Lang::pad("", '=')}
{Lang::pad($_c['note'],' ', 2)}</pre>
{/if}
</td>
</tr>
</table>
{if $nuxprint}
<a href="{$nuxprint}" class="btn btn-success text-black btn-sm" name="nux" value="print">
<i class="glyphicon glyphicon-print"></i>
Nux Print
<i class="glyphicon glyphicon-phone"></i>
</a>
<br>
<iframe src="{$nuxprint}" style="height: 2px;"><iframe>
{/if}
</div>
</div>
<script src="ui/ui/scripts/jquery-1.10.2.js"></script>
<script src="ui/ui/scripts/jquery.min.js"></script>
<script src="ui/ui/scripts/bootstrap.min.js"></script>
{if isset($xfooter)}
{$xfooter}
{/if}
</body>
</html>

View File

@ -5,37 +5,30 @@
<div class="panel panel-hovered panel-primary panel-stacked mb30">
<div class="panel-heading">{$in['invoice']}</div>
<div class="panel-body">
<form class="form-horizontal" method="post" action="{$_url}prepaid/print" target="_blank">
<pre id="content"></pre>
<textarea class="hidden" id="formcontent" name="content">{Lang::pad($_c['CompanyName'],' ', 2)}
{Lang::pad($_c['address'],' ', 2)}
{Lang::pad($_c['phone'],' ', 2)}
{Lang::pad("", '=')}
{Lang::pads("Invoice", $in['invoice'], ' ')}
{Lang::pads(Lang::T('Date'), $date, ' ')}
{Lang::pads(Lang::T('Sales'), $_admin['fullname'], ' ')}
{Lang::pad("", '=')}
{Lang::pads(Lang::T('Type'), $in['type'], ' ')}
{Lang::pads(Lang::T('Plan Name'), $in['plan_name'], ' ')}
{Lang::pads(Lang::T('Plan Price'), Lang::moneyFormat($in['price']), ' ')}
{Lang::pad($in['method'], ' ', 2)}
{Lang::pads(Lang::T('Username'), $in['username'], ' ')}
{Lang::pads(Lang::T('Password'), '**********', ' ')}
{if $in['type'] != 'Balance'}
{Lang::pads(Lang::T('Created On'), Lang::dateAndTimeFormat($in['recharged_on'],$in['recharged_time']), ' ')}
{Lang::pads(Lang::T('Expires On'), Lang::dateAndTimeFormat($in['expiration'],$in['time']), ' ')}
{/if}
{Lang::pad("", '=')}
{Lang::pad($_c['note'],' ', 2)}</textarea>
<input type="hidden" name="id" value="{$in['id']}">
<a href="{$_url}prepaid/list" class="btn btn-primary btn-sm"><i
class="ion-reply-all"></i>{Lang::T('Finish')}</a>
<a href="{$_url}prepaid/view/{$in['id']}/send" class="btn btn-info text-black btn-sm"><i
class="glyphicon glyphicon-envelope"></i> {Lang::T("Resend To Customer")}</a>
<button type="submit" class="btn btn-default btn-sm"><i class="fa fa-print"></i>
{Lang::T('Click Here to Print')}</button>
</form>
<form class="form-horizontal" method="post" action="{$_url}prepaid/print" target="_blank">
<pre id="content"></pre>
<textarea class="hidden" id="formcontent" name="content">{$invoice}</textarea>
<input type="hidden" name="id" value="{$in['id']}">
<a href="{$_url}prepaid/list" class="btn btn-default btn-sm"><i
class="ion-reply-all"></i>{Lang::T('Finish')}</a>
<a href="https://api.whatsapp.com/send/?text={$whatsapp}" target="_blank"
class="btn btn-primary btn-sm">
<i class="glyphicon glyphicon-share"></i> WhatsApp</a>
<a href="{$_url}prepaid/view/{$in['id']}/send" class="btn btn-info text-black btn-sm"><i
class="glyphicon glyphicon-envelope"></i> {Lang::T("Resend")}</a>
<button type="submit" class="btn btn-info text-black btn-sm"><i class="glyphicon glyphicon-print"></i>
Print</button>
<a href="nux://print?text={urlencode($invoice)}"
class="btn btn-success text-black btn-sm hidden-md hidden-lg">
<i class="glyphicon glyphicon-phone"></i>
NuxPrint
</a>
<a href="https://github.com/hotspotbilling/android-printer"
class="btn btn-success text-black btn-sm hidden-xs hidden-sm" target="_blank">
<i class="glyphicon glyphicon-phone"></i>
NuxPrint
</a>
</form>
</div>
</div>
</div>

View File

@ -36,18 +36,16 @@
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>#</th>
<th>{Lang::T('Name Pool')}</th>
<th>{Lang::T('Range IP')}</th>
<th>{Lang::T('Routers')}</th>
<th>{Lang::T('Manage')}</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{$no = 1}
{foreach $d as $ds}
<tr>
<td align="center">{$no++}</td>
<td>{$ds['pool_name']}</td>
<td>{$ds['range_ip']}</td>
<td>{$ds['routers']}</td>
@ -57,6 +55,7 @@
onclick="return confirm('{Lang::T('Delete')}?')"
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
</td>
<td>{$ds['id']}</td>
</tr>
{/foreach}
</tbody>

View File

@ -43,6 +43,7 @@
<th>{Lang::T('Expired IP Pool')}</th>
<th>{Lang::T('Routers')}</th>
<th>{Lang::T('Manage')}</th>
<th>ID</th>
</tr>
</thead>
<tbody>
@ -70,6 +71,7 @@
onclick="return confirm('{Lang::T('Delete')}?')" id="{$ds['id']}"
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
</td>
<td>{$ds['id']}</td>
</tr>
{/foreach}
</tbody>

View File

@ -31,7 +31,6 @@
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>IP</th>
<th>Type</th>
@ -40,12 +39,12 @@
<th>Community</th>
<th>Routers</th>
<th>{Lang::T('Manage')}</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{foreach $nas as $ds}
<tr>
<td align="center">{$ds['id']}</td>
<td>{$ds['shortname']}</td>
<td>{$ds['nasname']}</td>
<td>{$ds['type']}</td>
@ -59,6 +58,7 @@
onclick="return confirm('{Lang::T('Delete')}?')"
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
</td>
<td align="center">{$ds['id']}</td>
</tr>
{/foreach}
</tbody>

View File

@ -4,15 +4,15 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{$_title} - {Lang::T('Register')}</title>
<title>{Lang::T('Register')} - {$_c['CompanyName']}</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
<link rel="stylesheet" href="ui/ui/styles/sweetalert2.min.css" />
<script src="ui/ui/scripts/sweetalert2.all.min.js"></script>
</head>

View File

@ -4,15 +4,15 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{$_title} - {Lang::T('Register')}</title>
<title>{Lang::T('Register')} - {$_c['CompanyName']}</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
<link rel="stylesheet" href="ui/ui/styles/sweetalert2.min.css" />
<script src="ui/ui/scripts/sweetalert2.all.min.js"></script>
</head>

View File

@ -4,15 +4,15 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{$_title} - {Lang::T('Register')}</title>
<title>{Lang::T('Register')} - {$_c['CompanyName']}</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
<link rel="stylesheet" href="ui/ui/styles/sweetalert2.min.css" />
<script src="ui/ui/scripts/sweetalert2.all.min.js"></script>
</head>

View File

@ -31,19 +31,18 @@
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>ID</th>
<th>{Lang::T('Router Name')}</th>
<th>{Lang::T('IP Address')}</th>
<th>{Lang::T('Username')}</th>
<th>{Lang::T('Description')}</th>
<th>{Lang::T('Status')}</th>
<th>{Lang::T('Manage')}</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['enabled'] != 1}class="danger" title="disabled" {/if}>
<td>{$ds['id']}</td>
<td>{$ds['name']}</td>
<td>{$ds['ip_address']}</td>
<td>{$ds['username']}</td>
@ -56,6 +55,7 @@
onclick="return confirm('{Lang::T('Delete')}?')"
class="btn btn-danger btn-xs"><i class="glyphicon glyphicon-trash"></i></a>
</td>
<td>{$ds['id']}</td>
</tr>
{/foreach}
</tbody>

View File

@ -21,10 +21,32 @@
<script>
$(document).ready(function() {
$('.select2').select2({theme: "bootstrap"});
});
$(document).ready(function() {
$('.select2tag').select2({theme: "bootstrap", tags: true});
var listAtts = document.querySelectorAll(`button[type="submit"]`);
listAtts.forEach(function(el) {
if (el.addEventListener) { // all browsers except IE before version 9
el.addEventListener("click", function() {
$(this).html(
`<span class="glyphicon glyphicon-refresh" role="status" aria-hidden="true"></span>`
);
setTimeout(() => {
$(this).prop("disabled", true);
}, 100);
}, false);
} else {
if (el.attachEvent) { // IE before version 9
el.attachEvent("click", function() {
$(this).html(
`<span class="glyphicon glyphicon-refresh" role="status" aria-hidden="true"></span>`
);
setTimeout(() => {
$(this).prop("disabled", true);
}, 100);
});
}
}
});
});
var listAtts = document.querySelectorAll(`[api-get-text]`);

View File

@ -41,19 +41,11 @@
}
}
@media only screen and (max-width: 40em) {
thead th:not(:first-child) {
display: none;
}
td,
th {
display: block;
}
td[data-th]:before {
content: attr(data-th);
}
th:first-child,
td:first-child {
position: sticky;
left: 0px;
background-color: #f9f9f9;
}

View File

@ -79,6 +79,33 @@
el.innerHTML = data;
});
});
$(document).ready(function() {
var listAtts = document.querySelectorAll(`button[type="submit"]`);
listAtts.forEach(function(el) {
if (el.addEventListener) { // all browsers except IE before version 9
el.addEventListener("click", function() {
$(this).html(
`<span class="glyphicon glyphicon-refresh" role="status" aria-hidden="true"></span>`
);
setTimeout(() => {
$(this).prop("disabled", true);
}, 100);
}, false);
} else {
if (el.attachEvent) { // IE before version 9
el.attachEvent("click", function() {
$(this).html(
`<span class="glyphicon glyphicon-refresh" role="status" aria-hidden="true"></span>`
);
setTimeout(() => {
$(this).prop("disabled", true);
}, 100);
});
}
}
});
});
</script>
{/literal}

View File

@ -7,7 +7,7 @@
<div class="panel-heading">{Lang::T('List Activated Voucher')}</div>
<div class="panel-body">
<div class="table-responsive">
<table id="datatable" class="table table-bordered table-striped">
<table id="datatable" class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{Lang::T('Username')}</th>

View File

@ -4,12 +4,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{$_title} - {Lang::T('Login')}</title>
<title>{Lang::T('Login')} - {$_c['CompanyName']}</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
</head>

View File

@ -4,13 +4,11 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{$_title} - {Lang::T('Login')}</title>
<title>{Lang::T('Login')} - {$_c['CompanyName']}</title>
<link rel="shortcut icon" href="ui/ui/images/logo.png" type="image/x-icon" />
<link rel="stylesheet" href="ui/ui/styles/bootstrap.min.css">
<link rel="stylesheet" href="ui/ui/styles/modern-AdminLTE.min.css">
</head>
<body>

View File

@ -7,7 +7,7 @@
<div class="panel-heading">{Lang::T('Order History')}</div>
<div class="panel-body">
<div class="table-responsive">
<table id="datatable" class="table table-bordered table-striped">
<table id="datatable" class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>{Lang::T('Plan Name')}</th>

View File

@ -0,0 +1,80 @@
{include file="sections/user-header.tpl"}
<!-- user-phone-update -->
<div class="box box-danger">
<div class="box-header with-border">
<h3 class="box-title">{Lang::T('Change Phone Number')}</h3>
</div>
<div class="box-body">
<div class="form-horizontal">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Current Number')}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="phonenumber" id="phonenumber"
value="{$d['phonenumber']}" readonly placeholder="{Lang::T('Phone Number')}">
</div>
</div>
</div>
<form method="post" role="form" action="{$_url}accounts/phone-update-otp">
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('New Number')}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="number" class="form-control" name="phone" id="phone" value="" required
placeholder="{Lang::T('Input your phone number')}">
<span class="input-group-btn">
<button type="submit" class="btn btn-info btn-flat">{Lang::T('Request OTP')}</button>
</span>
</div>
</div>
</div>
</form>
<form method="post" role="form" action="{$_url}accounts/phone-update-post">
<!-- Form 2 -->
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('OTP')}</label>
<div class="col-md-6">
<input type="number" class="form-control" id="otp" name="otp"
placeholder="{Lang::T('Enter OTP that was sent to your phone')}" required>
</div>
</div>
<!-- Hidden field to store the phone number value -->
<input type="hidden" name="phone" id="hidden_phone" required>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-success waves-effect waves-light" type="submit"
onclick="return validateForm()">{Lang::T('Update')}</button>
Or <a href="{$_url}home">{Lang::T('Cancel')}</a>
</div>
</div>
</form>
<script>
function validateForm() {
var phoneNumber = document.getElementById("phone").value;
var otp = document.getElementById("otp").value;
if (phoneNumber.trim() === "") {
alert("Phone number is required.");
return false; // Prevent form submission
}
if (otp.trim() === "") {
alert("OTP code is required.");
return false; // Prevent form submission
}
// Set the phone number value in the hidden field
document.getElementById("hidden_phone").value = phoneNumber;
}
</script>
</div>
</div>
</div>
{include file="sections/user-footer.tpl"}

View File

@ -34,17 +34,35 @@
<textarea name="address" id="address" class="form-control">{$d['address']}</textarea>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Phone Number')}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="phonenumber" id="phonenumber"
value="{$d['phonenumber']}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
{if $_c['allow_phone_otp'] != 'yes'}
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Phone Number')}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="phonenumber" id="phonenumber"
value="{$d['phonenumber']}"
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
</div>
</div>
</div>
</div>
{else}
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Phone Number')}</label>
<div class="col-md-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">+</span>
<input type="text" class="form-control" name="phonenumber" id="phonenumber"
value="{$d['phonenumber']}" readonly
placeholder="{if $_c['country_code_phone']!= ''}{$_c['country_code_phone']}{/if} {Lang::T('Phone Number')}">
<span class="input-group-btn">
<a href="{$_url}accounts/phone-update" type="button"
class="btn btn-info btn-flat">{Lang::T('Change')}</a>
</span>
</div>
</div>
</div>
{/if}
<div class="form-group">
<label class="col-md-2 control-label">{Lang::T('Email')}</label>
<div class="col-md-6">
@ -54,8 +72,8 @@
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-success waves-effect waves-light"
type="submit">{Lang::T('Save Changes')}</button>
<button class="btn btn-success waves-effect waves-light" type="submit">
{Lang::T('Save Changes')}</button>
Or <a href="{$_url}home">{Lang::T('Cancel')}</a>
</div>
</div>

View File

@ -27,10 +27,9 @@
</div>&nbsp;
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<table class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>ID</th>
<th>{Lang::T('Username')}</th>
<th>{Lang::T('Full Name')}</th>
<th>{Lang::T('Phone')}</th>
@ -40,12 +39,12 @@
<th>{Lang::T('Agent')}</th>
<th>{Lang::T('Last Login')}</th>
<th>{Lang::T('Manage')}</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{foreach $d as $ds}
<tr {if $ds['status'] != 'Active'}class="danger"{/if}>
<td>{$ds['id']}</td>
<td>{$ds['username']}</td>
<td>{$ds['fullname']}</td>
<td>{$ds['phone']}</td>
@ -66,6 +65,7 @@
class="btn btn-danger btn-xs" onclick="return confirm('{Lang::T('Delete')}?')"><i class="glyphicon glyphicon-trash"></i></a>
{/if}
</td>
<td>{$ds['id']}</td>
</tr>
{/foreach}
</tbody>

View File

@ -8,12 +8,23 @@
<pre id="content"></pre>
<textarea class="hidden" id="formcontent" name="content">{$print}</textarea>
<input type="hidden" name="id" value="{$in['id']}">
<a href="{$_url}prepaid/voucher" class="btn btn-primary btn-sm"><i
<a href="{$_url}prepaid/voucher" class="btn btn-default btn-sm"><i
class="ion-reply-all"></i>{Lang::T('Finish')}</a>
<a href="https://api.whatsapp.com/send/?text={$wa}" target="_blank" class="btn btn-info text-black btn-sm"><i
class="glyphicon glyphicon-envelope"></i> {Lang::T("Send To Customer")}</a>
<button type="submit" class="btn btn-default btn-sm"><i class="fa fa-print"></i>
{Lang::T('Click Here to Print')}</button>
<a href="https://api.whatsapp.com/send/?text={$whatsapp}" target="_blank"
class="btn btn-primary btn-sm">
<i class="glyphicon glyphicon-share"></i> WhatsApp</a>
<button type="submit" class="btn btn-info text-black btn-sm"><i class="glyphicon glyphicon-print"></i>
Print</button>
<a href="nux://print?text={urlencode($print)}"
class="btn btn-success text-black btn-sm hidden-md hidden-lg">
<i class="glyphicon glyphicon-phone"></i>
NuxPrint
</a>
<a href="https://github.com/hotspotbilling/android-printer"
class="btn btn-success text-black btn-sm hidden-xs hidden-sm" target="_blank">
<i class="glyphicon glyphicon-phone"></i>
NuxPrint
</a>
</form>
<javascript type="text/javascript">
</javascript>

View File

@ -43,7 +43,7 @@
</div>&nbsp;
</div>
<div class="table-responsive">
<table id="datatable" class="table table-bordered table-striped">
<table id="datatable" class="table table-bordered table-striped table-condensed">
<thead>
<tr>
<th>ID</th>

View File

@ -1,3 +1,3 @@
{
"version": "2024.2.20"
"version": "2024.2.23"
}