feat: classification

This commit is contained in:
myuqinurrohman 2025-02-27 08:41:37 +07:00
parent 5f460c3b6e
commit 17e4b379a4
34 changed files with 1854 additions and 16 deletions

View File

@ -1,5 +1,6 @@
<?php
use Hashids\Hashids;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
@ -64,3 +65,29 @@ function shorten_text($text, $maxLength = 100) {
return $text;
}
}
if (! function_exists('is_role')) {
function is_role($roles) {
if (Auth::check()) {
return in_array(Auth::user()->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;
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller;
use App\Http\Requests\ClassificationRequest;
use App\Models\Classification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
class ClassificationController extends Controller
{
public function index(){
return view('dashboard.classifications.index', [
'title' => '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);
}
}
}

View File

@ -0,0 +1,144 @@
<?php
namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller;
use App\Models\Classification;
use App\Models\SubClassification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use SebastianBergmann\Type\TrueType;
use Yajra\DataTables\DataTables;
class DatatableController extends Controller
{
public function classification(Request $request){
if ($request->ajax()) {
$data = Classification::with(['subClassifications'])->get();
return DataTables::of($data)
->addIndexColumn()
->addColumn('status', function ($data) {
if ($data->status == '0') {
return '<span class="badge bg-danger" style="display:inline-block;font-size:0.8rem;">Nonaktif</span>';
}else{
return '<span class="badge bg-primary" style="display:inline-block;font-size:0.8rem;">Aktif</span>';
}
})
->addColumn('sub_classifications', function ($data) {
$subClassificationCount = $data->subClassifications->count();
if($subClassificationCount > 0){
return $subClassificationCount. ' [<a href="'.route('dashboard.sub.classifications.index', ['classification' => $data->slug]).'">Lihat</a>]';
}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 = '<div class="dropdown" style="display:flex; justify-content:center;">
<a class="dropdown-toggle btn btn-icon btn-light" data-bs-toggle="dropdown"><em class="icon ni ni-more-v"></em></a>
<div class="dropdown-menu dropdown-menu-end">
<ul class="link-list-opt">
<li><a href="'.$showUrl.'"><em class="icon ni ni-eye"></em><span>Detail</span></a></li>';
if (is_role([1])) {
$dropdown .= '<li><a href="'.$addSubClassificationUrl.'"><em class="icon ni ni-plus"></em><span>Tambah Sub Klasifikasi</span></a></li>';
}
if (is_role([1])) {
$dropdown .= '<li><a href="'.$editUrl.'"><em class="icon ni ni-edit"></em><span>Ubah</span></a></li>';
}
if (is_role([1])) {
$dropdown .= '<li><a href="javascript:void(0);" onclick="deleteItem(\''.$deleteUrl.'\', \'Apakah Anda yakin ingin menghapus klasifikasi '.$data->name.'? Item ini akan dihapus secara permanen!\')"><em class="icon ni ni-trash"></em><span>Hapus</span></a></li>';
}
$dropdown .= '</ul>
</div>
</div>';
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 '<span class="badge bg-danger" style="display:inline-block;font-size:0.8rem;">Nonaktif</span>';
}else{
return '<span class="badge bg-primary" style="display:inline-block;font-size:0.8rem;">Aktif</span>';
}
})
->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 = '<div class="dropdown" style="display:flex; justify-content:center;">
<a class="dropdown-toggle btn btn-icon btn-light" data-bs-toggle="dropdown"><em class="icon ni ni-more-v"></em></a>
<div class="dropdown-menu dropdown-menu-end">
<ul class="link-list-opt">
<li><a href="'.$showUrl.'"><em class="icon ni ni-eye"></em><span>Detail</span></a></li>';
if (is_role([1])) {
$dropdown .= '<li><a href="'.$editUrl.'"><em class="icon ni ni-edit"></em><span>Ubah</span></a></li>';
}
if (is_role([1])) {
$dropdown .= '<li><a href="javascript:void(0);" onclick="deleteItem(\''.$deleteUrl.'\', \'Apakah Anda yakin ingin menghapus sub klasifikasi '.$data->name.'? Item ini akan dihapus secara permanen!\')"><em class="icon ni ni-trash"></em><span>Hapus</span></a></li>';
}
$dropdown .= '</ul>
</div>
</div>';
return $dropdown;
})
->rawColumns(['status', 'action'])
->make(true);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
}

View File

@ -10,7 +10,6 @@ class OverviewController extends Controller
public function index(){
return view('dashboard.overview.index', [
'title' => 'Ikhtisar',
'page' => 'overview'
]);
}
}

View File

@ -0,0 +1,101 @@
<?php
namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller;
use App\Http\Requests\SubClassificationRequest;
use App\Models\Classification;
use App\Models\SubClassification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
class SubClassificationController extends Controller
{
public function index(Request $request){
$viewData = [
'title' => '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);
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
class ClassificationRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return Auth::check() && is_role(['1']);
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|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.',
];
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class SubClassificationRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return Auth::check() && is_role(['1']);
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|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.',
];
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Classification extends Model
{
protected $table = 'classifications';
protected $fillable = [
'name',
'slug',
'status',
'description',
'enhancer_id'
];
public function subClassifications(){
return $this->hasMany(SubClassification::class, 'classification_id', 'id');
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class SubClassification extends Model
{
protected $table = 'sub_classifications';
protected $fillable = [
'name',
'slug',
'status',
'description',
'classification_id',
'enhancer_id'
];
public function classification(){
return $this->belongsTo(Classification::class, 'classification_id', 'id');
}
}

View File

@ -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",

352
composer.lock generated
View File

@ -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": [

127
config/datatables.php Normal file
View File

@ -0,0 +1,127 @@
<?php
return [
/*
* DataTables search options.
*/
'search' => [
/*
* 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'],
];

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('classifications', function (Blueprint $table) {
$table->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');
}
};

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('sub_classifications', function (Blueprint $table) {
$table->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');
}
};

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ClassificationSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class SubClassificationSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
}
}

View File

@ -44,3 +44,33 @@ .valid {
input:focus {
outline: none; /* Menghilangkan outline default */
}
/* Menambahkan margin bawah pada Show Entries */
.dataTables_length {
margin-bottom: 15px; /* Ubah nilai sesuai kebutuhan */
}
/* Menambahkan margin bawah pada Search */
.dataTables_filter {
margin-bottom: 15px; /* Ubah nilai sesuai kebutuhan */
}
/* Jika ingin menambahkan padding pada input search */
.dataTables_filter input {
padding-bottom: 10px; /* Tambahkan padding bawah pada input search */
margin-left: -0.5rem !important;
}
.validation-error{
display: block;
color: red;
font-size: 0.7rem;
}
.description-content{
background-color: #F5F6FA;
border: 1px solid #DBDFEA;
padding: 0.7rem;
border-radius: 0.4rem;
}

View File

@ -79,7 +79,7 @@ :root {
--bs-dark: #1f2b3a;
--bs-gray: #8091a7;
--bs-lighter: #f5f6fa;
--bs-primary-rgb: 133, 79, 255;
--bs-primary-rgb: 53, 114, 239;
--bs-secondary-rgb: 54, 74, 99;
--bs-success-rgb: 30, 224, 172;
--bs-info-rgb: 9, 194, 222;

View File

@ -22,14 +22,19 @@
if ($(_minimal).exists()) {
$(_minimal).each(function () {
$(this).summernote({
placeholder: 'Hello stand alone ui',
placeholder: '',
tabsize: 2,
height: 120,
toolbar: [['style', ['style']], ['font', ['bold', 'underline', 'clear']], ['para', ['ul', 'ol', 'paragraph']], ['table', ['table']], ['view', ['fullscreen']]]
});
});
}
}; // Tinymce Init @v1.0
};
$('form').on('submit', function() {
var summernoteContent = $('.summernote-minimal').summernote('code');
$('#richEeditorValue').val(summernoteContent);
});
NioApp.Tinymce = function () {
@ -161,4 +166,4 @@
};
NioApp.coms.docReady.push(NioApp.EditorInit);
}(NioApp, jQuery);
}(NioApp, jQuery);

View File

@ -0,0 +1,66 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="{{route('dashboard.classifications.store')}}" method="post">
@csrf
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama Klasifikasi<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama klasifikasi" value="{{old('name')}}">
</div>
@error('name')
<span class="validation-error">{{$message}}</span>
@enderror
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label">Status<span class="required-input">*</span></label>
<div class="form-control-wrap">
<select class="form-select js-select2" name="status">
<option value="1" {{old('status') == '1' ? 'selected' : ''}}>Aktif</option>
<option value="0" {{old('status') == '0' ? 'selected' : ''}}>Tidak Aktif</option>
</select>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="summernote-minimal">{!!old('description')!!}</div>
<input type="hidden" name="description" id="richEeditorValue">
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.classifications.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<button type="submit" class="btn btn-md btn-primary">Tambahkan</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])

View File

@ -0,0 +1,67 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="{{route('dashboard.classifications.update', ['id' => encryptId($classification->id)])}}" method="post">
@csrf
@method('put')
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama Klasifikasi<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama klasifikasi" value="{{ $classification->name}}">
</div>
@error('name')
<span class="validation-error">{{$message}}</span>
@enderror
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label">Status<span class="required-input">*</span></label>
<div class="form-control-wrap">
<select class="form-select js-select2" name="status">
<option value="1" {{$classification->status == '1' ? 'selected' : ''}}>Aktif</option>
<option value="0" {{$classification->status == '0' ? 'selected' : ''}}>Tidak Aktif</option>
</select>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="summernote-minimal">{!! $classification->description !!}</div>
<input type="hidden" name="description" id="richEeditorValue">
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.classifications.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<button type="submit" class="btn btn-md btn-primary">Simpan</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])

View File

@ -0,0 +1,62 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block-head nk-block-head-sm">
<div class="nk-block-between">
<div class="nk-block-head-content">
<h3 class="nk-block-title page-title">{{$title}}</h3>
</div><!-- .nk-block-head-content -->
<div class="nk-block-head-content">
<div class="toggle-wrap nk-block-tools-toggle">
<a href="#" class="btn btn-icon btn-trigger toggle-expand me-n1" data-target="pageMenu"><em class="icon ni ni-more-v"></em></a>
<div class="toggle-expand-content" data-content="pageMenu">
<ul class="nk-block-tools g-3">
{{-- <li>
<div class="drodown">
<a href="#" class="dropdown-toggle btn btn-white btn-dim btn-outline-light" data-bs-toggle="dropdown"><em class="d-none d-sm-inline icon ni ni-calender-date"></em><span><span class="d-none d-md-inline">Last</span> 30 Days</span><em class="dd-indc icon ni ni-chevron-right"></em></a>
<div class="dropdown-menu dropdown-menu-end">
<ul class="link-list-opt no-bdr">
<li><a href="#"><span>Last 30 Days</span></a></li>
<li><a href="#"><span>Last 6 Months</span></a></li>
<li><a href="#"><span>Last 1 Years</span></a></li>
</ul>
</div>
</div>
</li> --}}
<li class="nk-block-tools-opt"><a href="{{route('dashboard.classifications.create')}}" class="btn btn-primary"><em class="icon ni ni-plus"></em><span>Tambah</span></a></li>
</ul>
</div>
</div>
</div><!-- .nk-block-head-content -->
</div><!-- .nk-block-between -->
</div><!-- .nk-block-head -->
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="table-responsive">
<table class="table table-striped table-bordered nowrap" id="classificationsTable" border="1">
<thead>
<tr>
<th style="width: 10% !important;">No</th>
<th>Nama</th>
<th style="width: 13% !important;">Status</th>
<th style="width: 17% !important;">Sub Klasifikasi</th>
<th style="width: 10% !important;"></th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer' ,['datatable' => 'classification'])

View File

@ -0,0 +1,60 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="#" method="post">
@csrf
@method('put')
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama Klasifikasi</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama klasifikasi" value="{{ $classification->name}}" readonly>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="status">Status</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('status') border-danger @enderror" id="status" name="status" placeholder="Status klasifikasi" value="{{ $classification->status == '1' ? 'Aktif' : 'Tidak Aktif'}}" readonly>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="description-content">{!! $classification->description !!}</div>
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.classifications.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<a href="{{route('dashboard.classifications.edit', ['id' => encryptId($classification->id)])}}" class="btn btn-warning"><span>Ubah</span></a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])

View File

@ -1,5 +1,5 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar')
@include('partials.dashboard.sidebar', ['page' => 'overview'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">

View File

@ -0,0 +1,84 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'sub_classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="{{route('dashboard.sub.classifications.store')}}" method="post">
@csrf
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama Sub Klasifikasi<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama klasifikasi" value="{{old('name')}}">
</div>
@error('name')
<span class="validation-error">{{$message}}</span>
@enderror
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label">Klasifikasi<span class="required-input">*</span></label>
<div class="form-control-wrap">
@if ($fromClassification)
<select class="form-select js-select2" name="classification_id" aria-readonly="on">
<option value="{{$classification->id}}" {{old('classification_id') == $classification->id ? 'selected' : ''}}>{{$classification->name}}</option>
</select>
@else
<select class="form-select js-select2" data-search="on" name="classification_id">
@foreach ($classifications as $classification)
<option value="{{$classification->id}}" {{old('classification_id') == $classification->id ? 'selected' : ''}}>{{$classification->name}}</option>
@endforeach
</select>
@endif
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label">Status<span class="required-input">*</span></label>
<div class="form-control-wrap">
<select class="form-select js-select2" name="status">
<option value="1" {{old('status') == '1' ? 'selected' : ''}}>Aktif</option>
<option value="0" {{old('status') == '0' ? 'selected' : ''}}>Tidak Aktif</option>
</select>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="summernote-minimal">{!!old('description')!!}</div>
<input type="hidden" name="description" id="richEeditorValue">
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.sub.classifications.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<button type="submit" class="btn btn-md btn-primary">Tambahkan</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])

View File

@ -0,0 +1,79 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'sub_classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="{{route('dashboard.sub.classifications.update', ['id' => encryptId($subClassification->id)])}}" method="post">
@csrf
@method('put')
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama Sub Klasifikasi<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama klasifikasi" value="{{$subClassification->name}}">
</div>
@error('name')
<span class="validation-error">{{$message}}</span>
@enderror
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label">Klasifikasi<span class="required-input">*</span></label>
<div class="form-control-wrap">
<select class="form-select js-select2" data-search="on" name="classification_id">
@foreach ($classifications as $classification)
<option value="{{$classification->id}}" {{$subClassification->classification_id == $classification->id ? 'selected' : ''}}>{{$classification->name}}</option>
@endforeach
</select>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label">Status<span class="required-input">*</span></label>
<div class="form-control-wrap">
<select class="form-select js-select2" name="status">
<option value="1" {{$subClassification->status == '1' ? 'selected' : ''}}>Aktif</option>
<option value="0" {{$subClassification->status == '0' ? 'selected' : ''}}>Tidak Aktif</option>
</select>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="summernote-minimal">{!!$subClassification->description!!}</div>
<input type="hidden" name="description" id="richEeditorValue">
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.sub.classifications.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<button type="submit" class="btn btn-md btn-primary">Simpan</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])

View File

@ -0,0 +1,62 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'sub_classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block-head nk-block-head-sm">
<div class="nk-block-between">
<div class="nk-block-head-content">
<h3 class="nk-block-title page-title">{{$title}}</h3>
</div><!-- .nk-block-head-content -->
<div class="nk-block-head-content">
<div class="toggle-wrap nk-block-tools-toggle">
<a href="#" class="btn btn-icon btn-trigger toggle-expand me-n1" data-target="pageMenu"><em class="icon ni ni-more-v"></em></a>
<div class="toggle-expand-content" data-content="pageMenu">
<ul class="nk-block-tools g-3">
{{-- <li>
<div class="drodown">
<a href="#" class="dropdown-toggle btn btn-white btn-dim btn-outline-light" data-bs-toggle="dropdown"><em class="d-none d-sm-inline icon ni ni-calender-date"></em><span><span class="d-none d-md-inline">Last</span> 30 Days</span><em class="dd-indc icon ni ni-chevron-right"></em></a>
<div class="dropdown-menu dropdown-menu-end">
<ul class="link-list-opt no-bdr">
<li><a href="#"><span>Last 30 Days</span></a></li>
<li><a href="#"><span>Last 6 Months</span></a></li>
<li><a href="#"><span>Last 1 Years</span></a></li>
</ul>
</div>
</div>
</li> --}}
<li class="nk-block-tools-opt"><a href="{{route('dashboard.sub.classifications.create')}}" class="btn btn-primary"><em class="icon ni ni-plus"></em><span>Tambah</span></a></li>
</ul>
</div>
</div>
</div><!-- .nk-block-head-content -->
</div><!-- .nk-block-between -->
</div><!-- .nk-block-head -->
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="table-responsive">
<table class="table table-striped table-bordered nowrap" id="subClassificationsTable" border="1">
<thead>
<tr>
<th style="width: 10% !important;">No</th>
<th>Klasifikasi</th>
<th>Nama</th>
<th style="width: 13% !important;">Status</th>
<th style="width: 10% !important;"></th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer' ,['datatable' => 'sub_classification'])

View File

@ -0,0 +1,68 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'sub_classifications'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="#" method="post">
@csrf
@method('put')
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama Sub Klasifikasi</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama klasifikasi" value="{{ $subClassification->name}}" readonly>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="classification_name">Klasifikasi</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('classification_name') border-danger @enderror" id="classification_name" name="classification_name" placeholder="Masukan nama klasifikasi" value="{{ $subClassification->classification->name}}" readonly>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="status">Status</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('status') border-danger @enderror" id="status" name="status" placeholder="Status klasifikasi" value="{{ $subClassification->status == '1' ? 'Aktif' : 'Tidak Aktif'}}" readonly>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="description-content">{!! $subClassification->description !!}</div>
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.sub.classifications.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<a href="{{route('dashboard.sub.classifications.edit', ['id' => encryptId($subClassification->id)])}}" class="btn btn-warning"><span>Ubah</span></a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])

View File

@ -0,0 +1,70 @@
{{-- <script>
alert('hai');
</script> --}}
<script>
var datatableLanguage = {
search: "", // Menghilangkan teks 'Search :'
searchPlaceholder: "Cari data...", // Placeholder untuk input pencarian
zeroRecords: "Tidak ditemukan data yang sesuai", // Teks ketika data tidak ditemukan
info: "Menampilkan _START_ sampai _END_ dari _TOTAL_ entri", // Info menampilkan data
infoEmpty: "Menampilkan 0 sampai 0 dari 0 entri", // Jika tidak ada data
infoFiltered: "(difilter dari _MAX_ total entri)", // Info setelah difilter
lengthMenu: "_MENU_", // Custom teks untuk Show Entries
paginate: {
previous: "Sebelumnya", // Custom teks Previous
next: "Berikutnya" // Custom teks Next
},
processing: '<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>',
emptyTable: "Tidak ada data tersedia",
zeroRecords: "Tidak ditemukan data yang sesuai"
};
</script>
@if ($datatable === 'classification')
<script>
$(document).ready(function() {
$('#classificationsTable').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route('dashboard.classifications.data') }}',
columns: [
{ data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false },
{ data: 'name', name: 'name' },
{ data: 'status', name: 'status' },
{ data: 'sub_classifications', name: 'sub_classifications' },
{ data: 'action', name: 'action', orderable: false, searchable: false },
{ data: 'id', name: 'id', orderable: true, searchable: false, visible: false },
],
language: datatableLanguage,
autoWidth: false,
order: [[1, 'desc']],
lengthMenu: [[10, 25, 50, 100, -1], ['Tampilkan 10 data', 'Tampilkan 25 data', 'Tampilkan 50 data', 'Tampilkan 100 data', 'Tampilkan semua']]
});
});
</script>
@endif
@if ($datatable === 'sub_classification')
<script>
$(document).ready(function() {
$('#subClassificationsTable').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route('dashboard.sub.classifications.data', ["classification" => $classification]) }}',
columns: [
{ data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false },
{ data: 'classification', name: 'classification' },
{ data: 'name', name: 'name' },
{ data: 'status', name: 'status' },
{ data: 'action', name: 'action', orderable: false, searchable: false },
{ data: 'id', name: 'id', orderable: true, searchable: false, visible: false },
],
language: datatableLanguage,
autoWidth: false,
order: [[1, 'desc']],
lengthMenu: [[10, 25, 50, 100, -1], ['Tampilkan 10 data', 'Tampilkan 25 data', 'Tampilkan 50 data', 'Tampilkan 100 data', 'Tampilkan semua']]
});
});
</script>
@endif

View File

@ -0,0 +1,68 @@
<script>
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
});
function deleteItem(url, message) {
Swal.fire({
title: 'Apakah Anda yakin?',
text: message,
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Ya, hapus!',
cancelButtonText: 'Batal',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
type: "DELETE",
url: url,
success: function(response) {
$('#usersTable').DataTable().ajax.reload();
Swal.fire(
'Terhapus!',
response.message,
'success'
).then(() => {
location.reload();
});
},
error: function(xhr) {
Swal.fire(
'Terjadi kesalahan!',
xhr.responseText,
'error'
);
}
});
}
});
}
</script>
@if (session('success-status'))
<script>
Swal.fire({
icon: 'success',
title: 'Sukses',
text: '{{ session('success-status') }}',
confirmButtonText: 'OK'
});
</script>
@endif
@if (session('failed-status'))
<script>
Swal.fire({
icon: 'error',
title: 'Gagal',
text: '{{ session('failed-status') }}',
confirmButtonText: 'OK'
});
</script>
@endif

View File

@ -51,7 +51,19 @@
<!-- JavaScript -->
<script src="{{asset('assets/dashboard/js/bundle.js?ver=3.0.3')}}"></script>
<script src="{{asset('assets/dashboard/js/scripts.js?ver=3.0.3')}}"></script>
<script src="{{asset('assets/dashboard/js/charts/chart-ecommerce.js?ver=3.0.3')}}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
@include('partials.app.sweetalert')
@if (isset($datatable))
@include('partials.app.datatable', ['datatable' => $datatable])
@endif
@if (isset($rich_editor))
<link rel="stylesheet" href="{{asset('assets/dashboard/css/editors/summernote.css?ver=3.0.3')}}">
<script src="{{asset('assets/dashboard/js/libs/editors/summernote.js?ver=3.0.3')}}"></script>
<script src="{{asset('assets/dashboard/js/editors.js?ver=3.0.3')}}"></script>
@endif
</body>
</html>

View File

@ -4,7 +4,8 @@
<head>
<base href="../">
<meta charset="utf-8">
<meta name="author" content="Softnio">
<meta name="author" content="Yuqi">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="A powerful and conceptual apps base dashboard template that especially build for developers and programmers.">
<!-- Fav Icon -->
@ -15,4 +16,9 @@
<link rel="stylesheet" href="{{asset('assets/dashboard/css/dashlite.css?ver=3.0.3')}}">
<link rel="stylesheet" href="{{asset('assets/dashboard/css/custom.css')}}">
<link id="skin-default" rel="stylesheet" href="{{asset('assets/dashboard/css/theme.css?ver=3.0.3')}}">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
</head>

View File

@ -34,13 +34,13 @@
<h6 class="overline-title text-primary-alt">Master</h6>
</li><!-- .nk-menu-item -->
<li class="nk-menu-item">
<a href="javascript:void(0);" class="nk-menu-link">
<a href="{{route('dashboard.classifications.index')}}" class="nk-menu-link {{$page === 'classifications' ? 'active-page' : ''}}">
<span class="nk-menu-icon"><em class="icon ni ni-dot-box"></em></span>
<span class="nk-menu-text">Klasifikasi</span>
</a>
</li><!-- .nk-menu-item -->
<li class="nk-menu-item">
<a href="javascript:void(0);" class="nk-menu-link">
<a href="{{route('dashboard.sub.classifications.index')}}" class="nk-menu-link {{$page === 'sub_classifications' ? 'active-page' : ''}}">
<span class="nk-menu-icon"><em class="icon ni ni-dot-box"></em></span>
<span class="nk-menu-text">Sub Klasifikasi</span>
</a>

View File

@ -1,7 +1,10 @@
<?php
use App\Http\Controllers\AuthController;
use App\Http\Controllers\Dashboard\ClassificationController;
use App\Http\Controllers\Dashboard\DatatableController;
use App\Http\Controllers\Dashboard\OverviewController;
use App\Http\Controllers\Dashboard\SubClassificationController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
@ -23,11 +26,37 @@
});
Route::middleware(['auth', 'role:1,2,3,4'])->group(function(){
Route::name('dashboard.')->group(function(){
Route::prefix('dashboard')->group(function(){
Route::controller(OverviewController::class)->group(function(){
Route::get('/overview', 'index')->name('overview');
Route::prefix('dashboard')->name('dashboard.')->group(function(){
Route::controller(OverviewController::class)->group(function(){
Route::get('/overview', 'index')->name('overview');
});
Route::prefix('classifications')->name('classifications.')->group(function(){
Route::controller(ClassificationController::class)->group(function(){
Route::get('/', 'index')->name('index');
Route::get('/create', 'create')->name('create');
Route::post('/', 'store')->name('store');
Route::get('/{id}/show', 'show')->name('show');
Route::get('/{id}/edit', 'edit')->name('edit');
Route::put('/{id}', 'update')->name('update');
Route::delete('/{id}', 'destroy')->name('destroy');
});
Route::get('/data', [DatatableController::class, 'classification'])->name('data');
});
Route::prefix('sub-classifications')->name('sub.classifications.')->group(function(){
Route::controller(SubClassificationController::class)->group(function(){
Route::get('/', 'index')->name('index');
Route::get('/create', 'create')->name('create');
Route::post('/', 'store')->name('store');
Route::get('/{id}/show', 'show')->name('show');
Route::get('/{id}/edit', 'edit')->name('edit');
Route::put('/{id}', 'update')->name('update');
Route::delete('/{id}', 'destroy')->name('destroy');
});
Route::get('/data', [DatatableController::class, 'subClassification'])->name('data');
});
});
});