diff --git a/app/Helpers/CustomHelper.php b/app/Helpers/CustomHelper.php index aab0549..4ff2c6e 100644 --- a/app/Helpers/CustomHelper.php +++ b/app/Helpers/CustomHelper.php @@ -1,5 +1,6 @@ role_id, (array) $roles); + } + return false; + } +} + +if (! function_exists('encryptId')) { + function encryptId($id) + { + $hashids = new Hashids('alwayssaybismillahirrahmanirrahim', 15); + return $hashids->encode($id); + } +} + +if (! function_exists('decryptId')) { + function decryptId($hash) + { + $hashids = new Hashids('alwayssaybismillahirrahmanirrahim', 15); + $result = $hashids->decode($hash); + return $result ? $result[0] : null; + } +} diff --git a/app/Http/Controllers/Dashboard/ClassificationController.php b/app/Http/Controllers/Dashboard/ClassificationController.php new file mode 100644 index 0000000..ea5cf08 --- /dev/null +++ b/app/Http/Controllers/Dashboard/ClassificationController.php @@ -0,0 +1,83 @@ + 'Klasifikasi' + ]); + } + + public function create(){ + return view('dashboard.classifications.create', [ + 'title' => 'Tambah Klasifikasi' + ]); + } + + public function store(ClassificationRequest $request){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $createdClassification = Classification::create($validatedData); + + if($createdClassification){ + return redirect()->back()->with('success-status', 'Berhasil menambahkan klasifikasi.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal menambahkan klasifikasi'); + } + } + + public function edit($id){ + $classification = Classification::find(decryptId($id)); + + return view('dashboard.classifications.edit', [ + 'title' => 'Ubah Klasifikasi', + 'classification' => $classification + ]); + } + + public function update(ClassificationRequest $request, $id){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $updatedClassification = Classification::find(decryptId($id))->update($validatedData); + + if($updatedClassification){ + return redirect()->back()->with('success-status', 'Berhasil mengubah klasifikasi.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal mengubah klasifikasi'); + } + } + + public function show($id){ + $classification = Classification::find(decryptId($id)); + + return view('dashboard.classifications.show', [ + 'title' => 'Detail Klasifikasi', + 'classification' => $classification + ]); + } + + public function destroy($id){ + try { + $classification = Classification::findOrFail(decryptId($id)); + + $classification->delete(); + + return response()->json(['message' => 'Berhasil menghapus klasifikasi']); + } catch (\Exception $e) { + return response()->json(['message' => 'Gagal menghapus klasifikasi.'], 500); + } + } +} diff --git a/app/Http/Controllers/Dashboard/DatatableController.php b/app/Http/Controllers/Dashboard/DatatableController.php new file mode 100644 index 0000000..c409a95 --- /dev/null +++ b/app/Http/Controllers/Dashboard/DatatableController.php @@ -0,0 +1,144 @@ +ajax()) { + + + + $data = Classification::with(['subClassifications'])->get(); + + return DataTables::of($data) + ->addIndexColumn() + ->addColumn('status', function ($data) { + if ($data->status == '0') { + return 'Nonaktif'; + }else{ + return 'Aktif'; + } + }) + ->addColumn('sub_classifications', function ($data) { + $subClassificationCount = $data->subClassifications->count(); + + if($subClassificationCount > 0){ + return $subClassificationCount. ' [Lihat]'; + }else{ + return $subClassificationCount; + } + + }) + ->addColumn('action', function ($data) { + $showUrl = route('dashboard.classifications.show', ['id' => encryptId($data->id)]); + + $addSubClassificationUrl = route('dashboard.sub.classifications.create', ['classification' => $data->slug]); + + $editUrl = route('dashboard.classifications.edit', ['id' => encryptId($data->id)]); + + $deleteUrl = route('dashboard.classifications.destroy', ['id' => encryptId($data->id)]); + + $dropdown = '
'; + + return $dropdown; + }) + + ->rawColumns(['sub_classifications', 'status', 'action']) + ->make(true); + } + + return response()->json(['error' => 'Unauthorized'], 401); + + } + + public function subClassification(Request $request){ + if ($request->ajax()) { + + $classificationParam = $request->input('classification', null); + + if($classificationParam){ + $classification = Classification::where('slug', '=', $classificationParam)->first(); + $data = SubClassification::with(['classification'])->where('classification_id', '=', $classification->id)->get(); + }else{ + $data = SubClassification::with(['classification'])->get(); + } + + return DataTables::of($data) + ->addIndexColumn() + ->addColumn('classification', function ($data) { + return $data->classification->name; + }) + ->addColumn('status', function ($data) { + if ($data->status == '0') { + return 'Nonaktif'; + }else{ + return 'Aktif'; + } + }) + ->addColumn('action', function ($data) { + $showUrl = route('dashboard.sub.classifications.show', ['id' => encryptId($data->id)]); + + $editUrl = route('dashboard.sub.classifications.edit', ['id' => encryptId($data->id)]); + + $deleteUrl = route('dashboard.sub.classifications.destroy', ['id' => encryptId($data->id)]); + + $dropdown = ''; + + return $dropdown; + }) + + ->rawColumns(['status', 'action']) + ->make(true); + } + + return response()->json(['error' => 'Unauthorized'], 401); + + } +} diff --git a/app/Http/Controllers/Dashboard/OverviewController.php b/app/Http/Controllers/Dashboard/OverviewController.php index fe86706..fcc50c6 100644 --- a/app/Http/Controllers/Dashboard/OverviewController.php +++ b/app/Http/Controllers/Dashboard/OverviewController.php @@ -10,7 +10,6 @@ class OverviewController extends Controller public function index(){ return view('dashboard.overview.index', [ 'title' => 'Ikhtisar', - 'page' => 'overview' ]); } } diff --git a/app/Http/Controllers/Dashboard/SubClassificationController.php b/app/Http/Controllers/Dashboard/SubClassificationController.php new file mode 100644 index 0000000..dd3cbf7 --- /dev/null +++ b/app/Http/Controllers/Dashboard/SubClassificationController.php @@ -0,0 +1,101 @@ + 'Sub Klasifikasi', + 'classification' => $request->input('classification', null), + ]; + + return view('dashboard.sub-classifications.index', $viewData); + } + + public function create(Request $request){ + + $viewData = [ + 'title' => 'Tambah Sub Klasifikasi', + 'fromClassification' => false + ]; + + if($request->has('classification')){ + $classificationSlug = $request->query('classification'); + $viewData['classification'] = Classification::where('slug', '=', $classificationSlug)->first(); + $viewData['fromClassification'] = true; + }else{ + $viewData['classifications'] = Classification::all(); + } + + return view('dashboard.sub-classifications.create', $viewData); + } + + public function store(SubClassificationRequest $request){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $createdSubClassification = SubClassification::create($validatedData); + + if($createdSubClassification){ + return redirect()->back()->with('success-status', 'Berhasil menambahkan sub klasifikasi.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal menambahkan sub klasifikasi'); + } + } + + public function edit($id){ + $subClassification = SubClassification::find(decryptId($id)); + + return view('dashboard.sub-classifications.edit', [ + 'title' => 'Ubah Sub Klasifikasi', + 'subClassification' => $subClassification, + 'classifications' => Classification::all() + ]); + } + + public function update(SubClassificationRequest $request, $id){ + $validatedData = $request->validated(); + $validatedData['slug'] = Str::slug($validatedData['name']); + $validatedData['enhancer_id'] = Auth::id(); + + $updatedSubClassification = SubClassification::find(decryptId($id))->update($validatedData); + + if($updatedSubClassification){ + return redirect()->back()->with('success-status', 'Berhasil mengubah sub klasifikasi.'); + }else{ + return redirect()->back()->with('failed-status', 'Gagal mengubah sub klasifikasi'); + } + } + + public function show($id){ + $subClassification = SubClassification::with(['classification'])->find(decryptId($id)); + + return view('dashboard.sub-classifications.show', [ + 'title' => 'Detail Sub Klasifikasi', + 'subClassification' => $subClassification, + ]); + } + + public function destroy($id){ + try { + $subClassification = SubClassification::findOrFail(decryptId($id)); + + $subClassification->delete(); + + return response()->json(['message' => 'Berhasil menghapus sub klasifikasi']); + } catch (\Exception $e) { + return response()->json(['message' => 'Gagal menghapus sub klasifikasi.'], 500); + } + } +} diff --git a/app/Http/Requests/ClassificationRequest.php b/app/Http/Requests/ClassificationRequest.php new file mode 100644 index 0000000..f8dd5ba --- /dev/null +++ b/app/Http/Requests/ClassificationRequest.php @@ -0,0 +1,43 @@ +|string> + */ + public function rules(): array + { + return [ + 'name' => ['required'], + 'status' => ['required', 'in:0,1'], + 'description' => ['nullable'] + ]; + } + + + public function messages(): array + { + return [ + 'name.required' => 'Nama klasifikasi harus diisi.', + 'status.required' => 'Status harus dipilih.', + 'status.in' => 'Status harus memiliki nilai aktif atau tidak aktif.', + 'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.', + ]; + } +} diff --git a/app/Http/Requests/SubClassificationRequest.php b/app/Http/Requests/SubClassificationRequest.php new file mode 100644 index 0000000..c661a85 --- /dev/null +++ b/app/Http/Requests/SubClassificationRequest.php @@ -0,0 +1,46 @@ +|string> + */ + public function rules(): array + { + return [ + 'name' => ['required'], + 'classification_id' => ['required', 'exists:classifications,id'], + 'status' => ['required', 'in:0,1'], + 'description' => ['nullable'] + ]; + } + + + public function messages(): array + { + return [ + 'name.required' => 'Nama klasifikasi harus diisi.', + 'classification_id.required' => 'Klasifikasi utama harus dipilih.', + 'classification_id.exists' => 'Klasifikasi yang dipilih tidak valid.', + 'status.required' => 'Status harus dipilih.', + 'status.in' => 'Status harus bernilai aktif atau tidak aktif.', + 'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.', + ]; + } + +} diff --git a/app/Models/Classification.php b/app/Models/Classification.php new file mode 100644 index 0000000..5c32a56 --- /dev/null +++ b/app/Models/Classification.php @@ -0,0 +1,22 @@ +hasMany(SubClassification::class, 'classification_id', 'id'); + } +} diff --git a/app/Models/SubClassification.php b/app/Models/SubClassification.php new file mode 100644 index 0000000..9187a10 --- /dev/null +++ b/app/Models/SubClassification.php @@ -0,0 +1,23 @@ +belongsTo(Classification::class, 'classification_id', 'id'); + } +} diff --git a/composer.json b/composer.json index 3b202cf..b959675 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,10 @@ "require": { "php": "^8.2", "laravel/framework": "^11.31", - "laravel/tinker": "^2.9" + "laravel/tinker": "^2.9", + "sqids/sqids": "^0.5.0", + "vinkla/hashids": "^12.0", + "yajra/laravel-datatables-oracle": "^11.1" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock index 31cd171..ba08001 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "626b9e7ddd47fb7eff9aaa53cce0c9ad", + "content-hash": "f3ee170125eab7ff7a88cc38da21105b", "packages": [ { "name": "brick/math", @@ -581,6 +581,76 @@ ], "time": "2023-10-12T05:21:21+00:00" }, + { + "name": "graham-campbell/manager", + "version": "v5.1.1", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Laravel-Manager.git", + "reference": "176b211828cdeabb39d97677fb14057c7cbf36a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Manager/zipball/176b211828cdeabb39d97677fb14057c7cbf36a6", + "reference": "176b211828cdeabb39d97677fb14057c7cbf36a6", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.75 || ^9.0 || ^10.0 || ^11.0", + "illuminate/support": "^8.75 || ^9.0 || ^10.0 || ^11.0", + "php": "^7.4.15 || ^8.0.2" + }, + "require-dev": { + "graham-campbell/analyzer": "^4.2.1", + "graham-campbell/testbench-core": "^4.1.1", + "mockery/mockery": "^1.6.12", + "phpunit/phpunit": "^9.6.22 || ^10.5.41" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\Manager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Manager Provides Some Manager Functionality For Laravel", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Laravel Manager", + "Laravel-Manager", + "connector", + "framework", + "interface", + "laravel", + "manager" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Laravel-Manager/issues", + "source": "https://github.com/GrahamCampbell/Laravel-Manager/tree/v5.1.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/manager", + "type": "tidelift" + } + ], + "time": "2025-01-13T18:36:30+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.3", @@ -1054,6 +1124,75 @@ ], "time": "2025-02-03T10:55:03+00:00" }, + { + "name": "hashids/hashids", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/vinkla/hashids.git", + "reference": "197171016b77ddf14e259e186559152eb3f8cf33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vinkla/hashids/zipball/197171016b77ddf14e259e186559152eb3f8cf33", + "reference": "197171016b77ddf14e259e186559152eb3f8cf33", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-bcmath": "Required to use BC Math arbitrary precision mathematics (*).", + "ext-gmp": "Required to use GNU multiple precision mathematics (*)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hashids\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ivan Akimov", + "email": "ivan@barreleye.com" + }, + { + "name": "Vincent Klaiber", + "email": "hello@doubledip.se" + } + ], + "description": "Generate short, unique, non-sequential ids (like YouTube and Bitly) from numbers", + "homepage": "https://hashids.org/php", + "keywords": [ + "bitly", + "decode", + "encode", + "hash", + "hashid", + "hashids", + "ids", + "obfuscate", + "youtube" + ], + "support": { + "issues": "https://github.com/vinkla/hashids/issues", + "source": "https://github.com/vinkla/hashids/tree/5.0.2" + }, + "time": "2023-02-23T15:00:54+00:00" + }, { "name": "laravel/framework", "version": "v11.43.2", @@ -3299,6 +3438,61 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "sqids/sqids", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/sqids/sqids-php.git", + "reference": "d594b87134f581578422caca005bc7ec99f958b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sqids/sqids-php/zipball/d594b87134f581578422caca005bc7ec99f958b2", + "reference": "d594b87134f581578422caca005bc7ec99f958b2", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.5|^11.2" + }, + "suggest": { + "ext-bcmath": "Required to use BC Math arbitrary precision mathematics (*).", + "ext-gmp": "Required to use GNU multiple precision mathematics (*)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Sqids\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Generate short YouTube-looking IDs from numbers", + "homepage": "https://sqids.org/php", + "keywords": [ + "decode", + "encode", + "generate", + "hashids", + "ids", + "sqids" + ], + "support": { + "issues": "https://github.com/sqids/sqids-php/issues", + "source": "https://github.com/sqids/sqids-php/tree/0.5.0" + }, + "time": "2025-01-05T05:37:48+00:00" + }, { "name": "symfony/clock", "version": "v7.2.0", @@ -5582,6 +5776,73 @@ }, "time": "2024-12-21T16:25:41+00:00" }, + { + "name": "vinkla/hashids", + "version": "12.0.0", + "source": { + "type": "git", + "url": "https://github.com/vinkla/laravel-hashids.git", + "reference": "71e4be8347d8c77dd728b61c1ff3b53cb4941ef1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vinkla/laravel-hashids/zipball/71e4be8347d8c77dd728b61c1ff3b53cb4941ef1", + "reference": "71e4be8347d8c77dd728b61c1ff3b53cb4941ef1", + "shasum": "" + }, + "require": { + "graham-campbell/manager": "^5.0", + "hashids/hashids": "^5.0", + "illuminate/contracts": "^11.0", + "illuminate/support": "^11.0", + "php": "^8.2" + }, + "require-dev": { + "graham-campbell/analyzer": "^4.1", + "graham-campbell/testbench": "^6.1", + "mockery/mockery": "^1.6.6", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Hashids": "Vinkla\\Hashids\\Facades\\Hashids" + }, + "providers": [ + "Vinkla\\Hashids\\HashidsServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "12.0-dev" + } + }, + "autoload": { + "psr-4": { + "Vinkla\\Hashids\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Vincent Klaiber", + "homepage": "https://github.com/vinkla" + } + ], + "description": "A Hashids bridge for Laravel", + "keywords": [ + "hashids", + "laravel" + ], + "support": { + "issues": "https://github.com/vinkla/laravel-hashids/issues", + "source": "https://github.com/vinkla/laravel-hashids/tree/12.0.0" + }, + "time": "2024-02-05T08:07:21+00:00" + }, { "name": "vlucas/phpdotenv", "version": "v5.6.1", @@ -5797,6 +6058,95 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "yajra/laravel-datatables-oracle", + "version": "v11.1.6", + "source": { + "type": "git", + "url": "https://github.com/yajra/laravel-datatables.git", + "reference": "b48eb614d0474c23a9c8041563beef9dda39656d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/b48eb614d0474c23a9c8041563beef9dda39656d", + "reference": "b48eb614d0474c23a9c8041563beef9dda39656d", + "shasum": "" + }, + "require": { + "illuminate/database": "^11", + "illuminate/filesystem": "^11", + "illuminate/http": "^11", + "illuminate/support": "^11", + "illuminate/view": "^11", + "php": "^8.2" + }, + "require-dev": { + "algolia/algoliasearch-client-php": "^3.4.1", + "larastan/larastan": "^2.9.1", + "laravel/pint": "^1.14", + "laravel/scout": "^10.8.3", + "meilisearch/meilisearch-php": "^1.6.1", + "orchestra/testbench": "^9", + "rector/rector": "^1.0" + }, + "suggest": { + "yajra/laravel-datatables-buttons": "Plugin for server-side exporting of dataTables.", + "yajra/laravel-datatables-editor": "Plugin to use DataTables Editor (requires a license).", + "yajra/laravel-datatables-export": "Plugin for server-side exporting using livewire and queue worker.", + "yajra/laravel-datatables-fractal": "Plugin for server-side response using Fractal.", + "yajra/laravel-datatables-html": "Plugin for server-side HTML builder of dataTables." + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "DataTables": "Yajra\\DataTables\\Facades\\DataTables" + }, + "providers": [ + "Yajra\\DataTables\\DataTablesServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "files": [ + "src/helper.php" + ], + "psr-4": { + "Yajra\\DataTables\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arjay Angeles", + "email": "aqangeles@gmail.com" + } + ], + "description": "jQuery DataTables API for Laravel", + "keywords": [ + "datatables", + "jquery", + "laravel", + "yajra" + ], + "support": { + "issues": "https://github.com/yajra/laravel-datatables/issues", + "source": "https://github.com/yajra/laravel-datatables/tree/v11.1.6" + }, + "funding": [ + { + "url": "https://github.com/sponsors/yajra", + "type": "github" + } + ], + "time": "2025-01-21T03:15:46+00:00" } ], "packages-dev": [ diff --git a/config/datatables.php b/config/datatables.php new file mode 100644 index 0000000..bdb963f --- /dev/null +++ b/config/datatables.php @@ -0,0 +1,127 @@ + [ + /* + * Smart search will enclose search keyword with wildcard string "%keyword%". + * SQL: column LIKE "%keyword%" + */ + 'smart' => true, + + /* + * Multi-term search will explode search keyword using spaces resulting into multiple term search. + */ + 'multi_term' => true, + + /* + * Case insensitive will search the keyword in lower case format. + * SQL: LOWER(column) LIKE LOWER(keyword) + */ + 'case_insensitive' => true, + + /* + * Wild card will add "%" in between every characters of the keyword. + * SQL: column LIKE "%k%e%y%w%o%r%d%" + */ + 'use_wildcards' => false, + + /* + * Perform a search which starts with the given keyword. + * SQL: column LIKE "keyword%" + */ + 'starts_with' => false, + ], + + /* + * DataTables internal index id response column name. + */ + 'index_column' => 'DT_RowIndex', + + /* + * List of available builders for DataTables. + * This is where you can register your custom DataTables builder. + */ + 'engines' => [ + 'eloquent' => Yajra\DataTables\EloquentDataTable::class, + 'query' => Yajra\DataTables\QueryDataTable::class, + 'collection' => Yajra\DataTables\CollectionDataTable::class, + 'resource' => Yajra\DataTables\ApiResourceDataTable::class, + ], + + /* + * DataTables accepted builder to engine mapping. + * This is where you can override which engine a builder should use + * Note, only change this if you know what you are doing! + */ + 'builders' => [ + // Illuminate\Database\Eloquent\Relations\Relation::class => 'eloquent', + // Illuminate\Database\Eloquent\Builder::class => 'eloquent', + // Illuminate\Database\Query\Builder::class => 'query', + // Illuminate\Support\Collection::class => 'collection', + ], + + /* + * Nulls last sql pattern for PostgreSQL & Oracle. + * For MySQL, use 'CASE WHEN :column IS NULL THEN 1 ELSE 0 END, :column :direction' + */ + 'nulls_last_sql' => ':column :direction NULLS LAST', + + /* + * User friendly message to be displayed on user if error occurs. + * Possible values: + * null - The exception message will be used on error response. + * 'throw' - Throws a \Yajra\DataTables\Exceptions\Exception. Use your custom error handler if needed. + * 'custom message' - Any friendly message to be displayed to the user. You can also use translation key. + */ + 'error' => env('DATATABLES_ERROR', null), + + /* + * Default columns definition of DataTable utility functions. + */ + 'columns' => [ + /* + * List of columns hidden/removed on json response. + */ + 'excess' => ['rn', 'row_num'], + + /* + * List of columns to be escaped. If set to *, all columns are escape. + * Note: You can set the value to empty array to disable XSS protection. + */ + 'escape' => '*', + + /* + * List of columns that are allowed to display html content. + * Note: Adding columns to list will make us available to XSS attacks. + */ + 'raw' => ['action'], + + /* + * List of columns are forbidden from being searched/sorted. + */ + 'blacklist' => ['password', 'remember_token'], + + /* + * List of columns that are only allowed for search/sort. + * If set to *, all columns are allowed. + */ + 'whitelist' => '*', + ], + + /* + * JsonResponse header and options config. + */ + 'json' => [ + 'header' => [], + 'options' => 0, + ], + + /* + * Default condition to determine if a parameter is a callback or not. + * Callbacks needs to start by those terms, or they will be cast to string. + */ + 'callback' => ['$', '$.', 'function'], +]; diff --git a/database/migrations/2025_02_25_085358_create_classifications_table.php b/database/migrations/2025_02_25_085358_create_classifications_table.php new file mode 100644 index 0000000..8c7365e --- /dev/null +++ b/database/migrations/2025_02_25_085358_create_classifications_table.php @@ -0,0 +1,33 @@ +id(); + $table->string('name'); + $table->string('slug'); + $table->text('description')->nullable(); + $table->enum('status', ['0', '1'])->default('0'); + $table->unsignedBigInteger('enhancer_id'); + $table->foreign('enhancer_id')->references('id')->on('users'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('classifications'); + } +}; diff --git a/database/migrations/2025_02_25_085404_create_sub_classifications_table.php b/database/migrations/2025_02_25_085404_create_sub_classifications_table.php new file mode 100644 index 0000000..5e6fad8 --- /dev/null +++ b/database/migrations/2025_02_25_085404_create_sub_classifications_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('name'); + $table->string('slug'); + $table->text('description')->nullable(); + $table->enum('status', ['0', '1'])->default('0'); + $table->unsignedBigInteger('classification_id'); + $table->foreign('classification_id')->references('id')->on('classifications'); + $table->unsignedBigInteger('enhancer_id'); + $table->foreign('enhancer_id')->references('id')->on('users'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sub_classifications'); + } +}; diff --git a/database/seeders/ClassificationSeeder.php b/database/seeders/ClassificationSeeder.php new file mode 100644 index 0000000..09bd9d3 --- /dev/null +++ b/database/seeders/ClassificationSeeder.php @@ -0,0 +1,17 @@ + 'classifications']) +@include('partials.dashboard.header') + +