diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php
index e9cae43..2d998ff 100644
--- a/app/Http/Controllers/CustomerController.php
+++ b/app/Http/Controllers/CustomerController.php
@@ -224,18 +224,18 @@ class CustomerController extends Controller
}
}
//code...
- DB::commit();
- return response()->json([
- 'status' => true,
- 'data' => $order,
- 'message' => 'Data berhasil disimpan'
- ]);
+ DB::commit();
+ return response()->json([
+ 'status' => true,
+ 'data' => $order,
+ 'message' => 'Data berhasil disimpan'
+ ]);
} catch (\Throwable $th) {
- DB::rollBack();
- return response()->json([
- 'status' => false,
- 'message' => 'Data gagal disimpan ' . $th->getMessage()
- ]);
+ DB::rollBack();
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Data gagal disimpan ' . $th->getMessage()
+ ]);
}
}
diff --git a/app/Http/Controllers/KarbohidratController.php b/app/Http/Controllers/KarbohidratController.php
new file mode 100644
index 0000000..cdd5b5f
--- /dev/null
+++ b/app/Http/Controllers/KarbohidratController.php
@@ -0,0 +1,130 @@
+ 'Karbohidrat'
+ ];
+ return view('dashboard.karbohidrat.index', $payload);
+ }
+
+ /**
+ * Show the form for creating a new resource.
+ */
+ public function create()
+ {
+ //
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ */
+ public function store(RequestKarbohidrat $request)
+ {
+ DB::connection('dbOrderGizi')->beginTransaction();
+ try {
+ $request->validated();
+ $datas = $request->input('data');
+ foreach ($datas as $data) {
+ $payload = [
+ 'pegawai_id_entry' => auth()->user()->id,
+ 'pegawai_nama_entry' => auth()->user()->full_name,
+ 'nama_karbohidrat' => $data['nama_karbohidrat']
+ ];
+ Karbohidrat::create($payload);
+ };
+ DB::connection('dbOrderGizi')->commit();
+ return response()->json([
+ 'status' => true,
+ 'message' => 'Berhasil menambahkan data'
+ ], 201);
+ } catch (\Throwable $th) {
+ DB::connection('dbOrderGizi')->rollBack();
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Gagal menambahkan data'
+ ], 500);
+ }
+ }
+
+ /**
+ * Display the specified resource.
+ */
+ public function show(string $id)
+ {
+ //
+ }
+
+ /**
+ * Show the form for editing the specified resource.
+ */
+ public function edit(string $id)
+ {
+ //
+ }
+
+ /**
+ * Update the specified resource in storage.
+ */
+ public function update(RequestUpdateKarbohidrat $request, string $id)
+ {
+ $request->validated();
+ try {
+ $karbohidrat = Karbohidrat::where('karbohidrat_id', $id)->first();
+ $payload = [
+ 'nama_karbohidrat' => $request->input('nama_karbohidrat'),
+ 'pegawai_id_entry' => auth()->user()->id,
+ 'pegawai_nama_entry' => auth()->user()->full_name,
+ 'modified_at' => Carbon::now()
+ ];
+ $karbohidrat->update($payload);
+ return response()->json([
+ 'status' => true,
+ 'message' => 'Berhasil memperbarui data'
+ ], 200);
+ } catch (\Throwable $th) {
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Gagal memperbarui data'
+ ], 500);
+ }
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ */
+ public function destroy(string $id)
+ {
+ $data = Karbohidrat::where(['statusenabled' => true, 'karbohidrat_id' => $id])->first();
+ $payload = [
+ 'statusenabled' => false,
+ 'pegawai_id_entry' => auth()->user()->id,
+ 'pegawai_nama_entry' => auth()->user()->full_name,
+ 'modified_at' => Carbon::now()
+ ];
+ $data->update($payload);
+ return response()->json([
+ 'status' => true,
+ 'message' => 'Berhasil menghapus data'
+ ], 200);
+ }
+
+ public function datatable(){
+ $data = Karbohidrat::where('statusenabled', true)->get();
+ return $data;
+ }
+}
diff --git a/app/Http/Controllers/KlasifikasiMenuController.php b/app/Http/Controllers/KlasifikasiMenuController.php
index 0f361e7..5df687a 100644
--- a/app/Http/Controllers/KlasifikasiMenuController.php
+++ b/app/Http/Controllers/KlasifikasiMenuController.php
@@ -2,7 +2,12 @@
namespace App\Http\Controllers;
+use App\Http\Requests\KlasifikasiMenu\RequestKlasifikasiMenu;
+use App\Http\Requests\KlasifikasiMenu\RequestUpdateKlasifikasiMenu;
+use App\Models\KlasifikasiMenu;
+use Carbon\Carbon;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\DB;
class KlasifikasiMenuController extends Controller
{
@@ -11,7 +16,10 @@ class KlasifikasiMenuController extends Controller
*/
public function index()
{
- //
+ $payload = [
+ 'title' => 'Master Klasifikasi Menu'
+ ];
+ return view('dashboard.klasifikasi_menu.index', $payload);
}
/**
@@ -25,9 +33,32 @@ class KlasifikasiMenuController extends Controller
/**
* Store a newly created resource in storage.
*/
- public function store(Request $request)
+ public function store(RequestKlasifikasiMenu $request)
{
- //
+ DB::connection('dbOrderGizi')->beginTransaction();
+ try {
+ $request->validated();
+ $datas = $request->input('data');
+ foreach ($datas as $data) {
+ $payload = [
+ 'pegawai_id_entry' => auth()->user()->id,
+ 'pegawai_nama_entry' => auth()->user()->full_name,
+ 'nama_kategori_diet' => $data['nama_kategori_diet']
+ ];
+ KlasifikasiMenu::create($payload);
+ };
+ DB::connection('dbOrderGizi')->commit();
+ return response()->json([
+ 'status' => true,
+ 'message' => 'Berhasil menambahkan data'
+ ], 201);
+ } catch (\Throwable $th) {
+ DB::connection('dbOrderGizi')->rollBack();
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Gagal menambahkan data'
+ ], 500);
+ }
}
/**
@@ -49,9 +80,28 @@ class KlasifikasiMenuController extends Controller
/**
* Update the specified resource in storage.
*/
- public function update(Request $request, string $id)
+ public function update(RequestUpdateKlasifikasiMenu $request, string $id)
{
- //
+ $request->validated();
+ try {
+ $km = KlasifikasiMenu::where('kategori_diet_id', $id)->first();
+ $payload = [
+ 'nama_kategori_diet' => $request->input('nama_kategori_diet'),
+ 'pegawai_id_entry' => auth()->user()->id,
+ 'pegawai_nama_entry' => auth()->user()->full_name,
+ 'modified_at' => Carbon::now()
+ ];
+ $km->update($payload);
+ return response()->json([
+ 'status' => true,
+ 'message' => 'Berhasil memperbarui data'
+ ], 200);
+ } catch (\Throwable $th) {
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Gagal memperbarui data'
+ ], 500);
+ }
}
/**
@@ -59,6 +109,21 @@ class KlasifikasiMenuController extends Controller
*/
public function destroy(string $id)
{
- //
+ $data = KlasifikasiMenu::where(['statusenabled' => true, 'kategori_diet_id' => $id])->first();
+ $payload = [
+ 'statusenabled' => false,
+ 'pegawai_id_entry' => auth()->user()->id,
+ 'pegawai_nama_entry' => auth()->user()->full_name,
+ 'modified_at' => Carbon::now()
+ ];
+ $data->update($payload);
+ return response()->json([
+ 'status' => true,
+ 'message' => 'Berhasil menghapus data'
+ ], 200);
+ }
+
+ public function datatable(){
+ return KlasifikasiMenu::where('statusenabled', true)->get();
}
}
diff --git a/app/Http/Requests/Karbohidrat/RequestKarbohidrat.php b/app/Http/Requests/Karbohidrat/RequestKarbohidrat.php
new file mode 100644
index 0000000..d9fbedb
--- /dev/null
+++ b/app/Http/Requests/Karbohidrat/RequestKarbohidrat.php
@@ -0,0 +1,75 @@
+ 'required|array|min:1',
+ 'data.*.nama_karbohidrat' => 'required|string'
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'data.array' => 'Format data harus berupa array',
+ 'data.min' => 'Minimal harus ada satu data klasifikasi menu',
+ 'data.*.nama_karbohidrat.required' => 'Nama Klasifikasi Menu wajib diisi',
+ 'data.*.nama_karbohidrat.string' => 'Nama Kategori Soal harus berupa teks',
+ ];
+ }
+
+ protected function failedValidation(Validator $validator){
+ throw new HttpResponseException(
+ response()->json([
+ 'status' => 'VALIDATION_FAILED',
+ 'message' => 'Validasi Gagal',
+ 'errors' => $validator->errors()->messages(),
+ ], 422)
+ );
+ }
+
+ public function withValidator($validator){
+ $validator->after(function ($validator){
+ $namaListAsli = collect($this->input('data'))->pluck('nama_karbohidrat')->filter();
+ $namaListLower = $namaListAsli->map(fn($n) => strtolower(trim($n)));
+ $duplicates = $namaListLower->duplicates();
+
+ if ($duplicates->isNotEmpty()) {
+ foreach ($namaListAsli as $index => $nama) {
+ if ($duplicates->contains(strtolower(trim($nama)))) {
+ $validator->errors()->add("data.$index.nama_kategori_diet", "Nama '$nama' duplikat dalam input.");
+ }
+ }
+ }
+ $namaList = $namaListAsli->map(fn($n) => strtolower(trim($n)));
+
+ if($namaList->isEmpty()) return;
+
+ $exists = DB::connection('dbOrderGizi')
+ ->table('public.karbohidrat')
+ ->where('statusenabled', true)
+ ->whereIn(DB::raw('LOWER(nama_karbohidrat)'), $namaList->toArray())
+ ->selectRaw('LOWER(nama_karbohidrat) as nama')
+ ->pluck('nama')
+ ->toArray();
+
+ foreach ($namaListAsli as $index => $nama) {
+ $lowerNama = strtolower(trim($nama));
+ if(in_array($lowerNama, $exists)){
+ $validator->errors()->add("data.$index.nama_karbohidrat", "Nama '$nama' Sudah digunakan.");
+ }
+ }
+ });
+ }
+}
diff --git a/app/Http/Requests/Karbohidrat/RequestUpdateKarbohidrat.php b/app/Http/Requests/Karbohidrat/RequestUpdateKarbohidrat.php
new file mode 100644
index 0000000..1188325
--- /dev/null
+++ b/app/Http/Requests/Karbohidrat/RequestUpdateKarbohidrat.php
@@ -0,0 +1,57 @@
+ 'required|string'
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'nama_karbohidrat.required' => 'Nama Karbohidrat wajib diisi'
+ ];
+ }
+
+ protected function failedValidation(Validator $validator){
+ throw new HttpResponseException(
+ response()->json([
+ 'status' => 'VALIDATION_FAILED',
+ 'message' => 'Validasi Gagal',
+ 'errors' => $validator->errors()->messages(),
+ ], 422)
+ );
+ }
+
+ public function withValidator($validator){
+ $validator->after(function($validator){
+ $id = $this->route('karbohidrat') ?? $this->karbohidrat_id ?? null;
+ $exists = DB::connection('dbOrderGizi')
+ ->table('public.karbohidrat')
+ ->where('statusenabled', true)
+ ->where('nama_karbohidrat', 'ILIKE', $this->input('nama_karbohidrat'));
+
+ if($id) $exists->where('karbohidrat_id', '!=', $id);
+
+ if($exists->exists()){
+ $validator->errors()->add(
+ 'nama_karbohidrat',
+ 'Nama Karbohidrat sudah digunakan'
+ );
+ }
+ });
+ }
+
+}
diff --git a/app/Http/Requests/KlasifikasiMenu/RequestKlasifikasiMenu.php b/app/Http/Requests/KlasifikasiMenu/RequestKlasifikasiMenu.php
new file mode 100644
index 0000000..736975f
--- /dev/null
+++ b/app/Http/Requests/KlasifikasiMenu/RequestKlasifikasiMenu.php
@@ -0,0 +1,89 @@
+|string>
+ */
+ public function rules(): array
+ {
+ return [
+ 'data' => 'required|array|min:1',
+ 'data.*.nama_kategori_diet' => 'required|string'
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'data.array' => 'Format data harus berupa array',
+ 'data.min' => 'Minimal harus ada satu data klasifikasi menu',
+ 'data.*.nama_kategori_diet.required' => 'Nama Klasifikasi Menu wajib diisi',
+ 'data.*.nama_kategori_diet.string' => 'Nama Kategori Soal harus berupa teks',
+ ];
+ }
+
+ protected function failedValidation(Validator $validator){
+ throw new HttpResponseException(
+ response()->json([
+ 'status' => 'VALIDATION_FAILED',
+ 'message' => 'Validasi Gagal',
+ 'errors' => $validator->errors()->messages(),
+ ], 422)
+ );
+ }
+
+ public function withValidator($validator){
+ $validator->after(function ($validator){
+ $namaListAsli = collect($this->input('data'))->pluck('nama_kategori_diet')->filter();
+
+ $namaListLower = $namaListAsli->map(fn($n) => strtolower(trim($n)));
+
+ // ✅ Cek duplikat antar input user
+ $duplicates = $namaListLower->duplicates();
+
+ if ($duplicates->isNotEmpty()) {
+ foreach ($namaListAsli as $index => $nama) {
+ if ($duplicates->contains(strtolower(trim($nama)))) {
+ $validator->errors()->add("data.$index.nama_kategori_diet", "Nama '$nama' duplikat dalam input.");
+ }
+ }
+ }
+
+ $namaList = $namaListAsli->map(fn($n) => strtolower(trim($n)));
+
+ if($namaList->isEmpty()) return;
+
+ $exists = DB::connection('dbOrderGizi')
+ ->table('public.kategori_diet')
+ ->where('statusenabled', true)
+ ->whereIn(DB::raw('LOWER(nama_kategori_diet)'), $namaList->toArray())
+ ->selectRaw('LOWER(nama_kategori_diet) as nama')
+ ->pluck('nama')
+ ->toArray();
+
+ foreach ($namaListAsli as $index => $nama) {
+ $lowerNama = strtolower(trim($nama));
+ if(in_array($lowerNama, $exists)){
+ $validator->errors()->add("data.$index.nama_kategori_diet", "Nama '$nama' Sudah digunakan.");
+ }
+ }
+ });
+ }
+}
diff --git a/app/Http/Requests/KlasifikasiMenu/RequestUpdateKlasifikasiMenu.php b/app/Http/Requests/KlasifikasiMenu/RequestUpdateKlasifikasiMenu.php
new file mode 100644
index 0000000..4a07bcd
--- /dev/null
+++ b/app/Http/Requests/KlasifikasiMenu/RequestUpdateKlasifikasiMenu.php
@@ -0,0 +1,66 @@
+|string>
+ */
+ public function rules(): array
+ {
+ return [
+ 'nama_kategori_diet' => 'required|string'
+ ];
+ }
+
+ public function messages(){
+ return [
+ 'nama_kategori_diet.required' => 'Nama Klasifikasi Menu wajib diisi'
+ ];
+ }
+
+ protected function failedValidation(Validator $validator){
+ throw new HttpResponseException(
+ response()->json([
+ 'status' => 'VALIDATION_FAILED',
+ 'message' => 'Validasi Gagal',
+ 'errors' => $validator->errors()->messages(),
+ ], 422)
+ );
+ }
+
+ public function withValidator($validator){
+ $validator->after(function($validator){
+ $id = $this->route('klasifikasi_menu') ?? $this->kategori_diet_id ?? null;
+ $exists = DB::connection('dbOrderGizi')
+ ->table('public.kategori_diet')
+ ->where('nama_kategori_diet', 'ILIKE', $this->input('nama_kategori_diet'));
+
+ if($id) $exists->where('kategori_diet_id', '!=', $id);
+
+ if($exists->exists()){
+ $validator->errors()->add(
+ 'nama_kategori_diet',
+ 'Nama Klasifikasi Menu sudah digunakan'
+ );
+ }
+ });
+ }
+
+}
diff --git a/app/Models/Karbohidrat.php b/app/Models/Karbohidrat.php
new file mode 100644
index 0000000..a79ee1d
--- /dev/null
+++ b/app/Models/Karbohidrat.php
@@ -0,0 +1,23 @@
+ {
+ const responseData = await res.json();
+
+ if (res.status === 422) {
+ // Tampilkan semua error ke swal
+ const errors = responseData.errors || {};
+ let htmlList = '
';
+ for (const key in errors) {
+ errors[key].forEach(message => {
+ htmlList += `- ${message}
`;
+ });
+ }
+ htmlList += '
';
+
+ Swal.fire({
+ icon: 'error',
+ title: 'Validasi Gagal',
+ html: htmlList,
+ });
+
+ throw new Error(); // Supaya masuk ke catch, tapi tidak tampil swal lagi
+ }
+
+ if (responseData.status) {
+ const handler = function () {
+ Swal.fire({
+ icon: 'success',
+ title: 'Berhasil',
+ text: responseData.message || 'Berhasil melakukan aksi!',
+ timer: 2000,
+ showConfirmButton: false,
+ backdrop: true,
+ });
+ $("#col_add_karbohidrat").html('');
+ colCount = 0; // reset counter
+ formKarbohidrat[0].reset();
+ datatableKarbohidrat.bootstrapTable('refresh');
+ modalKarbohidrat.removeEventListener('hidden.bs.modal', handler);
+ };
+ modalKarbohidrat.addEventListener('hidden.bs.modal', handler);
+ bootstrap.Modal.getInstance(modalKarbohidrat).hide();
+ } else {
+ throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.');
+ }
+
+ }).catch(err => {
+ if (err.message) {
+ Swal.fire({
+ icon: 'error',
+ title: 'Gagal',
+ text: err.message
+ });
+ }
+ });
+});
+
+
+function deleteKarbohidrat(e){
+ let id =$(e).data('karbohidrat_id')
+ Swal.fire({
+ title: "Apakah kamu yakin ingin menghapus data ini?",
+ text : $(e).data('nama'),
+ icon: "warning",
+ showCancelButton: true,
+ backdrop: true,
+ }).then((result) => {
+ if(result.isConfirmed){
+ fetch(`/dashboard/karbohidrat/${id}`, {
+ method:'DELETE',
+ headers: {
+ "X-CSRF-TOKEN": document.querySelector('input[name="_token"]').value,
+ "Content-Type": "application/json"
+ }
+ }).then((response) => {
+ if(!response.ok){
+ throw new Error("Network response was not ok");
+ }
+ return response.json();
+ })
+ .then((data) => {
+ if(data.status){
+ Swal.fire({
+ title: "Success",
+ text: "Data berhasil dihapus",
+ icon:"success",
+ showConfirmButton: false,
+ timer: 1000
+ }).then(() => {
+ datatableKarbohidrat.bootstrapTable("refresh")
+ })
+ }else{
+ Swal.fire({
+ title: "Error!",
+ text: data.message || "Failed to delete Item.",
+ icon: "error"
+ });
+ }
+ })
+ .catch(error => {
+ Swal.fire({
+ title: "Error!",
+ text: "Something went wrong. Please try again later.",
+ icon: "error"
+ });
+ });
+ }
+ })
+}
+
+function editKarbohidrat(e){
+ const data = $(e).data();
+ new bootstrap.Modal(modalKarbohidratEdit).show();
+ formKarbohidratEdit.attr('action', `/dashboard/karbohidrat/${data?.karbohidrat_id}`)
+ $("#nama_karbohidrat").val(data.nama)
+}
+
+formKarbohidratEdit.on('submit', function(e){
+ e.preventDefault();
+
+ const form = this;
+ const actionUrl = formKarbohidratEdit.attr('action');
+ const formData = new FormData(form);
+ formData.append('_method', 'PUT')
+ fetch(actionUrl, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value,
+ },
+ body: formData
+ }).then(async(res) => {
+ const responseData = await res.json();
+
+ if (res.status === 422) {
+ // Tampilkan semua error ke swal
+ const errors = responseData.errors || {};
+ Swal.fire({
+ icon: 'error',
+ title: 'Validasi Gagal',
+ html: errors.nama_karbohidrat[0],
+ });
+
+ throw new Error(); // Supaya masuk ke catch, tapi tidak tampil swal lagi
+ }
+
+ if (responseData.status) {
+ const handler = function () {
+ Swal.fire({
+ icon: 'success',
+ title: 'Berhasil',
+ text: responseData.message || 'Berhasil melakukan aksi!',
+ timer: 2000,
+ showConfirmButton: false,
+ backdrop: true,
+ });
+ $("#nama_kategori_diet").val('');
+ colCount = 0; // reset counter
+ formKarbohidratEdit[0].reset();
+ datatableKarbohidrat.bootstrapTable('refresh');
+ modalKarbohidratEdit.removeEventListener('hidden.bs.modal', handler);
+ };
+ modalKarbohidratEdit.addEventListener('hidden.bs.modal', handler);
+ bootstrap.Modal.getInstance(modalKarbohidratEdit).hide();
+ } else {
+ throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.');
+ }
+
+ }).catch(err => {
+ if (err.message) {
+ Swal.fire({
+ icon: 'error',
+ title: 'Gagal',
+ text: err.message
+ });
+ }
+ });
+});
diff --git a/public/js/karbohidrat/dt.js b/public/js/karbohidrat/dt.js
new file mode 100644
index 0000000..c5cafdd
--- /dev/null
+++ b/public/js/karbohidrat/dt.js
@@ -0,0 +1,51 @@
+
+ datatableKarbohidrat.bootstrapTable({
+ url: "/dashboard/datatable/karbohidrat",
+ showColumns: true,
+ showColumnsToggleAll: true,
+ showRefresh: true,
+ sortable: true,
+ search: true,
+ searchOnEnterKey: false,
+ searchHighlight: true,
+ pagination: true,
+ serverSide:true,
+ pageSize: 10,
+ pageList: [10, 20, 30],
+ cookie: true,
+ cookieIdTable: "datatableKlasifikasiMenu",
+ icons: {
+ refresh: "fas fa-sync-alt", // atau ganti ke icon lain
+ columns: "fas fa-th-large"
+ },
+
+ columns: [
+ {
+ title: "Action",
+ field: 'karbohidrat_id',
+ formatter: function(value, row) {
+ let buttons = ''
+ buttons += `
+
+ `
+ buttons += `
+
+ `
+ return `
+
+ ${buttons}
+
+ `;
+ },
+ width: 120
+ },
+ {
+ title:"Nama Karbohidrat",
+ field:"nama_karbohidrat"
+ }
+ ],
+ });
diff --git a/public/js/karbohidrat/function.js b/public/js/karbohidrat/function.js
new file mode 100644
index 0000000..3c4bc02
--- /dev/null
+++ b/public/js/karbohidrat/function.js
@@ -0,0 +1,27 @@
+let colCount = 1;
+function addForm(){
+ let col = $("#col_add_karbohidrat")
+
+ let html = '';
+
+ html += `
+
+
+
+
+
+
+
+
+
+ `
+ col.append(html)
+ colCount++;
+
+}
+
+
+function removeCol(count){
+ $(`#col-${count}`).remove()
+}
+
diff --git a/public/js/klasifikasi_menu/_init.js b/public/js/klasifikasi_menu/_init.js
new file mode 100644
index 0000000..6426269
--- /dev/null
+++ b/public/js/klasifikasi_menu/_init.js
@@ -0,0 +1,6 @@
+const datatableKlasifikasiMenu = $("#datatableKlasifikasiMenu")
+
+const modalKlasifikasiMenu = document.getElementById("modalKlasifikasiMenu")
+const formKlasifikasiMenu = $("#formKlasifikasiMenu")
+const modalKlasifikasiMenuEdit = document.getElementById("modalKlasifikasiMenuEdit")
+const formKlasifikasiMenuEdit = $("#formKlasifikasiMenuEdit")
diff --git a/public/js/klasifikasi_menu/action.js b/public/js/klasifikasi_menu/action.js
new file mode 100644
index 0000000..d922ace
--- /dev/null
+++ b/public/js/klasifikasi_menu/action.js
@@ -0,0 +1,195 @@
+function addKlasifikasi(){
+ new bootstrap.Modal(modalKlasifikasiMenu).show();
+ formKlasifikasiMenu.attr('action', `/dashboard/klasifikasi-menu`)
+}
+
+formKlasifikasiMenu.on('submit', function(e){
+ e.preventDefault();
+
+ const form = this;
+ const actionUrl = formKlasifikasiMenu.attr('action');
+ const formData = new FormData(form);
+
+ fetch(actionUrl, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value,
+ },
+ body: formData
+ }).then(async(res) => {
+ const responseData = await res.json();
+
+ if (res.status === 422) {
+ // Tampilkan semua error ke swal
+ const errors = responseData.errors || {};
+ let htmlList = '';
+ for (const key in errors) {
+ errors[key].forEach(message => {
+ htmlList += `- ${message}
`;
+ });
+ }
+ htmlList += '
';
+
+ Swal.fire({
+ icon: 'error',
+ title: 'Validasi Gagal',
+ html: htmlList,
+ });
+
+ throw new Error(); // Supaya masuk ke catch, tapi tidak tampil swal lagi
+ }
+
+ if (responseData.status) {
+ const handler = function () {
+ Swal.fire({
+ icon: 'success',
+ title: 'Berhasil',
+ text: responseData.message || 'Berhasil melakukan aksi!',
+ timer: 2000,
+ showConfirmButton: false,
+ backdrop: true,
+ });
+ $("#col_add_klasifikasi").html('');
+ colCount = 0; // reset counter
+ formKlasifikasiMenu[0].reset();
+ datatableKlasifikasiMenu.bootstrapTable('refresh');
+ modalKlasifikasiMenu.removeEventListener('hidden.bs.modal', handler);
+ };
+ modalKlasifikasiMenu.addEventListener('hidden.bs.modal', handler);
+ bootstrap.Modal.getInstance(modalKlasifikasiMenu).hide();
+ } else {
+ throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.');
+ }
+
+ }).catch(err => {
+ if (err.message) {
+ Swal.fire({
+ icon: 'error',
+ title: 'Gagal',
+ text: err.message
+ });
+ }
+ });
+});
+
+
+function editKlasifikasi(e){
+ const data = $(e).data();
+ new bootstrap.Modal(modalKlasifikasiMenuEdit).show();
+ formKlasifikasiMenuEdit.attr('action', `/dashboard/klasifikasi-menu/${data?.kategori_diet_id}`)
+ $("#nama_kategori_diet").val(data.nama)
+}
+
+
+formKlasifikasiMenuEdit.on('submit', function(e){
+ e.preventDefault();
+
+ const form = this;
+ const actionUrl = formKlasifikasiMenuEdit.attr('action');
+ const formData = new FormData(form);
+ formData.append('_method', 'PUT')
+ fetch(actionUrl, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value,
+ },
+ body: formData
+ }).then(async(res) => {
+ const responseData = await res.json();
+
+ if (res.status === 422) {
+ // Tampilkan semua error ke swal
+ const errors = responseData.errors || {};
+ Swal.fire({
+ icon: 'error',
+ title: 'Validasi Gagal',
+ html: errors.nama_kategori_diet[0],
+ });
+
+ throw new Error(); // Supaya masuk ke catch, tapi tidak tampil swal lagi
+ }
+
+ if (responseData.status) {
+ const handler = function () {
+ Swal.fire({
+ icon: 'success',
+ title: 'Berhasil',
+ text: responseData.message || 'Berhasil melakukan aksi!',
+ timer: 2000,
+ showConfirmButton: false,
+ backdrop: true,
+ });
+ $("#nama_kategori_diet").val('');
+ colCount = 0; // reset counter
+ formKlasifikasiMenuEdit[0].reset();
+ datatableKlasifikasiMenu.bootstrapTable('refresh');
+ modalKlasifikasiMenuEdit.removeEventListener('hidden.bs.modal', handler);
+ };
+ modalKlasifikasiMenuEdit.addEventListener('hidden.bs.modal', handler);
+ bootstrap.Modal.getInstance(modalKlasifikasiMenuEdit).hide();
+ } else {
+ throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.');
+ }
+
+ }).catch(err => {
+ if (err.message) {
+ Swal.fire({
+ icon: 'error',
+ title: 'Gagal',
+ text: err.message
+ });
+ }
+ });
+});
+
+function deleteKlasifikasi(e){
+ let id =$(e).data('kategori_diet_id')
+ Swal.fire({
+ title: "Apakah kamu yakin ingin menghapus data ini?",
+ text : $(e).data('nama'),
+ icon: "warning",
+ showCancelButton: true,
+ backdrop: true,
+ }).then((result) => {
+ if(result.isConfirmed){
+ fetch(`/dashboard/klasifikasi-menu/${id}`, {
+ method:'DELETE',
+ headers: {
+ "X-CSRF-TOKEN": document.querySelector('input[name="_token"]').value,
+ "Content-Type": "application/json"
+ }
+ }).then((response) => {
+ if(!response.ok){
+ throw new Error("Network response was not ok");
+ }
+ return response.json();
+ })
+ .then((data) => {
+ if(data.status){
+ Swal.fire({
+ title: "Success",
+ text: "Data berhasil dihapus",
+ icon:"success",
+ showConfirmButton: false,
+ timer: 1000
+ }).then(() => {
+ datatableKlasifikasiMenu.bootstrapTable("refresh")
+ })
+ }else{
+ Swal.fire({
+ title: "Error!",
+ text: data.message || "Failed to delete Item.",
+ icon: "error"
+ });
+ }
+ })
+ .catch(error => {
+ Swal.fire({
+ title: "Error!",
+ text: "Something went wrong. Please try again later.",
+ icon: "error"
+ });
+ });
+ }
+ })
+}
diff --git a/public/js/klasifikasi_menu/dt.js b/public/js/klasifikasi_menu/dt.js
new file mode 100644
index 0000000..eecd274
--- /dev/null
+++ b/public/js/klasifikasi_menu/dt.js
@@ -0,0 +1,51 @@
+
+ datatableKlasifikasiMenu.bootstrapTable({
+ url: "/dashboard/datatable/klasifikasi-menu",
+ showColumns: true,
+ showColumnsToggleAll: true,
+ showRefresh: true,
+ sortable: true,
+ search: true,
+ searchOnEnterKey: false,
+ searchHighlight: true,
+ pagination: true,
+ serverSide:true,
+ pageSize: 10,
+ pageList: [10, 20, 30],
+ cookie: true,
+ cookieIdTable: "datatableKlasifikasiMenu",
+ icons: {
+ refresh: "fas fa-sync-alt", // atau ganti ke icon lain
+ columns: "fas fa-th-large"
+ },
+
+ columns: [
+ {
+ title: "Action",
+ field: 'kategori_diet_id',
+ formatter: function(value, row) {
+ let buttons = ''
+ buttons += `
+
+ `
+ buttons += `
+
+ `
+ return `
+
+ ${buttons}
+
+ `;
+ },
+ width: 120
+ },
+ {
+ title:"Nama Klasifikasi Menu",
+ field:"nama_kategori_diet"
+ }
+ ],
+ });
diff --git a/public/js/klasifikasi_menu/function.js b/public/js/klasifikasi_menu/function.js
new file mode 100644
index 0000000..230d24d
--- /dev/null
+++ b/public/js/klasifikasi_menu/function.js
@@ -0,0 +1,27 @@
+let colCount = 1;
+function addForm(){
+ let col = $("#col_add_klasifikasi")
+
+ let html = '';
+
+ html += `
+
+
+
+
+
+
+
+
+
+ `
+ col.append(html)
+ colCount++;
+
+}
+
+
+function removeCol(count){
+ $(`#col-${count}`).remove()
+}
+
diff --git a/resources/views/dashboard/karbohidrat/index.blade.php b/resources/views/dashboard/karbohidrat/index.blade.php
new file mode 100644
index 0000000..23f2a1d
--- /dev/null
+++ b/resources/views/dashboard/karbohidrat/index.blade.php
@@ -0,0 +1,30 @@
+@extends('dashboard.layouts.main')
+
+@section('body_main')
+
+
+
+ Dashboard / Master Karbohidrat
+
+
+
+
+
+ @include('dashboard.karbohidrat.modal.create')
+ @include('dashboard.karbohidrat.modal.edit')
+
+
+
+
+
+@endsection
diff --git a/resources/views/dashboard/karbohidrat/modal/create.blade.php b/resources/views/dashboard/karbohidrat/modal/create.blade.php
new file mode 100644
index 0000000..521d8c1
--- /dev/null
+++ b/resources/views/dashboard/karbohidrat/modal/create.blade.php
@@ -0,0 +1,41 @@
+
+
diff --git a/resources/views/dashboard/karbohidrat/modal/edit.blade.php b/resources/views/dashboard/karbohidrat/modal/edit.blade.php
new file mode 100644
index 0000000..8cdeca8
--- /dev/null
+++ b/resources/views/dashboard/karbohidrat/modal/edit.blade.php
@@ -0,0 +1,40 @@
+
+
diff --git a/resources/views/dashboard/klasifikasi_menu/index.blade.php b/resources/views/dashboard/klasifikasi_menu/index.blade.php
new file mode 100644
index 0000000..0741756
--- /dev/null
+++ b/resources/views/dashboard/klasifikasi_menu/index.blade.php
@@ -0,0 +1,30 @@
+@extends('dashboard.layouts.main')
+
+@section('body_main')
+
+
+
+ Dashboard / Master Klasifikasi Menu
+
+
+
+
+
+ @include('dashboard.klasifikasi_menu.modal.create')
+ @include('dashboard.klasifikasi_menu.modal.edit')
+
+
+
+
+
+@endsection
diff --git a/resources/views/dashboard/klasifikasi_menu/modal/create.blade.php b/resources/views/dashboard/klasifikasi_menu/modal/create.blade.php
new file mode 100644
index 0000000..76a5a2c
--- /dev/null
+++ b/resources/views/dashboard/klasifikasi_menu/modal/create.blade.php
@@ -0,0 +1,41 @@
+
+
diff --git a/resources/views/dashboard/klasifikasi_menu/modal/edit.blade.php b/resources/views/dashboard/klasifikasi_menu/modal/edit.blade.php
new file mode 100644
index 0000000..18f3024
--- /dev/null
+++ b/resources/views/dashboard/klasifikasi_menu/modal/edit.blade.php
@@ -0,0 +1,40 @@
+
+
diff --git a/resources/views/dashboard/partials/sidenav.blade.php b/resources/views/dashboard/partials/sidenav.blade.php
index a8cf2de..9df6379 100644
--- a/resources/views/dashboard/partials/sidenav.blade.php
+++ b/resources/views/dashboard/partials/sidenav.blade.php
@@ -17,7 +17,7 @@