added logic for updating user profile plus other bug fixes

This commit is contained in:
Kwesi Banson Jnr
2026-03-16 16:41:32 +00:00
parent 9cd017fb9a
commit 72180de8e4
30 changed files with 1346 additions and 49 deletions

View File

@@ -39,36 +39,61 @@ class ClientsController extends Controller
// dd('foo bar'); // dd('foo bar');
return view('client.index-inactive', $data); return view('client.index-inactive', $data);
} }
public function indexBak(){
$client_arr = new Models\Client;
$client_arr = $client_arr->with('auth_user_info','country_info', 'created_by_info')->orderBy('name', 'ASC')->paginate(10);
$data = [
'page_title' => 'Clients',
'current_user' => session('current_user')
];
return view('client.index-rawjs', $data);
}
public function getClientJson(Request $request){ public function getClientJson(Request $request){
// $this->log_query();
$client_arr = \DB::table('clients') $client_arr = \DB::table('clients')
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->join('flags AS flags', 'flags.country', '=', 'clients.country') ->join('flags AS flags', 'flags.country', '=', 'clients.country')
->select('clients.id', 'clients.name', 'clients.status','clients.progress_indicator_score', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') ->select('clients.id', 'clients.name', 'clients.status','clients.progress_indicator_score', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag')
->whereRaw("status NOT IN ('inactive', 'Cancelled')")
->orderBy('name', 'ASC') ->orderBy('name', 'ASC')
->get(); ->get();
// ->paginate(15); // ->paginate(15);
if($request->has('keyword')){ if($request->has('keyword')){
$keyword = $request->keyword; $keyword = $request->keyword;
if (strpos('inactive', $keyword) !== false ) {
// dump('foo bars');
$client_arr = \DB::table('clients') $client_arr = \DB::table('clients')
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->join('flags AS flags', 'flags.country', '=', 'clients.country') ->join('flags AS flags', 'flags.country', '=', 'clients.country')
->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag')
->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%' OR clients.progress_indicator_score like '%$keyword%'") // ->whereRaw("status IN ('Live', 'Prospective')")
->whereRaw("status NOT IN ('inactive', 'Cancelled')")
->whereRaw("clients.name LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name LIKE '%$keyword%'")
->orderBy('name', 'ASC') ->orderBy('name', 'ASC')
->get(); ->get();
// foreach ($client_arr as $value) {
// // code...
// dd($value);
// }
dump($client_arr->contains('status', 'inactive'));
}
elseif (strpos('Cancelled', $keyword) !== false ) {
$client_arr = \DB::table('clients')
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->join('flags AS flags', 'flags.country', '=', 'clients.country')
->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag')
// ->whereRaw("status IN ('Live', 'Prospective')")
->whereRaw("status NOT IN ('inactive', 'Cancelled')")
->whereRaw("clients.name LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name LIKE '%$keyword%' OR aumodify.name LIKE '%$keyword%'")
->orderBy('name', 'ASC')
->get();
}else{
$client_arr = \DB::table('clients')
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->join('flags AS flags', 'flags.country', '=', 'clients.country')
->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag')
->whereRaw("status IN ('Live', 'Prospective')")
->whereRaw("clients.name LIKE '%$keyword%' OR clients.status LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name LIKE '%$keyword%' OR aumodify.name LIKE '%$keyword%'")
->orderBy('name', 'ASC')
->get();
}
// ->paginate(15); // ->paginate(15);
} }
@@ -82,7 +107,7 @@ class ClientsController extends Controller
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->select('clients.id', 'clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') ->select('clients.id', 'clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy')
->whereRaw("status <> 'Inactive'")
->paginate(10); ->paginate(10);
if($request->has('keyword')){ if($request->has('keyword')){
@@ -91,7 +116,8 @@ class ClientsController extends Controller
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->select('clients.id','clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') ->select('clients.id','clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy')
->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'") ->whereRaw("status <> 'Inactive'")
->whereRaw("clients.name like '%$keyword%' OR clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'")
->paginate(10); ->paginate(10);
} }
return response()->json($client_arr); return response()->json($client_arr);
@@ -104,7 +130,7 @@ class ClientsController extends Controller
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->join('flags AS flags', 'flags.country', '=', 'clients.country') ->join('flags AS flags', 'flags.country', '=', 'clients.country')
->select('clients.id', 'clients.name', 'clients.status','clients.progress_indicator_score', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') ->select('clients.id', 'clients.name', 'clients.status','clients.progress_indicator_score', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag')
->whereRaw("status = 'inactive'") ->whereRaw("status IN ('inactive', 'Cancelled')")
->orderBy('name', 'ASC') ->orderBy('name', 'ASC')
->get(); ->get();
// ->paginate(15); // ->paginate(15);
@@ -116,8 +142,8 @@ class ClientsController extends Controller
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->join('flags AS flags', 'flags.country', '=', 'clients.country') ->join('flags AS flags', 'flags.country', '=', 'clients.country')
->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag') ->select('clients.id','clients.name', 'clients.status', 'clients.progress_indicator_score','clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy', 'flags.url AS theflag')
->whereRaw("status = 'inactive'") ->whereRaw("status IN ('inactive', 'Cancelled')")
->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%' OR clients.progress_indicator_score like '%$keyword%'") ->whereRaw("clients.name LIKE '%$keyword%' OR clients.status LIKE '%$keyword%' OR clients.country LIKE '%$keyword%' OR aumngr.name LIKE '%$keyword%' OR aumodify.name LIKE '%$keyword%' OR clients.progress_indicator_score LIKE '%$keyword%'")
->orderBy('name', 'ASC') ->orderBy('name', 'ASC')
->get(); ->get();
// ->paginate(15); // ->paginate(15);
@@ -130,7 +156,7 @@ class ClientsController extends Controller
->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id') ->join('auth_users AS aumngr', 'aumngr.id', '=', 'clients.auth_user_id')
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->select('clients.id', 'clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') ->select('clients.id', 'clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy')
->whereRaw("status = 'inactive'") ->whereRaw("status = 'Inactive'")
->paginate(10); ->paginate(10);
if($request->has('keyword')){ if($request->has('keyword')){
@@ -140,7 +166,7 @@ class ClientsController extends Controller
->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by') ->join('auth_users AS aumodify', 'aumodify.id', '=', 'clients.last_modified_by')
->select('clients.id','clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy') ->select('clients.id','clients.name', 'clients.status', 'clients.country', 'aumngr.name As accountMgr', 'aumodify.name AS modifiedBy')
// ->where('status', 'inactive') // ->where('status', 'inactive')
->whereRaw("status = 'inactive'") ->whereRaw("status = 'Inactive'")
->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'") ->whereRaw("clients.name like '%$keyword%' or clients.status like '%$keyword%' OR clients.country like '%$keyword%' OR aumngr.name like '%$keyword%' OR aumodify.name like '%$keyword%'")
->paginate(10); ->paginate(10);
} }
@@ -159,7 +185,7 @@ class ClientsController extends Controller
$service_type = Models\Service::pluck('name', 'name'); $service_type = Models\Service::pluck('name', 'name');
$payment_type = ['Prepaid' => 'Prepaid', 'Postpaid' => 'Postpaid']; //Models\PaymentType::pluck('name', 'id'); $payment_type = ['Prepaid' => 'Prepaid', 'Postpaid' => 'Postpaid']; //Models\PaymentType::pluck('name', 'id');
$auth_users = Models\SystemUser::pluck('name', 'id'); $auth_users = Models\SystemUser::pluck('name', 'id');
$status = ['Live' => 'Live', 'inactive' => 'Inactive', 'Prospective' => 'Prospective', 'Cancelled' => 'Cancelled']; $status = ['Live' => 'Live', 'Inactive' => 'Inactive', 'Prospective' => 'Prospective', 'Cancelled' => 'Cancelled'];
$currency = Models\Currency::pluck('name','name'); $currency = Models\Currency::pluck('name','name');
$company_types = ['Aggregator/Supplier' => 'Aggregator/Supplier', 'Enterprise' => 'Enterprise', 'Hybrid' => 'Hybrid']; $company_types = ['Aggregator/Supplier' => 'Aggregator/Supplier', 'Enterprise' => 'Enterprise', 'Hybrid' => 'Hybrid'];
$industries = Models\Industry::orderBy('name', 'ASC')->pluck('name', 'name'); $industries = Models\Industry::orderBy('name', 'ASC')->pluck('name', 'name');

View File

@@ -24,7 +24,7 @@ class DashboardController extends Controller
$recent_clients = Models\Client::with('auth_user_info')->orderBy('id', 'DESC')->take(5)->get(); $recent_clients = Models\Client::with('auth_user_info')->orderBy('id', 'DESC')->take(5)->get();
// $upcoming_birthdays = Models\StaffMember::whereDate('dob', '>=', $currentdate)->orderBy('dob', 'ASC')->take(5)->get(); // $upcoming_birthdays = Models\StaffMember::whereDate('dob', '>=', $currentdate)->orderBy('dob', 'ASC')->take(5)->get();
$upcoming_birthdays = Models\StaffMember::whereRaw("(month(dob) >= month(curdate())) AND day(dob) >= day(curdate())")->orderBy('dob', 'ASC')->take(5)->get(); $upcoming_birthdays = Models\StaffMember::whereRaw("(month(dob) >= month(curdate())) AND day(dob) >= day(curdate())")->orderBy('dob', 'ASC')->take(5)->get();
$upcoming_hodidays = Models\NationalHoliday::whereRaw("(month(event_date) >= month(curdate()))")->orderBy('event_date', 'ASC')->take(5)->get(); $upcoming_hodidays = Models\NationalHoliday::whereRaw("(month(event_date) >= month(curdate()))")->whereRaw("(year(event_date) >= year(curdate()))")->orderBy('event_date', 'ASC')->take(15)->get();
// dd($upcoming_hodidays); // dd($upcoming_hodidays);
// $recent_clients = Models\Client::orderBy('id', 'DESC')->take(5)->get(); // $recent_clients = Models\Client::orderBy('id', 'DESC')->take(5)->get();

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Http\Controllers;
use Webklex\PHPIMAP\ClientManager;
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
use App\Libs\ImapService;
use Illuminate\Http\JsonResponse;
class EmailController extends Controller
{
public function indexInbox(ImapService $imap): JsonResponse{
try {
$emails = $imap->getLatestEmails(10);
return response()->json($emails);
// Or for view: return view('emails.index', compact('emails'));
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function index()
{
try {
// Initialize IMAP client
$client = app(ClientManager::class)->account('default');
$client->connect();
// Get INBOX folder
$folder = $client->getFolder('INBOX');
// Fetch last 10 emails (newest first)
$messages = $folder->messages()->unseen()->limit(10)->get();
// Prepare data for view
$emails = $messages->map(function ($message) {
return [
'subject' => $message->getSubject() ?? '(No Subject)',
'sender' => $message->getFrom()[0]->mail ?? 'Unknown',
'email_date' => $message->getDate()->toDateTimeString(),
'email_body' => substr(strip_tags($message->getTextBody()), 0, 200) . '...',
];
});
// Disconnect
$client->disconnect();
dd($emails);
// Return view or JSON
// return view('emails.index', compact('emails'));
// Or for API: return response()->json($emails);
} catch (ConnectionFailedException $e) {
return response()->json(['error' => 'Failed to connect: ' . $e->getMessage()], 500);
} catch (\Exception $e) {
return response()->json(['error' => 'Error: ' . $e->getMessage()], 500);
}
}
}

View File

@@ -21,8 +21,6 @@ class StaffMembersController extends Controller
} }
public function profile($staff_member_id){ public function profile($staff_member_id){
$staff_member = Models\StaffMember::find($staff_member_id); $staff_member = Models\StaffMember::find($staff_member_id);
// dd($staff_member);
$data = [ $data = [
'page_title' => 'Staff Profile', 'page_title' => 'Staff Profile',
'staff_member' => $staff_member, 'staff_member' => $staff_member,
@@ -30,6 +28,12 @@ class StaffMembersController extends Controller
]; ];
return view('staff_members.profile', $data); return view('staff_members.profile', $data);
} }
public function profile_json(){
$staff_member_id = session('current_user.id');
$staff_member = Models\StaffMember::findOrFail($staff_member_id);
return response()->json(['code' => 1, 'staff_member' => $staff_member]);
}
public function indexOld(){ public function indexOld(){
$staff_members_arr = new Models\StaffMember; $staff_members_arr = new Models\StaffMember;
$data = [ $data = [
@@ -38,6 +42,26 @@ class StaffMembersController extends Controller
]; ];
return view('staff_members.index', $data); return view('staff_members.index', $data);
} }
public function profileupdate(Request $request)
{
$account_arr = Models\StaffMember::find($request->user_id);
$account_arr->name = $request->name;
$account_arr->email = $request->email;
$account_arr->phone = $request->phone;
$msg_text = 'Staff detials successfully Updated';
if ($request->password == true) {
$account_arr->password = md5($request->password);
$msg_text = "Staff details and password successfully updated";
}
$result = $account_arr->save();
if ($result == true) {
$data = ['code' => 1, 'msg' => $msg_text];
}
else{
$data = ['code' => 1, 'msg' => 'Staff details could not be updated at this time. Try again!'];
}
return response()->json($data);
}
public function getstaffMemberssJson(Request $request) public function getstaffMemberssJson(Request $request)
{ {
#$this->log_query(); #$this->log_query();

View File

@@ -53,6 +53,12 @@ class SystemUsersController extends Controller
return view('systemusers.index', $data); return view('systemusers.index', $data);
} }
public function profile_json(){
$staff_member_id = session('current_user.id');
$staff_member = Models\SystemUser::findOrFail($staff_member_id);
return response()->json(['code' => 1, 'staff_member' => $staff_member]);
}
/** /**
* Show the form for creating a new resource. * Show the form for creating a new resource.
@@ -156,6 +162,25 @@ class SystemUsersController extends Controller
Session::flash('success_message', 'Account successfully Updated'); Session::flash('success_message', 'Account successfully Updated');
return redirect(url('systemusers')); return redirect(url('systemusers'));
} }
public function profileupdate(Request $request){
$account_arr = Models\SystemUser::find($request->user_id);
$account_arr->name = $request->name;
$account_arr->email = $request->email;
$account_arr->phone = $request->phone;
$msg_text = 'Account successfully Updated';
if ($request->password == true) {
$account_arr->password = md5($request->password);
$msg_text = "Account details and password successfully updated";
}
$result = $account_arr->save();
if ($result == true) {
$data = ['code' => 1, 'msg' => $msg_text];
}
else{
$data = ['code' => 1, 'msg' => 'Account could not be updated at this time. Try again!'];
}
return response()->json($data);
}
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.

57
app/Libs/ImapService.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
namespace App\Libs;
class ImapService
{
protected $connection;
public function __construct()
{
/*
$hostname = '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX';
$username = "kwesibanson@gmail.com"; // env('IMAP_USERNAME', 'your.email@gmail.com');
$password = "yutbgxtlqwwepalr"; //env('IMAP_PASSWORD', 'your-app-password');
*/
$hostname = '{imap-mail.outlook.com:993/imap/ssl/novalidate-cert}INBOX';
$username = "kwesi_banson@hotmail.com"; // env('IMAP_USERNAME', 'your.email@gmail.com');
$password = "uyligiqtreyubvvp"; //"okxixwlqppkpfepy"; //env('IMAP_PASSWORD', 'your-app-password');
$this->connection = @imap_open($hostname, $username, $password);
if (!$this->connection) {
throw new \Exception('Cannot connect: ' . imap_last_error());
}
}
public function getLatestEmails($limit = 10): array
{
$emails = imap_search($this->connection, 'ALL', SE_UID);
if (!$emails) {
return [];
}
rsort($emails); // Newest first
$result = [];
foreach (array_slice($emails, 0, $limit) as $uid) {
$header = imap_headerinfo($this->connection, imap_msgno($this->connection, $uid), FT_UID);
$body = imap_fetchbody($this->connection, imap_msgno($this->connection, $uid), 1, FT_UID);
$body = quoted_printable_decode($body);
$result[] = [
'subject' => isset($header->subject) ? imap_utf8($header->subject) : '(No Subject)',
'from' => $header->from[0]->mailbox . '@' . $header->from[0]->host,
'date' => $header->date ?? 'Unknown',
'body' => substr(strip_tags($body), 0, 200) . '...',
];
}
return $result;
}
public function __destruct()
{
if ($this->connection) {
imap_close($this->connection);
}
}
}

View File

@@ -1,12 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DailyQoute extends Model
{
// public $timestamps = false;
protected $guarded = array('id');
public $table = "daily_qoutes";
}

10
app/Models/DailyQuote.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DailyQuote extends Model
{
//
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\models;
use Illuminate\Database\Eloquent\Model;
class IncomingEmail extends Model
{
protected $guarded = array('id');
public $table = "incoming_emails";
}

View File

@@ -12,7 +12,8 @@
"laravelcollective/html": "^5.4.0", "laravelcollective/html": "^5.4.0",
"maatwebsite/excel": "^3.1", "maatwebsite/excel": "^3.1",
"pusher/pusher-php-server": "^7.2", "pusher/pusher-php-server": "^7.2",
"thibaud-dauce/laravel-mattermost-logger": "^1.2" "thibaud-dauce/laravel-mattermost-logger": "^1.2",
"webklex/laravel-imap": "^4.1"
}, },
"require-dev": { "require-dev": {
"filp/whoops": "~2.0", "filp/whoops": "~2.0",

160
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "55c340daa242a9f806959c576ed88b31", "content-hash": "c423f959b14bacba91bd6e5f5eabde1b",
"packages": [ "packages": [
{ {
"name": "dnoegel/php-xdg-base-dir", "name": "dnoegel/php-xdg-base-dir",
@@ -4840,6 +4840,164 @@
} }
], ],
"time": "2021-01-20T14:39:13+00:00" "time": "2021-01-20T14:39:13+00:00"
},
{
"name": "webklex/laravel-imap",
"version": "4.1.2",
"source": {
"type": "git",
"url": "https://github.com/Webklex/laravel-imap.git",
"reference": "9038139b8789e60c998eb389d419d41b969f2713"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Webklex/laravel-imap/zipball/9038139b8789e60c998eb389d419d41b969f2713",
"reference": "9038139b8789e60c998eb389d419d41b969f2713",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"ext-iconv": "*",
"ext-mbstring": "*",
"laravel/framework": ">=5.0.0",
"php": ">=5.5.9",
"webklex/php-imap": "^4.1.2"
},
"type": "library",
"extra": {
"laravel": {
"aliases": {
"Client": "Webklex\\IMAP\\Facades\\Client"
},
"providers": [
"Webklex\\IMAP\\Providers\\LaravelServiceProvider"
]
},
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Webklex\\IMAP\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Malte Goldenbaum",
"email": "github@webklex.com",
"role": "Developer"
}
],
"description": "Laravel IMAP client",
"homepage": "https://github.com/webklex/laravel-imap",
"keywords": [
"idle",
"imap",
"laravel",
"laravel-imap",
"mail",
"oauth",
"pop3",
"webklex"
],
"support": {
"issues": "https://github.com/Webklex/laravel-imap/issues",
"source": "https://github.com/Webklex/laravel-imap/tree/4.1.2"
},
"funding": [
{
"url": "https://www.buymeacoffee.com/webklex",
"type": "custom"
},
{
"url": "https://ko-fi.com/webklex",
"type": "ko_fi"
}
],
"time": "2023-01-18T18:33:20+00:00"
},
{
"name": "webklex/php-imap",
"version": "4.1.2",
"source": {
"type": "git",
"url": "https://github.com/Webklex/php-imap.git",
"reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Webklex/php-imap/zipball/94bf93ae8868ac1e073cfbaef377f0ca1acac2bc",
"reference": "94bf93ae8868ac1e073cfbaef377f0ca1acac2bc",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-mbstring": "*",
"ext-openssl": "*",
"illuminate/pagination": ">=5.0.0",
"nesbot/carbon": ">=1.0",
"php": ">=7.0.0",
"symfony/http-foundation": ">=2.8.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"suggest": {
"symfony/mime": "Recomended for better extension support"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Webklex\\PHPIMAP\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Malte Goldenbaum",
"email": "github@webklex.com",
"role": "Developer"
}
],
"description": "PHP IMAP client",
"homepage": "https://github.com/webklex/php-imap",
"keywords": [
"imap",
"mail",
"php-imap",
"pop3",
"webklex"
],
"support": {
"issues": "https://github.com/Webklex/php-imap/issues",
"source": "https://github.com/Webklex/php-imap/tree/4.1.2"
},
"funding": [
{
"url": "https://www.buymeacoffee.com/webklex",
"type": "custom"
},
{
"url": "https://ko-fi.com/webklex",
"type": "ko_fi"
}
],
"time": "2022-12-14T15:45:15+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [

246
config/imap.php Normal file
View File

@@ -0,0 +1,246 @@
<?php
/*
* File: imap.php
* Category: config
* Author: M. Goldenbaum
* Created: 24.09.16 22:36
* Updated: -
*
* Description:
* -
*/
return [
/*
|--------------------------------------------------------------------------
| IMAP default account
|--------------------------------------------------------------------------
|
| The default account identifier. It will be used as default for any missing account parameters.
| If however the default account is missing a parameter the package default will be used.
| Set to 'false' [boolean] to disable this functionality.
|
*/
'default' => env('IMAP_DEFAULT_ACCOUNT', 'default'),
/*
|--------------------------------------------------------------------------
| Default date format
|--------------------------------------------------------------------------
|
| The default date format is used to convert any given Carbon::class object into a valid date string.
| These are currently known working formats: "d-M-Y", "d-M-y", "d M y"
|
*/
'date_format' => 'd-M-Y',
/*
|--------------------------------------------------------------------------
| Available IMAP accounts
|--------------------------------------------------------------------------
|
| Please list all IMAP accounts which you are planning to use within the
| array below.
|
*/
'accounts' => [
'default' => [// account identifier
'host' => env('IMAP_HOST', 'localhost'),
'port' => env('IMAP_PORT', 993),
'protocol' => env('IMAP_PROTOCOL', 'imap'), //might also use imap, [pop3 or nntp (untested)]
'encryption' => env('IMAP_ENCRYPTION', 'ssl'), // Supported: false, 'ssl', 'tls', 'notls', 'starttls'
'validate_cert' => env('IMAP_VALIDATE_CERT', true),
'username' => env('IMAP_USERNAME', 'root@example.com'),
'password' => env('IMAP_PASSWORD', ''),
'authentication' => env('IMAP_AUTHENTICATION', null),
'proxy' => [
'socket' => null,
'request_fulluri' => false,
'username' => null,
'password' => null,
],
"timeout" => 30,
"extensions" => []
],
/*
'gmail' => [ // account identifier
'host' => 'imap.gmail.com',
'port' => 993,
'encryption' => 'ssl',
'validate_cert' => true,
'username' => 'example@gmail.com',
'password' => 'PASSWORD',
'authentication' => 'oauth',
],
'another' => [ // account identifier
'host' => '',
'port' => 993,
'encryption' => false,
'validate_cert' => true,
'username' => '',
'password' => '',
'authentication' => null,
]
*/
],
/*
|--------------------------------------------------------------------------
| Available IMAP options
|--------------------------------------------------------------------------
|
| Available php imap config parameters are listed below
| -Delimiter (optional):
| This option is only used when calling $oClient->
| You can use any supported char such as ".", "/", (...)
| -Fetch option:
| IMAP::FT_UID - Message marked as read by fetching the body message
| IMAP::FT_PEEK - Fetch the message without setting the "seen" flag
| -Fetch sequence id:
| IMAP::ST_UID - Fetch message components using the message uid
| IMAP::ST_MSGN - Fetch message components using the message number
| -Body download option
| Default TRUE
| -Flag download option
| Default TRUE
| -Soft fail
| Default FALSE - Set to TRUE if you want to ignore certain exception while fetching bulk messages
| -RFC822
| Default TRUE - Set to FALSE to prevent the usage of \imap_rfc822_parse_headers().
| See https://github.com/Webklex/php-imap/issues/115 for more information.
| -Debug enable to trace communication traffic
| -UID cache enable the UID cache
| -Fallback date is used if the given message date could not be parsed
| -Boundary regex used to detect message boundaries. If you are having problems with empty messages, missing
| attachments or anything like this. Be advised that it likes to break which causes new problems..
| -Message key identifier option
| You can choose between the following:
| 'id' - Use the MessageID as array key (default, might cause hickups with yahoo mail)
| 'number' - Use the message number as array key (isn't always unique and can cause some interesting behavior)
| 'list' - Use the message list number as array key (incrementing integer (does not always start at 0 or 1)
| 'uid' - Use the message uid as array key (isn't always unique and can cause some interesting behavior)
| -Fetch order
| 'asc' - Order all messages ascending (probably results in oldest first)
| 'desc' - Order all messages descending (probably results in newest first)
| -Disposition types potentially considered an attachment
| Default ['attachment', 'inline']
| -Common folders
| Default folder locations and paths assumed if none is provided
| -Open IMAP options:
| DISABLE_AUTHENTICATOR - Disable authentication properties.
| Use 'GSSAPI' if you encounter the following
| error: "Kerberos error: No credentials cache
| file found (try running kinit) (...)"
| or ['GSSAPI','PLAIN'] if you are using outlook mail
|
*/
'options' => [
'delimiter' => '/',
'fetch' => \Webklex\PHPIMAP\IMAP::FT_PEEK,
'sequence' => \Webklex\PHPIMAP\IMAP::ST_UID,
'fetch_body' => true,
'fetch_flags' => true,
'soft_fail' => false,
'rfc822' => true,
'debug' => false,
'uid_cache' => true,
// 'fallback_date' => "01.01.1970 00:00:00",
'boundary' => '/boundary=(.*?(?=;)|(.*))/i',
'message_key' => 'list',
'fetch_order' => 'asc',
'dispositions' => ['attachment', 'inline'],
'common_folders' => [
"root" => "INBOX",
"junk" => "INBOX/Junk",
"draft" => "INBOX/Drafts",
"sent" => "INBOX/Sent",
"trash" => "INBOX/Trash",
],
'open' => [
// 'DISABLE_AUTHENTICATOR' => 'GSSAPI'
]
],
/**
* |--------------------------------------------------------------------------
* | Available decoding options
* |--------------------------------------------------------------------------
* |
* | Available php imap config parameters are listed below
* | -options: Decoder options (currently only the message subject and attachment name decoder can be set)
* | 'utf-8' - Uses imap_utf8($string) to decode a string
* | 'mimeheader' - Uses mb_decode_mimeheader($string) to decode a string
* | -decoder: Decoder to be used. Can be replaced by custom decoders if needed.
* | 'header' - HeaderDecoder
* | 'message' - MessageDecoder
* | 'attachment' - AttachmentDecoder
*/
'decoding' => [
'options' => [
'header' => 'utf-8', // mimeheader
'message' => 'utf-8', // mimeheader
'attachment' => 'utf-8' // mimeheader
],
'decoder' => [
'header' => \Webklex\PHPIMAP\Decoder\HeaderDecoder::class,
'message' => \Webklex\PHPIMAP\Decoder\MessageDecoder::class,
'attachment' => \Webklex\PHPIMAP\Decoder\AttachmentDecoder::class
]
],
/*
|--------------------------------------------------------------------------
| Available flags
|--------------------------------------------------------------------------
|
| List all available / supported flags. Set to null to accept all given flags.
*/
'flags' => ['recent', 'flagged', 'answered', 'deleted', 'seen', 'draft'],
/*
|--------------------------------------------------------------------------
| Available events
|--------------------------------------------------------------------------
|
*/
'events' => [
"message" => [
'new' => \Webklex\IMAP\Events\MessageNewEvent::class,
'moved' => \Webklex\IMAP\Events\MessageMovedEvent::class,
'copied' => \Webklex\IMAP\Events\MessageCopiedEvent::class,
'deleted' => \Webklex\IMAP\Events\MessageDeletedEvent::class,
'restored' => \Webklex\IMAP\Events\MessageRestoredEvent::class,
],
"folder" => [
'new' => \Webklex\IMAP\Events\FolderNewEvent::class,
'moved' => \Webklex\IMAP\Events\FolderMovedEvent::class,
'deleted' => \Webklex\IMAP\Events\FolderDeletedEvent::class,
],
"flag" => [
'new' => \Webklex\IMAP\Events\FlagNewEvent::class,
'deleted' => \Webklex\IMAP\Events\FlagDeletedEvent::class,
],
],
/*
|--------------------------------------------------------------------------
| Available masking options
|--------------------------------------------------------------------------
|
| By using your own custom masks you can implement your own methods for
| a better and faster access and less code to write.
|
| Checkout the two examples custom_attachment_mask and custom_message_mask
| for a quick start.
|
| The provided masks below are used as the default masks.
*/
'masks' => [
'message' => \Webklex\PHPIMAP\Support\Masks\MessageMask::class,
'attachment' => \Webklex\PHPIMAP\Support\Masks\AttachmentMask::class
]
];

10
issues-20-02-2026.md Normal file
View File

@@ -0,0 +1,10 @@
1. The logo looks stretched. Can we get that fixed? resized and repositioned it nut we need a new one
2. we need to get ERP SSL sorted. -- this needs a domain name
3. Sams message of the day: Sam suggested we have an email that the quotes can be sent to and automatically update on the ERP.
And maybe add other quotes from different people. Not just Sams quote.
Have Effie, maybe Mansa, maybe you. And it should be changed to weekly not daily
implemented a solution with the emails
4. for contract validity (expiry date), add a feature for Auto Renewal which wont be asking for the validity.
This is of contracts that dont expire. done. need to upload
5. for the Holidays, he asked that I send emails to Country Managers every month asking for the following month holidays of their respective countries
6. How far with the profile page? -- done

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,16 @@
{"senderid":"IKKODE","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"KREEZUS","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"AIR CI","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"BENIN CTRL","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"AMNESTY","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"Sun King","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":"_"}
{"senderid":"ECOBANK","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"SGB","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"SimAU","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"CORIS MESO","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"ADKONTACT","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"Missebo app","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"Boo co","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"TransAfrika","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"MOON","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}
{"senderid":"SONAM HONDA","direct_mno":"NO","mno_name":"MOOV(Benin)","supplier_name":null,"status":"Approved on MNO","remarks":null}

View File

@@ -0,0 +1,108 @@
@extends('layouts.master')
@section('page_title')
@if(isset($page_title))
{{ $page_title }}
@endif
@endsection
@section('content')
<div class="">
<div class="page-title">
<div class="title_left" style="width:800px !important;">
<ol class="breadcrumb">
<li><a href="{!! url('dashboard') !!}">Dashboard</a></li>
<li class="active"><a href="{!! url('ss') !!}">dailyquote</a></li>
<li class="active">New Daily Quote</li>
</ol>
</div>
</div>
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
New Daily Quote
@include('commons.notifications')
<div class="clearfix"></div>
</div>
{{-- start of content --}}
<div class="x_content">
<br>
{!! Form::open(['url' => 'dailyquotes', 'id' => 'dailyQuoteCreateForm', 'class' => 'form-horizontal form-label-left']) !!}
<div class="row">
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="quoteIDD">dailyquote ID</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('quote') ? 'has-error' : ''}}">
{!! Form::text('quote', old('quote'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter quote , 'id' => 'quoteIDD', 'required' => 'true']) !!}
{!! $errors->first('quote', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="directMno">Direct MNO</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('direct_mno') ? 'has-error' : ''}}">
{!! Form::select('direct_mno', $direct_mno_arr ,old('direct_mno'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select one ' , 'id' => 'directMno', 'required' => 'true']) !!}
{!! $errors->first('direct_mno', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group " id="mnoDiv">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="networkName">MNO Name</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('network') ? 'has-error' : ''}}">
{!! Form::select('mno_name', $network_arr, old('mno_name'), ['class' => 'form-control col-md-7 col-xs-12', 'id' => 'networkName', 'placeholder' => '-- Select --', 'required' => 'true', 'style' => 'width:100%;']) !!}
{!! $errors->first('network', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group " id="supplierDiv">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="supplierName">Supplier Name</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('name') ? 'has-error' : ''}}">
<!-- 'required' => 'true', -->
{!! Form::select('supplier_name', $clients, old('supplier_name'), ['class' => 'form-control', 'id' => 'supplierName', 'placeholder' => '-- Select --', 'style' => 'width:100%;']) !!}
{!! $errors->first('client_id', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="status">Status</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('status') ? 'has-error' : ''}}">
{!! Form::select('status', $status ,old('status'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select Status ' , 'id' => 'status', 'required' => 'true']) !!}
{!! $errors->first('status', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="remarks">Remarks</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('remarks') ? 'has-error' : ''}}">
{!! Form::text('remarks', old('remarks'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter remarks here' , 'id' => 'remarks']) !!}
{!! $errors->first('remarks', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="ln_solid"></div>
<div class="form-group">
<div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-3">
<button type="submit" class="btn btn-success btn-block"><i class="fa fa-save"></i> Submit</button>
&nbsp;
<button type="button" class="btn btn-warning btn-block" id="resetBtn"><i class="fa fa-save"></i> Reset</button>
</div>
</div>
{!! Form::close() !!}
</div>
{{-- end of x_content --}}
</div>
{{-- end of x_panel --}}
</div>
</div>
</div>
@endsection
@section('javascript')
<script type="text/javascript" src="{!! url('public/assets/js/dailyquotes.js') !!}"></script>
<script type="text/javascript">
$(function(){
$('select').select2();
});
</script>
@endsection

View File

@@ -0,0 +1,105 @@
@extends('layouts.master')
@section('page_title')
@if(isset($page_title))
{{ $page_title }}
@endif
@endsection
@section('content')
<div class="">
<div class="page-title">
<div class="title_left" style="width:800px !important;">
<ol class="breadcrumb">
<li><a href="{!! url('dashboard') !!}">Dashboard</a></li>
<li class="active"><a href="{!! url('senderids') !!}">Sender IDs</a></li>
<li class="active">Update Sender ID</li>
</ol>
</div>
</div>
<div class="clearfix"></div>
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
Update Sender ID
@include('commons.notifications')
<div class="clearfix"></div>
</div>
{{-- start of content --}}
<div class="x_content">
<br>
{!! Form::model($senderid, [
'method' => 'PATCH',
'url' => ['senderids', $senderid],
'class' => 'form-horizontal form-label-left'
]) !!}
<div class="row">
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="senderIddEdit">Sender ID</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('senderid') ? 'has-error' : ''}}">
{!! Form::text('senderid', old('senderid'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter sender ID' , 'id' => 'senderIddEdit', 'required' => 'true']) !!}
{!! $errors->first('name', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="directMnoEdit">Direct MNO</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('direct_mno') ? 'has-error' : ''}}">
{!! Form::select('direct_mno', $direct_mno_arr ,old('direct_mno'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select one ' , 'id' => 'directMnoEdit', 'required' => 'true']) !!}
{!! $errors->first('direct_mno', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group <?php //echo ($senderid->direct_mno == 'YES') ? "" : "hidden"; ?>" id="mnoDivEdit">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="networkNameEdit">MNO Name</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('network') ? 'has-error' : ''}}">
{!! Form::select('mno_name', $network_arr, old('mno_name'), ['class' => 'form-control col-md-7 col-xs-12', 'id' => 'networkNameEdit', 'placeholder' => '-- Select --', 'style' => 'width:100%;']) !!}
{!! $errors->first('network', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group <?php //echo ($senderid->direct_mno == 'YES') ? "hidden" : ""; ?>" id="supplierDivEdit">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="supplierNameEdit">Supplier Name</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('name') ? 'has-error' : ''}}">
{!! Form::select('supplier_name', $clients, old('supplier_name'), ['class' => 'form-control', 'id' => 'supplierNameEdit', 'placeholder' => '-- Select --', 'style' => 'width:100%;']) !!}
{!! $errors->first('client_id', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="statusEdit">Status</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('status') ? 'has-error' : ''}}">
{!! Form::select('status', $status ,old('status'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Select Status ' , 'id' => 'statusEdit', 'required' => 'true']) !!}
{!! $errors->first('status', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12" for="remarksEdit">Remarks</label>
<div class="col-md-6 col-sm-6 col-xs-12 {{ $errors->has('remarks') ? 'has-error' : ''}}">
{!! Form::text('remarks', old('remarks'), ['class' => 'form-control col-md-7 col-xs-12', 'placeholder'=>'Enter remarks here' , 'id' => 'remarksEdit']) !!}
{!! $errors->first('remarks', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="ln_solid"></div>
<div class="form-group">
<div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-3">
<button type="submit" class="btn btn-success btn-block"><i class="fa fa-save"></i> Submit</button>
</div>
</div>
{!! Form::close() !!}
</div>
{{-- end of x_content --}}
</div>
{{-- end of x_panel --}}
</div>
</div>
</div>
@endsection
@section('javascript')
<script type="text/javascript" src="{!! url('public/assets/js/senderid.js') !!}"></script>
<script type="text/javascript">
$(function(){
$('select').select2();
});
</script>
@endsection

View File

@@ -0,0 +1,199 @@
@extends('layouts.master')
@section('page_title')
@if(isset($page_title))
{{ $page_title }}
@endif
@endsection
@section('css')
<link href="{!! url('public/assets/vendors/tabulator/css/bootstrap/tabulator_bootstrap.css') !!}" type="text/css" rel="stylesheet">
@endsection
@section('content')
<div class="">
<div class="page-title">
<div class="title_left">
<div class="title_left">
<ol class="breadcrumb">
<li><a href="{!! url('dashboard') !!}">Dashboard</a></li>
<li class="active">Sender IDs</li>
</ol>
</div>
</div>
<div class="title_right">
<div class="row">
<form method="GET" action="{!! url('senderids') !!}">
<div class="col-md-5 col-sm-5 col-xs-12 form-group">
<div style="margin-top:1px; margin-right:-90px;" class="top_search">
</div>
</div>
<div class="col-md-5 col-sm-5 col-xs-12 form-group pull-right top_search" style="margin-top: -2px;">
<div class="input-group">
<input type="text" name="keyword" class="form-control" id="keywordField" placeholder="Keyword here...">
<span class="input-group-btn">
<button type="submit" class="btn btn-primary" style="color: #fff;" type="button">Go!</button>
</span>
</div>
</div>
</form>
</div>
<div class="row">
<div class="col-sm-12">
<div class="pull-right"></div>
</div>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="row">
@include('commons.notifications')
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2> Sender IDs </h2>
<div class="pull-right">
<a class="btn btn-warning btn-sm" href="{!! url('senderids/upload') !!}"><i class="fa fa-cloud-upload"></i> Upload Sender IDs</a>
<a class="btn btn-primary btn-sm" href="{!! url('senderids/create') !!}"><i class="fa fa-plus-circle"></i> New Sender ID</a>
<a class="btn btn-success btn-sm" href="{!! url('senderids/exportall') !!}"><i class="fa fa-plus-circle"></i> Download All</a>
</div>
<div class="clearfix"></div>
</div>
<div class="x_content">
@if(session('current_user.rejected_rows_filename') !== null)
<div class=" well" >
<?php $url = session('current_user.rejected_rows_filename');?>
<a href="{{ url('senderids/uploadreportdownload', $url) }}" class="btn btn-link">View Sender ID Bulk Upload Report</a>
</div>
@endif
<div>
<!-- <button id="senderid-download-xlsx" class="btn btn-success btn-sm"><i class="fa fa-file-excel-o"></i> Download XLSX</button>
<button id="senderid-download-pdf" class="btn btn-danger btn-sm"><i class="fa fa-file-pdf-o"></i> Download PDF</button> -->
</div>
<div id="senderIdsTable"></div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('javascript')
<script src="{!! url('public/assets/vendors/tabulator/js/tabulator.js') !!}"></script>
<script type="text/javascript" src="{!! url('public/assets/vendors/tabulator/js/xlsx.full.min.js') !!}"></script>
<script type="text/javascript" src="{!! url('public/assets/vendors/tabulator/js/jspdf.min.js') !!}"></script>
<script type="text/javascript" src="{!! url('public/assets/vendors/tabulator/js/jspdf.plugin.autotable.js') !!}"></script>
<script type="text/javascript">
$(document).ready(function(){
function link(cell, formatterParams){
var url = cell.getValue();
var rowID = cell.getData().id
return "<a href='"+ base_url + "/senderids/"+rowID+"/edit' class='btn btn-link'>"+url+"</a>";
}
function cellDesign (cell, formatterParams){
var value = cell.getValue();
return "<span style='color:#54B4D3; font-weight:bold;'>" + value + "</span>";
}
function statusDesign (cell, formatterParams){
var value = cell.getValue();
// if(value === 'Approved'){
// console.log(value !== null);
if (value !== null) {
if(value.includes('Approved')){
return "<span style='color:#3FB449; font-weight:bold;'>" + value + "</span>";
}
else if(value.includes('Active')){
return "<span style='color:#3FB449; font-weight:bold;'>" + value + "</span>";
}
else{
return "<span style='color:#E4A11B;'>" + value + "</span>";
}
}
}
var table = new Tabulator("#senderIdsTable", {
ajaxURL: "senderids/all",
paginationSize: 15,
layout: "fitColumns",
pagination: "remote",
selectable: false,
printAsHtml: true,
ajaxLoaderLoading: $('#logo_spinner').html(),
columns: [
{
title: "Sender ID",
field: "senderid",
sorter: "string",
formatter: cellDesign,
formatter:link,
},
{
title: "Direct MNO",
field: "direct_mno",
sorter: "string",
},
{
title: "Network",
field: "mno_name",
sorter: "string",
},
{
title: "Supplier",
field: "supplier_name",
sorter: "string",
},
{
title: "Status",
field: "status",
sorter: "string",
formatter: statusDesign,
},
{
title: "Remarks",
field: "remarks",
sorter: "string",
formatter: statusDesign,
},
{
title: "Created By",
field: "createdBy",
sorter: "string",
},
// {
// title: "Last Modified By",
// field: "modifiedBy",
// sorter: "string",
// }
],
rowClick:function(e, row){
var userID = row.getData().id;
console.log(userID);
//$('#userEditModal').modal('show');
},
});
document.getElementById("senderid-download-xlsx").addEventListener("click", function(){
table.download("xlsx", "senderid-list.xlsx", {sheetName:"Sheet 1"});
});
//trigger download of data.pdf file
document.getElementById("senderid-download-pdf").addEventListener("click", function(){
table.download("pdf", "client-list.pdf", {
orientation:"portrait", //set page orientation to portrait
title:"Click Mobile - Sender ID", //add title to report
});
});
$('#keywordField').on('keyup', function(){
console.log('up');
var keyword = $(this).val();
table.setData("senderids/all?keyword=" + keyword);
});
});
</script>
@endsection

View File

@@ -35,6 +35,7 @@
</head> </head>
<body class="nav-md"> <body class="nav-md">
@include('systemusers.partials.profile')
<div class="container-fluid "> <div class="container-fluid ">
<div class="row"> <div class="row">
<nav id="sidebarMenu" class=" col-lg-1 col-md-1 d-md-block sidebar collapse"> <nav id="sidebarMenu" class=" col-lg-1 col-md-1 d-md-block sidebar collapse">

View File

@@ -51,12 +51,14 @@
</head> </head>
<body class="nav-md"> <body class="nav-md">
@include('systemusers.partials.profile')
<div class="container body"> <div class="container body">
<div class="main_container"> <div class="main_container">
<div class="col-md-3 left_col"> <div class="col-md-3 left_col">
<div class="left_col scroll-view"> <div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;"> <div class="navbar nav_title" style="padding-top: 10px; padding-left: 15px;">
<img src="{{ url('public/assets/img/cml-final-3.png') }}" width="230px" height="70px" style="background-color: #fff;"> <!-- <img src="{{ url('public/assets/img/cml-logo.png') }}" style="background-color: #fff;"> -->
<img src="{{ url('public/assets/img/cml-final-3_no-bg.png') }}" width="200" style="background-color: #fff;">
<!-- <a href="{{ url('/') }}" class="site_title"><i class="fa fa-paw"></i> <!-- <a href="{{ url('/') }}" class="site_title"><i class="fa fa-paw"></i>
<span>Click ERP</span> <span>Click ERP</span>
</a> --> </a> -->
@@ -143,11 +145,105 @@
<script src="{!! url('public/assets/vendors/bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js') !!}"></script> <script src="{!! url('public/assets/vendors/bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js') !!}"></script>
<script src="{!! url('public/assets/js/jquery-confirm.min.js') !!}"></script> <script src="{!! url('public/assets/js/jquery-confirm.min.js') !!}"></script>
<script> <script>
$(document).ready(function(){
$('.profileLink').click(function(evt){
evt.preventDefault();
$.ajax({
type: "GET",
url: base_url + '/getprofile',
processData: false,
contentType: false,
async: false,
success: function (data){
if (data.code === 1) {
console.log(data);
$('.staffId').val(data.staff_member.id);
$('.staffName').val(data.staff_member.name);
$('.staffEmail').val(data.staff_member.email);
// $('.staffPhone').val(data.staff_member.status).change();
$('.staffPhone').val(data.staff_member.phone);
// $('.staffDesignation').val(data.staff_member.designation);
$('.staffDateAdded').val(data.staff_member.created_at);
$('#profileModal').modal('show');
}
else if (data.code > 1) {
$.alert({
title: 'Alert!',
content: data.msg,
});
}
else {
$.alert({
title: 'Alert!',
content: 'Your request could not be handled. Try again !',
});
}
}
});
});
$('#staffProfileForm').submit(function(evt){
evt.preventDefault(evt);
$('#successArea').addClass('d-none');
$('#errorsArea').removeClass('d-none');
var formData = new FormData($('#staffProfileForm')[0]);
$.ajax({
url: base_url + '/profileupdate',
type: 'POST',
data: formData,
processData: false,
contentType: false,
beforeSend: function() {
$('#successArea').text("");
$('#successArea').text("Please wait ... profile update in progress!");
},
success: function(data) {
if (data['code'] === 1) {
$('#successArea').removeClass('d-none');
$('#errorsArea').addClass('d-none');
$('#successArea').text("");
$('#successArea').text(data['msg']);
// location.reload();
$.alert({
title: 'Alert!',
content: data['msg'],
});
setTimeout(function() {
$('#profileModal').modal('hide');
//location.reload(); // Reloads the current page
}, 2000);
}
else{
$('#successArea').addClass('d-none');
$('#errorArea').removeClass('d-none');
$('#errorArea').text("");
$('#errorArea').text("Account could not be updated!");
$.alert({
title: 'Alert!',
content: 'Account could not updated!',
});
}
},
error: function(xhr, status, error) {
console.error('Error:', error);
$('#successArea').text(error);
$('#successArea').text(error);
$.alert({
title: 'Alert!',
content: error,
});
}
});
});
if ($('.notification-alert').length) { if ($('.notification-alert').length) {
setTimeout(() => { setTimeout(() => {
$('.notification-alert').slideUp() $('.notification-alert').slideUp()
}, 2000); }, 2000);
} }
});
</script> </script>
@yield('javascript') @yield('javascript')
@@ -158,3 +254,6 @@
</body> </body>
</html> </html>
1. User Service, 2. Payment Service 3. Notification Service 4. Transaction Service 5. Reporting Service.

View File

@@ -51,6 +51,8 @@
<li><a href="{!! url('underconstruction') !!}">Company Types</a></li> <li><a href="{!! url('underconstruction') !!}">Company Types</a></li>
<li><a href="{!! url('underconstruction') !!}">How We Got A Client</a></li> <li><a href="{!! url('underconstruction') !!}">How We Got A Client</a></li>
<li><a href="{!! url('underconstruction') !!}">Countries & Currencies </a></li> <li><a href="{!! url('underconstruction') !!}">Countries & Currencies </a></li>
<li><a href="{!! url('dailyquotes') !!}">Daily Quotes </a></li>
<li><a href="{!! url('underconstruction') !!}">National Holidays </a></li>
</ul> </ul>
</li> </li>
</ul> </ul>

View File

@@ -16,7 +16,8 @@ $staff_member_id = session('current_user.id');
<span class=" fa fa-angle-down"></span> <span class=" fa fa-angle-down"></span>
</a> </a>
<ul class="dropdown-menu dropdown-usermenu pull-right"> <ul class="dropdown-menu dropdown-usermenu pull-right">
<li><a href="{{ url('staffmembers/profile', $staff_member_id) }}"> Profile</a></li> <!-- <li><a href="{{ url('staffmembers/profile', $staff_member_id) }}"> Profile</a></li> -->
<li><a class="profileLink">Profile</a></li>
<!-- <li> <!-- <li>
<a href="javascript:;"> <a href="javascript:;">
<span class="badge bg-red pull-right">50%</span> <span class="badge bg-red pull-right">50%</span>

View File

@@ -69,8 +69,8 @@
@endif @endif
<div> <div>
<button id="senderid-download-xlsx" class="btn btn-success btn-sm"><i class="fa fa-file-excel-o"></i> Download XLSX</button> <!-- <button id="senderid-download-xlsx" class="btn btn-success btn-sm"><i class="fa fa-file-excel-o"></i> Download XLSX</button>
<button id="senderid-download-pdf" class="btn btn-danger btn-sm"><i class="fa fa-file-pdf-o"></i> Download PDF</button> <button id="senderid-download-pdf" class="btn btn-danger btn-sm"><i class="fa fa-file-pdf-o"></i> Download PDF</button> -->
</div> </div>
<div id="senderIdsTable"></div> <div id="senderIdsTable"></div>
</div> </div>

View File

@@ -0,0 +1,66 @@
<div class="modal fade" id="profileModal" tabindex="-1" role="dialog" aria-labelledby="profileModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header" style="background-color: #f8f8f8; border-bottom: 1px solid #eee;">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="profileModalLabel"><i class="glyphicon glyphicon-user"></i> User Profile</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<form method="POST" id="staffProfileForm">
<input type="hidden" name="user_id" class="staffId" value="">
{{ csrf_field() }}
<table class="table table-user-information">
<tbody>
<tr>
<td><strong>Full Name:</strong></td>
<td><input type="text" class="form-control staffName" name="name"></td>
</tr>
<tr>
<td><strong>Email:</strong></td>
<td><input type="text" class="form-control staffEmail" name="email"></td>
</tr>
<tr>
<td><strong>Phone:</strong></td>
<td><input type="text" class="form-control staffPhone" name="phone"></td>
</tr>
<!-- <tr>
<td><strong>Designation:</strong></td>
<td><input type="text" class="form-control staffDesignation" name="designation"></td>
</tr> -->
<tr>
<td><strong>Password :</strong></td>
<td>
<input type="password" name="password" class="form-control passwordReset" placeholder="**********">
<p class="text-help text-danger">Enter new password to reset</p>
</td>
</tr>
<tr>
<td><strong>Date Added:</strong></td>
<td><input type="text" readonly class="form-control staffDateAdded"></td>
</tr>
</tbody>
</table>
<button class="btn btn-block btn-primary"><i class="glyphicon glyphicon-floppy-disk"></i> Update</button>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<!-- <div class="pull-left">
<button type="button" class="btn btn-danger btn-sm">
<i class="glyphicon glyphicon-lock"></i> Reset Password
</button>
</div> -->
<!-- <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Edit Profile</button> -->
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Profile</title>
<!-- Bootstrap CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f9f9f9; /* Light background */
}
.profile-container {
background-color: #ffffff; /* White background */
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
max-width: 600px;
margin: 50px auto;
}
.btn-reset {
background-color: #ff8c00; /* Orange Color */
color: white;
}
.btn-reset:hover {
background-color: #e07b00; /* Darker orange on hover */
}
</style>
</head>
<body>
<div class="container profile-container">
<h2>User Profile</h2>
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" value="John Doe" readonly>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" value="johndoe@example.com" readonly>
</div>
<div class="mb-3">
<label for="phone" class="form-label">Phone</label>
<input type="tel" class="form-control" id="phone" value="+1234567890" readonly>
</div>
<div class="mb-3">
<label for="designation" class="form-label">Designation</label>
<input type="text" class="form-control" id="designation" value="Software Developer" readonly>
</div>
<div class="mb-3">
<label for="date-added" class="form-label">Date Added</label>
<input type="text" class="form-control" id="date-added" value="November 3, 2021" readonly>
</div>
<div class="d-flex justify-content-between">
<button class="btn btn-reset">Reset Password</button>
</div>
</div>
<!-- Bootstrap JS and dependencies -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.11.6/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.min.js"></script>
</body>
</html>

View File

@@ -29,6 +29,9 @@ Route::get('loggingtest', 'UtilityController@loggingTest');
Route::get('notifytest', 'UtilityController@sendEmailNotification'); Route::get('notifytest', 'UtilityController@sendEmailNotification');
Route::get('incoming_gmail', 'EmailController@indexInbox');
Route::get('incoming_outlook', 'EmailController@index');
Route::get('loadcodes', 'UtilityController@loadShortCodes'); Route::get('loadcodes', 'UtilityController@loadShortCodes');
Route::get('migrate_senders', 'UtilityController@migrateSenderids'); Route::get('migrate_senders', 'UtilityController@migrateSenderids');
Route::get('/testlog', function () { Route::get('/testlog', function () {
@@ -151,7 +154,11 @@ Route::group(['middleware' => ['checklogin', 'checkcurrentlylogged']], function(
Route::get('supporttickets/list', 'SupportTicketsController@ticketlist'); Route::get('supporttickets/list', 'SupportTicketsController@ticketlist');
Route::resource('supporttickets', 'SupportTicketsController'); Route::resource('supporttickets', 'SupportTicketsController');
Route::post('profileupdate', 'SystemUsersController@profileupdate');
Route::get('getprofile', 'SystemUsersController@profile_json');
Route::get('staffmembers/profile/{staff_member_id}', 'StaffMembersController@profile'); Route::get('staffmembers/profile/{staff_member_id}', 'StaffMembersController@profile');
Route::get('staffmembers/getprofile', 'StaffMembersController@profile_json');
Route::get('staffmembers/index', 'StaffMembersController@index'); Route::get('staffmembers/index', 'StaffMembersController@index');
Route::get('staffmembers/all', 'StaffMembersController@getstaffMemberssJson'); Route::get('staffmembers/all', 'StaffMembersController@getstaffMemberssJson');
Route::resource('staffmembers', 'StaffMembersController'); Route::resource('staffmembers', 'StaffMembersController');

View File

@@ -0,0 +1,9 @@
Steps for Lazy Migration:
Add a Column: Add a hash_version or new_password column to your database to differentiate between legacy (MD5) and new hashes.
Update Login Logic:
User enters plaintext_password.
Check if password_hash is MD5.
If yes, check if (md5(plaintext_password) == stored_md5_hash).
If matches, compute new_hash = password_hash(plaintext_password, PASSWORD_DEFAULT).
Update database with new_hash and set hash_version to "new".
Handle Remaining Users: After a set period, force a password reset for any remaining accounts still using the MD5 hash.