Compare commits

2 Commits
49 changed files with 4384 additions and 155 deletions
@@ -0,0 +1,138 @@
<?php
namespace App\Http\Controllers\Web\Ekosistem;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use App\Models\Ekosistem\GroupBasisData;
class GroupBasisDataController extends Controller
{
public function index(Request $request): View
{
Gate::authorize('super_admin');
$title = 'Program';
$perPage = $request->query('per_page', 10);
$search = strtolower($request->query('search', ''));
$group = GroupBasisData::with('tabel')
->whereRaw('lower(\'group\') LIKE ?', ["%$search%"])
->paginate($perPage);
return view('ekosistem.group-basis-data.index', compact('title', 'group'));
}
/**
* Show the form for creating a new resource.
*/
public function create(): View
{
return view('ekosistem.group-basis-data.add');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): RedirectResponse
{
Gate::authorize('super_admin');
$validated = $request->validate([
'group' => ['required',
'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
'unique:ekosistem_basis_data_group,group'
],
'label' => ['required', 'string'],
'urutan' => ['nullable', 'integer', 'min:1'],
'deskripsi' => ['nullable', 'string'],
]);
GroupBasisData::create([...$validated,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return redirect()->route('group.index')->with('success', 'Kelompok basis data berhasil ditambahkan.');
}
/**
* Display the specified resource.
*/
public function show(string $id): View
{
Gate::authorize('super_admin');
$group = GroupBasisData::find($id);
if (!$group) {
return redirect()->route('group-basis-data.index')->with('error', 'Kelompok basis data tidak ditemukan.');
}
return view('ekosistem.group-basis-data.view', compact('group'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id): View
{
Gate::authorize('super_admin');
$group = GroupBasisData::find($id);
if (!$group) {
return redirect()->route('group-basis-data.index')->with('error', 'Kelompok basis data tidak ditemukan.');
}
return view('ekosistem.group-basis-data.edit', compact('group'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id): RedirectResponse
{
Gate::authorize('super_admin');
$group = GroupBasisData::find($id);
if (!$group) {
return redirect()->route('group-basis-data.index')->with('error', 'Kelompok basis data tidak ditemukan.');
}
$validated = $request->validate([
'group' => ['required',
'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
'unique:ekosistem_basis_data_tabel,tabel'
],
'label' => ['required', 'string'],
'urutan' => ['nullable', 'integer', 'min:1'],
'deskripsi' => ['nullable', 'string'],
]);
$group->update([...$validated,
'updated_by' => auth()->id(),
]);
return redirect()->route('group.index')->with('success', 'Kelompok basis data berhasil diperbarui.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
Gate::authorize('super_admin');
$group = TabelBasisData::find($id);
if (!$group) {
return redirect()->route('group.index')->with('error', 'Kelompok basis data tidak ditemukan.');
}
$group->delete();
return redirect()->route('group.index')->with('success', 'Kelompok basis data berhasil dihapus.');
}
}
@@ -0,0 +1,218 @@
<?php
namespace App\Http\Controllers\Web\Ekosistem;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rule;
use Illuminate\Http\JsonResponse;
use App\Models\Ekosistem\KolomBasisData;
use App\Models\Ekosistem\TabelBasisData;
class KolomBasisDataController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request, string $tabelId): JsonResponse
{
Gate::authorize('super_admin');
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
return response()->json([
'status' => 'error',
'message' => 'Data tabel tidak ditemukan.'
], 404);
}
$validated = $request->validate([
'kolom' => ['required',
'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
Rule::unique('ekosistem_basis_data_kolom')->where(function ($query) use ($request) {
return $query->where('tabel_id', $request->tabel_id)->whereNull('deleted_at');
})
],
'label' => ['required', 'string'],
'tipe' => ['required', 'string', Rule::in(['varchar', 'integer', 'text', 'date', 'boolean', 'datetime', 'float'])],
'validasi' => ['nullable', 'json'],
]);
KolomBasisData::create([...$validated,
'tabel_id' => $tabelId,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return response()->json([
'status' => 'success',
'message' => 'Kolom basis data berhasil ditambahkan.'
], 201);
}
/**
* Display the specified resource.
*/
public function show(Request $request, string $tabelId, string $id): JsonResponse
{
Gate::authorize('super_admin');
$kolom = KolomBasisData::where('tabel_id', $tabelId)->find($id);
if (!$kolom) {
return response()->json([
'status' => 'error',
'message' => 'Data kolom tidak ditemukan.'
], 404);
}
return response()->json(['data' => $kolom, 'status' => 'success']);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $tabelId, string $id): JsonResponse
{
Gate::authorize('super_admin');
$kolom = KolomBasisData::where('tabel_id', $tabelId)->find($id);
if (!$kolom) {
return response()->json([
'status' => 'error',
'message' => 'Data kolom tidak ditemukan.'
], 404);
}
$validated = $request->validate([
'kolom' => ['required',
'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
Rule::unique('ekosistem_basis_data_kolom')->where(function ($query) use ($request) {
return $query->where('tabel_id', $request->tabel_id)->whereNull('deleted_at');
})
],
'label' => ['required', 'string'],
'tipe' => ['required', 'string', Rule::in(['varchar', 'integer', 'text', 'date', 'boolean', 'datetime', 'float'])],
'validasi' => ['nullable', 'json'],
]);
$kolom->update([...$validated,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return response()->json([
'status' => 'success',
'message' => 'Kolom basis data berhasil diperbarui.'
], 200);
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Request $request, string $tabelId, string $id): JsonResponse
{
Gate::authorize('super_admin');
$kolom = KolomBasisData::where('tabel_id', $tabelId)->find($id);
if (!$kolom) {
return response()->json([
'status' => 'error',
'message' => 'Data kolom tidak ditemukan.'
], 404);
}
$kolom->delete();
return response()->json([
'status' => 'success',
'message' => 'Kolom basis data berhasil dihapus.'
], 200);
}
public function moveUp(Request $request, string $tabelId, string $id): JsonResponse
{
Gate::authorize('super_admin');
$current = KolomBasisData::where('tabel_id', $tabelId)->find($id);
if (!$current) {
return response()->json([
'status' => 'error',
'message' => 'Data kolom tidak ditemukan.'
], 404);
}
$prev = KolomBasisData::where('tabel_id', $current->tabel_id)
->where('urutan', '<', $current->urutan)
->orderBy('urutan', 'desc')
->first();
if ($prev) {
// swap
[$current->urutan, $prev->urutan] = [$prev->urutan, $current->urutan];
$current->save();
$prev->save();
}
return response()->json([
'status' => 'success',
'message' => 'Kolom basis data berhasil diperbarui.'
], 200);
}
public function moveDown(Request $request, string $tabelId, string $id): JsonResponse
{
Gate::authorize('super_admin');
$current = KolomBasisData::where('tabel_id', $tabelId)->find($id);
if (!$current) {
return response()->json([
'status' => 'error',
'message' => 'Data kolom tidak ditemukan.'
], 404);
}
$next = KolomBasisData::where('tabel_id', $current->tabel_id)
->where('urutan', '>', $current->urutan)
->orderBy('urutan', 'asc')
->first();
if ($next) {
// swap
[$current->urutan, $next->urutan] = [$next->urutan, $current->urutan];
$current->save();
$next->save();
}
return response()->json([
'status' => 'success',
'message' => 'Kolom basis data berhasil diperbarui.'
], 200);
}
}
@@ -0,0 +1,204 @@
<?php
namespace App\Http\Controllers\Web\Ekosistem;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\JsonResponse;
use App\Models\Ekosistem\TabelBasisData;
use App\Models\Ekosistem\GroupBasisData;
class TabelBasisDataController extends Controller
{
public function index(Request $request): View
{
Gate::authorize('super_admin');
$title = 'Program';
$perPage = $request->query('per_page', 10);
$search = strtolower($request->query('search', ''));
$tabel = TabelBasisData::with('kolom')
->whereRaw('lower(tabel) LIKE ?', ["%$search%"])
->paginate($perPage);
return view('ekosistem.tabel-basis-data.index', compact('title', 'tabel'));
}
/**
* Show the form for creating a new resource.
*/
public function create(): View
{
$group = GroupBasisData::all();
return view('ekosistem.tabel-basis-data.add', compact('group'));
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): RedirectResponse
{
Gate::authorize('super_admin');
$validated = $request->validate([
'tabel' => ['required',
'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
'unique:ekosistem_basis_data_tabel,tabel'
],
'label' => ['required', 'string'],
'menu' => ['required', 'string'],
'deskripsi' => ['nullable', 'string'],
'group_id' => ['nullable', 'exists:ekosistem_basis_data_group,id'],
]);
TabelBasisData::create([...$validated,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return redirect()->route('tabel.index')->with('success', 'Tabel basis data berhasil ditambahkan.');
}
/**
* Display the specified resource.
*/
public function show(string $id): View
{
Gate::authorize('super_admin');
$tabel = TabelBasisData::with('kolom')->find($id);
if (!$tabel) {
return redirect()->route('tabel-basis-data.index')->with('error', 'Tabel basis data tidak ditemukan.');
}
return view('ekosistem.tabel-basis-data.view', compact('tabel'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id): View
{
Gate::authorize('super_admin');
$tabel = TabelBasisData::find($id);
if (!$tabel) {
return redirect()->route('tabel-basis-data.index')->with('error', 'Tabel basis data tidak ditemukan.');
}
$group = GroupBasisData::all();
return view('ekosistem.tabel-basis-data.edit', compact('tabel', 'group'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id): RedirectResponse
{
Gate::authorize('super_admin');
$tabel = TabelBasisData::find($id);
if (!$tabel) {
return redirect()->route('tabel-basis-data.index')->with('error', 'Tabel basis data tidak ditemukan.');
}
$validated = $request->validate([
'tabel' => ['required',
'string',
'regex:/^[a-z0-9]+(_[a-z0-9]+)*$/',
'unique:ekosistem_basis_data_tabel,tabel'
],
'label' => ['required', 'string'],
'menu' => ['required', 'string'],
'deskripsi' => ['nullable', 'string'],
'group_id' => ['nullable', 'exists:ekosistem_basis_data_group,id'],
]);
$tabel->update([...$validated,
'updated_by' => auth()->id(),
]);
return redirect()->route('tabel.index')->with('success', 'Tabel basis data berhasil diperbarui.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
Gate::authorize('super_admin');
$tabel = TabelBasisData::find($id);
if (!$tabel) {
return redirect()->route('tabel.index')->with('error', 'Tabel basis data tidak ditemukan.');
}
$tabel->delete();
return redirect()->route('tabel.index')->with('success', 'Tabel basis data berhasil dihapus.');
}
public function moveUp(Request $request, string $id): JsonResponse
{
Gate::authorize('super_admin');
$current = TabelBasisData::find($id);
if (!$current) {
return response()->json([
'status' => 'error',
'message' => 'Data tabel tidak ditemukan.'
], 404);
}
$prev = TabelBasisData::where('urutan', '<', $current->urutan)
->orderBy('urutan', 'desc')
->first();
if ($prev) {
// swap
[$current->urutan, $prev->urutan] = [$prev->urutan, $current->urutan];
$current->save();
$prev->save();
}
return response()->json([
'status' => 'success',
'message' => 'Tabel basis data berhasil diperbarui.'
], 200);
}
public function moveDown(Request $request, string $id): JsonResponse
{
Gate::authorize('super_admin');
$current = TabelBasisData::find($id);
if (!$current) {
return response()->json([
'status' => 'error',
'message' => 'Data tabel tidak ditemukan.'
], 404);
}
$next = TabelBasisData::where('urutan', '>', $current->urutan)
->orderBy('urutan', 'asc')
->first();
if ($next) {
// swap
[$current->urutan, $next->urutan] = [$next->urutan, $current->urutan];
$current->save();
$next->save();
}
return response()->json([
'status' => 'success',
'message' => 'Tabel basis data berhasil diperbarui.'
], 200);
}
}
@@ -0,0 +1,359 @@
<?php
namespace App\Http\Controllers\Web\Ekosistem;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;
use App\Models\Ekosistem\TabelBasisData;
use App\Models\Ekosistem\KolomBasisData;
use App\Models\Ekosistem\ValueBasisData;
use App\Models\Core\Program;
class ValueBasisDataController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request, string $tabelId): View
{
if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
}
$perPage = $request->query('per_page', 10);
$search = strtolower($request->query('search', ''));
$program = null;
$programList = Program::get();
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
}
}
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
$selects = [];
foreach ($kolom as $k) {
$selects[] = "
MAX(
CASE
WHEN kolom_id = {$k->id}
THEN value_{$k->tipe}
ELSE NULL
END
) AS \"{$k->kolom}\"
";
}
$base = ValueBasisData::query()
->where('tabel_id', $tabelId)
->when($program, function ($query) use ($program) {
$query->where('program_id', $program->id);
})
->selectRaw("
program_id,
tabel_id,
value_id,
" . implode(",\n", $selects) . "
")
->groupBy('program_id', 'tabel_id', 'value_id')
->orderBy('value_id', 'asc');
$values = DB::query()->fromSub($base, 'pivot')
->when($search, function ($query) use ($search, $kolom) {
$query->where(function ($q) use ($search, $kolom) {
foreach ($kolom as $k) {
if ($k->tipe == 'text' || $k->tipe == 'varchar') {
$q->orWhereRaw("lower({$k->kolom}) LIKE ?", ["%$search%"]);
}
}
});
})
->paginate($perPage);
return view('ekosistem.value-basis-data.index', compact('programList', 'program', 'tabel', 'kolom', 'values'));
}
/**
* Show the form for creating a new resource.
*/
public function create(Request $request, string $tabelId): View
{
if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
}
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
return view('ekosistem.value-basis-data.add', compact('tabel', 'kolom', 'program'));
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request, string $tabelId): RedirectResponse
{
if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
}
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$validationRules = [];
foreach ($kolom as $k) {
if ($k->validasi && is_array($k->validasi)) {
$validationRules[$k->kolom] = $k->validasi;
} else {
$validationRules[$k->kolom] = ['nullable'];
}
}
$validated = $request->validate($validationRules);
DB::transaction(function () use ($program, $tabelId, $validated, $kolom) {
$maxId = ValueBasisData::where('tabel_id', $tabelId)
->where('program_id', $program->id)
->whereNotNull('value_id')
->max('value_id');
foreach ($kolom as $k) {
$values = [
'program_id' => $program->id,
'tabel_id' => (int)$tabelId,
'kolom_id' => $k->id,
'value_id' => ($maxId ?? 0) + 1,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
];
$values['value_' . $k->tipe] = $validated[$k->kolom] ?? null;
ValueBasisData::create($values);
}
});
return redirect()->route('tabel.data.index', [$tabelId, 'program' => $program->id])->with('success', 'Data berhasil ditambahkan.');
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Request $request, string $tabelId, string $id)
{
if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
}
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$values = ValueBasisData::query()
->where('tabel_id', $tabelId)
->where('value_id', $id)
->where('program_id', $program->id)
->get();
if ($values->isEmpty()) {
abort(404, 'Data tidak ditemukan.');
}
$value_id = $id;
return view('ekosistem.value-basis-data.edit', compact('tabel', 'kolom', 'program', 'values', 'value_id'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $tabelId, string $id)
{
if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
}
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$values = ValueBasisData::query()
->where('tabel_id', $tabelId)
->where('value_id', $id)
->where('program_id', $program->id)
->get();
if ($values->isEmpty()) {
abort(404, 'Data tidak ditemukan.');
}
$validationRules = [];
foreach ($kolom as $k) {
if ($k->validasi && is_array($k->validasi)) {
$validationRules[$k->kolom] = $k->validasi;
} else {
$validationRules[$k->kolom] = ['nullable'];
}
}
$validated = $request->validate($validationRules);
DB::transaction(function () use ($program, $tabelId, $validated, $kolom, $id, $values) {
foreach ($values as $v) {
$k = $kolom->where('id', $v->kolom_id)->first();
$v->update([
'value_' . $k->tipe => $validated[$k->kolom] ?? null,
'updated_by' => auth()->id(),
]);
}
});
return redirect()->route('tabel.data.index', [$tabelId, 'program' => $program->id])->with('success', 'Data berhasil diperbarui.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Request $request, string $tabelId, string $id)
{
if (!Gate::any(['super_admin', 'admin'])) {
abort(403);
}
$tabel = TabelBasisData::find($tabelId);
if (!$tabel) {
abort(404, 'Data tabel tidak ditemukan.');
}
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
if ($kolom->isEmpty()) {
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
}
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
} else {
if ($request->has('program_id') && $request->query('program_id')) {
$programId = $request->query('program_id');
$program = Program::find($programId);
if (!$program) {
abort(400, 'Program tidak ditemukan.');
}
} else {
abort(400, 'Program tidak ditemukan.');
}
}
$values = ValueBasisData::query()
->where('tabel_id', $tabelId)
->where('value_id', $id)
->where('program_id', $program->id)
->get();
if ($values->isEmpty()) {
abort(404, 'Data tidak ditemukan.');
}
ValueBasisData::query()
->where('tabel_id', $tabelId)
->where('value_id', $id)
->where('program_id', $program->id)
->delete();
return redirect()->route('tabel.data.index', [$tabelId, 'program' => $program->id])->with('success', 'Data berhasil dihapus.');
}
}
@@ -0,0 +1,134 @@
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Models\Core\Program;
use App\Models\Wilayah\Provinsi;
use App\Models\Pertanian\Komoditas;
class ProgramController extends Controller
{
public function index(Request $request)
{
$title = 'Program';
$perPage = $request->query('per_page', 10);
$search = $request->query('search', '');
$program = Program::where('nama', 'like', "%$search%")
->paginate($perPage);
return view('core.program.index', compact('title', 'program'));
}
public function create()
{
$provinsi = Provinsi::orderBy('nama', 'asc')->get();
$komoditas = Komoditas::orderBy('nama', 'asc')->get();
return view('core.program.add', compact('provinsi', 'komoditas'));
}
public function getProgram()
{
$program = Program::select(['id', 'nama', 'sub_domain'])->get();
return response()->json(['data' => $program]);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'nama' => ['required'],
'sub_domain' => ['required', Rule::unique(Program::class, 'sub_domain')],
'tahun' => ['required', 'integer'],
'instansi' => ['nullable', 'string'],
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => $validator->errors()->first()
], 422);
}
Program::create([...$validator->validated(),
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return redirect()->route('program.index')->with('success', 'Data program berhasil disimpan!');
}
public function show($id)
{
$program = Program::find($id);
if (!$program) {
return redirect()->route('program.index')->with('error', 'Data program tidak ditemukan.');
}
$komoditas = Komoditas::all();
$provinsi = Provinsi::all();
return view('core.program.view', compact('program', 'komoditas', 'provinsi'));
}
public function edit($id)
{
$program = Program::find($id);
if (!$program) {
return redirect()->route('program.index')->with('error', 'Data program tidak ditemukan.');
}
return view('core.program.edit', compact('program'));
}
public function update(Request $request, $id)
{
$validator = Validator::make($request->all(), [
'nama' => ['required'],
'sub_domain' => ['required', Rule::unique(Program::class, 'sub_domain')->ignore($id)],
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$program = Program::find($id);
if (!$program) {
return redirect()->route('program.index')->with('error', 'Data program tidak ditemukan!');
}
$program->update([
'nama' => $request->nama,
'sub_domain' => $request->sub_domain,
'updated_by' => auth()->id(),
]);
return redirect()->route('program.index')->with('success', 'Data program berhasil diperbarui!');
}
public function destroy($id)
{
$program = Program::find($id);
if (!$program) {
return response()->json([
'status' => 'error',
'message' => 'Data tidak ditemukan.'
], 404);
}
$program->deleted_by = auth()->user()->id;
$program->save();
$program->delete();
return response()->json([
'status' => 'success',
'message' => 'Data program berhasil dihapus.'
]);
}
}
@@ -0,0 +1,110 @@
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Models\Core\Program;
use App\Models\Core\KomoditasProgram;
use App\Models\Wilayah\Provinsi;
use App\Models\Pertanian\Komoditas;
class ProgramKomoditasController extends Controller
{
public function store(Request $request, int $programId)
{
$program = Program::find($programId);
if (!$program) {
return response()->json([
'status' => 'error',
'message' => 'Data program tidak ditemukan.'
], 404);
}
$validator = Validator::make($request->all(), [
'komoditas_id' => [
'required',
'exists:master_komoditas,id',
Rule::unique('core_program_komoditas')
->where(fn ($query) => $query->where('program_id', $programId))->whereNull('deleted_at'),
],
'default' => ['nullable', 'boolean'],
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => $validator->errors()->first()
], 422);
}
KomoditasProgram::where('program_id', $programId)->update(['default' => false]);
KomoditasProgram::create([...$validator->validated(),
'program_id' => $programId,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return response()->json([
'status' => 'success',
'message' => 'Data komoditas program berhasil disimpan.'
]);
}
public function update(Request $request, int $programId, int $id)
{
$komoditasProgram = KomoditasProgram::where('program_id', $programId)->where('id', $id)->first();
if (!$komoditasProgram) {
return response()->json([
'status' => 'error',
'message' => 'Data komoditas program tidak ditemukan.'
], 404);
}
$validator = Validator::make($request->all(), [
'default' => ['nullable', 'boolean'],
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => $validator->errors()->first()
], 422);
}
KomoditasProgram::where('program_id', $programId)->update(['default' => false]);
$komoditasProgram->update([...$validator->validated(),
'updated_by' => auth()->id(),
]);
return response()->json([
'status' => 'success',
'message' => 'Data komoditas program berhasil diperbarui.'
]);
}
public function destroy(int $programId, int $id)
{
$komoditasProgram = KomoditasProgram::where('program_id', $programId)->where('id', $id)->first();
if (!$komoditasProgram) {
return response()->json([
'status' => 'error',
'message' => 'Data komoditas program tidak ditemukan.'
], 404);
}
$komoditasProgram->deleted_by = auth()->user()->id;
$komoditasProgram->save();
$komoditasProgram->delete();
return response()->json([
'status' => 'success',
'message' => 'Data komoditas program berhasil dihapus.'
]);
}
}
@@ -0,0 +1,144 @@
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Models\Core\Program;
use App\Models\Core\LokasiProgram;
use App\Models\Wilayah\Provinsi;
use App\Models\Pertanian\Komoditas;
class ProgramLokasiController extends Controller
{
public function index()
{
}
public function create(int $programId)
{
}
public function getProgram()
{
$program = Program::select(['id', 'nama', 'sub_domain'])->get();
return response()->json(['data' => $program]);
}
public function store(Request $request, int $programId)
{
$program = Program::find($programId);
if (!$program) {
return response()->json([
'status' => 'error',
'message' => 'Data program tidak ditemukan.'
], 404);
}
$validator = Validator::make($request->all(), [
'provinsi_id' => ['required', 'exists:master_provinsi,id'],
'kabupaten_kota_id' => ['nullable', 'exists:master_kabupaten_kota,id'],
'kecamatan_id' => ['nullable', 'exists:master_kecamatan,id'],
'desa_kelurahan_id' => ['nullable', 'exists:master_desa_kelurahan,id'],
'default' => ['nullable', 'boolean'],
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => $validator->errors()->first()
], 422);
}
LokasiProgram::where('program_id', $programId)->update(['default' => false]);
LokasiProgram::create([...$validator->validated(),
//'default' => $request->has('default'),
'program_id' => $programId,
'created_by' => auth()->id(),
'updated_by' => auth()->id(),
]);
return response()->json([
'status' => 'success',
'message' => 'Data lokasi program berhasil disimpan.'
]);
}
public function show($id)
{
$program = Program::find($id);
if (!$program) {
return redirect()->route('program.index')->with('error', 'Data program tidak ditemukan.');
}
return view('core.program.view', compact('program'));
}
public function edit($id)
{
$program = Program::find($id);
if (!$program) {
return redirect()->route('program.index')->with('error', 'Data program tidak ditemukan.');
}
return view('core.program.edit', compact('program'));
}
public function update(Request $request, int $programId, int $id)
{
$lokasiProgram = LokasiProgram::where('program_id', $programId)->where('id', $id)->first();
if (!$lokasiProgram) {
return response()->json([
'status' => 'error',
'message' => 'Data lokasi program tidak ditemukan.'
], 404);
}
$validator = Validator::make($request->all(), [
'default' => ['nullable', 'boolean'],
]);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'message' => $validator->errors()->first()
], 422);
}
LokasiProgram::where('program_id', $programId)->update(['default' => false]);
$lokasiProgram->update([...$validator->validated(),
'updated_by' => auth()->id(),
]);
return response()->json([
'status' => 'success',
'message' => 'Data lokasi program berhasil diperbarui!'
]);
}
public function destroy(int $programId, int $id)
{
$lokasiProgram = LokasiProgram::where('program_id', $programId)->where('id', $id)->first();
if (!$lokasiProgram) {
return response()->json([
'status' => 'error',
'message' => 'Data lokasi program tidak ditemukan.'
], 404);
}
$lokasiProgram->deleted_by = auth()->user()->id;
$lokasiProgram->save();
$lokasiProgram->delete();
return response()->json([
'status' => 'success',
'message' => 'Data lokasi program berhasil dihapus.'
]);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Models\Core\Program;
class ResolveProgram
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$host = $request->getHost();
$parts = explode('.', $host);
if ($host === 'localhost' || filter_var($host, FILTER_VALIDATE_IP)) {
return $next($request);
}
if (count($parts) < 3) {
return $next($request);
}
$subdomain = $parts[0];
$program = Program::where('sub_domain', $subdomain)->firstOrFail();
app()->instance('SystemProgram', $program);
return $next($request);
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Models\Core;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Pertanian\Komoditas;
class KomoditasProgram extends Model
{
use SoftDeletes;
protected $table = 'core_program_komoditas';
protected $fillable = [
"program_id",
"komoditas_id",
"default",
];
public function komoditas(): BelongsTo
{
return $this->belongsTo(Komoditas::class, 'komoditas_id');
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
namespace App\Models\Core;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Wilayah\Provinsi;
use App\Models\Wilayah\KabupatenKota;
use App\Models\Wilayah\Kecamatan;
use App\Models\Wilayah\DesaKelurahan;
class LokasiProgram extends Model
{
use SoftDeletes;
protected $table = 'core_program_lokasi';
protected $fillable = [
"program_id",
"provinsi_id",
"kabupaten_kota_id",
"kecamatan_id",
"desa_kelurahan_id",
"default",
];
public function provinsi(): BelongsTo
{
return $this->belongsTo(Provinsi::class, 'provinsi_id');
}
public function kabupatenKota(): BelongsTo
{
return $this->belongsTo(KabupatenKota::class, 'kabupaten_kota_id');
}
public function kecamatan(): BelongsTo
{
return $this->belongsTo(Kecamatan::class, 'kecamatan_id');
}
public function desaKelurahan(): BelongsTo
{
return $this->belongsTo(DesaKelurahan::class, 'desa_kelurahan_id');
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace App\Models\Core;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Core\KomoditasProgram;
use App\Models\Core\LokasiProgram;
class Program extends Model
{
use SoftDeletes;
protected $table = 'core_program';
protected $fillable = [
"nama",
"sub_domain",
"tahun",
"instansi",
];
public function komoditas(): HasMany
{
return $this->hasMany(KomoditasProgram::class, 'program_id', 'id');
}
public function lokasi(): HasMany
{
return $this->hasMany(LokasiProgram::class, 'program_id', 'id');
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace App\Models\Ekosistem;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
use App\Models\Ekosistem\TabelBasisData;
class GroupBasisData extends Model
{
use SoftDeletes;
protected $table = 'ekosistem_basis_data_group';
protected $fillable = [
'group',
'label',
'urutan',
'deskripsi',
];
public function tabel(): HasMany
{
return $this->hasMany(TabelBasisData::class, 'group_id')->orderBy('urutan');
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace App\Models\Ekosistem;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Ekosistem\TabelBasisData;
class KolomBasisData extends Model
{
use SoftDeletes;
protected $table = 'ekosistem_basis_data_kolom';
protected $fillable = [
'tabel_id',
'kolom',
'label',
'tipe',
'validasi',
'urutan',
];
protected $casts = [
'validasi' => 'array',
];
protected static function booted()
{
static::creating(function ($model) {
$max = self::where('tabel_id', $model->tabel_id)->max('urutan');
$model->urutan = ($max ?? 0) + 1;
});
static::addGlobalScope('order', function (Builder $builder) {
$builder->orderBy('urutan');
});
}
public function tabel(): BelongsTo
{
return $this->belongsTo(TabelBasisData::class, 'tabel_id');
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\Models\Ekosistem;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Ekosistem\KolomBasisData;
class TabelBasisData extends Model
{
use SoftDeletes;
protected $table = 'ekosistem_basis_data_tabel';
protected $fillable = [
'tabel',
'label',
'menu',
'deskripsi',
'group_id',
'urutan'
];
protected static function booted()
{
static::creating(function ($model) {
$max = self::where('group_id', $model->group_id)->max('urutan');
$model->urutan = ($max ?? 0) + 1;
});
static::addGlobalScope('order', function (Builder $builder) {
$builder->orderBy('urutan');
});
}
public function kolom(): HasMany
{
return $this->hasMany(KolomBasisData::class, 'tabel_id')->orderBy('urutan');
}
public function group(): BelongsTo
{
return $this->belongsTo(GroupBasisData::class, 'group_id');
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace App\Models\Ekosistem;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\Ekosistem\TabelBasisData;
use App\Models\Ekosistem\KolomBasisData;
class ValueBasisData extends Model
{
use SoftDeletes;
protected $table = 'ekosistem_basis_data_value';
protected $fillable = [
'program_id',
'tabel_id',
'kolom_id',
'value_id',
'value_varchar',
'value_integer',
'value_float',
'value_boolean',
'value_date',
'value_datetime',
'value_text',
];
public function tabel(): BelongsTo
{
return $this->belongsTo(TabelBasisData::class, 'tabel_id');
}
public function kolom(): BelongsTo
{
return $this->belongsTo(KolomBasisData::class, 'kolom_id');
}
public function program(): BelongsTo
{
return $this->belongsTo(Program::class, 'program_id');
}
}
+13
View File
@@ -4,6 +4,7 @@ namespace App\Models\Pertanian;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Builder;
class Komoditas extends Model
{
@@ -17,4 +18,16 @@ class Komoditas extends Model
'updated_by',
'deleted_by',
];
protected static function booted()
{
static::addGlobalScope('program', function (Builder $builder) {
if (!app()->has('SystemProgram')) {
return;
}
$builder->whereIn('id', app('SystemProgram')->komoditas()->pluck('id'));
});
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Models\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class KomoditasProgramScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*/
public function apply(Builder $builder, Model $model): void
{
if (app()->has('SystemProgram')) {
$program = app('SystemProgram');
$builder->whereIn('komoditas_id', $program->komoditas()->pluck('id'));
}
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ return Application::configure(basePath: dirname(__DIR__))
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
//
$middleware->append(\App\Http\Middleware\ResolveProgram::class);
})
->withExceptions(function (Exceptions $exceptions): void {
//
@@ -18,7 +18,7 @@ return new class extends Migration
$table->foreignId('profile_id')->constrained('profiles');
$table->foreignId('keluarga_pengelola_id')->nullable()->constrained('keluarga')->onDelete('set null');
$table->foreignId('adat_pemilik_id')->nullable()->constrained('keluarga')->onDelete('set null');
$table->foreignId('adat_pemilik_id')->nullable()->constrained('adat')->onDelete('set null');
$table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan');
$table->text('path')->nullable();
@@ -0,0 +1,42 @@
<?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::table('map_lahan', function (Blueprint $table) {
$table->jsonb('path')->nullable()->change();
});
Schema::table('master_provinsi', function (Blueprint $table) {
$table->jsonb('path')->nullable()->change();
});
Schema::table('master_kabupaten_kota', function (Blueprint $table) {
$table->jsonb('path')->nullable()->change();
});
Schema::table('master_kecamatan', function (Blueprint $table) {
$table->jsonb('path')->nullable()->change();
});
Schema::table('master_desa_kelurahan', function (Blueprint $table) {
$table->jsonb('path')->nullable()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
}
};
@@ -0,0 +1,74 @@
<?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('core_program', function (Blueprint $table) {
$table->id();
$table->string('nama');
$table->string('sub_domain');
$table->integer('tahun');
$table->string('instansi')->nullable();
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
Schema::create('core_program_komoditas', function (Blueprint $table) {
$table->id();
$table->foreignId('program_id')->nullable()->constrained('core_program')->nullOnDelete();
$table->foreignId('komoditas_id')->nullable()->constrained('master_komoditas')->nullOnDelete();
$table->boolean('default')->default(false);
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
Schema::create('core_program_lokasi', function (Blueprint $table) {
$table->id();
$table->foreignId('program_id')->nullable()->constrained('core_program')->nullOnDelete();
$table->foreignId('provinsi_id')->nullable()->constrained('master_provinsi')->nullOnDelete();
$table->foreignId('kabupaten_kota_id')->nullable()->constrained('master_kabupaten_kota')->nullOnDelete();
$table->foreignId('kecamatan_id')->nullable()->constrained('master_kecamatan')->nullOnDelete();
$table->foreignId('desa_kelurahan_id')->nullable()->constrained('master_desa_kelurahan')->nullOnDelete();
$table->boolean('default')->default(false);
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('core_program_lokasi');
Schema::dropIfExists('core_program_komoditas');
Schema::dropIfExists('core_program');
}
};
@@ -0,0 +1,82 @@
<?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('ekosistem_basis_data_tabel', function (Blueprint $table) {
$table->id();
$table->string('tabel')->unique();
$table->string('label');
$table->string('menu');
$table->string('deskripsi', 1000)->nullable();
$table->timestamps();
$table->softDeletes();
});
Schema::create('ekosistem_basis_data_kolom', function (Blueprint $table) {
$table->id();
$table->foreignId('tabel_id')->constrained('ekosistem_basis_data_tabel')->restrictOnDelete();
$table->string('kolom');
$table->string('label');
$table->enum('tipe', ['varchar', 'integer', 'float', 'boolean', 'date', 'datetime', 'text'])->default('varchar');
$table->jsonb('validasi')->nullable();
$table->integer('urutan')->default(1);
$table->timestamps();
$table->softDeletes();
});
DB::statement("
CREATE UNIQUE INDEX ekosistem_basis_data_kolom_unique_active
ON ekosistem_basis_data_kolom (tabel_id, kolom)
WHERE deleted_at IS NULL
");
Schema::create('ekosistem_basis_data_value', function (Blueprint $table) {
$table->id();
$table->foreignId('program_id')->constrained('core_program')->restrictOnDelete();
$table->foreignId('tabel_id')->constrained('ekosistem_basis_data_tabel')->restrictOnDelete();
$table->foreignId('kolom_id')->constrained('ekosistem_basis_data_kolom')->restrictOnDelete();
$table->string('value_id');
$table->string('value_varchar')->nullable();
$table->integer('value_integer')->nullable();
$table->float('value_float', 10, 2)->nullable();
$table->boolean('value_boolean')->nullable();
$table->date('value_date')->nullable();
$table->datetime('value_datetime')->nullable();
$table->text('value_text')->nullable();
$table->foreignId('created_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('updated_by')->nullable()->constrained('users')->onDelete('set null');
$table->foreignId('deleted_by')->nullable()->constrained('users')->onDelete('set null');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('ekosistem_basis_data_value');
Schema::dropIfExists('ekosistem_basis_data_kolom');
Schema::dropIfExists('ekosistem_basis_data_tabel');
}
};
@@ -0,0 +1,25 @@
<?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::table('profiles', function (Blueprint $table) {
$table->foreignId('adat_id')->nullable()->constrained('adat');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
}
};
@@ -0,0 +1,53 @@
<?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('ekosistem_basis_data_group', function (Blueprint $table) {
$table->id();
$table->string('group')->unique();
$table->string('label');
$table->integer('urutan')->default(1);
$table->string('deskripsi', 1000)->nullable();
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('deleted_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
Schema::table('ekosistem_basis_data_tabel', function (Blueprint $table) {
$table->foreignId('group_id')->nullable()->constrained('ekosistem_basis_data_group')->nullOnDelete();
$table->integer('urutan')->default(1);
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('deleted_by')->nullable()->constrained('users')->nullOnDelete();
});
Schema::table('ekosistem_basis_data_kolom', function (Blueprint $table) {
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('deleted_by')->nullable()->constrained('users')->nullOnDelete();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('ekosistem_basis_data_group');
}
};
@@ -0,0 +1,87 @@
<div
class="offcanvas offcanvas-end"
tabindex="-1"
id="offcanvasAddProgramKomoditas"
aria-labelledby="offcanvasAddProgramKomoditasLabel">
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasAddProgramKomoditasLabel" class="offcanvas-title">Tambah Komoditas</h5>
<button
type="button"
class="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Tutup"></button>
</div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form class="add-new-program-komoditas pt-0" id="addNewProgramKomoditasForm" action="{{ route('program.komoditas.store', $program->id) }}" method="POST">
@csrf
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-program-komoditas-komoditas_id">Komoditas<span class="text-danger">*</span></label>
<select name="komoditas_id" class="form-select select2" id="add-program-komoditas-komoditas_id" data-placeholder="Pilih Komoditas">
<option value="">Pilih Komoditas</option>
@foreach($komoditas as $k)
<option value="{{ $k->id }}">{{ $k->nama }}</option>
@endforeach
</select>
</div>
<div class="mb-6 form-control-validation">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="defaultSwitch" name="default" value="1">
<label class="form-check-label" for="defaultSwitch">Default</label>
</div>
</div>
<button type="submit" class="btn btn-primary me-3 data-submit">Simpan</button>
<button type="reset" class="btn btn-label-danger" data-bs-dismiss="offcanvas">Batal</button>
</form>
</div>
</div>
@push('scripts')
<script>
$(document).ready(function() {
$('#add-program-komoditas-komoditas_id').select2({
dropdownParent: $('#offcanvasAddProgramKomoditas'),
width: '100%',
});
const offcanvasAdd = new bootstrap.Offcanvas(document.getElementById('offcanvasAddProgramKomoditas'));
$('#addNewProgramKomoditasForm').validate({
rules: {
komoditas_id: { required: true },
},
messages: {
komoditas_id: { required: "Komoditas wajib dipilih" }
},
submitHandler: function (form) {
$.ajax({
url: $(form).attr('action'),
type: 'POST',
data: $(form).serialize(),
success: function () {
offcanvasAdd.hide();
form.reset();
Swal.fire({ icon: 'success', title: 'Berhasil!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
}
});
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,88 @@
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasEditProgram" aria-labelledby="offcanvasEditProgramLabel">
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasEditProgramLabel" class="offcanvas-title">Edit Program</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Tutup"></button>
</div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form id="editProgramForm" class="pt-0" method="POST" action="{{ route('program.update', ':id') }}">
@csrf
@method('PUT')
<input type="hidden" id="edit-program-id" name="id" />
<div class="mb-6 form-control-validation">
<label class="form-label" for="edit-program-name">Nama Program<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="edit-program-name" name="nama" />
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="edit-program-subdomain">Sub Domain</label>
<textarea class="form-control" id="edit-program-subdomain" name="sub_domain" rows="3"></textarea>
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="edit-program-tahun">Tahun<span class="text-danger">*</span></label>
<input type="number" id="edit-program-tahun" class="form-control" name="tahun" />
</div>
<button type="submit" class="btn btn-primary me-3">Update Data</button>
<button type="reset" class="btn btn-label-danger" data-bs-dismiss="offcanvas">Tutup</button>
</form>
</div>
</div>
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
const offcanvasEdit = new bootstrap.Offcanvas(document.getElementById('offcanvasEditProgram'));
$('.edit-record').click(function (e) {
e.preventDefault();
const id = $(this).data('id');
$.get("{{ route('program.show', ':id') }}".replace(':id', id), function (res) {
$('#edit-program-id').val(res.data.id);
$('#edit-program-name').val(res.data.nama);
$('#edit-program-subdomain').val(res.data.sub_domain);
$('#edit-program-tahun').val(res.data.tahun);
offcanvasEdit.show();
}).fail(function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
});
});
$('#editProgramForm').validate({
rules: {
nama: { required: true },
sub_domain: { required: true },
tahun: { required: true, number: true }
},
messages: {
nama: { required: "Nama provinsi wajib diisi" },
sub_domain: { required: "Sub domain wajib diisi" },
tahun: { required: "Tahun wajib diisi", number: "Harus berupa angka" }
},
submitHandler: function (form) {
const id = $('#edit-program-id').val();
$.ajax({
url: $(form).attr('action').replace(':id', id),
type: 'POST',
data: $(form).serialize(),
success: function () {
offcanvasEdit.hide();
form.reset();
Swal.fire({ icon: 'success', title: 'Berhasil!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
}
});
}
});
});
</script>
@endpush
@@ -0,0 +1,113 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-body border-bottom">
<form method="GET" action="{{ route('program.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
<option value="50" {{ request('per_page') == 50 ? 'selected' : '' }}>50</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama Program..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<button type="button" class="btn btn-sm btn-primary add-new" data-bs-toggle="offcanvas" data-bs-target="#offcanvasAddProgram">
<i class="ti tabler-plus me-1"></i> Tambah
</button>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Program</th>
<th>Subdomain</th>
<th>Tahun</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@forelse($program as $index => $prg)
<tr>
<td>{{ $program->firstItem() + $index }}</td>
<td><span class="text-heading">{{ $prg->nama }}</span></td>
<td><span class="text-muted">{{ $prg->sub_domain }}</span></td>
<td><span class="text-muted">{{ $prg->tahun }}</span></td>
<td>
<div class="d-flex align-items-center">
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill edit-record" data-id="{{ $prg->id }}"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $prg->id }}" data-nama="{{ $prg->nama }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill view-record" data-id="{{ $prg->id }}"><i class="ti tabler-eye ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="4" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $program->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
@include('core.program.add')
@include('core.program.view')
@include('core.program.edit')
</div>
@endsection
@push('scripts')
<script>
'use strict';
const csrfToken = "{{ csrf_token() }}";
$(document).ready(function () {
$('.delete-record').on('click', function (e) {
e.preventDefault();
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Hapus?',
text: `Provinsi ${name} akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-primary me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: `/provinsi/${id}`,
type: 'DELETE',
headers: { 'X-CSRF-TOKEN': csrfToken },
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
}
});
}
});
});
});
</script>
@endpush
@@ -0,0 +1,52 @@
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasViewProgram" aria-labelledby="offcanvasViewProgramLabel">
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasViewProgramLabel" class="offcanvas-title">Detail Program</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Tutup"></button>
</div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form id="viewProgramForm" class="pt-0" onsubmit="return false;">
<div class="mb-6">
<label class="form-label" for="view-program-name">Nama Program</label>
<input type="text" class="form-control" id="view-program-name" readonly />
</div>
<div class="mb-6">
<label class="form-label" for="view-program-subdomain">Sub Domain</label>
<input type="text" id="view-program-subdomain" class="form-control" readonly />
</div>
<div class="mb-6">
<label class="form-label" for="view-program-tahun">Tahun</label>
<input type="text" id="view-program-tahun" class="form-control" readonly />
</div>
<button type="button" class="btn btn-label-secondary" data-bs-dismiss="offcanvas">Tutup</button>
</form>
</div>
</div>
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
const offcanvasView = new bootstrap.Offcanvas(document.getElementById('offcanvasViewProgram'));
$('.view-record').click(function (e) {
e.preventDefault();
console.log('View button clicked');
const id = $(this).data('id');
$.get("{{ route('program.show', ':id') }}".replace(':id', id), function (res) {
$('#view-program-name').val(res.data.nama);
$('#view-program-subdomain').val(res.data.sub_domain);
$('#view-program-tahun').val(res.data.tahun);
offcanvasView.show();
}).fail(function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
});
});
});
</script>
@endpush
@@ -0,0 +1,156 @@
<div
class="offcanvas offcanvas-end"
tabindex="-1"
id="offcanvasAddProgramLokasi"
aria-labelledby="offcanvasAddProgramLokasiLabel">
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasAddProgramLokasiLabel" class="offcanvas-title">Tambah Lokasi</h5>
<button
type="button"
class="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Tutup"></button>
</div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form class="add-new-program-lokasi pt-0" id="addNewProgramLokasiForm" action="{{ route('program.lokasi.store', $program->id) }}" method="POST">
@csrf
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-program-lokasi-provinsi_id">Provinsi<span class="text-danger">*</span></label>
<select name="provinsi_id" class="form-select select2" id="add-program-lokasi-provinsi_id" data-placeholder="Pilih Provinsi">
<option value="">Pilih Provinsi</option>
@foreach($provinsi as $p)
<option value="{{ $p->id }}">{{ $p->kode }} {{ $p->nama }}</option>
@endforeach
</select>
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-program-lokasi-kabupaten_kota_id">Kabupaten/Kota</label>
<select name="kabupaten_kota_id" class="form-select select2" id="add-program-lokasi-kabupaten_kota_id" data-placeholder="Pilih Kabupaten/Kota">
<option value="">Pilih Kabupaten/Kota</option>
</select>
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-program-lokasi-kecamatan_id">Kecamatan</label>
<select name="kecamatan_id" class="form-select select2" id="add-program-lokasi-kecamatan_id" data-placeholder="Pilih Kecamatan">
<option value="">Pilih Kecamatan</option>
</select>
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-program-lokasi-desa_kelurahan_id">Desa/Kelurahan</label>
<select name="desa_kelurahan_id" class="form-select select2" id="add-program-lokasi-desa_kelurahan_id" data-placeholder="Pilih Desa/Kelurahan">
<option value="">Pilih Desa/Kelurahan</option>
</select>
</div>
<div class="mb-6 form-control-validation">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="defaultSwitch" name="default" value="1">
<label class="form-check-label" for="defaultSwitch">Default</label>
</div>
</div>
<button type="submit" class="btn btn-primary me-3 data-submit">Simpan</button>
<button type="reset" class="btn btn-label-danger" data-bs-dismiss="offcanvas">Batal</button>
</form>
</div>
</div>
@push('scripts')
<script>
$(document).ready(function() {
const $provinsi = $('#add-program-lokasi-provinsi_id');
const $kabupaten = $('#add-program-lokasi-kabupaten_kota_id');
const $kecamatan = $('#add-program-lokasi-kecamatan_id');
const $desa = $('#add-program-lokasi-desa_kelurahan_id');
$('#add-program-lokasi-provinsi_id, #add-program-lokasi-kabupaten_kota_id, #add-program-lokasi-kecamatan_id, #add-program-lokasi-desa_kelurahan_id').select2({
dropdownParent: $('#offcanvasAddProgramLokasi'),
width: '100%',
});
$provinsi.on('change', function () {
const id = $(this).val();
// reset bawahnya
$kabupaten.empty().append('<option value="">Pilih Kabupaten/Kota</option>').trigger('change');
$kecamatan.empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
$desa.empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (!id) return;
$.get("{{ route('kabupatenkota.byprovinsi', ':id') }}".replace(':id', id), function (data) {
data.forEach(kab => {
$kabupaten.append(new Option(`${kab.kode} ${kab.nama}`, kab.id));
});
});
});
$kabupaten.on('change', function () {
const id = $(this).val();
// reset kecamatan
$kecamatan.empty().append('<option value="">Pilih Kecamatan</option>').trigger('change');
if (!id) return;
$.get("{{ route('kecamatan.bykabupatenkota', ':id') }}".replace(':id', id), function (data) {
data.forEach(kec => {
$kecamatan.append(new Option(`${kec.kode} ${kec.nama}`, kec.id));
});
});
});
$kecamatan.on('change', function () {
const id = $(this).val();
// reset desa
$desa.empty().append('<option value="">Pilih Desa/Kelurahan</option>').trigger('change');
if (!id) return;
$.get("{{ route('desakelurahan.bykecamatan', ':id') }}".replace(':id', id), function (data) {
data.forEach(desa => {
$desa.append(new Option(`${desa.kode} ${desa.nama}`, desa.id));
});
});
});
$.validator.setDefaults({
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
const offcanvasAdd = new bootstrap.Offcanvas(document.getElementById('offcanvasAddProgramLokasi'));
$('#addNewProgramLokasiForm').validate({
rules: {
provinsi_id: { required: true },
},
messages: {
provinsi_id: { required: "Provinsi wajib dipilih" }
},
submitHandler: function (form) {
$.ajax({
url: $(form).attr('action'),
type: 'POST',
data: $(form).serialize(),
success: function () {
offcanvasAdd.hide();
form.reset();
Swal.fire({ icon: 'success', title: 'Berhasil!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
}
});
}
});
});
</script>
@endpush
@@ -0,0 +1,75 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Tambah Program Baru</h5>
</div>
<div class="card-body">
<form id="addNewProgramForm" action="{{ route('program.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<h6 class="mb-3">Informasi Program</h6>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-program-nama">Nama Program<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-program-nama" name="nama" placeholder="Cth: Program Pertanian" />
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-program-subdomain">Sub Domain<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-program-subdomain" name="sub_domain" placeholder="Cth: budi@email.com" />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-program-tahun">Tahun<span class="text-danger">*</span></label>
<input type="number" class="form-control" id="add-program-tahun" name="tahun" placeholder="Cth: 2023" />
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-program-instansi">Instansi</label>
<input type="text" class="form-control" id="add-program-instansi" name="instansi" placeholder="Cth: Dinas Pertanian" />
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('program.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Program</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#addNewProgramForm').validate({
rules: {
nama: { required: true },
sub_domain: { required: true },
tahun: { required: true }
},
messages: {
nama: { required: "Nama program wajib diisi" },
sub_domain: { required: "Subdomain wajib diisi" },
tahun: { required: "Tahun wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,80 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Update Program</h5>
</div>
<div class="card-body">
<form id="addEditProgramForm" action="{{ route('program.update', $program->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
<h6 class="mb-3">Informasi Program</h6>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-program-nama">Nama Program<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-program-nama" name="nama" placeholder="Cth: Program Pertanian" value="{{ old('nama', $program->nama) }}" />
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-program-subdomain">Sub Domain<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-program-subdomain" name="sub_domain" placeholder="Cth: budi@email.com" value="{{ old('sub_domain', $program->sub_domain) }}" />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-program-tahun">Tahun<span class="text-danger">*</span></label>
<input type="number" class="form-control" id="add-program-tahun" name="tahun" placeholder="Cth: 2023" value="{{ old('tahun', $program->tahun) }}" />
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-program-instansi">Instansi</label>
<input type="text" class="form-control" id="add-program-instansi" name="instansi" placeholder="Cth: Dinas Pertanian" value="{{ old('instansi', $program->instansi) }}" />
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('program.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Update Program</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$.validator.setDefaults({
});
$('#addEditProgramForm').validate({
rules: {
nama: { required: true },
sub_domain: { required: true },
tahun: { required: true }
},
messages: {
nama: { required: "Nama program wajib diisi" },
sub_domain: { required: "Subdomain wajib diisi" },
tahun: { required: "Tahun wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,84 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-body border-bottom">
<form method="GET" action="{{ route('program.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
<option value="50" {{ request('per_page') == 50 ? 'selected' : '' }}>50</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama Program..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('program.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Program</th>
<th>Subdomain</th>
<th>Tahun</th>
<th>Instansi</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($program as $index => $prg)
<tr>
<td>{{ $loop->iteration }}</td>
<td><span class="text-heading">{{ $prg->nama }}</span></td>
<td><span class="text-muted">{{ $prg->sub_domain }}</span></td>
<td><span class="text-muted">{{ $prg->tahun }}</span></td>
<td><span class="text-muted">{{ $prg->instansi ?? '-' }}</span></td>
<td>
<div class="d-flex align-items-center">
<a href="{{ route('program.edit', $prg->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $prg->id }}" data-nama="{{ $prg->nama }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('program.show', $prg->id) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $program->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
});
</script>
@endpush
+279
View File
@@ -0,0 +1,279 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Update Program</h5>
</div>
<div class="card-body">
<form id="addViewProgramForm" method="POST">
<h6 class="mb-3">Informasi Program</h6>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-program-nama">Nama Program<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-program-nama" name="nama" placeholder="Cth: Program Pertanian" value="{{ old('nama', $program->nama) }}" readonly />
</div>
</div>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-program-subdomain">Sub Domain<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-program-subdomain" name="sub_domain" placeholder="Cth: budi@email.com" value="{{ old('sub_domain', $program->sub_domain) }}" readonly />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-program-tahun">Tahun<span class="text-danger">*</span></label>
<input type="number" class="form-control" id="add-program-tahun" name="tahun" placeholder="Cth: 2023" value="{{ old('tahun', $program->tahun) }}" readonly />
</div>
<div class="col-md-6 mb-4 form-control-validation">
<label class="form-label" for="add-program-instansi">Instansi</label>
<input type="text" class="form-control" id="add-program-instansi" name="instansi" placeholder="Cth: Dinas Pertanian" value="{{ old('instansi', $program->instansi) }}" readonly />
</div>
</div>
</form>
<hr class="my-4 mx-n4" />
<div class="row">
<div class="col-md-4 col-sm-12 mb-4">
<h6 class="mb-3">Komoditas</h6>
<div class="row mb-4">
<div class="col-md-auto d-flex gap-2">
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="offcanvas" data-bs-target="#offcanvasAddProgramKomoditas">
<i class="ti tabler-plus me-1"></i> Tambah
</button>
</div>
</div>
<div class="table-responsive text-nowrap mb-4">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Komoditas</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($program->komoditas as $index => $kmd)
<tr>
<td>{{ $loop->iteration }}</td>
<td>
<span class="text-heading">{{ $kmd->komoditas->nama }}</span>
@if($kmd->default)
<span class="badge rounded-pill text-bg-success ms-2">Default</span>
@endif
</td>
<td>
<div class="d-flex align-items-center">
@if(!$kmd->default)
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill default-komoditas"
data-id="{{ $kmd->id }}"><i class="ti tabler-square-check ti-md"></i></a>
@endif
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-komoditas"
data-id="{{ $kmd->id }}" data-nama="{{ $kmd->komoditas->nama }}"><i class="ti tabler-trash ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
<div class="col-md-8 col-sm-12 mb-4">
<h6 class="mb-3">Lokasi</h6>
<div class="row mb-4">
<div class="col-md-auto d-flex gap-2">
<button class="btn btn-sm btn-primary" data-bs-toggle="offcanvas" data-bs-target="#offcanvasAddProgramLokasi">
<i class="ti tabler-plus me-1"></i> Tambah
</button>
</div>
</div>
<div class="table-responsive text-nowrap mb-4">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Provinsi</th>
<th>Kabupaten/Kota</th>
<th>Kecamatan</th>
<th>Kelurahan/Desa</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($program->lokasi as $index => $lok)
<tr>
<td>{{ $loop->iteration }}</td>
<td>
<span class="text-heading">{{ $lok->provinsi->nama }}</span>
@if($lok->default && !$lok->kabupaten_kota_id && !$lok->kecamatan_id && !$lok->desa_kelurahan_id)
<span class="badge rounded-pill text-bg-success ms-2">Default</span>
@endif
</td>
<td>
<span class="text-muted">{{ $lok->kabupatenKota?->nama }}</span>
@if($lok->default && $lok->kabupaten_kota_id && !$lok->kecamatan_id && !$lok->desa_kelurahan_id)
<span class="badge rounded-pill text-bg-success ms-2">Default</span>
@endif
</td>
<td>
<span class="text-muted">{{ $lok->kecamatan?->nama }}</span>
@if($lok->default && $lok->kabupaten_kota_id && $lok->kecamatan_id && !$lok->desa_kelurahan_id)
<span class="badge rounded-pill text-bg-success ms-2">Default</span>
@endif
</td>
<td>
<span class="text-muted">{{ $lok->desaKelurahan?->nama }}</span>
@if($lok->default && $lok->kabupaten_kota_id && $lok->kecamatan_id && $lok->desa_kelurahan_id)
<span class="badge rounded-pill text-bg-success ms-2">Default</span>
@endif
</td>
<td>
@if(!$lok->default)
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill default-lokasi"
data-id="{{ $lok->id }}"><i class="ti tabler-square-check ti-md"></i></a>
@endif
<div class="d-flex align-items-center">
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-lokasi"
data-id="{{ $lok->id }}"
data-provinsi="{{ $lok->provinsi->nama }}"
data-kabupaten="{{ $lok->kabupatenKota?->nama }}"
data-kecamatan="{{ $lok->kecamatan?->nama }}"
data-desa="{{ $lok->desaKelurahan?->nama }}">
<i class="ti tabler-trash ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('program.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
</div>
</div>
</div>
@include('core.program-komoditas.add')
@include('core.program-lokasi.add')
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$(".delete-komoditas").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Hapus?',
text: `Komoditas ${name} akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: "{{ route('program.komoditas.destroy', ['program' => $program->id, 'komodita' => ':id']) }}".replace(':id', id),
type: 'DELETE',
data: {
_token: '{{ csrf_token() }}'
},
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
}
});
}
});
});
$(".default-komoditas").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
console.log(id);
$.ajax({
url: "{{ route('program.komoditas.update', ['program' => $program->id, 'komodita' => ':id']) }}".replace(':id', id),
type: 'PUT',
data: {
_token: '{{ csrf_token() }}',
default: 1
},
success: function () {
Swal.fire({ icon: 'success', title: 'Disimpan!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
}
});
});
$(".delete-lokasi").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
const name = $(this).data('provinsi') + ', ' + $(this).data('kabupaten') + ', ' + $(this).data('kecamatan') + ', ' + $(this).data('desa');
Swal.fire({
title: 'Hapus?',
text: `Lokasi ${name} akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: "{{ route('program.lokasi.destroy', ['program' => $program->id, 'lokasi' => ':id']) }}".replace(':id', id),
type: 'DELETE',
data: {
_token: '{{ csrf_token() }}'
},
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
}
});
}
});
});
$(".default-lokasi").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
console.log(id);
$.ajax({
url: "{{ route('program.lokasi.update', ['program' => $program->id, 'lokasi' => ':id']) }}".replace(':id', id),
type: 'PUT',
data: {
_token: '{{ csrf_token() }}',
default: 1
},
success: function () {
Swal.fire({ icon: 'success', title: 'Disimpan!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
}
});
});
});
</script>
@endpush
@@ -0,0 +1,77 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Tambah Kelompok Baru</h5>
</div>
<div class="card-body">
<form id="addNewGroupForm" action="{{ route('group.store') }}" method="POST" >
@csrf
<h6 class="mb-3">Informasi Kelompok Tabel</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-group-nama">Nama Kelompok<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('group') is-invalid @enderror" id="add-group-nama" name="group" placeholder="Cth: Tabel Pertanian" value="{{ old('group') }}" />
@error('group')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-group-label">Label<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('label') is-invalid @enderror" id="add-group-label" name="label" placeholder="Cth: budi@email.com" value="{{ old('label') }}" />
@error('label')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-group-deskripsi">Deskripsi</label>
<input type="text" class="form-control @error('deskripsi') is-invalid @enderror" id="add-group-deskripsi" name="deskripsi" placeholder="Cth: Deskripsi tabel pertanian" value="{{ old('deskripsi') }}" />
@error('deskripsi')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('group.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Kelompok</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)");
$('#addNewGroupForm').validate({
rules: {
group: { required: true, snakecase: true },
label: { required: true },
},
messages: {
group: { required: "Nama kelompok wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,78 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Update Data Kelompok</h5>
</div>
<div class="card-body">
<form id="addUpdateGroupForm" action="{{ route('group.update', $group->id) }}" method="POST" >
@csrf
@method('PUT')
<h6 class="mb-3">Informasi Kelompok Tabel</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-group-nama">Nama Kelompok<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('group') is-invalid @enderror" id="add-group-nama" name="group" placeholder="Cth: Tabel Pertanian" value="{{ old('group', $group->group) }}" />
@error('tabel')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-group-label">Label<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('group') is-invalid @enderror" id="add-group-label" name="label" placeholder="Cth: budi@email.com" value="{{ old('label', $group->label) }}" />
@error('label')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-group-deskripsi">Deskripsi</label>
<input type="text" class="form-control @error('deskripsi') is-invalid @enderror" id="add-group-deskripsi" name="deskripsi" placeholder="Cth: Deskripsi tabel pertanian" value="{{ old('deskripsi', $group->deskripsi) }}" />
@error('deskripsi')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('group.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Kelompok</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)");
$('#addUpdateTabelForm').validate({
rules: {
group: { required: true, snakecase: true },
label: { required: true }
},
messages: {
group: { required: "Nama kelompok wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,109 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-body border-bottom">
<form method="GET" action="{{ route('tabel.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
<option value="50" {{ request('per_page') == 50 ? 'selected' : '' }}>50</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama Kelompok..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('group.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Kelompok</th>
<th>Label</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($group as $index => $gr)
<tr>
<td>{{ $loop->iteration }}</td>
<td><span class="text-heading">{{ $gr->group }}</span></td>
<td><span class="text-muted">{{ $gr->label }}</span></td>
<td>
<div class="d-flex align-items-center">
<a href="{{ route('group.edit', $gr->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $gr->id }}" data-nama="{{ $gr->group }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('group.show', $gr->id) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $group->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$(".delete-record").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Hapus?',
text: `Kolom ${name} akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: "{{ route('group.destroy', ':id') }}".replace(':id', id),
type: 'POST',
data: {
_token: '{{ csrf_token() }}',
_method: 'DELETE'
},
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => location.reload());
}
});
}
});
});
});
</script>
@endpush
@@ -0,0 +1,44 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Lihat Data Kelompok</h5>
</div>
<div class="card-body">
<form id="addViewGroupForm" >
<h6 class="mb-3">Informasi Kelompok Tabel</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-group-nama">Nama Kelompok</label>
<input type="text" class="form-control" id="add-group-nama" name="group" placeholder="Cth: Tabel Pertanian" value="{{ $group->group }}" readonly />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-group-label">Label</label>
<input type="text" class="form-control" id="add-group-label" name="label" placeholder="Cth: budi@email.com" value="{{ $group->label }}" readonly />
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-group-deskripsi">Deskripsi</label>
<input type="text" class="form-control" id="add-group-deskripsi" name="deskripsi" placeholder="Cth: Deskripsi tabel pertanian" value="{{ $group->deskripsi }}" readonly />
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('group.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
</script>
@endpush
@@ -0,0 +1,104 @@
<div
class="offcanvas offcanvas-end"
tabindex="-1"
id="offcanvasAddKolom"
aria-labelledby="offcanvasAddKolomLabel">
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasAddKolomLabel" class="offcanvas-title">Tambah Kolom</h5>
<button
type="button"
class="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Tutup"></button>
</div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form class="add-new-kolom pt-0" id="addNewKolomForm" action="{{ route('tabel.kolom.store', $tabel->id) }}" method="POST">
@csrf
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-kolom-nama">Nama Kolom<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-kolom-nama" name="kolom" placeholder="Cth: Nama Petani" />
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-kolom-label">Label<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="add-kolom-label" name="label" placeholder="Cth: Nama Petani" />
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-kolom-jenis_data">Jenis Data<span class="text-danger">*</span></label>
<select class="form-select" id="add-kolom-jenis_data" name="tipe">
<option value="">Pilih Jenis Data</option>
<option value="varchar">Varchar</option>
<option value="integer">Integer</option>
<option value="float">Float</option>
<option value="boolean">Boolean</option>
<option value="date">Date</option>
<option value="datetime">Datetime</option>
<option value="text">Text</option>
</select>
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="add-kolom-validasi">Validasi<span class="text-danger">*</span></label>
<textarea class="form-control" id="add-kolom-validasi" name="validasi" value="1" placeholder="Cth: required"></textarea>
</div>
<button type="submit" class="btn btn-success me-3 data-submit">Simpan</button>
<button type="reset" class="btn btn-label-danger" data-bs-dismiss="offcanvas">Batal</button>
</form>
</div>
</div>
@push('scripts')
<script>
$(document).ready(function() {
$('#add-kolom-jenis_data').select2({
dropdownParent: $('#offcanvasAddKolom'),
width: '100%',
});
$.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)");
const offcanvasAdd = new bootstrap.Offcanvas(document.getElementById('offcanvasAddKolom'));
$('#addNewKolomForm').validate({
rules: {
kolom: { required: true, snakecase: true },
label: { required: true },
tipe: { required: true }
},
messages: {
kolom: { required: "Kolom wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
tipe: { required: "Jenis data wajib diisi" }
},
submitHandler: function (form) {
$.ajax({
url: $(form).attr('action'),
type: 'POST',
data: $(form).serialize(),
success: function () {
offcanvasAdd.hide();
form.reset();
Swal.fire({ icon: 'success', title: 'Berhasil!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
}
});
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,130 @@
<div
class="offcanvas offcanvas-end"
tabindex="-1"
id="offcanvasUpdateKolom"
aria-labelledby="offcanvasUpdateKolomLabel">
<div class="offcanvas-header border-bottom">
<h5 id="offcanvasUpdateKolomLabel" class="offcanvas-title">Update Kolom</h5>
<button
type="button"
class="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Tutup"></button>
</div>
<div class="offcanvas-body mx-0 flex-grow-0 p-6 h-100">
<form class="add-new-kolom pt-0" id="updateKolomForm" action="{{ route('tabel.kolom.update', [$tabel->id, ':id']) }}" method="POST">
@csrf
@method('PUT')
<input type="hidden" id="update-kolom-id" name="id" />
<div class="mb-6 form-control-validation">
<label class="form-label" for="update-kolom-nama">Nama Kolom<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="update-kolom-nama" name="kolom" placeholder="Cth: Nama Petani" />
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="update-kolom-label">Label<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="update-kolom-label" name="label" placeholder="Cth: Nama Petani" />
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="update-kolom-jenis_data">Jenis Data<span class="text-danger">*</span></label>
<select class="form-select" id="update-kolom-jenis_data" name="tipe">
<option value="">Pilih Jenis Data</option>
<option value="varchar">Varchar</option>
<option value="integer">Integer</option>
<option value="float">Float</option>
<option value="boolean">Boolean</option>
<option value="date">Date</option>
<option value="datetime">Datetime</option>
<option value="text">Text</option>
</select>
</div>
<div class="mb-6 form-control-validation">
<label class="form-label" for="update-kolom-validasi">Validasi<span class="text-danger">*</span></label>
<textarea class="form-control" id="update-kolom-validasi" name="validasi" value="1" placeholder="Cth: required"></textarea>
</div>
<button type="submit" class="btn btn-success me-3 data-submit">Simpan</button>
<button type="reset" class="btn btn-label-danger" data-bs-dismiss="offcanvas">Batal</button>
</form>
</div>
</div>
@push('scripts')
<script>
$(document).ready(function() {
$('#update-kolom-jenis_data').select2({
dropdownParent: $('#offcanvasUpdateKolom'),
width: '100%',
});
$.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)");
const offcanvasUpdate = new bootstrap.Offcanvas(document.getElementById('offcanvasUpdateKolom'));
$(".edit-record").click(function () {
const id = $(this).data('id');
console.log("Edit record with ID:", id);
const editForm = $('#updateKolomForm');
editForm.validate().resetForm();
editForm.find('.is-invalid').removeClass('is-invalid');
$.get("{{ route('tabel.kolom.show', [$tabel->id, ':id']) }}".replace(':id', id), function (res) {
if (res.status === 'success') {
console.log("Data kolom:", res.data);
$('#update-kolom-id').val(res.data.id);
$('#update-kolom-nama').val(res.data.kolom);
$('#update-kolom-label').val(res.data.label);
$('#update-kolom-jenis_data').val(res.data.tipe).trigger('change');
$('#update-kolom-validasi').val(res.data.required ? 'required' : '');
offcanvasUpdate.show();
}
});
});
$('#updateKolomForm').validate({
rules: {
kolom: { required: true, snakecase: true },
label: { required: true },
tipe: { required: true }
},
messages: {
kolom: { required: "Kolom wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
tipe: { required: "Jenis data wajib diisi" }
},
submitHandler: function (form) {
$.ajax({
url: $(form).attr('action').replace(':id', $('#update-kolom-id').val()),
type: 'PUT',
data: $(form).serialize(),
success: function () {
offcanvasUpdate.hide();
form.reset();
Swal.fire({ icon: 'success', title: 'Berhasil!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
},
error: function (xhr) {
Swal.fire({ icon: 'error', title: 'Gagal!', text: xhr.responseJSON?.message || 'Error' });
}
});
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,96 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Tambah Tabel Baru</h5>
</div>
<div class="card-body">
<form id="addNewTabelForm" action="{{ route('tabel.store') }}" method="POST" >
@csrf
<h6 class="mb-3">Informasi Tabel</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-nama">Nama Tabel<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('tabel') is-invalid @enderror" id="add-tabel-nama" name="tabel" placeholder="Cth: Tabel Pertanian" value="{{ old('tabel') }}" />
@error('tabel')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-label">Label<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('label') is-invalid @enderror" id="add-tabel-label" name="label" placeholder="Cth: budi@email.com" value="{{ old('label') }}" />
@error('label')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-menu">Judul Menu<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('menu') is-invalid @enderror" id="add-tabel-menu" name="menu" placeholder="Cth: Pertanian" value="{{ old('menu') }}" />
@error('menu')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-group">Kelompok Tabel</label>
<select class="form-select @error('group_id') is-invalid @enderror" id="add-tabel-group" name="group_id">
<option value="">--- Pilih Kelompok Tabel ---</option>
@foreach ($group as $g)
<option value="{{ $g->id }}">{{ $g->label }}</option>
@endforeach
</select>
@error('group_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-deskripsi">Deskripsi</label>
<input type="text" class="form-control @error('deskripsi') is-invalid @enderror" id="add-tabel-deskripsi" name="deskripsi" placeholder="Cth: Deskripsi tabel pertanian" value="{{ old('deskripsi') }}" />
@error('deskripsi')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('tabel.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Tabel</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#add-tabel-group').select2();
$.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)");
$('#addNewTabelForm').validate({
rules: {
tabel: { required: true, snakecase: true },
label: { required: true },
menu: { required: true }
},
messages: {
tabel: { required: "Nama tabel wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
menu: { required: "Judul menu wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,97 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Update Data Tabel</h5>
</div>
<div class="card-body">
<form id="addUpdateTabelForm" action="{{ route('tabel.update', $tabel->id) }}" method="POST" >
@csrf
@method('PUT')
<h6 class="mb-3">Informasi Tabel</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-nama">Nama Tabel<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('tabel') is-invalid @enderror" id="add-tabel-nama" name="tabel" placeholder="Cth: Tabel Pertanian" value="{{ old('tabel', $tabel->tabel) }}" />
@error('tabel')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-label">Label<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('label') is-invalid @enderror" id="add-tabel-label" name="label" placeholder="Cth: budi@email.com" value="{{ old('label', $tabel->label) }}" />
@error('label')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-menu">Judul Menu<span class="text-danger">*</span></label>
<input type="text" class="form-control @error('menu') is-invalid @enderror" id="add-tabel-menu" name="menu" placeholder="Cth: Pertanian" value="{{ old('menu', $tabel->menu) }}" />
@error('menu')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-group">Kelompok Tabel</label>
<select class="form-select @error('group_id') is-invalid @enderror" id="add-tabel-group" name="group_id">
<option value="">--- Pilih Kelompok Tabel ---</option>
@foreach ($group as $g)
<option value="{{ $g->id }}" {{ old('group', $tabel->group_id) == $g->id ? 'selected' : '' }}>{{ $g->label }}</option>
@endforeach
</select>
@error('group_id')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-deskripsi">Deskripsi</label>
<input type="text" class="form-control @error('deskripsi') is-invalid @enderror" id="add-tabel-deskripsi" name="deskripsi" placeholder="Cth: Deskripsi tabel pertanian" value="{{ old('deskripsi', $tabel->deskripsi) }}" />
@error('deskripsi')<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('tabel.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Tabel</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#add-tabel-group').select2();
$.validator.addMethod("snakecase", function(value, element) {
return this.optional(element) || /^[a-z0-9]+(_[a-z0-9]+)*$/.test(value);
}, "Gunakan format snake_case (huruf kecil dan underscore)");
$('#addUpdateTabelForm').validate({
rules: {
tabel: { required: true, snakecase: true },
label: { required: true },
menu: { required: true }
},
messages: {
tabel: { required: "Nama tabel wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
menu: { required: "Judul menu wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,155 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-body border-bottom">
<form method="GET" action="{{ route('tabel.index') }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
<option value="50" {{ request('per_page') == 50 ? 'selected' : '' }}>50</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama Tabel..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('tabel.create') }}" class="btn btn-sm btn-primary">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Tabel</th>
<th>Label</th>
<th>Menu</th>
<th>Kelompok</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($tabel as $index => $tbl)
<tr>
<td>{{ $loop->iteration }}</td>
<td><span class="text-heading">{{ $tbl->tabel }}</span></td>
<td><span class="text-muted">{{ $tbl->label }}</span></td>
<td><span class="text-muted">{{ $tbl->menu }}</span></td>
<td><span class="text-muted">{{ $tbl->group?->group }}</span></td>
<td>
<div class="d-flex align-items-center">
@if (!$loop->first)
<button type="button"
class="btn btn-icon btn-text-secondary move-up"
data-id="{{ $tbl->id }}">
<i class="ti tabler-arrow-up"></i>
</button>
@endif
@if (!$loop->last)
<button type="button"
class="btn btn-icon btn-text-secondary move-down"
data-id="{{ $tbl->id }}">
<i class="ti tabler-arrow-down"></i>
</button>
@endif
<a href="{{ route('tabel.edit', $tbl->id) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $tbl->id }}" data-nama="{{ $tbl->nama }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('tabel.show', $tbl->id) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $tabel->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$(".move-up").click(function (e) {
e.preventDefault();
let id = $(this).data('id');
$.post("{{ route('tabel.move-up', ':id') }}".replace(':id', id), {
_token: '{{ csrf_token() }}',
_method: 'PUT'
}, function (res) {
if (res.status === 'success') {
location.reload();
}
});
});
$(".move-down").click(function (e) {
e.preventDefault();
let id = $(this).data('id');
$.post("{{ route('tabel.move-down', ':id') }}".replace(':id', id), {
_token: '{{ csrf_token() }}',
_method: 'PUT'
}, function (res) {
if (res.status === 'success') {
location.reload();
}
});
});
$(".delete-record").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Hapus?',
text: `Kolom ${name} akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: "{{ route('tabel.destroy', ':id') }}".replace(':id', id),
type: 'POST',
data: {
_token: '{{ csrf_token() }}',
_method: 'DELETE'
},
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => location.reload());
}
});
}
});
});
});
</script>
@endpush
@@ -0,0 +1,173 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Lihat Data Tabel</h5>
</div>
<div class="card-body">
<form id="addViewTabelForm" >
<h6 class="mb-3">Informasi Tabel</h6>
<div class="row">
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-nama">Nama Tabel</label>
<input type="text" class="form-control" id="add-tabel-nama" name="tabel" placeholder="Cth: Tabel Pertanian" value="{{ $tabel->tabel }}" readonly />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-label">Label</label>
<input type="text" class="form-control" id="add-tabel-label" name="label" placeholder="Cth: budi@email.com" value="{{ $tabel->label }}" readonly />
</div>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-menu">Judul Menu</label>
<input type="text" class="form-control" id="add-tabel-menu" name="menu" placeholder="Cth: Pertanian" value="{{ $tabel->menu }}" readonly />
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4 form-control-validation">
<label class="form-label" for="add-tabel-deskripsi">Deskripsi</label>
<input type="text" class="form-control" id="add-tabel-deskripsi" name="deskripsi" placeholder="Cth: Deskripsi tabel pertanian" value="{{ $tabel->deskripsi }}" readonly />
</div>
</div>
<h6 class="mb-3">Informasi Kolom-Kolom</h6>
<hr class="my-4 mx-n4" />
<div class="row mb-4">
<div class="col-md-auto d-flex gap-2">
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="offcanvas" data-bs-target="#offcanvasAddKolom" >
<i class="ti tabler-plus me-1"></i> Tambah
</button>
</div>
</div>
<div class="row mb-4">
<div class="col-md-12 mb-4 form-control-validation">
<div class="table-responsive text-nowrap mb-4">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
<th>Nama Kolom</th>
<th>Label</th>
<th>Jenis Data</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($tabel->kolom as $index => $kolom)
<tr>
<td>{{ $loop->iteration }}</td>
<td><span class="text-heading">{{ $kolom->kolom }}</span></td>
<td><span class="text-muted">{{ $kolom->label }}</span></td>
<td><span class="text-muted">{{ $kolom->tipe }}</span></td>
<td>
<div class="d-flex align-items-center">
@if (!$loop->first)
<button type="button"
class="btn btn-icon btn-text-secondary move-up"
data-id="{{ $kolom->id }}">
<i class="ti tabler-arrow-up"></i>
</button>
@endif
@if (!$loop->last)
<button type="button"
class="btn btn-icon btn-text-secondary move-down"
data-id="{{ $kolom->id }}">
<i class="ti tabler-arrow-down"></i>
</button>
@endif
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill edit-record" data-id="{{ $kolom->id }}"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $kolom->id }}" data-nama="{{ $kolom->nama }}"><i class="ti tabler-trash ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="5" class="text-center py-4">Tidak ada kolom ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
<div class="mt-4 text-end">
<a href="{{ route('tabel.index') }}" class="btn btn-label-secondary me-2">Kembali</a>
</div>
</form>
</div>
</div>
@include('ekosistem.kolom-basis-data.add')
@include('ekosistem.kolom-basis-data.edit')
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$(".move-up").click(function (e) {
e.preventDefault();
let id = $(this).data('id');
$.post("{{ route('tabel.kolom.move-up', [$tabel->id, ':id']) }}".replace(':id', id), {
_token: '{{ csrf_token() }}',
_method: 'PUT'
}, function (res) {
if (res.status === 'success') {
location.reload();
}
});
});
$(".move-down").click(function (e) {
e.preventDefault();
let id = $(this).data('id');
$.post("{{ route('tabel.kolom.move-down', [$tabel->id, ':id']) }}".replace(':id', id), {
_token: '{{ csrf_token() }}',
_method: 'PUT'
}, function (res) {
if (res.status === 'success') {
location.reload();
}
});
});
$(".delete-record").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
const name = $(this).data('nama');
Swal.fire({
title: 'Hapus?',
text: `Kolom ${name} akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: "{{ route('tabel.kolom.destroy', [$tabel->id, ':id']) }}".replace(':id', id),
type: 'DELETE',
data: {
_token: '{{ csrf_token() }}'
},
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => window.location.reload());
}
});
}
});
});
});
</script>
@endpush
@@ -0,0 +1,92 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Tambah Data {{ $tabel->label }}</h5>
</div>
<div class="card-body">
<form id="addNewDataForm" action="{{ route('tabel.data.store', [$tabel->id, 'program_id' => $program->id]) }}" method="POST" >
@csrf
<h6 class="mb-3">Informasi {{ $tabel->label }}</h6>
<div class="row">
@foreach($kolom as $k)
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-data-{{ $k->kolom }}">{{ $k->label }}<span class="text-danger">*</span></label>
@if($k->tipe == 'varchar')
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" />
@elseif($k->tipe == 'text')
<textarea class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}">{{ old($k->kolom) }}</textarea>
@elseif($k->tipe == 'integer')
<input type="number" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" step="1" />
@elseif($k->tipe == 'float')
<input type="number" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" step="any" />
@elseif($k->tipe == 'date')
<input type="date" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" />
@elseif($k->tipe == 'datetime')
<input type="datetime" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" />
@elseif($k->tipe == 'boolean')
<select class="form-select @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" name="{{ $k->kolom }}">
<option value="1" {{ old($k->kolom) == 1 ? 'selected' : '' }}>Ya</option>
<option value="0" {{ old($k->kolom) == 0 ? 'selected' : '' }}>Tidak</option>
</select>
@else
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) }}" />
@endif
@error($k->kolom)<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
@endforeach
</div>
<div class="mt-4 text-end">
<a href="{{ route('tabel.data.index', [$tabel->id, 'program' => $program->id]) }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Data</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#addNewDataForm').validate({
rules: {
tabel: { required: true, snakecase: true },
label: { required: true },
menu: { required: true }
},
messages: {
tabel: { required: "Nama tabel wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
menu: { required: "Judul menu wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,96 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom mb-4">
<h5 class="card-title mb-0">Tambah Data {{ $tabel->label }}</h5>
</div>
<div class="card-body">
<form id="addUpdateDataForm" action="{{ route('tabel.data.update', [$tabel->id, $value_id, 'program_id' => $program->id]) }}" method="POST" >
@csrf
@method('PUT')
<h6 class="mb-3">Informasi {{ $tabel->label }}</h6>
<div class="row">
@foreach($kolom as $k)
<?php
$value = $values->where('kolom_id', $k->id)->first();
?>
<div class="col-md-3 mb-4 form-control-validation">
<label class="form-label" for="add-data-{{ $k->kolom }}">{{ $k->label }}<span class="text-danger">*</span></label>
@if($k->tipe == 'varchar')
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@elseif($k->tipe == 'text')
<textarea class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}">{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}</textarea>
@elseif($k->tipe == 'integer')
<input type="number" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" step="1" />
@elseif($k->tipe == 'float')
<input type="number" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" step="any" />
@elseif($k->tipe == 'date')
<input type="date" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@elseif($k->tipe == 'datetime')
<input type="datetime" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@elseif($k->tipe == 'boolean')
<select class="form-select @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}" name="{{ $k->kolom }}">
<option value="1" {{ old($k->kolom) ?? $value['value_'.$k->tipe] == 1 ? 'selected' : '' }}>Ya</option>
<option value="0" {{ old($k->kolom) ?? $value['value_'.$k->tipe] == 0 ? 'selected' : '' }}>Tidak</option>
</select>
@else
<input type="text" class="form-control @error($k->kolom) is-invalid @enderror" id="add-data-{{ $k->kolom }}"
name="{{ $k->kolom }}" placeholder="Cth: {{ $k->label }}" value="{{ old($k->kolom) ?? $value['value_'.$k->tipe] }}" />
@endif
@error($k->kolom)<div class="error invalid-feedback">{{ $message }}</div>@enderror
</div>
@endforeach
</div>
<div class="mt-4 text-end">
<a href="{{ route('tabel.data.index', [$tabel->id, 'program' => $program->id]) }}" class="btn btn-label-secondary me-2">Kembali</a>
<button type="submit" class="btn btn-success data-submit">Simpan Data</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$('#addNewDataForm').validate({
rules: {
tabel: { required: true, snakecase: true },
label: { required: true },
menu: { required: true }
},
messages: {
tabel: { required: "Nama tabel wajib diisi", snakecase: "Gunakan format snake_case (huruf kecil dan underscore)" },
label: { required: "Label wajib diisi" },
menu: { required: "Judul menu wajib diisi" }
},
errorElement: 'div',
errorPlacement: function (error, element) {
error.addClass('invalid-feedback');
element.closest('.mb-6, .form-control-validation').append(error);
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
}
});
});
</script>
@endpush
@@ -0,0 +1,129 @@
@extends('layout.main')
@section('content')
<div class="container-xxl flex-grow-1 container-p-y">
<div class="card">
<div class="card-header border-bottom">
<h5 class="card-title mb-0">Data {{ $tabel->label }}</h5>
</div>
<div class="card-body border-bottom pt-4">
<form method="GET" action="{{ route('tabel.data.index', $tabel->id) }}" class="d-flex justify-content-between align-items-center row gap-3 gap-md-0">
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Show</label>
<select name="per_page" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="10" {{ request('per_page') == 10 ? 'selected' : '' }}>10</option>
<option value="25" {{ request('per_page') == 25 ? 'selected' : '' }}>25</option>
<option value="50" {{ request('per_page') == 50 ? 'selected' : '' }}>50</option>
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
<div class="col-md-auto d-flex gap-2">
@if (app()->has('SystemProgram'))
@else
<div class="col-md-auto">
<div class="d-flex align-items-center">
<label class="me-2 text-nowrap">Program</label>
<select name="program_id" class="form-select form-select-sm w-auto" onchange="this.form.submit()">
<option value="">Pilih Program</option>
@foreach($programList as $prog)
<option value="{{ $prog->id }}" {{ request('program_id') == $prog->id ? 'selected' : '' }}>{{ $prog->nama }}</option>
@endforeach
</select>
<label class="ms-2 text-nowrap">entries</label>
</div>
</div>
@endif
<div class="input-group input-group-sm w-auto">
<input type="text" name="search" class="form-control" placeholder="Cari Nama Tabel..." value="{{ request('search') }}">
<button type="submit" class="btn btn-outline-primary"><i class="ti tabler-search"></i></button>
</div>
<a href="{{ route('tabel.data.create', [$tabel->id, 'program_id' => request('program')]) }}" class="btn btn-sm btn-primary add-new">
<i class="ti tabler-plus me-1"></i> Tambah
</a>
</div>
</form>
</div>
<div class="table-responsive text-nowrap">
<table class="table table-hover">
<thead class="border-top">
<tr>
<th>No</th>
@foreach($kolom as $k)
<th>{{ $k->label }}</th>
@endforeach
<th>Aksi</th>
</tr>
</thead>
<tbody>
@forelse($values as $v)
<tr>
<td>{{ $loop->iteration }}</td>
@foreach($kolom as $k)
<td>{{ $v->{$k->kolom} }}</td>
@endforeach
<td>
<div class="d-flex align-items-center">
<a href="{{ route('tabel.data.edit', [$tabel->id, $v->value_id, 'program_id' => $k->program_id]) }}" class="btn btn-icon btn-text-secondary rounded-pill edit-record"><i class="ti tabler-edit ti-md"></i></a>
<a href="javascript:;" class="btn btn-icon btn-text-secondary rounded-pill delete-record" data-id="{{ $v->value_id }}" data-program-id="{{ $k->program_id }}"><i class="ti tabler-trash ti-md"></i></a>
<a href="{{ route('tabel.data.show', [$tabel->id, $v->value_id, 'program_id' => $k->program_id]) }}" class="btn btn-icon btn-text-secondary rounded-pill view-record"><i class="ti tabler-eye ti-md"></i></a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="{{ count($kolom) + 2 }}" class="text-center py-4">Tidak ada data ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="card-footer d-flex justify-content-center justify-content-md-end border-top">
{{ $values->appends(request()->query())->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
'use strict';
$(document).ready(function () {
$(".delete-record").click(function (e) {
e.preventDefault();
const id = $(this).data('id');
const programId = $(this).data('program-id');
Swal.fire({
title: 'Hapus?',
text: `Data tersebut akan dihapus!`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
customClass: { confirmButton: 'btn btn-danger me-3', cancelButton: 'btn btn-label-secondary' },
buttonsStyling: false
}).then(function (result) {
if (result.value) {
$.ajax({
url: "{{ route('tabel.data.destroy', [$tabel->id, ':id', 'program_id' => ':programId']) }}".replace(':id', id).replace(':programId', programId),
type: 'POST',
data: {
_token: '{{ csrf_token() }}',
_method: 'DELETE'
},
success: function () {
Swal.fire({ icon: 'success', title: 'Terhapus!', showConfirmButton: false, timer: 1500 })
.then(() => location.reload());
}
});
}
});
});
});
</script>
@endpush
+8 -144
View File
@@ -15,36 +15,15 @@
</div>
</div>
<!-- /Search -->
<ul class="navbar-nav flex-row align-items-center ms-md-auto">
<li class="nav-item dropdown-language dropdown me-2 me-xl-0">
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
<i class="icon-base ti tabler-language icon-22px text-heading"></i>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="javascript:void(0);" data-language="en" data-text-direction="ltr">
<span>English</span>
</a>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0);" data-language="fr" data-text-direction="ltr">
<span>French</span>
</a>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0);" data-language="ar" data-text-direction="rtl">
<span>Arabic</span>
</a>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0);" data-language="de" data-text-direction="ltr">
<span>German</span>
</a>
</li>
</ul>
@if (app()->has('SystemProgram'))
<li class="nav-item">
<span>{{ app('SystemProgram')->nama }}</span>
</li>
@endif
<!--/ Language -->
<!-- Style Switcher -->
@@ -97,101 +76,8 @@
</li>
<!-- / Style Switcher-->
<!-- Quick links -->
<li class="nav-item dropdown-shortcuts navbar-dropdown dropdown">
<a
class="nav-link dropdown-toggle hide-arrow btn btn-icon btn-text-secondary rounded-pill"
href="javascript:void(0);"
data-bs-toggle="dropdown"
data-bs-auto-close="outside"
aria-expanded="false">
<i class="icon-base ti tabler-layout-grid-add icon-22px text-heading"></i>
</a>
<div class="dropdown-menu dropdown-menu-end p-0">
<div class="dropdown-menu-header border-bottom">
<div class="dropdown-header d-flex align-items-center py-3">
<h6 class="mb-0 me-auto">Shortcuts</h6>
<a
href="javascript:void(0)"
class="dropdown-shortcuts-add py-2 btn btn-text-secondary rounded-pill btn-icon"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Add shortcuts"
><i class="icon-base ti tabler-plus icon-20px text-heading"></i
></a>
</div>
</div>
<div class="dropdown-shortcuts-list scrollable-container">
<div class="row row-bordered overflow-visible g-0">
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-calendar icon-26px text-heading"></i>
</span>
<a href="app-calendar.html" class="stretched-link">Calendar</a>
<small>Appointments</small>
</div>
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-file-dollar icon-26px text-heading"></i>
</span>
<a href="app-invoice-list.html" class="stretched-link">Invoice App</a>
<small>Manage Accounts</small>
</div>
</div>
<div class="row row-bordered overflow-visible g-0">
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-user icon-26px text-heading"></i>
</span>
<a href="app-user-list.html" class="stretched-link">User App</a>
<small>Manage Users</small>
</div>
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-users icon-26px text-heading"></i>
</span>
<a href="app-access-roles.html" class="stretched-link">Role Management</a>
<small>Permission</small>
</div>
</div>
<div class="row row-bordered overflow-visible g-0">
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-device-desktop-analytics icon-26px text-heading"></i>
</span>
<a href="index.html" class="stretched-link">Dashboard</a>
<small>User Dashboard</small>
</div>
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-settings icon-26px text-heading"></i>
</span>
<a href="pages-account-settings-account.html" class="stretched-link">Setting</a>
<small>Account Settings</small>
</div>
</div>
<div class="row row-bordered overflow-visible g-0">
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-help-circle icon-26px text-heading"></i>
</span>
<a href="pages-faq.html" class="stretched-link">FAQs</a>
<small>FAQs & Articles</small>
</div>
<div class="dropdown-shortcuts-item col">
<span class="dropdown-shortcuts-icon rounded-circle mb-3">
<i class="icon-base ti tabler-square icon-26px text-heading"></i>
</span>
<a href="modal-examples.html" class="stretched-link">Modals</a>
<small>Useful Popups</small>
</div>
</div>
</div>
</div>
</li>
<!-- Quick links -->
<!-- Notification -->
<!--
<li class="nav-item dropdown-notifications navbar-dropdown dropdown me-3 me-xl-2">
<a
class="nav-link dropdown-toggle hide-arrow btn btn-icon btn-text-secondary rounded-pill"
@@ -442,6 +328,7 @@
</li>
</ul>
</li>
-->
<!--/ Notification -->
<!-- User -->
@@ -476,35 +363,12 @@
<li>
<a class="dropdown-item" href="pages-profile-user.html">
<i class="icon-base ti tabler-user me-3 icon-md"></i
><span class="align-middle">My Profile</span>
</a>
</li>
<li>
<a class="dropdown-item" href="pages-account-settings-account.html">
<i class="icon-base ti tabler-settings me-3 icon-md"></i
><span class="align-middle">Settings</span>
</a>
</li>
<li>
<a class="dropdown-item" href="pages-account-settings-billing.html">
<span class="d-flex align-items-center align-middle">
<i class="flex-shrink-0 icon-base ti tabler-file-dollar me-3 icon-md"></i
><span class="flex-grow-1 align-middle">Billing</span>
<span class="flex-shrink-0 badge bg-danger d-flex align-items-center justify-content-center"
>4</span
>
</span>
><span class="align-middle">Profil Saya</span>
</a>
</li>
<li>
<div class="dropdown-divider my-1 mx-n2"></div>
</li>
<li>
<a class="dropdown-item" href="pages-pricing.html">
<i class="icon-base ti tabler-currency-dollar me-3 icon-md"></i
><span class="align-middle">Pricing</span>
</a>
</li>
<li>
<a class="dropdown-item" href="pages-faq.html">
<i class="icon-base ti tabler-question-mark me-3 icon-md"></i
+27 -3
View File
@@ -50,14 +50,14 @@
<ul class="menu-inner py-1">
<!-- Dashboards -->
<li class="menu-item active open">
<li class="menu-item">
<a href="javascript:void(0);" class="menu-link menu-toggle">
<i class="menu-icon icon-base ti tabler-smart-home"></i>
<div data-i18n="Dashboards">Dashboards</div>
<div class="badge text-bg-danger rounded-pill ms-auto">5</div>
</a>
<ul class="menu-sub">
<li class="menu-item active">
<li class="menu-item">
<a href="{{ route('dashboard.summary') }}" class="menu-link">
<div data-i18n="Summary">Summary</div>
</a>
@@ -260,12 +260,36 @@
<span class="menu-header-text" data-i18n="Konfigurasi">Konfigurasi</span>
</li>
<li class="menu-item">
<li class="menu-item {{ request()->routeIs('users.*') ? 'active' : '' }}">
<a href="{{ route('users.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-users"></i>
<div data-i18n="Daftar Pengguna">Daftar Pengguna</div>
</a>
</li>
<li class="menu-item {{ request()->routeIs('program.*') ? 'active' : '' }}">
<a href="{{ route('program.index') }}" class="menu-link">
<i class="menu-icon icon-base ti tabler-transform"></i>
<div data-i18n="Daftar Program">Daftar program</div>
</a>
</li>
<li class="menu-item {{ request()->routeIs(['group.*', 'tabel.*']) ? 'active open' : '' }}">
<a href="javascript:void(0);" class="menu-link menu-toggle">
<i class="menu-icon icon-base ti tabler-database"></i>
<div data-i18n="Basis Data Ekosistem">Basis Data Ekosistem</div>
</a>
<ul class="menu-sub">
<li class="menu-item {{ request()->routeIs('group.*') ? 'active' : '' }}">
<a href="{{ route('group.index') }}" class="menu-link">
<div data-i18n="Kelompok">Kelompok</div>
</a>
</li>
<li class="menu-item {{ request()->routeIs('tabel.*') ? 'active' : '' }}">
<a href="{{ route('tabel.index') }}" class="menu-link">
<div data-i18n="Tabel">Tabel</div>
</a>
</li>
</ul>
</li>
<!-- Misc -->
<li class="menu-header small">
+15
View File
@@ -104,4 +104,19 @@ Route::middleware('auth')
Route::put('/tanaman/{id}', [App\Http\Controllers\Web\Produktivitas\TanamanController::class, 'update'])->name('tanaman.update');
Route::delete('/tanaman/{id}', [App\Http\Controllers\Web\Produktivitas\TanamanController::class, 'destroy'])->name('tanaman.destroy');
Route::get('/tanaman/{id}', [App\Http\Controllers\Web\Produktivitas\TanamanController::class, 'show'])->name('tanaman.show');
// Program
Route::resource('program', App\Http\Controllers\Web\ProgramController::class);
Route::resource('program.komoditas', App\Http\Controllers\Web\ProgramKomoditasController::class)->only(['store', 'update', 'destroy']);
Route::resource('program.lokasi', App\Http\Controllers\Web\ProgramLokasiController::class)->only(['store', 'update', 'destroy']);
// Basis Data Ekosistem
Route::resource('group', App\Http\Controllers\Web\Ekosistem\GroupBasisDataController::class);
Route::put('tabel/{id}/move-up', [App\Http\Controllers\Web\Ekosistem\TabelBasisDataController::class, 'moveUp'])->name('tabel.move-up');
Route::put('tabel/{id}/move-down', [App\Http\Controllers\Web\Ekosistem\TabelBasisDataController::class, 'moveDown'])->name('tabel.move-down');
Route::resource('tabel', App\Http\Controllers\Web\Ekosistem\TabelBasisDataController::class);
Route::put('tabel/{tabelId}/kolom/{id}/move-up', [App\Http\Controllers\Web\Ekosistem\KolomBasisDataController::class, 'moveUp'])->name('tabel.kolom.move-up');
Route::put('tabel/{tabelId}/kolom/{id}/move-down', [App\Http\Controllers\Web\Ekosistem\KolomBasisDataController::class, 'moveDown'])->name('tabel.kolom.move-down');
Route::resource('tabel.kolom', App\Http\Controllers\Web\Ekosistem\KolomBasisDataController::class)->only(['show', 'store', 'update', 'destroy']);
Route::resource('tabel.data', App\Http\Controllers\Web\Ekosistem\ValueBasisDataController::class);
});