diff --git a/app/Helpers/Helper.php b/app/Helpers/Helper.php index b43bf3e..5f001b2 100644 --- a/app/Helpers/Helper.php +++ b/app/Helpers/Helper.php @@ -7,7 +7,7 @@ use App\Helpers; * @param $lang code like fa * @return string */ -function getEmojiLanguagebyCode($lang) +function getEmojiLanguagebyCode($lang) : string { $languages = [ "af" => "🇿🇦", // Afrikaans @@ -88,13 +88,14 @@ function getEmojiLanguagebyCode($lang) /** * has route as named we want this model? * @param $name string + * @param $endRoute string 'index' or alt list * @return bool */ -function hasRoute($name) +function hasRoute($name,$endRoute = 'index') : bool { // create route - $cRuote = str_replace('index', $name, request()->route()->getName()); + $cRuote = str_replace($endRoute, $name, request()->route()->getName()); if (\Illuminate\Support\Facades\Route::has($cRuote)) { return true; } else { @@ -106,14 +107,15 @@ function hasRoute($name) * get named route url * @param $name string * @param $args array + * @param $endRoute string 'index' or alt list * @return string|null */ -function getRoute($name,$args = []) +function getRoute($name, $args = [],$endRoute = 'index') : string | null { // create route - $cRuote = str_replace('index', $name, request()->route()->getName()); + $cRuote = str_replace($endRoute, $name, request()->route()->getName()); if (\Illuminate\Support\Facades\Route::has($cRuote)) { - return \route($cRuote,$args); + return \route($cRuote, $args); } else { return null; } @@ -125,14 +127,79 @@ function getRoute($name,$args = []) * @param $col string * @return string */ -function sortSuffix($col){ - if (request()->sort == $col){ - if (request('sortType','asc') == 'desc'){ +function sortSuffix($col) : string +{ + if (request()->sort == $col) { + if (request('sortType', 'asc') == 'desc') { return '&sortType=asc'; - }else{ + } else { return '&sortType=desc'; } - }else{ + } else { return ''; } } + + +/** + * make array compatible | help us to translate + * @param $array + * @param $translate + * @return false|string + */ +function arrayNormolizeVueCompatible($array, $translate = false): false | string +{ + $result = []; + foreach ($array as $index => $item) { + $result[] = ['id' => $index, 'name' => ($translate ? __($item) : $item)]; + } + return json_encode($result); +} + + +/** + * check string is json or not + * @param $string + * @return bool + */ +function isJson($string) : bool { + json_decode($string); + return json_last_error() === JSON_ERROR_NONE; +} + + +/** + * save admin batch log + * @param $method + * @param $cls class + * @param $ids + * @return void + */ +function logAdminBatch($method, $cls, $ids): void +{ + $act = explode('\\', $method); + foreach ($ids as $id) { + auth()->user()->logs()->create([ + 'action' => $act[count($act) - 1], + 'loggable_type' => $cls, + 'loggable_id' => $id, + ]); + } +} + +/** + * save admin log + * @param $method + * @param $cls class + * @param $id + * @return void + */ +function logAdmin($method, $cls, $id) :void +{ + $act = explode('\\', $method); + auth()->user()->logs()->create([ + 'action' => $act[count($act) - 1], + 'loggable_type' => $cls, + 'loggable_id' => $id, + ]); +} diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index eeba43f..87b6da1 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -2,13 +2,81 @@ namespace App\Http\Controllers\Admin; +use App\CreateOrUpdate; use App\Http\Controllers\Controller; use App\Http\Controllers\XController; +use App\Models\Item; +use App\Models\User; +use App\SafeController; use Illuminate\Http\Request; use App\Helper; use function App\Helpers\hasCreateRoute; class UserController extends XController { - protected $cols = ['name','email','role','mobile']; + protected $cols = ['name', 'email', 'role', 'mobile']; + protected $filterables = ['role']; + + protected $searchable = ['name','mobile','email']; + + protected $buttons = [ + 'edit' => + ['title' => "Edit", 'class' => 'btn-outline-primary', 'icon' => 'ri-edit-2-line'], + 'show' => + ['title' => "Detail", 'class' => 'btn-outline-light', 'icon' => 'ri-eye-line'], + 'log' => + ['title' => "Logs", 'class' => 'btn-outline-light', 'icon' => 'ri-file-list-2-line'], + 'destroy' => + ['title' => "Remove", 'class' => 'btn-outline-danger delete-confirm', 'icon' => 'ri-close-line'], + ]; + + public function createOrUpdate( $item, $request) + { + + + } + + public function bulk(Request $request){ + +// dd($request->all()); + $data = explode('.', $request->input('action')); + $action = $data[0]; + $ids = $request->input('id'); + switch ($action) { + case 'delete': + $msg = __(':COUNT items deleted successfully',['COUNT' => count($ids)]); + $this->model::destroy($ids); + break; + case 'restore': + $msg = __(':COUNT items restored successfully',['COUNT' => count($ids)]); + foreach ($ids as $id) { + $this->model::withTrashed()->find($id)->restore(); + } + break; + case 'role': + foreach ($ids as $id) { + $user = User::where('id',$id)->first(); + $user->role = $data[1]; + $user->syncRoles([strtolower($data[1])]); + $user->save(); + } + $msg = __(':COUNT user role changed to :NEWROLE successfully',['COUNT' => count($ids), 'NEWROLE' => __($data[1])]); + break; + default: + $msg = __('Unknown bulk action : :ACTION', ["ACTION" => $action] ); + } + + return $this->do_bulk($msg,$action, $ids); + } + + public function destroy(User $item) + { + return parent::delete($item); + } + + public function restore($item) + { + + return parent::restoreing(User::withTrashed()->where('email',$item)->first()); + } } diff --git a/app/Http/Controllers/XController.php b/app/Http/Controllers/XController.php index df86313..d1bd6e8 100644 --- a/app/Http/Controllers/XController.php +++ b/app/Http/Controllers/XController.php @@ -3,9 +3,10 @@ namespace App\Http\Controllers; use App\Models\User; +use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; -class XController extends Controller +abstract class XController extends Controller { protected $model = User::class; @@ -14,27 +15,72 @@ class XController extends Controller protected $extra_cols = ['id']; protected $listView = 'admin.users.user-list'; protected $formView = 'admin.users.user-form'; + protected $filterables = []; + protected $searchable = []; - public function createOrUpdate($item, Request $request) + + protected $buttons = [ + 'edit' => + ['title' => "Edit", 'class' => 'btn-outline-primary', 'icon' => 'ri-edit-2-line'], + 'destroy' => + ['title' => "Remove", 'class' => 'btn-outline-danger delete-confirm', 'icon' => 'ri-edit-2-line'], + ]; + + + public function createOrUpdate($item, $request) { } protected function showList($query) { - $items = $query->paginate(config('app.panel.page_count'), array_merge($this->extra_cols, $this->cols)); + + + if (hasRoute('trashed')){ + $this->extra_cols[] = 'deleted_at'; + } + $items = $query->paginate(config('app.panel.page_count'), + array_merge($this->extra_cols, $this->cols)); $cols = $this->cols; - return view($this->listView, compact('items', 'cols')); + $buttons = $this->buttons; + return view($this->listView, compact('items', 'cols', 'buttons')); } protected function makeSortAndFilter() { + + if (!\request()->has('sort') || !in_array(\request('sort'), $this->cols)) { $query = $this->model::orderByDesc('id'); } else { $query = $this->model::orderBy(\request('sort'), \request('sortType', 'asc')); } + + foreach (\request()->input('filter', []) as $col => $filter) { + if (isJson($filter)) { + $vals = json_decode($filter); + if (count($vals) != 0) { + $query->whereIn($col, $vals); + } + } else { + $query->where($col, $filter); + } + } + + if (mb_strlen(trim(\request()->input('q', ''))) > 0) { + foreach ($this->searchable as $col) { + $query->where(function ($query) { + foreach ($this->searchable as $key => $col) { + if ($key === 0) { + $query->where($col, 'LIKE', '%' . \request()->input('q', '') . '%'); + } else { + $query->orWhere($col, 'LIKE', '%' . \request()->input('q', '') . '%'); + } + } + }); + } + } return $query; } @@ -64,6 +110,15 @@ class XController extends Controller public function store(Request $request) { // + $item = new $this->model(); + $item = $this->create($item,$request); + logAdmin(__METHOD__, $this->model , $item->id); + + if ($request->ajax()){ + return ['OK' => true,]; + }else{ + return redirect()->route('admin.'.$this->model.'.index')->with(['message' => __('As you wished created successfully')]); + } } /** @@ -93,9 +148,23 @@ class XController extends Controller /** * Remove the specified resource from storage. */ - public function destroy($user) + public function delete($item) { // + logAdmin(__METHOD__, $this->model , $item->id); + $item->delete(); + return redirect()->back()->with(['message' => __('As you wished removed successfully')]); + } + + /** + * restore removed the specified resource from storage. + */ + public function restoreing($item) + { + // + logAdmin(__METHOD__, $this->model , $item->id); + $item->restore(); + return redirect()->back()->with(['message' => __('As you wished restored successfully')]); } @@ -104,7 +173,13 @@ class XController extends Controller */ public function trashed() { - $query = User::onlyTrashed(); + $query = $this->makeSortAndFilter()->onlyTrashed(); return $this->showList($query); } + + protected function do_bulk($msg,$action,$ids) + { + logAdminBatch(__METHOD__ . '.' . $action, $this->model, $ids); + return redirect()->back()->with(['message' => $msg]); + } } diff --git a/app/Models/AdminLog.php b/app/Models/AdminLog.php index dee44a0..78e9b0b 100644 --- a/app/Models/AdminLog.php +++ b/app/Models/AdminLog.php @@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Model; class AdminLog extends Model { + protected $guarded = []; + public function user() { return $this->belongsTo(User::class); diff --git a/app/Models/User.php b/app/Models/User.php index 311c0b6..f10cc86 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -13,7 +13,7 @@ class User extends Authenticatable { use HasFactory, Notifiable, HasRoles, SoftDeletes; - static $roles = ['DEVELOPER', 'ADMIN', 'USER']; + static $roles = ['DEVELOPER', 'ADMIN', 'USER', 'SUSPENDED']; /** * The attributes that are mass assignable. @@ -26,6 +26,11 @@ class User extends Authenticatable 'password', ]; + public function getRouteKeyName() + { + return 'email'; + } + /** * The attributes that should be hidden for serialization. * @@ -49,7 +54,13 @@ class User extends Authenticatable ]; } - public function posts(){ + public function posts() + { return $this->hasMany(Post::class); } + + public function logs() + { + return $this->hasMany(AdminLog::class, 'user_id', 'id'); + } } diff --git a/app/Providers/BladeServiceProvider.php b/app/Providers/BladeServiceProvider.php index 1bd915f..e15e89a 100644 --- a/app/Providers/BladeServiceProvider.php +++ b/app/Providers/BladeServiceProvider.php @@ -32,7 +32,7 @@ class BladeServiceProvider extends ServiceProvider \$from = (\$currentPage - 1) * \$perPage + 1; \$to = min(\$currentPage * \$perPage, \$total); - echo \"(\$from | \$to | \$total) \"; ?>"; + echo \"( \$from - \$to ) \"; ?>"; }); } } diff --git a/app/SafeController.php b/app/SafeController.php new file mode 100644 index 0000000..a24eaac --- /dev/null +++ b/app/SafeController.php @@ -0,0 +1,9 @@ + +
+ {{ __("Saturday") }} + | ++ {{ __("Sunday") }} + | ++ {{ __("Monday") }} + | ++ {{ __("Tuesday") }} + | ++ {{ __("Wednesday") }} + | ++ {{ __("Thursday") }} + | ++ {{ __("Friday") }} + | +
---|---|---|---|---|---|---|
+ {{ td.text }} + + + + | +