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 @@ + +
+ + +
+ + + + diff --git a/resources/js/components/ExampleComponent.vue b/resources/js/components/ExampleComponent.vue index 3fb9f9a..20ebdcc 100644 --- a/resources/js/components/ExampleComponent.vue +++ b/resources/js/components/ExampleComponent.vue @@ -1,23 +1,100 @@ + + diff --git a/resources/js/components/FontAwesomeIconPicker.vue b/resources/js/components/FontAwesomeIconPicker.vue new file mode 100644 index 0000000..d604cf3 --- /dev/null +++ b/resources/js/components/FontAwesomeIconPicker.vue @@ -0,0 +1,2644 @@ + + + + + diff --git a/resources/js/components/Increment.vue b/resources/js/components/Increment.vue new file mode 100644 index 0000000..91d19cd --- /dev/null +++ b/resources/js/components/Increment.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/resources/js/components/RemixIconPicker.vue b/resources/js/components/RemixIconPicker.vue new file mode 100644 index 0000000..4f0afaa --- /dev/null +++ b/resources/js/components/RemixIconPicker.vue @@ -0,0 +1,2764 @@ + + + + + diff --git a/resources/js/components/SearchableSelect.vue b/resources/js/components/SearchableSelect.vue new file mode 100644 index 0000000..f6cd9ce --- /dev/null +++ b/resources/js/components/SearchableSelect.vue @@ -0,0 +1,199 @@ + + + + + diff --git a/resources/js/components/libs/persian-date.js b/resources/js/components/libs/persian-date.js new file mode 100644 index 0000000..8fe11e7 --- /dev/null +++ b/resources/js/components/libs/persian-date.js @@ -0,0 +1,209 @@ +class PersianDate { + + persianMonthNames = ['', 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']; + + settings= { + gSpliter: '/', + } + + /** + * from parsi date by mobin ghasem pour + * @param {integer} year + * @returns {Boolean} + */ + isLeapYear = function (year) { + if (((year % 4) === 0 && (year % 100) !== 0) || ((year % 400) === 0) && (year % 100) === 0) + return true; + else + return false; + }; + + + parseHindi = function (str) { + + let r = str.toString(); + let org = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + let hindi = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; + for (var ch in org) { + r = r.replace(new RegExp(org[ch], 'g'), hindi[ch]); + } + + return r; + } + + + exploiter = function (date_txt, determ) { + if (typeof determ === 'undefined') { + determ = '/'; + } + let a = date_txt.split(determ); + + if (typeof a[2] === 'undefined') { + return a; + } + if (a[0].length < a[2].length) { + return [a[2], a[1], a[0]]; + } + + return a; + }; + + imploiter = function (date_txt, determ) { + if (determ === undefined) { + determ = '/'; + } + + return date_txt[0] + determ + date_txt[1] + determ + date_txt[2]; + }; + + + /** + * from parsi date by mobin ghasem pour + * @param {Array} indate + * @returns {Array} + */ + persian2Gregorian = function (indate) { + let jy = indate[0]; + let jm = indate[1]; + let jd = indate[2]; + let gd; + let j_days_sum_month = [0, 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 365]; + let g_days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + let g_days_leap_month = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + gd = j_days_sum_month[parseInt(jm)] + parseInt(jd); + let gy = parseInt(jy) + 621; + if (gd > 286) + gy++; + if (this.isLeapYear(gy - 1) && 286 < gd) + gd--; + if (gd > 286) + gd -= 286; + else + gd += 79; + let gm; + if (this.isLeapYear(gy)) { + for (gm = 0; gd > g_days_leap_month[gm]; gm++) { + gd -= g_days_leap_month[gm]; + } + } else { + for (gm = 0; gd > g_days_in_month[gm]; gm++) + gd -= g_days_in_month[gm]; + } + gm++; + if (gm < 10) + gm = '0' + gm; + gd = gd < 10 ? '0'+gd: gd; + return [gy, gm, gd]; + }; + + + /** + * from parsi date by mobin ghasem pour + * @param {Array} indate + * @returns {Array} + */ + gregorian2Persian = function (indate) { + + let gy, gm, gd, j_days_in_month, g_days_sum_month, dayofyear, leab, leap, jd, jy, jm, i; + + gy = indate[0]; + gm = indate[1]; + gd = indate[2]; + + j_days_in_month = [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29]; + g_days_sum_month = [0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; + dayofyear = g_days_sum_month[parseInt(gm)] + parseInt(gd); + leab = this.isLeapYear(gy); + leap = this.isLeapYear(gy - 1); + if (dayofyear > 79) { + jd = (leab ? dayofyear - 78 : dayofyear - 79); + jy = gy - 621; + for (i = 0; jd > j_days_in_month[i]; i++) { + jd -= j_days_in_month[i]; + } + } else { + jd = ((leap || (leab && gm > 2)) ? 287 + dayofyear : 286 + dayofyear); + jy = gy - 622; + if (leap == 0 && jd == 366) + return [jy, 12, 30]; + for (i = 0; jd > j_days_in_month[i]; i++) { + jd -= j_days_in_month[i]; + } + } + jm = ++i; + jm = (jm < 10 ? jm = '0' + jm : jm); + if (jm == 13) { + jm = 12; + jd = 30; + } + if (jm.toString().length == 1) { + jm = '0' + jm; + } + if (jd.toString().length == 1) { + jd = '0' + jd; + } + return [jy.toString(), jm, jd]; + }; + + convertDate2Persian = function (dt){ + let tmp = dt.toLocaleString('fa-IR-u-nu-latn') + .split('،') + .join(','); + let date = tmp.split(','); + let result = date[0].split('/'); + result[1] = this.make2number(result[1]); + result[2] = this.make2number(result[2]); + return result; + + } + make2number = function (instr) { + let num = instr.toString(); + return num.length === 2 ? num : '0' + num; + } + + gDate2Timestamp = function (stri) { + return Math.round(new Date(stri + " 00:00:00").getTime() / 1000); + } + + gTimestamp2Date = function (unix_timestamp) { + let date = new Date(unix_timestamp * 1000); + return date.getFullYear() + settings.gSpliter + date.getMonth() + 1 + settings.gSpliter + date.getDate(); + } + pDate2Timestamp = function (stri) { + return this.gDate2Timestamp(this.imploiter(this.persian2Gregorian(this.exploiter(stri)))); + } + + pTimestamp2Date = function (unix_timestamp) { + let date = new Date(unix_timestamp * 1000); + return this.imploiter(this.gregorian2Persian([date.getFullYear(), date.getMonth() + 1, date.getDate()])); + } + + getPersianWeekDay = function (jdate) { + + let tmp = this.imploiter(this.persian2Gregorian(this.exploiter(jdate)), '/'); + let dd = new Date(tmp + " 00:00:00").getDay() + 1; + if (dd > 6) { + dd -= 7; + } + return dd; + }; + + pGetLastDayMonth = function (mn, yr) { + let tmp; + let last = 29; + let now = this.pDate2Timestamp(yr + '/' + mn + '/' + (29)); + for (let i = 1; i < 4; i++) { + now += 86400; + tmp = this.exploiter(this.pTimestamp2Date(now)); + if (tmp[2] < last) { + return last; + } else { + last = tmp[2]; + } + } + return last; + } + +} + +export default PersianDate; diff --git a/resources/js/components/searchableMultiSelect.vue b/resources/js/components/searchableMultiSelect.vue new file mode 100644 index 0000000..38ad4ef --- /dev/null +++ b/resources/js/components/searchableMultiSelect.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/resources/js/components/vueDateRangePicker.vue b/resources/js/components/vueDateRangePicker.vue new file mode 100644 index 0000000..3f0c9e1 --- /dev/null +++ b/resources/js/components/vueDateRangePicker.vue @@ -0,0 +1,1218 @@ + + + + + diff --git a/resources/js/components/vueDateTimePicker.vue b/resources/js/components/vueDateTimePicker.vue new file mode 100644 index 0000000..6dbb45c --- /dev/null +++ b/resources/js/components/vueDateTimePicker.vue @@ -0,0 +1,1189 @@ + + + + + diff --git a/resources/js/components/vueJalaliCalendar.vue b/resources/js/components/vueJalaliCalendar.vue new file mode 100644 index 0000000..57d7f42 --- /dev/null +++ b/resources/js/components/vueJalaliCalendar.vue @@ -0,0 +1,374 @@ + + + + + diff --git a/resources/js/panel/general-events.js b/resources/js/panel/general-events.js new file mode 100644 index 0000000..7a59d8b --- /dev/null +++ b/resources/js/panel/general-events.js @@ -0,0 +1,7 @@ +document.addEventListener('click', function(e) { + if (e.target.classList.contains('delete-confirm')) { + if (!confirm('Are you sure you want to delete this item?')) { // WIP Need to translate + e.preventDefault(); + } + } +}); diff --git a/resources/js/panel/list-checkboxs.js b/resources/js/panel/list-checkboxs.js index 666b72b..39b9c05 100644 --- a/resources/js/panel/list-checkboxs.js +++ b/resources/js/panel/list-checkboxs.js @@ -4,6 +4,42 @@ function clearSelection() else if (document.selection) {document.selection.empty();} } + +function serializeForm(selector) { + let form = document.querySelector(selector); + let formData = new FormData(form); + let serializedArray = []; + + formData.forEach(function(value, key) { + serializedArray.push({ + name: key, + value: value + }); + }); + + return serializedArray; +} + +function handleCheckChange () { + let frm = serializeForm('#main-form'); + let bi = document.querySelector('#bulk-idz'); + bi.innerHTML = ''; + for( const item of frm) { + let n =document.createElement("input"); + n.name = item.name; + n.value = item.value; + n.type = 'hidden'; + bi.appendChild(n); + } + + if (frm.length == 0){ + document.querySelector('#bulk-from').style.maxHeight = '0'; + }else{ + document.querySelector('#bulk-from').style.maxHeight = '250px'; + } + +} + window.addEventListener('load',function () { let chkall = document.querySelectorAll(".chkall"); @@ -18,6 +54,7 @@ window.addEventListener('load',function () { checkbox.removeAttribute("checked"); } }); + handleCheckChange(); }); // Attach an event listener for "change" and "click" events chkall.forEach(function(chkall) { @@ -44,6 +81,7 @@ window.addEventListener('load',function () { checkbox.removeAttribute("checked"); }); } + handleCheckChange(); } @@ -55,6 +93,7 @@ window.addEventListener('load',function () { chkboxes.forEach(chkbox => { chkbox.addEventListener('click', handleCheckboxClick); chkbox.parentNode.querySelector('label').addEventListener('click', handleCheckboxClick); + chkbox.addEventListener('change',handleCheckChange); }); function handleCheckboxClick(e) { @@ -80,9 +119,10 @@ window.addEventListener('load',function () { } + handleCheckChange(); lastChecked = self; } - + handleCheckChange(); }); diff --git a/resources/sass/panel/_breadcrumbs.scss b/resources/sass/panel/_breadcrumbs.scss index 9706743..56a9083 100644 --- a/resources/sass/panel/_breadcrumbs.scss +++ b/resources/sass/panel/_breadcrumbs.scss @@ -1,5 +1,61 @@ +$pnl-brc-height: 50px; + #panel-breadcrumb{ - height: 50px; - background: #00000033; + height: $pnl-brc-height; + background: #282d46; margin-bottom: 1rem; + + ul{ + padding: 0; + display: grid; + grid-auto-columns: minmax(0, 1fr); + grid-auto-flow: column; + list-style: none; + //border: 1px solid black; + border-radius: 4px ; + transition: .5s; + li{ + position: relative; + overflow: hidden; + a,span{ + height: $pnl-brc-height; + display: flex; + align-items: center; + justify-content: center; + padding: 0 1rem; + } + i{ + font-size: 25px; + margin: 0 .5rem; + } + + &:before { + content: ""; + width: 37px; + height: 37px; + border: 1px solid black; + transform: rotate(45deg); + position: absolute; + inset-inline-start: -1.05rem; + background: #282d46; + top: 7px; + } + + &:first-child:before { + display: none; + } + + + &:hover{ + background: #444e7c; + background-image: url("../images/pattern.png"); + + & + li:before{ + background: #444e7c; + background-image: url("../images/pattern.png"); + } + } + } + } + } diff --git a/resources/sass/panel/_common.scss b/resources/sass/panel/_common.scss index 05f64ab..7506f6a 100644 --- a/resources/sass/panel/_common.scss +++ b/resources/sass/panel/_common.scss @@ -47,7 +47,7 @@ a.btn,a.action-btn,a.circle-btn{ color: white; } position: fixed; - inset-inline-end: 1rem; + inset-inline-start: 4.2rem; bottom: 1rem; } diff --git a/resources/sass/panel/_item-list.scss b/resources/sass/panel/_item-list.scss index 01e6fde..43ca6af 100644 --- a/resources/sass/panel/_item-list.scss +++ b/resources/sass/panel/_item-list.scss @@ -10,7 +10,15 @@ font-weight: 200; margin: 0; } + h2,h3,h4,h5,h6{ + font-weight: 200; + font-size: 22px; + margin-bottom: 0; + } + h2{ + margin-bottom: .5rem; + } .item-search { form { padding: 1rem; @@ -28,6 +36,8 @@ } td,th{ + transition: 300ms; + transition-delay: 100ms; &:first-child{ width: 100px; } @@ -66,9 +76,10 @@ &:hover{ + background-image: url("../images/pattern.png"); + background-color: #00000044; td{ - background-color: #00000044; - background-image: url("../images/pattern.png"); + background-color: transparent; } } @@ -84,3 +95,10 @@ } + +#bulk-from{ + max-height: 0; + overflow: hidden; + box-sizing: border-box; + transition: 1s; +} diff --git a/resources/sass/panel/_navbar.scss b/resources/sass/panel/_navbar.scss index 0d26432..055cdd5 100644 --- a/resources/sass/panel/_navbar.scss +++ b/resources/sass/panel/_navbar.scss @@ -1,5 +1,5 @@ #panel-navbar { - height: calc(100vh - 55px); + height: calc(100vh - 60px); overflow-y: auto; position: relative; @@ -72,3 +72,8 @@ } } + +#panel-top-navbar{ + background: rgb(40, 45, 70); + padding-top: .8rem; +} diff --git a/resources/views/admin/templates/panel-list-template.blade.php b/resources/views/admin/templates/panel-list-template.blade.php index c004785..b2097da 100644 --- a/resources/views/admin/templates/panel-list-template.blade.php +++ b/resources/views/admin/templates/panel-list-template.blade.php @@ -5,8 +5,8 @@
{{-- list side bar start--}} -
-
+
+ {{-- list side bar end--}} {{-- list content start--}} -
-
+
+
@@ -68,9 +126,8 @@ @endforeach @yield('table-head') - @@ -79,7 +136,7 @@ @endforeach @@ -158,13 +252,6 @@ {{$items->withQueryString()->links()}}
-
- @paginated($items) -
-
@@ -172,10 +259,10 @@ {{-- pagination and toggle button end --}}
- {{__("Totol")}}: - {{$items->total()}} + +
+ name="id[{{$item->id}}]" value="{{$item->id}}"> @@ -87,7 +144,7 @@ @foreach($cols as $k => $col) @if($k == 0 && hasRoute('edit')) - + {{$item->name}} @@ -101,37 +158,74 @@ @endforeach @yield('table-body') - @if(hasRoute('destroy')) - - - - @endif - @if(hasRoute('edit')) - url(),'trashed') != false && hasRoute('restore')) + - + data-bs-title="{{__("Restore")}}"> + - @endif - @if(hasRoute('show')) - - + @else + + @endif - @yield('list-btn') +
+ @foreach($buttons as $btn => $btnData) + + @if(strpos($btnData['class'],'delete') == false ) + @if(strpos(request()->url(),'trashed') == false) + + + + + @endif + @else + @if( hasRoute('restore') && $item->trashed()) + + + + @else + + + + @endif + @endif + @endforeach +
-
- {{-- list content end--}}
+ {{-- list content end--}} +
@if(hasRoute('create')) diff --git a/resources/views/admin/users/user-list.blade.php b/resources/views/admin/users/user-list.blade.php index cb00944..27bf411 100644 --- a/resources/views/admin/users/user-list.blade.php +++ b/resources/views/admin/users/user-list.blade.php @@ -8,5 +8,20 @@ {{__("Users list")}} | @endsection @section('filter') - +

+ + {{__("Role filter")}}: +

+ +@endsection +@section('bulk') + @foreach(\App\Models\User::$roles as $role) + + @endforeach @endsection diff --git a/resources/views/components/err.blade.php b/resources/views/components/err.blade.php new file mode 100755 index 0000000..5d30f23 --- /dev/null +++ b/resources/views/components/err.blade.php @@ -0,0 +1,10 @@ +@if(session()->has('message')) +
+ {{ session()->get('message') }} +
+@endif +@foreach($errors->all() as $err) +
+ {{$err}} +
+@endforeach diff --git a/resources/views/components/panel-breadcrumb.blade.php b/resources/views/components/panel-breadcrumb.blade.php index 3f850ae..8fb3667 100644 --- a/resources/views/components/panel-breadcrumb.blade.php +++ b/resources/views/components/panel-breadcrumb.blade.php @@ -1,3 +1,28 @@
diff --git a/resources/views/components/panel-top-navbar.blade.php b/resources/views/components/panel-top-navbar.blade.php index 4665245..36bf6bf 100644 --- a/resources/views/components/panel-top-navbar.blade.php +++ b/resources/views/components/panel-top-navbar.blade.php @@ -1,4 +1,4 @@ -