diff --git a/app/Http/Controllers/Data/PengurusController.php b/app/Http/Controllers/Data/PengurusController.php index 7230a75e5..82f5bdfdf 100644 --- a/app/Http/Controllers/Data/PengurusController.php +++ b/app/Http/Controllers/Data/PengurusController.php @@ -31,21 +31,24 @@ namespace App\Http\Controllers\Data; -use App\Enums\JenisJabatan; use App\Enums\Status; -use App\Http\Controllers\Controller; -use App\Http\Requests\PengurusRequest; use App\Models\Agama; use App\Models\Jabatan; -use App\Models\PendidikanKK; use App\Models\Pengurus; +use App\Enums\JenisJabatan; +use App\Models\PendidikanKK; use Illuminate\Http\Request; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Storage; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Controllers\Controller; +use App\Http\Requests\PengurusRequest; +use Illuminate\Support\Facades\Storage; class PengurusController extends Controller { + use HandlesFileUpload; + /** * Display a listing of the resource. * @@ -135,13 +138,7 @@ public function store(PengurusRequest $request) { try { $input = $request->all(); - if ($request->hasFile('foto')) { - $file = $request->file('foto'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().'_'.$original_name; - Storage::putFileAs('public/pengurus', $file, $file_name); - $input['foto'] = $file_name; - } + $this->handleFileUpload($request, $input, 'foto', 'pengurus', false); Pengurus::create($input); } catch (\Exception $e) { report($e); @@ -185,18 +182,7 @@ public function update(PengurusRequest $request, $id) try { $input = $request->all(); - - if ($request->hasFile('foto')) { - $file = $request->file('foto'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().'_'.$original_name; - Storage::putFileAs('public/pengurus', $file, $file_name); - if ($pengurus->foto) { - Storage::delete('public/pengurus/'.$pengurus->getRawOriginal('foto')); - } - $input['foto'] = $file_name; - } - + $this->handleFileUpload($request, $input, 'foto', 'pengurus', false); $pengurus->update($input); } catch (\Exception $e) { report($e); @@ -207,19 +193,9 @@ public function update(PengurusRequest $request, $id) return redirect()->route('data.pengurus.index')->with('success', 'Pengurus berhasil diubah!'); } - /** - * Remove the specified resource from storage. - * - * @param int $id - * @return Response - */ - public function destroy($id) + public function destroy(Pengurus $pengurus) { try { - $pengurus = Pengurus::findOrFail($id); - if ($pengurus->foto) { - Storage::delete('public/pengurus/'.$pengurus->getRawOriginal('foto')); - } $pengurus->delete(); } catch (\Exception $e) { report($e); diff --git a/app/Http/Controllers/FrontEnd/PageController.php b/app/Http/Controllers/FrontEnd/PageController.php index 2a32e4049..d3ae449a8 100644 --- a/app/Http/Controllers/FrontEnd/PageController.php +++ b/app/Http/Controllers/FrontEnd/PageController.php @@ -41,6 +41,7 @@ use Illuminate\Support\Facades\Session; use willvincent\Feeds\Facades\FeedsFacade; use App\Http\Controllers\FrontEndController; +use App\Models\Kategori; use Jenssegers\Agent\Agent; class PageController extends FrontEndController @@ -54,7 +55,7 @@ public function index() return view('pages.index', [ 'page_title' => 'Beranda', 'cari' => null, - 'artikel' => Artikel::latest()->status()->paginate(config('setting.artikel_kecamatan_perhalaman') ?? 10), + 'artikel' => Artikel::with('kategori')->latest()->status()->paginate(config('setting.artikel_kecamatan_perhalaman') ?? 10), ]); } @@ -181,30 +182,39 @@ public function refresh_captcha() return response()->json(['captcha' => captcha_img('mini')]); } + public function kategoriBerita($slug) + { + $kategori = Kategori::where('slug', $slug)->firstOrFail(); + $artikel = Artikel::whereRelation('kategori', 'slug', $slug)->paginate(9); + return view('pages.berita.kategori', compact('artikel', 'kategori')); + } + public function detailBerita($slug, Request $request) { // Temukan artikel berdasarkan slug - $artikel = Artikel::where('slug', $slug) - ->with(['comments' => function ($query) use ($request) { - // Ambil komentar yang di-approve atau yang milik user dari session - $userCommentIds = $request->session()->get('session_user_comments', []); - - // Ambil komentar utama (tanpa parent) yang di-approve atau yang dimiliki oleh user - $query->whereNull('comment_id') - ->where(function ($query) use ($userCommentIds) { + $artikel = Artikel::with(['kategori', 'comments' => function ($query) use ($request) { + // Ambil komentar yang di-approve atau yang milik user dari session + $userCommentIds = $request->session()->get('session_user_comments', []); + + // Ambil komentar utama (tanpa parent) yang di-approve atau yang dimiliki oleh user + $query->whereNull('comment_id') + ->where(function ($query) use ($userCommentIds) { + $query->where('status', 'enable') + ->orWhereIn('id', $userCommentIds); + }) + ->with(['replies' => function ($query) use ($userCommentIds) { + // Ambil balasan yang di-approve atau yang milik user + $query->where(function ($query) use ($userCommentIds) { $query->where('status', 'enable') ->orWhereIn('id', $userCommentIds); - }) - ->with(['replies' => function ($query) use ($userCommentIds) { - // Ambil balasan yang di-approve atau yang milik user - $query->where(function ($query) use ($userCommentIds) { - $query->where('status', 'enable') - ->orWhereIn('id', $userCommentIds); - }); - }]); - }]) + }); + }]); + }]) + ->where('slug', $slug) + ->when(!auth()->check(), fn($query) => $query->status()) ->firstOrFail(); + $page_title = $artikel->judul; $page_description = substr($artikel->isi, 0, 300) . ' ...'; $page_image = $artikel->gambar; @@ -324,4 +334,22 @@ public function eventDetail($slug) return view('pages.event.event_detail', compact('page_title', 'page_description', 'event')); } + + public function kategori($slug) + { + // Temukan kategori berdasarkan slug + $kategori = \App\Models\ArtikelKategori::where('slug', $slug)->firstOrFail(); + + // Ambil semua artikel yang termasuk dalam kategori tersebut + $berita_kategori = Artikel::with('kategori') + ->where('id_kategori', $kategori->id_kategori) + ->where('status', '1') + ->latest() + ->paginate(10); + + return view('pages.berita.kategori', [ + 'artikel' => $berita_kategori, + 'kategori' => $kategori, + ]); + } } diff --git a/app/Http/Controllers/FrontEndController.php b/app/Http/Controllers/FrontEndController.php index 94fc40525..19f747216 100644 --- a/app/Http/Controllers/FrontEndController.php +++ b/app/Http/Controllers/FrontEndController.php @@ -35,6 +35,7 @@ use App\Models\Slide; use App\Models\Navigation; use App\Models\MediaSosial; +use App\Models\NavMenu; use App\Models\SinergiProgram; use Illuminate\Support\Facades\View; @@ -49,6 +50,7 @@ public function __construct() 'events' => Event::getOpenEvents(), 'medsos' => MediaSosial::where('status', 1)->get(), 'navigations' => Navigation::with('childrens')->whereNull('parent_id')->where('status', 1)->orderBy('order', 'asc')->get(), + 'navmenus' => NavMenu::with('children')->whereNull('parent_id')->where('is_show', 1)->orderBy('order', 'asc')->get(), 'sinergi' => SinergiProgram::where('status', 1)->orderBy('urutan', 'asc')->get(), 'slides' => Slide::orderBy('created_at', 'DESC')->get(), ]); diff --git a/app/Http/Controllers/Informasi/ArtikelController.php b/app/Http/Controllers/Informasi/ArtikelController.php index 602ed3508..4bbc85dad 100644 --- a/app/Http/Controllers/Informasi/ArtikelController.php +++ b/app/Http/Controllers/Informasi/ArtikelController.php @@ -31,27 +31,35 @@ namespace App\Http\Controllers\Informasi; -use App\Http\Controllers\Controller; -use App\Http\Requests\ArtikelRequest; use App\Models\Artikel; +use App\Models\ArtikelKategori; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Storage; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Controllers\Controller; +use App\Http\Requests\ArtikelRequest; +use Illuminate\Support\Facades\Storage; class ArtikelController extends Controller { + use HandlesFileUpload; + public function index() { $page_title = 'Artikel'; $page_description = 'Daftar Artikel'; - return view('informasi.artikel.index', compact('page_title', 'page_description')); + $kategori = \App\Models\ArtikelKategori::get(); + + return view('informasi.artikel.index', compact('page_title', 'page_description','kategori')); } public function getDataArtikel(Request $request) { if ($request->ajax()) { - return DataTables::of(Artikel::all()) + // Mengambil data artikel beserta kategori + $data = Artikel::with('kategori')->get(); + return DataTables::of($data) ->addIndexColumn() ->addColumn('aksi', function ($row) { $data['show_web'] = route('berita.detail', $row->slug); @@ -63,6 +71,10 @@ public function getDataArtikel(Request $request) return view('forms.aksi', $data); }) + ->addColumn('kategori', function ($row) { + // Cek apakah artikel memiliki kategori + return $row->kategori ? $row->kategori->nama_kategori : '-'; + }) ->editColumn('status', function ($row) { if ($row->status == 0) { return 'Tidak Aktif'; @@ -83,19 +95,16 @@ public function create() $page_title = 'Artikel'; $page_description = 'Tambah Artikel'; - return view('informasi.artikel.create', compact('page_title', 'page_description')); + $kategori = ArtikelKategori::where('status', 'Ya')->pluck('nama_kategori', 'id_kategori'); // Mengambil nama kategori dan ID + + return view('informasi.artikel.create', compact('page_title', 'page_description', 'kategori')); } public function store(ArtikelRequest $request) { try { $input = $request->all(); - if ($request->hasFile('gambar')) { - $file = $request->file('gambar'); - $path = Storage::putFile('public/artikel', $file); - - $input['gambar'] = substr($path, 15); - } + $this->handleFileUpload($request, $input, 'gambar', 'artikel', false); Artikel::create($input); } catch (\Exception $e) { @@ -112,22 +121,16 @@ public function edit(Artikel $artikel) $page_title = 'Artikel'; $page_description = 'Ubah Artikel'; - return view('informasi.artikel.edit', compact('artikel', 'page_title', 'page_description')); + $kategori = ArtikelKategori::where('status', 'Ya')->pluck('nama_kategori', 'id_kategori'); // Mengambil nama kategori dan ID + + return view('informasi.artikel.edit', compact('artikel', 'page_title', 'page_description', 'kategori')); } public function update(ArtikelRequest $request, Artikel $artikel) { try { $input = $request->all(); - - if ($request->hasFile('gambar')) { - $file = $request->file('gambar'); - $path = Storage::putFile('public/artikel', $file); - - Storage::delete('public/artikel/'.$artikel->getRawOriginal('gambar')); - - $input['gambar'] = substr($path, 15); - } + $this->handleFileUpload($request, $input, 'gambar', 'artikel', false); $artikel->update($input); } catch (\Exception $e) { @@ -142,9 +145,7 @@ public function update(ArtikelRequest $request, Artikel $artikel) public function destroy(Artikel $artikel) { try { - if ($artikel->delete()) { - Storage::delete('public/artikel/'.$artikel->getRawOriginal('gambar')); - } + $artikel->delete(); } catch (\Exception $e) { report($e); diff --git a/app/Http/Controllers/Informasi/ArtikelKategoriController.php b/app/Http/Controllers/Informasi/ArtikelKategoriController.php new file mode 100644 index 000000000..b950ac3bd --- /dev/null +++ b/app/Http/Controllers/Informasi/ArtikelKategoriController.php @@ -0,0 +1,172 @@ +page_title; + $page_description = 'Daftar Kategori'; + + return view('informasi.artikel_kategori.index', compact('page_title', 'page_description')); + } + + /* public function getDataKategori(Request $request) + { + if ($request->ajax()) { + $data = ArtikelKategori::get(); + + return DataTables::of($data) + ->addColumn('aksi', function ($row) { + if (!auth()->guest()) { + $data['edit_url'] = route('informasi.artikel-kategori.edit', $row->id_kategori); + $data['delete_url'] = route('informasi.artikel-kategori.destroy', $row->id_kategori); + } + + return view('forms.aksi', $data); + }) + ->rawColumns(['aksi']) //merender content column dalam bentuk html + ->make(true); + } + } */ + public function getDataKategori(Request $request) + { + if ($request->ajax()) { + // Ambil status dari request + $status = $request->input('status'); + + // Buat query dasar + $query = ArtikelKategori::query(); + + // Jika status bukan 'All', tambahkan filter berdasarkan status + if ($status && $status !== 'All') { + $query->where('status', $status); + } + + $data = $query->get(); + + return DataTables::of($data) + ->addColumn('aksi', function ($row) { + if (!auth()->guest()) { + $data['edit_url'] = route('informasi.artikel-kategori.edit', $row->id_kategori); + $data['delete_url'] = route('informasi.artikel-kategori.destroy', $row->id_kategori); + } + return view('forms.aksi', $data); + }) + ->editColumn('status', function ($row) { + if ($row->status == 'Ya') { + return 'Aktif'; + } else { + return 'Tidak'; + } + }) + ->rawColumns(['aksi', 'status']) + ->make(true); + } + } + + + /** + * Show the form for creating a new resource. + * + * @return \Illuminate\Http\Response + */ + public function create() + { + $page_title = $this->page_title; + $page_description = 'Tambah ' . $this->page_title; + + return view('informasi.artikel_kategori.create', compact('page_title', 'page_description')); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $request->validate([ + 'nama_kategori' => "required|max:191", + 'status' => 'required', + ]); + + try { + ArtikelKategori::create($request->all()); + } catch (\Exception $e) { + report($e); + + return back()->withInput()->with('error', 'Kategori gagal ditambah!'); + } + + return redirect()->route('informasi.artikel-kategori.index')->with('success', 'Kategori berhasil ditambah!'); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $kategori = ArtikelKategori::findOrFail($id); + $page_title = $this->page_title; + $page_description = 'Ubah '. $this->page_title; + + return view('informasi.artikel_kategori.edit', compact('page_title', 'page_description', 'kategori')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + try { + ArtikelKategori::findOrFail($id)->update($request->all()); + } catch (\Exception $e) { + report($e); + + return back()->withInput()->with('error', 'Kategori gagal diubah!'); + } + + return redirect()->route('informasi.artikel-kategori.index')->with('success', 'Kategori berhasil diubah!'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + try { + ArtikelKategori::findOrFail($id)->delete(); + } catch (\Exception $e) { + report($e); + + return redirect()->route('informasi.artikel-kategori.index')->with('error', 'Kategori gagal dihapus!'); + } + + return redirect()->route('informasi.artikel-kategori.index')->with('success', 'Kategori berhasil dihapus!'); + } +} diff --git a/app/Http/Controllers/Informasi/FormDokumenController.php b/app/Http/Controllers/Informasi/FormDokumenController.php index 59bd14bd6..e641ab63e 100644 --- a/app/Http/Controllers/Informasi/FormDokumenController.php +++ b/app/Http/Controllers/Informasi/FormDokumenController.php @@ -31,13 +31,16 @@ namespace App\Http\Controllers\Informasi; -use App\Http\Controllers\Controller; -use App\Http\Requests\DokumenRequest; use App\Models\FormDokumen; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Controllers\Controller; +use App\Http\Requests\DokumenRequest; class FormDokumenController extends Controller { + use HandlesFileUpload; + public function index() { $page_title = 'Dokumen'; @@ -73,15 +76,7 @@ public function store(DokumenRequest $request) { try { $input = $request->input(); - - if ($request->hasFile('file_dokumen')) { - $file = $request->file('file_dokumen'); - $fileName = $file->getClientOriginalName(); - $path = 'storage/form_dokumen/'; - $file->move($path, $fileName); - - $input['file_dokumen'] = $path.$fileName; - } + $this->handleFileUpload($request, $input, 'file_dokumen', 'form_dokumen'); FormDokumen::create($input); } catch (\Exception $e) { @@ -105,16 +100,7 @@ public function update(DokumenRequest $request, FormDokumen $dokumen) { try { $input = $request->all(); - - if ($request->hasFile('file_dokumen')) { - $file = $request->file('file_dokumen'); - $fileName = $file->getClientOriginalName(); - $path = 'storage/form_dokumen/'; - $file->move($path, $fileName); - unlink(base_path('public/'.$dokumen->file_dokumen)); - - $input['file_dokumen'] = $path.$fileName; - } + $this->handleFileUpload($request, $input, 'file_dokumen', 'form_dokumen'); $dokumen->update($input); } catch (\Exception $e) { @@ -129,9 +115,7 @@ public function update(DokumenRequest $request, FormDokumen $dokumen) public function destroy(FormDokumen $dokumen) { try { - if ($dokumen->delete()) { - unlink(base_path('public/'.$dokumen->file_dokumen)); - } + $dokumen->delete(); } catch (\Exception $e) { report($e); diff --git a/app/Http/Controllers/Informasi/MediaSosialController.php b/app/Http/Controllers/Informasi/MediaSosialController.php index 30af4b0fb..78b13eb16 100644 --- a/app/Http/Controllers/Informasi/MediaSosialController.php +++ b/app/Http/Controllers/Informasi/MediaSosialController.php @@ -31,14 +31,17 @@ namespace App\Http\Controllers\Informasi; -use App\Http\Controllers\Controller; -use App\Http\Requests\MediaSosialRequest; use App\Models\MediaSosial; use Illuminate\Http\Request; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Controllers\Controller; +use App\Http\Requests\MediaSosialRequest; class MediaSosialController extends Controller { + use HandlesFileUpload; + /** * Display a listing of the resource. * @@ -100,14 +103,7 @@ public function store(MediaSosialRequest $request) { try { $input = $request->validated(); - if ($request->hasFile('logo')) { - $file = $request->file('logo'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().rand(100, 999).'_'.$original_name; - $path = 'storage/medsos/'; - $file->move($path, $file_name); - $input['logo'] = $path.$file_name; - } + $this->handleFileUpload($request, $input, 'logo', 'medsos'); MediaSosial::create($input); } catch (\Exception $e) { @@ -119,15 +115,8 @@ public function store(MediaSosialRequest $request) return redirect()->route('informasi.media-sosial.index')->with('success', 'Media Sosial berhasil disimpan!'); } - /** - * Show the form for editing the specified resource. - * - * @param int $id - * @return Response - */ - public function edit($id) + public function edit(MediaSosial $medsos) { - $medsos = MediaSosial::findOrFail($id); $page_title = 'Media Sosial'; $page_description = 'Ubah Media Sosial : '.$medsos->nama; @@ -146,16 +135,7 @@ public function update(MediaSosialRequest $request, $id) try { $input = $request->validated(); - - if ($request->hasFile('logo')) { - $file = $request->file('logo'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().rand(100, 999).'_'.$original_name; - $path = 'storage/medsos/'; - $file->move($path, $file_name); - unlink(base_path('public/'.$medsos->logo)); - $input['logo'] = $path.$file_name; - } + $this->handleFileUpload($request, $input, 'logo', 'medsos'); $medsos->update($input); } catch (\Exception $e) { @@ -167,19 +147,10 @@ public function update(MediaSosialRequest $request, $id) return redirect()->route('informasi.media-sosial.index')->with('success', 'Media Sosial berhasil diubah!'); } - /** - * Remove the specified resource from storage. - * - * @param int $id - * @return Response - */ - public function destroy($id) + public function destroy(MediaSosial $medsos) { try { - $medsos = MediaSosial::findOrFail($id); - if ($medsos->delete()) { - unlink(base_path('public/'.$medsos->logo)); - } + $medsos->delete(); } catch (\Exception $e) { report($e); diff --git a/app/Http/Controllers/Informasi/ProsedurController.php b/app/Http/Controllers/Informasi/ProsedurController.php index de9f2f8d7..d850bbcb3 100644 --- a/app/Http/Controllers/Informasi/ProsedurController.php +++ b/app/Http/Controllers/Informasi/ProsedurController.php @@ -31,13 +31,16 @@ namespace App\Http\Controllers\Informasi; -use App\Http\Controllers\Controller; -use App\Http\Requests\ProsedurRequest; use App\Models\Prosedur; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Controllers\Controller; +use App\Http\Requests\ProsedurRequest; class ProsedurController extends Controller { + use HandlesFileUpload; + public function index() { $page_title = 'Prosedur'; @@ -78,18 +81,10 @@ public function store(ProsedurRequest $request) { try { $input = $request->all(); + $input['slug'] = str_slug($request->input('judul_prosedur')); + $this->handleFileUpload($request, $input, 'file_prosedur', 'regulasi'); - if ($request->hasFile('file_prosedur')) { - $file = $request->file('file_prosedur'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().rand(100, 999).'_'.$original_name; - $path = 'storage/regulasi/'; - $file->move($path, $file_name); - $input['slug'] = str_slug($request->input('judul_prosedur')); - $input['file_prosedur'] = $path.$file_name; - $input['mime_type'] = $file->getClientOriginalExtension(); - } - + $input['mime_type'] = $request->file('file_prosedur')->getClientMimeType(); Prosedur::create($input); } catch (\Exception $e) { report($e); @@ -120,20 +115,9 @@ public function update(Prosedur $prosedur, ProsedurRequest $request) { try { $input = $request->all(); + $this->handleFileUpload($request, $input, 'file_prosedur', 'regulasi'); - if ($request->hasFile('file_prosedur')) { - $file = $request->file('file_prosedur'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().rand(100, 999).'_'.$original_name; - $path = 'storage/regulasi/'; - $file->move($path, $file_name); - unlink(base_path('public/'.$prosedur->file_prosedur)); - - $input['file_prosedur'] = $path.$file_name; - $input['mime_type'] = $file->getClientOriginalExtension(); - } - $input['slug'] = str_slug($request->input('judul_prosedur')); - + $input['mime_type'] = $request->file('file_prosedur')->getClientMimeType(); $prosedur->update($input); } catch (\Exception $e) { report($e); @@ -147,9 +131,7 @@ public function update(Prosedur $prosedur, ProsedurRequest $request) public function destroy(Prosedur $prosedur) { try { - if ($prosedur->delete()) { - unlink(base_path('public/'.$prosedur->file_prosedur)); - } + $prosedur->delete(); } catch (\Exception $e) { report($e); diff --git a/app/Http/Controllers/Informasi/RegulasiController.php b/app/Http/Controllers/Informasi/RegulasiController.php index a2891ec53..d01dc9576 100644 --- a/app/Http/Controllers/Informasi/RegulasiController.php +++ b/app/Http/Controllers/Informasi/RegulasiController.php @@ -32,12 +32,15 @@ namespace App\Http\Controllers\Informasi; use App\Models\Regulasi; +use App\Traits\HandlesFileUpload; use App\Http\Controllers\Controller; use App\Http\Requests\RegulasiRequest; use Yajra\DataTables\Facades\DataTables; class RegulasiController extends Controller { + use HandlesFileUpload; + public function index() { $page_title = 'Regulasi'; @@ -76,17 +79,9 @@ public function store(RegulasiRequest $request) try { $input = $request->input(); $input['profil_id'] = $this->profil->id; + $this->handleFileUpload($request, $input, 'file_regulasi', 'regulasi'); - if ($request->hasFile('file_regulasi')) { - $lampiran1 = $request->file('file_regulasi'); - $fileName1 = $lampiran1->getClientOriginalName(); - $path = 'storage/regulasi/'; - $request->file('file_regulasi')->move($path, $fileName1); - - $input['file_regulasi'] = $path.$fileName1; - $input['mime_type'] = $lampiran1->getClientOriginalExtension(); - } - + $input['mime_type'] = $request->file('file_regulasi')->getMimeType(); Regulasi::create($input); } catch (\Exception $e) { report($e); @@ -118,17 +113,9 @@ public function update(RegulasiRequest $request, Regulasi $regulasi) try { $input = $request->input(); $input['profil_id'] = $this->profil->id; + $this->handleFileUpload($request, $input, 'file_regulasi', 'regulasi'); - if ($request->hasFile('file_regulasi')) { - $lampiran1 = $request->file('file_regulasi'); - $fileName1 = $lampiran1->getClientOriginalName(); - $path = 'storage/regulasi/'; - $lampiran1->move($path, $fileName1); - unlink(base_path('public/'.$regulasi->file_regulasi)); - - $input['file_regulasi'] = $path.$fileName1; - $input['mime_type'] = $lampiran1->getClientOriginalExtension(); - } + $input['mime_type'] = $request->file('file_regulasi')->getMimeType(); $regulasi->update($input); } catch (\Exception $e) { report($e); @@ -142,9 +129,7 @@ public function update(RegulasiRequest $request, Regulasi $regulasi) public function destroy(Regulasi $regulasi) { try { - if ($regulasi->delete()) { - unlink(base_path('public/'.$regulasi->file_regulasi)); - } + $regulasi->delete(); } catch (\Exception $e) { report($e); diff --git a/app/Http/Controllers/Informasi/SinergiProgramController.php b/app/Http/Controllers/Informasi/SinergiProgramController.php index 9a104ca45..cf62ebbee 100644 --- a/app/Http/Controllers/Informasi/SinergiProgramController.php +++ b/app/Http/Controllers/Informasi/SinergiProgramController.php @@ -31,14 +31,17 @@ namespace App\Http\Controllers\Informasi; -use App\Http\Controllers\Controller; -use App\Http\Requests\SinergiProgramRequest; -use App\Models\SinergiProgram; use Illuminate\Http\Request; +use App\Models\SinergiProgram; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Controllers\Controller; +use App\Http\Requests\SinergiProgramRequest; class SinergiProgramController extends Controller { + use HandlesFileUpload; + /** * Display a listing of the resource. * @@ -74,7 +77,7 @@ public function getDataSinergiProgram(Request $request) } }) ->editColumn('gambar', function ($row) { - return ''; + return ''; }) ->rawColumns(['status']) ->escapeColumns([]) @@ -105,14 +108,7 @@ public function store(SinergiProgramRequest $request) { try { $input = $request->validated(); - if ($request->hasFile('gambar')) { - $file = $request->file('gambar'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().rand(100, 999).'_'.$original_name; - $path = 'storage/sinergi/'; - $file->move($path, $file_name); - $input['gambar'] = $path.$file_name; - } + $this->handleFileUpload($request, $input, 'gambar', 'sinergi/'); SinergiProgram::create($input); } catch (\Exception $e) { report($e); @@ -123,43 +119,19 @@ public function store(SinergiProgramRequest $request) return redirect()->route('informasi.sinergi-program.index')->with('success', 'Sinergi Program berhasil disimpan!'); } - /** - * Show the form for editing the specified resource. - * - * @param int $id - * @return Response - */ - public function edit($id) + public function edit(SinergiProgram $sinergi) { - $sinergi = SinergiProgram::findOrFail($id); $page_title = 'Sinergi Program'; - $page_description = 'Ubah Sinergi Program : '.$sinergi->nama; + $page_description = 'Ubah Sinergi Program : ' . $sinergi->nama; return view('informasi.sinergi_program.edit', compact('page_title', 'page_description', 'sinergi')); } - /** - * Update the specified resource in storage. - * - * @param int $id - * @return Response - */ - public function update(SinergiProgramRequest $request, $id) + public function update(SinergiProgram $sinergi, SinergiProgramRequest $request) { - $sinergi = SinergiProgram::findOrFail($id); - try { $input = $request->validated(); - - if ($request->hasFile('gambar')) { - $file = $request->file('gambar'); - $original_name = strtolower(trim($file->getClientOriginalName())); - $file_name = time().rand(100, 999).'_'.$original_name; - $path = 'storage/sinergi/'; - $file->move($path, $file_name); - unlink(base_path('public/'.$sinergi->gambar)); - $input['gambar'] = $path.$file_name; - } + $this->handleFileUpload($request, $input, 'gambar', 'sinergi/'); $sinergi->update($input); } catch (\Exception $e) { @@ -177,13 +149,10 @@ public function update(SinergiProgramRequest $request, $id) * @param int $id * @return Response */ - public function destroy($id) + public function destroy(SinergiProgram $sinergi) { try { - $sinergi = SinergiProgram::findOrFail($id); - if ($sinergi->delete()) { - unlink(base_path('public/'.$sinergi->gambar)); - } + $sinergi->delete(); } catch (\Exception $e) { report($e); @@ -193,16 +162,9 @@ public function destroy($id) return redirect()->route('informasi.sinergi-program.index')->with('success', 'Sinergi Program berhasil dihapus!'); } - /** - * Update urutan daftar sinergi program. - * - * @param int $id, $urutan - * @return Response - */ - public function urut($id, $urutan) + public function urut(SinergiProgram $sinergi, $urutan) { try { - $sinergi = SinergiProgram::findOrFail($id); if ($urutan == -1 && SinergiProgram::min('urutan') == $sinergi->urutan) { return redirect()->route('informasi.sinergi-program.index')->with('error', 'Urutan Sinergi Program sudah berada diurutan pertama!'); } elseif ($urutan == 1 && SinergiProgram::max('urutan') == $sinergi->urutan) { diff --git a/app/Http/Controllers/Kerjasama/PendaftaranKerjasamaController.php b/app/Http/Controllers/Kerjasama/PendaftaranKerjasamaController.php new file mode 100644 index 000000000..d48786773 --- /dev/null +++ b/app/Http/Controllers/Kerjasama/PendaftaranKerjasamaController.php @@ -0,0 +1,34 @@ +profil['nama_kecamatan']; + $data['logo'] = $this->profil['file_logo']; + $data['random'] = substr(str_shuffle('0123456789'), 0, 4); + $data['hari'] = $date->format('d'); + $data['nama_hari'] = ucwords(hari($date->getTimestamp())); + $data['nama_tanggal'] = ucwords(to_word($date->format('d'))); + $data['bulan'] = $date->format('m'); + $data['nama_bulan'] = ucwords(getBulan($date->format('m'))); + $data['tahun'] = $date->format('Y'); + $data['nama_tahun'] = ucwords(to_word($date->format('Y'))); + $data['nama_camat'] = strtoupper($this->profil['nama_camat']); + $data['alamat'] = $this->profil['alamat']; + $data['stempel'] = asset('img/layanan/stempel.png'); + $data['layanan_logo'] = asset('img/layanan/logo.png'); + + Carbon::setLocale('id'); + $data['tanggal'] = $date->translatedFormat('l, d F Y'); + + return view('template.dokumen_kerjasama', $data); + } +} diff --git a/app/Http/Controllers/Setting/NavMenuController.php b/app/Http/Controllers/Setting/NavMenuController.php new file mode 100644 index 000000000..2c2bd5e50 --- /dev/null +++ b/app/Http/Controllers/Setting/NavMenuController.php @@ -0,0 +1,105 @@ +whereNull('parent_id') + ->with(['children' => function ($q) { + $q->selectRaw("id, parent_id , name as text, url as href, target, is_show,type,'fa fa-list' as icon"); + }]) + ->orderBy('order') + ->get() + ->toArray(); + + $nav_menus = json_encode($menus); + + $sourceItem = [ + 'Halaman' => Artikel::cursor()->pluck('judul', 'link')->toArray(), + 'Kategori' => Kategori::cursor()->pluck('nama', 'link')->toArray(), + ]; + + return view('setting.nav_menu.index', compact('page_title', 'page_description', 'nav_menus', 'sourceItem')); + } + + + public function store(Request $request) + { + NavMenu::whereNotNull('id')->delete(); + try { + // hapus data lama lalu buat lagi + $json = json_decode($request->json_menu, 1); + + $this->loopTree($json); + + return redirect()->route('setting.navmenu.index')->with('success', 'Menu berhasil disimpan!'); + } catch (\Throwable $th) { + throw $th; + } + } + + private function loopTree(array $elements, $parentId = null) + { + $sequence = 1; + foreach ($elements as $element) { + $input = [ + 'name' => $element['text'], + 'url' => $element['href'], + 'target' => $element['target'], + 'type' => $element['type'], + 'is_show' => isset($element['is_show']) ? $element['is_show'] : 1, + 'order' => $sequence, + 'parent_id' => $parentId, + ]; + + $model = NavMenu::create($input); + + // Jika ada children, rekursi untuk menyimpan sub-menu + if (isset($element['children'])) { + $this->loopTree($element['children'], $model->id); + } + $sequence++; + } + } +} diff --git a/app/Http/Controllers/User/UserController.php b/app/Http/Controllers/User/UserController.php index 3376bfc0e..1cdee03ae 100644 --- a/app/Http/Controllers/User/UserController.php +++ b/app/Http/Controllers/User/UserController.php @@ -31,18 +31,21 @@ namespace App\Http\Controllers\User; -use App\Http\Controllers\Controller; -use App\Http\Requests\UserRequest; -use App\Http\Requests\UserUpdateRequest; -use App\Models\Pengurus; use App\Models\User; +use App\Models\Pengurus; use Illuminate\Http\Request; use Illuminate\Http\Response; -use Spatie\Permission\Models\Role; use Yajra\DataTables\DataTables; +use App\Traits\HandlesFileUpload; +use App\Http\Requests\UserRequest; +use Spatie\Permission\Models\Role; +use App\Http\Controllers\Controller; +use App\Http\Requests\UserUpdateRequest; class UserController extends Controller { + use HandlesFileUpload; + /** * Display a listing of the resource. * @@ -82,11 +85,9 @@ public function store(UserRequest $request) try { $status = ! empty($request->status) ? 1 : 1; $request->merge(['status' => $status]); - $user = User::create($request->validated()); - if ($request->hasFile('image')) { - $user->uploadImage($request->image); - } - + $input = $request->validated(); + $this->handleFileUpload($request, $input, 'image', 'user', false); + $user = User::create($input); $roles = $request->input('role') ? $request->input('role') : []; $user->assignRole($roles); @@ -138,13 +139,10 @@ public function edit($id) public function update(UserRequest $request, $id) { try { + $input = $request->validated(); $user = User::findOrFail($id); - - $user->update($request->validated()); - if ($request->hasFile('image')) { - $user->uploadImage($request->image); - } - + $this->handleFileUpload($request, $input, 'image', 'user', false); + $user->update($input); if (! empty($request->role)) { $roles = $request->input('role') ? $request->input('role') : []; $user->syncRoles($roles); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 3181fa323..bdf2323d8 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -66,6 +66,7 @@ class Kernel extends HttpKernel \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \App\Http\Middleware\SecurityHeaders::class, + \App\Http\Middleware\GlobalShareMiddleware::class, ], 'api' => [ diff --git a/app/Http/Livewire/Components/Alert.php b/app/Http/Livewire/Components/Alert.php new file mode 100644 index 000000000..104a00f21 --- /dev/null +++ b/app/Http/Livewire/Components/Alert.php @@ -0,0 +1,24 @@ +message = $message; + $this->alertType = $type; + } + + public function render() + { + return view('livewire.components.alert'); + } +} diff --git a/app/Http/Livewire/Kerjasama/PendaftaranKerjasama.php b/app/Http/Livewire/Kerjasama/PendaftaranKerjasama.php new file mode 100644 index 000000000..bfc5a8099 --- /dev/null +++ b/app/Http/Livewire/Kerjasama/PendaftaranKerjasama.php @@ -0,0 +1,147 @@ +kecamatan_id = view()->shared('profil')->kecamatan_id; + + $this->domain = config('app.url'); + + // Ambil settings sebagai objek + $setting = (object) SettingAplikasi::pluck('value', 'key')->toArray(); + + // Periksa apakah 'layanan_opendesa_token' tidak ada + if (!property_exists($setting, 'layanan_opendesa_token')) { + DB::table('das_setting')->insert([ + 'key' => 'layanan_opendesa_token', + 'value' => 0, + 'type' => 'input', + 'description' => 'Token pelanggan Layanan OpenDESA', + 'kategori' => 'pelanggan', + 'option' => '{}', + ]); + } + } + + public function render() + { + $apiService = new ApiService(); + $response = $apiService->terdaftar($this->kecamatan_id); + + if ($response['success']) { + + $this->status_registrasi_id = $response['data']['data']['status_langgaan_id']; + $this->pesan_terdaftar = $response['data']['message']; + + $this->response = $response['data']['data']; + } else { + + $apiService = new ApiService(); + $res_form = $apiService->getFormRegister(); + + if ($res_form['success']) { + $this->response = $res_form['data']['data']; + $this->status_langganan = $this->response['status_langganan']; + } + } + + return view('livewire.kerjasama.pendaftaran_kerjasama.index'); + } + + public function rules() + { + return [ + 'email' => 'required|email', + 'domain' => 'required', + 'kontak_nama' => 'required|min:5', + 'kontak_no_hp' => 'required', + 'kecamatan_id' => 'required', + 'permohonan' => 'required:mimes:pdf|max:1024', + ]; + } + + public function updated($propertyName) + { + $this->validateOnly($propertyName); + } + + public function register() + { + + $this->validate(); + + try { + + $ext = $this->permohonan->guessExtension(); + $name = "dokumen-permohonan.{$ext}"; + $path = $this->permohonan->storeAs('public/kecamatan/upload/dokumen', $name); + + $data = [ + 'email' => $this->email, + 'domain' => $this->domain, + 'kontak_nama' => $this->kontak_nama, + 'desa' => view()->shared('profil')->nama_kecamatan, + 'kontak_no_hp' => $this->kontak_no_hp, + 'kecamatan_id' => $this->kecamatan_id, + 'status_langganan_id' => $this->status_registrasi_id, + 'permohonan' => $path + ]; + + $apiService = new ApiService(); + $response = $apiService->register($data); + + if ($response['success']) { + + SettingAplikasi::where('key', 'layanan_opendesa_token')->update([ + 'value' => $response['data']['data']['token'] + ]); + + // kalo sudah berhasil panggil service daftar + $apiService = new ApiService(); + $res_terdaftar = $apiService->terdaftar($this->kecamatan_id); + if ($res_terdaftar['success']) { + $this->response = $res_terdaftar; + $this->emit('triggerAlert', $response['data']['message'], 'success'); + } else { + $this->emit('triggerAlert', $response['message'], 'success'); + } + } else { + $this->emit('triggerAlert', $response['error']['message'], 'danger'); + } + } catch (\Exception $e) { + $this->emit('triggerAlert', $e->getMessage(), 'danger'); + } + } +} diff --git a/app/Http/Middleware/GlobalShareMiddleware.php b/app/Http/Middleware/GlobalShareMiddleware.php new file mode 100644 index 000000000..cd743aba5 --- /dev/null +++ b/app/Http/Middleware/GlobalShareMiddleware.php @@ -0,0 +1,173 @@ +profil = Profil::first(); + $this->umum = DataUmum::first(); + $this->nama_camat = Pengurus::status()->camat()->first(); + + // Pemeriksaan akun pengurus untuk alur pemeriksaan surat + $this->akun_camat = Pengurus::status()->akunCamat()->first(); + $this->akun_sekretaris = Pengurus::status()->akunSekretaris()->first(); + + if (! $this->akun_camat) { + SettingAplikasi::where('key', 'tte')->update(['value' => 0]); + SettingAplikasi::where('key', 'pemeriksaan_camat')->update(['value' => 0]); + } + + if (! $this->akun_sekretaris) { + SettingAplikasi::where('key', 'pemeriksaan_sekretaris')->update(['value' => 0]); + } + + // Tambahan global variabel di luar setting aplikasi + $this->sebutan_tambahan = [ + 'sebutan_camat' => Jabatan::where('jenis', JenisJabatan::Camat)->first()->nama, + 'sebutan_sekretaris' => Jabatan::where('jenis', JenisJabatan::Sekretaris)->first()->nama, + ]; + + // Global variabel setting aplikasi + $this->settings = SettingAplikasi::pluck('value', 'key'); + $this->settings = $this->settings->merge($this->sebutan_tambahan); + View::share('settings', $this->settings); + + if (in_array($this->profil->provinsi_id, [91, 92])) { + $this->sebutan_wilayah = 'Distrik'; + $this->sebutan_kepala_wilayah = 'Kepala Distrik'; + } else { + $this->sebutan_wilayah = 'Kecamatan'; + $this->sebutan_kepala_wilayah = 'Camat'; + } + + if ($this->settings['tte']) { + SettingAplikasi::where('key', 'pemeriksaan_camat')->update(['value' => 1]); + } + + $this->kirimTrack(); + + // TODO : Gunakan untuk semua pengaturan jika sudah tersedia + $this->browser_title = SettingAplikasi::where('key', 'judul_aplikasi')->first()->value ?? ucwords($this->sebutan_wilayah . ' ' . $this->profil->nama_kecamatan); + + $navdesa = DataDesa::all(); + $navpotensi = TipePotensi::orderby('nama_kategori', 'ASC')->get(); + $pengurus = Pengurus::status()->get(); + + + View::share([ + 'profil' => $this->profil, + 'sebutan_wilayah' => $this->sebutan_wilayah, + 'sebutan_kepala_wilayah' => $this->sebutan_kepala_wilayah, + 'browser_title' => $this->browser_title, + 'navdesa' => $navdesa, + 'navpotensi' => $navpotensi, + 'camat' => $this->nama_camat, + 'pengurus' => $pengurus->sortBy('jabatan.jenis'), + ]); + } + + return $next($request); + } + + protected function kirimTrack() + { + if (config('app.demo') == true) { // jika posisi demo, matikan tracking + return; + } + + if (cache()->get('track') != null && cache()->get('track') == date('Y m d')) { + return; + } + + $host_pantau = config('app.host_pantau'); + $data = [ + 'url' => url('/'), + 'versi' => config('app.version'), + 'jml_desa' => DataDesa::count(), + 'desa' => json_encode(DataDesa::select(['desa_id', 'nama', 'sebutan_desa', 'path', 'website'])->get()), + 'jumlahdesa_sinkronisasi' => DataDesa::count(), + 'jumlah_penduduk' => Penduduk::where('status_dasar', 1)->count(), + 'jumlah_keluarga' => Keluarga::count(), + 'peta_wilayah' => $this->umum->path ?? '[[[[]]]]', + 'batas_wilayah' => json_encode([ + 'bts_wil_utara' => $this->umum->bts_wil_utara, + 'bts_wil_timur' => $this->umum->bts_wil_timur, + 'bts_wil_selatan' => $this->umum->bts_wil_selatan, + 'bts_wil_barat' => $this->umum->bts_wil_barat, + ]), + 'sebutan_wilayah' => $this->sebutan_wilayah, + 'alamat' => $this->profil->alamat, + 'jumlah_bantuan' => Program::count(), + 'kode_kecamatan' => $this->profil->kecamatan_id, + 'kode_kabupaten' => $this->profil->kabupaten_id, + 'kode_provinsi' => $this->profil->provinsi_id, + 'nama_kecamatan' => $this->profil->nama_kecamatan, + 'nama_kabupaten' => $this->profil->nama_kabupaten, + 'nama_provinsi' => $this->profil->nama_provinsi, + 'nama_camat' => $this->nama_camat, + 'lat' => $this->umum->lat, + 'lng' => $this->umum->lng, + ]; + + try { + $response = Http::withHeaders([ + 'token' => config('app.token_pantau'), + ])->post($host_pantau . 'track/opendk?token=' . config('app.token_pantau'), $data); + cache()->put('track', date('Y m d'), 60 * 60 * 24); + + return; + } catch (Exception $e) { + Log::notice($e); + + return; + } + } +} diff --git a/app/Http/Requests/ArtikelRequest.php b/app/Http/Requests/ArtikelRequest.php index 177d05e9c..09c110436 100644 --- a/app/Http/Requests/ArtikelRequest.php +++ b/app/Http/Requests/ArtikelRequest.php @@ -55,6 +55,7 @@ public function rules() return [ 'judul' => 'required|string|max:191', 'isi' => 'required', + //'kategori_id' => 'required', 'status' => 'required', 'gambar' => 'nullable|image|mimes:jpg,jpeg,png|max:1024|valid_file', ]; diff --git a/app/Models/Artikel.php b/app/Models/Artikel.php index ace1f5343..7c3db5f08 100644 --- a/app/Models/Artikel.php +++ b/app/Models/Artikel.php @@ -31,25 +31,40 @@ namespace App\Models; +use App\Traits\HandlesResourceDeletion; +use Illuminate\Support\Str; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Storage; use Cviebrock\EloquentSluggable\Sluggable; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsTo; class Artikel extends Model { use Sluggable; use HasFactory; + use HandlesResourceDeletion; protected $table = 'das_artikel'; protected $fillable = [ + 'id_kategori', 'judul', 'gambar', + 'kategori_id', 'isi', 'status', ]; + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'gambar', + ]; + /** * Return the sluggable configuration array for this model. */ @@ -64,7 +79,7 @@ public function sluggable(): array public function getGambarAttribute() { - return $this->attributes['gambar'] ? Storage::url('artikel/'.$this->attributes['gambar']) : null; + return $this->attributes['gambar'] ? Storage::url('artikel/' . $this->attributes['gambar']) : null; } public function getIsiAttribute() @@ -77,9 +92,20 @@ public function scopeStatus($query, $value = 1) return $query->where('status', $value); } + // Relasi ke ArtikelKategori (Many-to-One) + public function kategori() + { + return $this->belongsTo(ArtikelKategori::class, 'id_kategori'); + + } // Relasi dengan model Comment public function comments() { return $this->hasMany(Comment::class, 'das_artikel_id')->orderBy('created_at', 'desc'); } + + public function getLinkAttribute(): string + { + return Str::replaceFirst(url('/'), '', route('berita.detail', ['slug' => $this->slug])); + } } diff --git a/app/Models/ArtikelKategori.php b/app/Models/ArtikelKategori.php new file mode 100644 index 000000000..ed8a85140 --- /dev/null +++ b/app/Models/ArtikelKategori.php @@ -0,0 +1,36 @@ + [ + 'source' => 'nama_kategori', + ], + ]; + } + + // Relasi ke Artikel (One-to-Many) + public function artikels() + { + return $this->hasMany(Artikel::class, 'id_kategori'); + } +} diff --git a/app/Models/FormDokumen.php b/app/Models/FormDokumen.php index 7ae51c276..82cef4460 100644 --- a/app/Models/FormDokumen.php +++ b/app/Models/FormDokumen.php @@ -31,14 +31,26 @@ namespace App\Models; +use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; class FormDokumen extends Model { + use HandlesResourceDeletion; + protected $table = 'das_form_dokumen'; protected $fillable = [ 'nama_dokumen', 'file_dokumen', ]; + + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'file_dokumen', + ]; } diff --git a/app/Models/Kategori.php b/app/Models/Kategori.php new file mode 100644 index 000000000..2988fe6b4 --- /dev/null +++ b/app/Models/Kategori.php @@ -0,0 +1,40 @@ + [ + 'source' => 'nama', + ], + ]; + } + + public function artikels(): HasMany + { + return $this->hasMany(Artikel::class, 'kategori_id'); + } + + public function getLinkAttribute(): string + { + return Str::replaceFirst(url('/'), '', route('berita.kategori', ['slug' => $this->slug])); + } +} diff --git a/app/Models/MediaSosial.php b/app/Models/MediaSosial.php index d89276027..c10350640 100644 --- a/app/Models/MediaSosial.php +++ b/app/Models/MediaSosial.php @@ -31,10 +31,13 @@ namespace App\Models; +use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; class MediaSosial extends Model { + use HandlesResourceDeletion; + protected $table = 'das_media_sosial'; protected $fillable = [ @@ -43,4 +46,13 @@ class MediaSosial extends Model 'nama', 'status', ]; + + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'logo', + ]; } diff --git a/app/Models/NavMenu.php b/app/Models/NavMenu.php new file mode 100644 index 000000000..b52eab2c1 --- /dev/null +++ b/app/Models/NavMenu.php @@ -0,0 +1,39 @@ + 'boolean' + ]; + + public function child(): HasMany + { + return $this->hasMany(NavMenu::class, 'parent_id', 'id'); + } + + public function children(): HasMany + { + return $this->hasMany(NavMenu::class, 'parent_id', 'id')->with(['children' => function ($q) { + return $q->selectRaw("id, parent_id , name as text, url as href, target, type, is_show,'fa fa-list' as icon"); + }]); + } +} diff --git a/app/Models/Pengurus.php b/app/Models/Pengurus.php index d013eb312..4c0539bb8 100644 --- a/app/Models/Pengurus.php +++ b/app/Models/Pengurus.php @@ -33,6 +33,7 @@ use App\Enums\Status; use App\Enums\JenisJabatan; +use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Storage; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -40,10 +41,24 @@ class Pengurus extends Model { use HasFactory; + use HandlesResourceDeletion; protected $table = 'das_pengurus'; - protected $guarded = ['id', 'created_at', 'updated_at']; + protected $guarded = [ + 'id', + 'created_at', + 'updated_at' + ]; + + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'foto', + ]; protected $with = [ 'jabatan', diff --git a/app/Models/Prosedur.php b/app/Models/Prosedur.php index 47591e9f5..d1a618d31 100644 --- a/app/Models/Prosedur.php +++ b/app/Models/Prosedur.php @@ -31,6 +31,7 @@ namespace App\Models; +use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; use Cviebrock\EloquentSluggable\Sluggable; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -39,6 +40,7 @@ class Prosedur extends Model { use HasFactory; use Sluggable; + use HandlesResourceDeletion; protected $table = 'das_prosedur'; @@ -49,6 +51,15 @@ class Prosedur extends Model 'slug', ]; + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'file_prosedur', + ]; + /** * Return the sluggable configuration array for this model. */ diff --git a/app/Models/Regulasi.php b/app/Models/Regulasi.php index 72cc63c6f..6a6c0b188 100644 --- a/app/Models/Regulasi.php +++ b/app/Models/Regulasi.php @@ -31,10 +31,13 @@ namespace App\Models; +use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; class Regulasi extends Model { + use HandlesResourceDeletion; + protected $table = 'das_regulasi'; protected $fillable = [ @@ -46,6 +49,15 @@ class Regulasi extends Model 'mime_type', ]; + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'file_regulasi', + ]; + public function tipe() { return $this->hasOne(TipeRegulasi::class, 'id', 'tipe_regulasi'); diff --git a/app/Models/SinergiProgram.php b/app/Models/SinergiProgram.php index cbbef0f8a..f551e6af0 100644 --- a/app/Models/SinergiProgram.php +++ b/app/Models/SinergiProgram.php @@ -31,10 +31,13 @@ namespace App\Models; +use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; class SinergiProgram extends Model { + use HandlesResourceDeletion; + protected $table = 'das_sinergi_program'; protected $fillable = [ @@ -45,6 +48,15 @@ class SinergiProgram extends Model 'urutan', ]; + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'gambar', + ]; + protected static function boot() { parent::boot(); diff --git a/app/Models/User.php b/app/Models/User.php index 9ab245171..0f528f95f 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -31,21 +31,23 @@ namespace App\Models; -use Illuminate\Auth\Authenticatable as AuthenticableTrait; -use Illuminate\Foundation\Auth\User as Authenticatable; -use Illuminate\Notifications\Notifiable; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Hash; -use Illuminate\Support\Facades\Storage; use Intervention\Image\Facades\Image; use Spatie\Permission\Traits\HasRoles; +use App\Traits\HandlesResourceDeletion; +use Illuminate\Support\Facades\Storage; use Tymon\JWTAuth\Contracts\JWTSubject; +use Illuminate\Notifications\Notifiable; +use Illuminate\Foundation\Auth\User as Authenticatable; +use Illuminate\Auth\Authenticatable as AuthenticableTrait; class User extends Authenticatable implements JWTSubject { use AuthenticableTrait; use HasRoles; use Notifiable; + use HandlesResourceDeletion; /** * Default password. @@ -71,6 +73,15 @@ class User extends Authenticatable implements JWTSubject 'pengurus_id', ]; + /** + * Daftar field-file yang harus dihapus. + * + * @var array + */ + protected $resources = [ + 'image', + ]; + /** * {@inheritDoc} */ @@ -105,28 +116,6 @@ public function getFotoAttribute() return $this->attributes['image'] ? Storage::url('user/'.$this->attributes['image']) : null; } - /** - * Uploads an image. - * - * @param $image The image - * @return ( description_of_the_return_value ) - */ - public function uploadImage($image) - { - $extension = $image->getClientOriginalExtension(); - $path = storage_path('app/public/user/'); - - if (! file_exists($path)) { - File::makeDirectory($path, 0777, true); - } - - $name = $this->id.'.'.$extension; - $img = Image::make($image->getRealPath()); - $img->save($path.$name); - - return $this->update(['image' => $name]); - } - public function scopeSuspend($query, $email) { return $query->where('email', $email)->where('status', 0)->get(); diff --git a/app/Services/ApiService.php b/app/Services/ApiService.php new file mode 100644 index 000000000..ac6232806 --- /dev/null +++ b/app/Services/ApiService.php @@ -0,0 +1,114 @@ +setting = (object) SettingAplikasi::pluck('value', 'key')->toArray(); + + $this->server = config('app.server_layanan'); + } + + public function register($data) + { + + $response = Http::withHeaders([ + 'X-Requested-With' => 'XMLHttpRequest', + ])->attach( + 'permohonan', + Storage::get($data['permohonan']), + 'dokumen-permohonan.pdf' + )->post("{$this->server}/api/v1/pelanggan/register-kecamatan", [ + 'user_id' => auth()->user()->id, + 'email' => email($data['email']), + 'kecamatan' => bilangan_titik($data['kecamatan_id']), + 'kontak_no_hp' => bilangan($data['kontak_no_hp']), + 'kontak_nama' => nama($data['kontak_nama']), + 'no_hp_pj' => bilangan($data['kontak_no_hp']), + 'nama_pj' => nama($data['kontak_nama']), + 'domain' => alamat_web($data['domain']), + 'status_langganan' => (int) $data['status_langganan_id'], + ]); + + if ($response->successful()) { + return [ + 'success' => true, + 'message' => 'Pendaftaran pelanggan berhasil.', + 'data' => $response->json(), + ]; + } elseif ($response->failed()) { + return [ + 'success' => false, + 'message' => 'Pendaftaran pelanggan gagal.', + 'error' => $response->json(), + ]; + } else { + return [ + 'success' => false, + 'message' => 'Terjadi masalah pada pendaftaran pelanggan.', + 'status' => $response->status(), + ]; + } + } + + public function terdaftar($kode_kecamatan) + { + $response = Http::withHeaders([ + 'Authorization' => 'Bearer ' . $this->setting->layanan_opendesa_token, + 'X-Requested-With' => 'XMLHttpRequest', + ])->post("{$this->server}/api/v1/pelanggan/terdaftar-kecamatan", [ + 'kecamatan_id' => $kode_kecamatan, + ]); + + if ($response->successful()) { + return [ + 'success' => true, + 'message' => 'Data berhasil diambil.', + 'data' => $response->json(), + ]; + } else { + + return [ + 'success' => false, + 'message' => $response->object()->message, + 'data' => $response->body(), + ]; + } + } + + public function getFormRegister() + { + $response = Http::withHeaders([ + 'Authorization' => 'Bearer ' . $this->setting->layanan_opendesa_token, + 'X-Requested-With' => 'XMLHttpRequest', + ])->get("{$this->server}/api/v1/pelanggan/form-register-kecamatan"); + + if ($response->successful()) { + return [ + 'success' => true, + 'message' => 'Data berhasil diambil.', + 'data' => $response->json(), + ]; + } + + return [ + 'success' => false, + 'message' => 'Gagal mengambil data.', + 'status' => $response->status(), + ]; + } +} diff --git a/app/Traits/HandlesFileUpload.php b/app/Traits/HandlesFileUpload.php index 62426921b..624ef2527 100644 --- a/app/Traits/HandlesFileUpload.php +++ b/app/Traits/HandlesFileUpload.php @@ -1,5 +1,34 @@ hasFile($field)) { $file = $request->file($field); @@ -24,6 +53,10 @@ public function handleFileUpload($request, &$input, $field = 'file', $directory $fileName = $file->hashName(); $path = $file->storeAs("public/{$directory}", $fileName); $input[$field] = str_replace('public/', 'storage/', $path); + + if (! $withDirectory) { + $input[$field] = $fileName; + } } } } diff --git a/catatan_rilis.md b/catatan_rilis.md index d456d2bad..b3ff80485 100644 --- a/catatan_rilis.md +++ b/catatan_rilis.md @@ -1,4 +1,4 @@ -Di rilis versi v2410.0.0 di versi ini terdapat modul komentar pada artikel dan perbaikan lain yang diminta Komunitas. +Di rilis versi v2411.0.0 di versi ini terdapat modul komentar pada artikel dan perbaikan lain yang diminta Komunitas. Terima kasih pada @uddinmtm telah ikut berkontribusi. @@ -6,12 +6,14 @@ Terima kasih pada @uddinmtm telah ikut berkontribusi. 1. [#632](https://github.com/OpenSID/OpenDK/issues/632) Penambahan fitur penanganan komentar dan balasan komentar pada halaman detail artikel. 2. [#1024](https://github.com/OpenSID/OpenDK/issues/1024) Penambahan fitur modul galeri pada website OpenDK. +3. [#1026](https://github.com/OpenSID/OpenDK/issues/1026) Penambahan menu kategori artikel. +4. [#1025](https://github.com/OpenSID/OpenDK/issues/1025) Penambahan menu dinamis pada halaman admin & penyesuaian halaman public. #### BUG 1. [#1028](https://github.com/OpenSID/OpenDK/issues/1028) Perbaikan migrasi navigasi. - +2. [#1065](https://github.com/OpenSID/OpenDK/issues/1065) Perbaikan preview artikel. #### TEKNIS @@ -25,4 +27,12 @@ Terima kasih pada @uddinmtm telah ikut berkontribusi. 8. [#1055](https://github.com/OpenSID/OpenDK/issues/1055) Penyesuaian form menggunakan modal untuk membuat dan memperbarui data kategori potensi. 9. [#1056](https://github.com/OpenSID/OpenDK/issues/1056) Penyesuaian form menggunakan modal untuk membuat dan memperbarui data kategori pengaduan. 10. [#1057](https://github.com/OpenSID/OpenDK/issues/1057) Penyesuaian form menggunakan modal untuk membuat dan memperbarui data jenis penyakit. -11. [#1058](https://github.com/OpenSID/OpenDK/issues/1058) Penyesuaian form menggunakan modal untuk membuat dan memperbarui data jenis peraturan. \ No newline at end of file +11. [#1058](https://github.com/OpenSID/OpenDK/issues/1058) Penyesuaian form menggunakan modal untuk membuat dan memperbarui data jenis peraturan. +12. [#1049](https://github.com/OpenSID/OpenDK/issues/1049) Penyesuaian use trait to upload and delete files prosedur. +13. [#1067](https://github.com/OpenSID/OpenDK/issues/1067) Penyesuaian use trait to upload and delete files regulasi. +14. [#1068](https://github.com/OpenSID/OpenDK/issues/1068) Penyesuaian use trait to upload and delete files artikel. +15. [#1069](https://github.com/OpenSID/OpenDK/issues/1069) Penyesuaian use trait to upload and delete files dokumen. +16. [#1070](https://github.com/OpenSID/OpenDK/issues/1070) Penyesuaian use trait to upload and delete files medsos. +17. [#1071](https://github.com/OpenSID/OpenDK/issues/1071) Penyesuaian use trait to upload and delete files sinergi program. +18. [#1072](https://github.com/OpenSID/OpenDK/issues/1072) Penyesuaian use trait to upload and delete files pengurus. +19. [#1073](https://github.com/OpenSID/OpenDK/issues/1073) Peneysuaian use trait to upload and delete files use. diff --git a/composer.json b/composer.json index 01e52491f..8b7ca6a19 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "laravel/helpers": "^1.3", "laravel/ui": "^3.0", "laravelcollective/html": "^6.2", + "livewire/livewire": "^2.12", "maatwebsite/excel": "^3.1", "mews/captcha": "^3.2", "proengsoft/laravel-jsvalidation": "^4.4", diff --git a/config/app.php b/config/app.php index dd5980bbb..556796a1f 100644 --- a/config/app.php +++ b/config/app.php @@ -39,7 +39,7 @@ |-------------------------------------------------------------------------- */ - 'version' => 'v2410.0.0', + 'version' => 'v2411.0.0', /* |-------------------------------------------------------------------------- @@ -57,6 +57,14 @@ 'host_pantau' => env('HOST_PANTAU', 'https://pantau.opensid.my.id/index.php/api/'), + /* + |-------------------------------------------------------------------------- + | Server Layanan + |-------------------------------------------------------------------------- + */ + + 'server_layanan' => env('SERVER_LAYANAN', 'https://layanan.opendesa.id'), + /* |-------------------------------------------------------------------------- | Token Pantau diff --git a/config/livewire.php b/config/livewire.php new file mode 100644 index 000000000..26074abcf --- /dev/null +++ b/config/livewire.php @@ -0,0 +1,171 @@ + 'App\\Http\\Livewire', + + /* + |-------------------------------------------------------------------------- + | View Path + |-------------------------------------------------------------------------- + | + | This value sets the path for Livewire component views. This affects + | file manipulation helper commands like `artisan make:livewire`. + | + */ + + 'view_path' => resource_path('views/livewire'), + + /* + |-------------------------------------------------------------------------- + | Layout + |-------------------------------------------------------------------------- + | The default layout view that will be used when rendering a component via + | Route::get('/some-endpoint', SomeComponent::class);. In this case the + | the view returned by SomeComponent will be wrapped in "layouts.app" + | + */ + + 'layout' => 'layouts.app', + + /* + |-------------------------------------------------------------------------- + | Livewire Assets URL + |-------------------------------------------------------------------------- + | + | This value sets the path to Livewire JavaScript assets, for cases where + | your app's domain root is not the correct path. By default, Livewire + | will load its JavaScript assets from the app's "relative root". + | + | Examples: "/assets", "myurl.com/app". + | + */ + + 'asset_url' => null, + + /* + |-------------------------------------------------------------------------- + | Livewire App URL + |-------------------------------------------------------------------------- + | + | This value should be used if livewire assets are served from CDN. + | Livewire will communicate with an app through this url. + | + | Examples: "https://my-app.com", "myurl.com/app". + | + */ + + 'app_url' => null, + + /* + |-------------------------------------------------------------------------- + | Livewire Endpoint Middleware Group + |-------------------------------------------------------------------------- + | + | This value sets the middleware group that will be applied to the main + | Livewire "message" endpoint (the endpoint that gets hit everytime + | a Livewire component updates). It is set to "web" by default. + | + */ + + 'middleware_group' => 'web', + + /* + |-------------------------------------------------------------------------- + | Livewire Temporary File Uploads Endpoint Configuration + |-------------------------------------------------------------------------- + | + | Livewire handles file uploads by storing uploads in a temporary directory + | before the file is validated and stored permanently. All file uploads + | are directed to a global endpoint for temporary storage. The config + | items below are used for customizing the way the endpoint works. + | + */ + + 'temporary_file_upload' => [ + 'disk' => null, // Example: 'local', 's3' Default: 'default' + 'rules' => null, // Example: ['file', 'mimes:png,jpg'] Default: ['required', 'file', 'max:12288'] (12MB) + 'directory' => null, // Example: 'tmp' Default 'livewire-tmp' + 'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1' + 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs. + 'png', + 'gif', + 'bmp', + 'svg', + 'wav', + 'mp4', + 'mov', + 'avi', + 'wmv', + 'mp3', + 'm4a', + 'jpg', + 'jpeg', + 'mpga', + 'webp', + 'wma', + ], + 'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated. + ], + + /* + |-------------------------------------------------------------------------- + | Manifest File Path + |-------------------------------------------------------------------------- + | + | This value sets the path to the Livewire manifest file. + | The default should work for most cases (which is + | "/bootstrap/cache/livewire-components.php"), but for specific + | cases like when hosting on Laravel Vapor, it could be set to a different value. + | + | Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php". + | + */ + + 'manifest_path' => null, + + /* + |-------------------------------------------------------------------------- + | Back Button Cache + |-------------------------------------------------------------------------- + | + | This value determines whether the back button cache will be used on pages + | that contain Livewire. By disabling back button cache, it ensures that + | the back button shows the correct state of components, instead of + | potentially stale, cached data. + | + | Setting it to "false" (default) will disable back button cache. + | + */ + + 'back_button_cache' => false, + + /* + |-------------------------------------------------------------------------- + | Render On Redirect + |-------------------------------------------------------------------------- + | + | This value determines whether Livewire will render before it's redirected + | or not. Setting it to "false" (default) will mean the render method is + | skipped when redirecting. And "true" will mean the render method is + | run before redirecting. Browsers bfcache can store a potentially + | stale view if render is skipped on redirect. + | + */ + + 'render_on_redirect' => false, + +]; diff --git a/database/migrations/2017_10_31_165347_create_nav_menus_table.php b/database/migrations/2017_10_31_165347_create_nav_menus_table.php new file mode 100644 index 000000000..647326b34 --- /dev/null +++ b/database/migrations/2017_10_31_165347_create_nav_menus_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('name'); + $table->string('url')->comment('bisa berisi link atau url'); + $table->enum('target', ['_self', '_blank', '_top'])->default('_self'); + $table->integer('parent_id')->nullable(); + $table->integer('order')->default(0); + $table->boolean('is_show')->default(true)->comment('Status ditampilkan'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('nav_menus'); + } +}; diff --git a/database/migrations/2021_10_15_100729_create_kategoris_table.php b/database/migrations/2021_10_15_100729_create_kategoris_table.php new file mode 100644 index 000000000..c58751790 --- /dev/null +++ b/database/migrations/2021_10_15_100729_create_kategoris_table.php @@ -0,0 +1,33 @@ +id(); + $table->string('nama'); + $table->string('slug')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('kategoris'); + } +}; diff --git a/database/migrations/2024_09_30_112202_create_artikel_kategoris_table.php b/database/migrations/2024_09_30_112202_create_artikel_kategoris_table.php new file mode 100644 index 000000000..bf4dc3900 --- /dev/null +++ b/database/migrations/2024_09_30_112202_create_artikel_kategoris_table.php @@ -0,0 +1,41 @@ +id('id_kategori'); + $table->string('nama_kategori'); + $table->string('slug')->unique(); + $table->enum('status', ['Ya', 'Tidak'])->default('Ya'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('das_artikel_kategori'); + } +}; diff --git a/database/migrations/2024_10_03_113405_add_id_kategori_to_das_artikel_table.php b/database/migrations/2024_10_03_113405_add_id_kategori_to_das_artikel_table.php new file mode 100644 index 000000000..85fec889b --- /dev/null +++ b/database/migrations/2024_10_03_113405_add_id_kategori_to_das_artikel_table.php @@ -0,0 +1,40 @@ +unsignedBigInteger('id_kategori')->nullable()->after('id'); + + // Menambahkan foreign key constraint + $table->foreign('id_kategori')->references('id_kategori')->on('das_artikel_kategori')->onDelete('set null'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('das_artikel', function (Blueprint $table) { + // Drop foreign key constraint terlebih dahulu sebelum menghapus kolom + $table->dropForeign(['id_kategori']); + + // Menghapus kolom id_kategori + $table->dropColumn('id_kategori'); + }); + } +}; diff --git a/database/migrations/2024_10_03_203704_add_field_kategori_id_in_table_artikel.php b/database/migrations/2024_10_03_203704_add_field_kategori_id_in_table_artikel.php new file mode 100644 index 000000000..dea9ccb82 --- /dev/null +++ b/database/migrations/2024_10_03_203704_add_field_kategori_id_in_table_artikel.php @@ -0,0 +1,33 @@ +foreignIdFor(Kategori::class)->nullable()->after('judul')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('das_artikel', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/migrations/2024_10_04_101813_add_field_type_in_table_nav_menus.php b/database/migrations/2024_10_04_101813_add_field_type_in_table_nav_menus.php new file mode 100644 index 000000000..fe1d35e28 --- /dev/null +++ b/database/migrations/2024_10_04_101813_add_field_type_in_table_nav_menus.php @@ -0,0 +1,32 @@ +enum('type', ['link', 'halaman', 'kategori', 'modul'])->default('modul')->after('target'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('nav_menus', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/migrations/2024_10_22_120555_add_menu_dinamis.php b/database/migrations/2024_10_22_120555_add_menu_dinamis.php new file mode 100644 index 000000000..97a70fc47 --- /dev/null +++ b/database/migrations/2024_10_22_120555_add_menu_dinamis.php @@ -0,0 +1,270 @@ + 1, + 'name' => 'Beranda', + 'url' => '/', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 1, + 'is_show' => 1 + ], + [ + 'id' => 2, + 'name' => 'Publikasi', + 'url' => '#', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 2, + 'is_show' => 1 + ], + [ + 'id' => 3, + 'name' => 'Galeri', + 'url' => '/publikasi/galeri', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 2, + 'order' => 1, + 'is_show' => 1 + ], + [ + 'id' => 4, + 'name' => 'Berita Desa', + 'url' => '/berita-desa', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 3, + 'is_show' => 1 + ], + [ + 'id' => 5, + 'name' => 'Profil', + 'url' => '#', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 4, + 'is_show' => 1 + ], + [ + 'id' => 6, + 'name' => 'Sejarah', + 'url' => '/profil/sejarah', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 5, + 'order' => 1, + 'is_show' => 1 + ], + [ + 'id' => 7, + 'name' => 'Letak Geografis', + 'url' => '/profil/letak-geografis', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 5, + 'order' => 2, + 'is_show' => 1 + ], + [ + 'id' => 8, + 'name' => 'Struktur Pemerintahan', + 'url' => '/profil/struktur-pemerintahan', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 5, + 'order' => 3, + 'is_show' => 1 + ], + [ + 'id' => 9, + 'name' => 'Visi & Misi', + 'url' => '/profil/visi-misi', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 5, + 'order' => 4, + 'is_show' => 1 + ], + [ + 'id' => 10, + 'name' => 'Kategori Berita', + 'url' => '#', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 5, + 'is_show' => 1 + ], + [ + 'id' => 11, + 'name' => 'Desa', + 'url' => '#', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 6, + 'is_show' => 1 + ], + [ + 'id' => 12, + 'name' => 'Potensi', + 'url' => '#', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 7, + 'is_show' => 1 + ], + [ + 'id' => 13, + 'name' => 'Statistik', + 'url' => '#', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 8, + 'is_show' => 1 + ], + [ + 'id' => 14, + 'name' => 'Penduduk', + 'url' => '/statistik/kependudukan', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 13, + 'order' => 1, + 'is_show' => 1 + ], + [ + 'id' => 15, + 'name' => 'Pendidikan', + 'url' => '/statistik/pendidikan', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 13, + 'order' => 2, + 'is_show' => 1 + ], + [ + 'id' => 16, + 'name' => 'Kesehatan', + 'url' => '/statistik/kesehatan', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 13, + 'order' => 3, + 'is_show' => 1 + ], + [ + 'id' => 17, + 'name' => 'Program dan Bantuan', + 'url' => '/statistik/program-dan-bantuan', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 13, + 'order' => 4, + 'is_show' => 1 + ], + [ + 'id' => 18, + 'name' => 'Anggaran dan Realisasi', + 'url' => '/statistik/anggaran-dan-realisasi', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 13, + 'order' => 5, + 'is_show' => 1 + ], + [ + 'id' => 19, + 'name' => 'Anggaran Desa', + 'url' => '/statistik/anggaran-desa', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 13, + 'order' => 6, + 'is_show' => 1 + ], + [ + 'id' => 20, + 'name' => 'Unduhan', + 'url' => '/statistik/anggaran-desa', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => NULL, + 'order' => 9, + 'is_show' => 1 + ], + [ + 'id' => 21, + 'name' => 'Prosedur', + 'url' => '/unduhan/prosedur', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 20, + 'order' => 1, + 'is_show' => 1 + ], + [ + 'id' => 22, + 'name' => 'Regulasi', + 'url' => '/unduhan/regulasi', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 20, + 'order' => 2, + 'is_show' => 1 + ], + [ + 'id' => 23, + 'name' => 'Dokumen', + 'url' => '/unduhan/form-dokumen', + 'target' => '_self', + 'type' => 'modul', + 'parent_id' => 20, + 'order' => 3, + 'is_show' => 1 + ], + [ + 'id' => 24, + 'name' => 'FAQ', + 'url' => 'https://demodk.opendesa.id/faq', + 'target' => '_blank', + 'type' => 'link', + 'parent_id' => NULL, + 'order' => 10, + 'is_show' => 1 + ], + ]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +}; diff --git a/database/migrations/2024_11_01_161123_remove_foreign_key_kategori.php b/database/migrations/2024_11_01_161123_remove_foreign_key_kategori.php new file mode 100644 index 000000000..18d147ab5 --- /dev/null +++ b/database/migrations/2024_11_01_161123_remove_foreign_key_kategori.php @@ -0,0 +1,31 @@ +dropForeignIdFor(Kategori::class, 'kategori_id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 1277e402c..e5dc0e3dd 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -47,6 +47,7 @@ public function run() DB::statement('SET FOREIGN_KEY_CHECKS=0;'); $this->call(RoleSpatieSeeder::class); + $this->call(RefKategori::class); $this->call(RefPekerjaanTableSeeder::class); $this->call(RefAgamaTableSeeder::class); $this->call(RefKawinTableSeeder::class); diff --git a/database/seeders/RefKategori.php b/database/seeders/RefKategori.php new file mode 100644 index 000000000..f0ea320a6 --- /dev/null +++ b/database/seeders/RefKategori.php @@ -0,0 +1,66 @@ + 'Kebijakan Publik', 'slug' => Str::slug('Kebijakan Publik')], + ['nama' => 'Hukum dan Regulasi', 'slug' => Str::slug('Hukum dan Regulasi')], + ['nama' => 'Pemerintahan Daerah', 'slug' => Str::slug('Pemerintahan Daerah')], + ['nama' => 'Politik dan Demokrasi', 'slug' => Str::slug('Politik dan Demokrasi')], + ['nama' => 'Pelayanan Publik', 'slug' => Str::slug('Pelayanan Publik')], + ['nama' => 'Keuangan dan Anggaran', 'slug' => Str::slug('Keuangan dan Anggaran')], + ['nama' => 'Reformasi Birokrasi', 'slug' => Str::slug('Reformasi Birokrasi')], + ['nama' => 'Pembangunan dan Infrastruktur', 'slug' => Str::slug('Pembangunan dan Infrastruktur')], + ['nama' => 'Keamanan dan Pertahanan', 'slug' => Str::slug('Keamanan dan Pertahanan')], + ['nama' => 'Lingkungan dan Energi', 'slug' => Str::slug('Lingkungan dan Energi')], + ['nama' => 'Hubungan Internasional', 'slug' => Str::slug('Hubungan Internasional')], + ['nama' => 'Pendidikan dan Kebudayaan', 'slug' => Str::slug('Pendidikan dan Kebudayaan')], + ['nama' => 'Kesejahteraan Sosial', 'slug' => Str::slug('Kesejahteraan Sosial')], + ['nama' => 'Tenaga Kerja dan Ketenagakerjaan', 'slug' => Str::slug('Tenaga Kerja dan Ketenagakerjaan')], + ['nama' => 'Kesehatan Masyarakat', 'slug' => Str::slug('Kesehatan Masyarakat')], + ]); + } +} diff --git a/helpers/general_helper.php b/helpers/general_helper.php index 19ec81d05..0bc51bfc3 100644 --- a/helpers/general_helper.php +++ b/helpers/general_helper.php @@ -519,3 +519,180 @@ function getFeeds() }); } } + + + +// Email hanya boleh berisi karakter alpha, numeric, titik, strip dan Tanda et, +function email($str): ?string +{ + return preg_replace('/[^a-zA-Z0-9@\\.\\-]/', '', htmlentities($str)); +} + +function bilangan_titik($str): ?string +{ + return preg_replace('/[^0-9\.]/', '', strip_tags($str)); +} + +// website hanya boleh berisi karakter alpha, numeric, titik, titik dua dan garis miring +function alamat_web($str): ?string +{ + return preg_replace('/[^a-zA-Z0-9:\\/\\.\\-]/', '', htmlentities($str)); +} + +function bilangan($str) +{ + if ($str == null) { + return null; + } + + return preg_replace('/[^0-9]/', '', strip_tags($str)); +} + +// Nama hanya boleh berisi karakter alpha, spasi, titik, koma, tanda petik dan strip +function nama($str): ?string +{ + return preg_replace("/[^a-zA-Z '\\.,\\-]/", '', strip_tags($str)); +} + +// Kode Wilayah Dengan Titik +// Dari 5201142005 --> 52.01.14.2005 +function kode_wilayah($kode_wilayah): string +{ + $kode_prov_kab_kec = str_split(substr($kode_wilayah, 0, 6), 2); + $kode_desa = (strlen($kode_wilayah) > 6) ? '.' . substr($kode_wilayah, 6) : ''; + + return implode('.', $kode_prov_kab_kec) . $kode_desa; +} + +function hari($tgl): string +{ + $hari = [ + 0 => 'Minggu', + 1 => 'Senin', + 2 => 'Selasa', + 3 => 'Rabu', + 4 => 'Kamis', + 5 => 'Jumat', + 6 => 'Sabtu', + ]; + $dayofweek = date('w', strtotime($tgl)); + + return $hari[$dayofweek]; +} + + +/* + * ======================================= + * Rupiah terbilang + */ +function number_to_words($number, $nol_sen = true): string +{ + $before_comma = trim(to_word($number)); + $after_comma = trim(comma($number)); + $result = $before_comma . ($nol_sen ? '' : ' koma ' . $after_comma); + + return ucwords($result . ' Rupiah'); +} + +function to_word($number): string +{ + $words = ''; + $arr_number = [ + '', + 'satu', + 'dua', + 'tiga', + 'empat', + 'lima', + 'enam', + 'tujuh', + 'delapan', + 'sembilan', + 'sepuluh', + 'sebelas', + ]; + + $unit = ['', 'ribu', 'juta', 'milyar', 'triliun', 'kuadriliun', 'kuintiliun', 'sekstiliun', 'septiliun', 'oktiliun', 'noniliun', 'desiliun', 'undesiliun', 'duodesiliun', 'tredesiliun', 'kuatuordesiliun']; + + if (strpos($number, ',') === true) { + $parts = explode(',', $number); + $intPart = (int) $parts[0]; + $decimalPart = (int) $parts[1]; + + $words = to_word($intPart) . ' koma ' . to_word($decimalPart); + } else { + $number = (int) str_replace('.', '', $number); // Ubah menjadi integer untuk memastikan hanya bilangan bulat yang diproses + + if ($number < 12) { + $words = ' ' . $arr_number[$number]; + } elseif ($number < 20) { + $words = to_word($number - 10) . ' belas'; + } elseif ($number < 100) { + $words = to_word(intdiv($number, 10)) . ' puluh' . to_word($number % 10); + } elseif ($number < 200) { + $words = ' seratus' . to_word($number - 100); + } elseif ($number < 1000) { + $words = to_word(intdiv($number, 100)) . ' ratus' . to_word($number % 100); + } elseif ($number >= 1000 && $number < 2000) { + $words = ' seribu' . to_word($number - 1000); + } else { + for ($i = count($unit) - 1; $i >= 0; $i--) { + $divider = 10 ** (3 * $i); + if ($number < $divider) { + continue; + } + + $div = intdiv($number, $divider); + $mod = $number % $divider; + + $words = to_word($div) . ' ' . $unit[$i] . to_word($mod); + break; + } + } + } + + return $words; +} + +function comma($number): string +{ + $after_comma = stristr($number, ','); + $arr_number = [ + 'nol', + 'satu', + 'dua', + 'tiga', + 'empat', + 'lima', + 'enam', + 'tujuh', + 'delapan', + 'sembilan', + ]; + + $results = ''; + $length = strlen($after_comma); + $i = 1; + + while ($i < $length) { + $get = substr($after_comma, $i, 1); + $results .= ' ' . $arr_number[$get]; + $i++; + } + + return $results; +} + + +function bulan() +{ + return [1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni', 7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember']; +} + +function getBulan(int $bln) +{ + $bulan = bulan(); + + return $bulan[$bln]; +} + diff --git a/public/bower_components/menu-editor/bootstrap-iconpicker.min.js b/public/bower_components/menu-editor/bootstrap-iconpicker.min.js new file mode 100644 index 000000000..8a3107e9f --- /dev/null +++ b/public/bower_components/menu-editor/bootstrap-iconpicker.min.js @@ -0,0 +1,11 @@ +/*!======================================================================== +* File: bootstrap-iconpicker.min.js v1.10.0 by @victor-valencia +* https://victor-valencia.github.com/bootstrap-iconpicker +* ======================================================================== +* Copyright 2013-2018 Victor Valencia Rico. +* Licensed under MIT license. +* https://github.com/victor-valencia/bootstrap-iconpicker/blob/master/LICENSE +* ======================================================================== +*/ + +!function($){"use strict";var Iconpicker=function(element,options){if("undefined"==typeof $.fn.popover||"undefined"==typeof $.fn.popover.Constructor.VERSION)throw new TypeError("Bootstrap iconpicker require Bootstrap popover");this.$element=$(element),this.options=$.extend({},Iconpicker.DEFAULTS,this.$element.data()),this.options=$.extend({},this.options,options)};Iconpicker.VERSION="1.10.0",Iconpicker.ICONSET_EMPTY={iconClass:"",iconClassFix:"",icons:[]},Iconpicker.ICONSET={_custom:null,elusiveicon:$.iconset_elusiveicon||Iconpicker.ICONSET_EMPTY,flagicon:$.iconset_flagicon||Iconpicker.ICONSET_EMPTY,fontawesome4:$.iconset_fontawesome_4||Iconpicker.ICONSET_EMPTY,fontawesome5:$.iconset_fontawesome_5||Iconpicker.ICONSET_EMPTY,glyphicon:$.iconset_glyphicon||Iconpicker.ICONSET_EMPTY,ionicon:$.iconset_ionicon||Iconpicker.ICONSET_EMPTY,mapicon:$.iconset_mapicon||Iconpicker.ICONSET_EMPTY,materialdesign:$.iconset_materialdesign||Iconpicker.ICONSET_EMPTY,octicon:$.iconset_octicon||Iconpicker.ICONSET_EMPTY,typicon:$.iconset_typicon||Iconpicker.ICONSET_EMPTY,weathericon:$.iconset_weathericon||Iconpicker.ICONSET_EMPTY},Iconpicker.DEFAULTS={align:"center",arrowClass:"btn-primary",arrowNextIconClass:"fas fa-arrow-right",arrowPrevIconClass:"fas fa-arrow-left",cols:4,icon:"",iconset:"fontawesome5",iconsetVersion:"lastest",header:!0,labelHeader:"{0} / {1}",footer:!0,labelFooter:"{0} - {1} of {2}",placement:"bottom",rows:4,search:!0,searchText:"Search icon",selectedClass:"btn-warning",unselectedClass:"btn-secondary"},Iconpicker.prototype.bindEvents=function(){var op=this.options,el=this;op.table.find(".btn-previous, .btn-next").off("click").on("click",function(e){if(e.preventDefault(),!$(this).hasClass("disabled")){var inc=parseInt($(this).val(),10);el.changeList(op.page+inc)}}),op.table.find(".btn-icon").off("click").on("click",function(e){e.preventDefault(),el.select($(this).val()),op.inline===!1?el.$element.popover("3.x"===$.fn.bsVersion()?"destroy":"dispose"):op.table.find("i[class$='"+$(this).val()+"']").parent().addClass(op.selectedClass)}),op.table.find(".search-control").off("keyup").on("keyup",function(){el.changeList(1)})},Iconpicker.prototype.changeList=function(page){this.filterIcons(),this.updateLabels(page),this.updateIcons(page),this.options.page=page,this.bindEvents()},Iconpicker.prototype.filterIcons=function(){var op=this.options,search=op.table.find(".search-control").val(),icons=[];if("lastest"!=op.iconsetVersion&&"undefined"!=typeof Iconpicker.ICONSET[op.iconset].allVersions?$.each(Iconpicker.ICONSET[op.iconset].allVersions,function(i,v){op.iconsetVersion==v.version&&(icons=v.icons)}):icons=Iconpicker.ICONSET[op.iconset].icons,""===search)op.icons=icons;else{var result=[];$.each(icons,function(i,v){v.toLowerCase().indexOf(search)>-1&&result.push(v)}),op.icons=result}},Iconpicker.prototype.removeAddClass=function(target,remove,add){return this.options.table.find(target).removeClass(remove).addClass(add),add},Iconpicker.prototype.reset=function(){this.updatePicker(),this.changeList(1)},Iconpicker.prototype.select=function(icon){var op=this.options,el=this.$element;op.selected=$.inArray(icon.replace(op.iconClassFix,""),op.icons),-1===op.selected&&(op.selected=0,icon=op.iconClassFix+op.icons[op.selected]),""!==icon&&op.selected>=0&&(op.icon=icon,op.inline===!1&&(el.find("input").val(icon),el.find("i").attr("class","").addClass(op.iconClass).addClass(icon)),icon===op.iconClassFix?el.trigger({type:"change",icon:"empty"}):(el.trigger({type:"change",icon:icon}),el.find("input").val(icon)),op.table.find("button."+op.selectedClass).removeClass(op.selectedClass))},Iconpicker.prototype.switchPage=function(icon){var op=this.options;if(op.selected=$.inArray(icon.replace(op.iconClassFix,""),op.icons),op.selected>=0){var page=Math.ceil((op.selected+1)/this.totalIconsPerPage());this.changeList(page)}""===icon?op.table.find("i."+op.iconClassFix).parent().addClass(op.selectedClass):op.table.find("i."+icon).parent().addClass(op.selectedClass)},Iconpicker.prototype.totalPages=function(){return Math.ceil(this.totalIcons()/this.totalIconsPerPage())},Iconpicker.prototype.totalIcons=function(){return this.options.icons.length},Iconpicker.prototype.totalIconsPerPage=function(){return 0===this.options.rows?this.options.icons.length:this.options.cols*this.options.rows},Iconpicker.prototype.updateArrows=function(page){var op=this.options,total_pages=this.totalPages();1===page?op.table.find(".btn-previous").addClass("disabled"):op.table.find(".btn-previous").removeClass("disabled"),page===total_pages||0===total_pages?op.table.find(".btn-next").addClass("disabled"):op.table.find(".btn-next").removeClass("disabled")},Iconpicker.prototype.updateIcons=function(page){var op=this.options,tbody=op.table.find("tbody").empty(),offset=(page-1)*this.totalIconsPerPage(),length=op.rows;0===op.rows&&(length=op.icons.length);for(var i=0;length>i;i++){for(var tr=$(""),j=0;j').hide();if(pos').show(),op.icon===v&&btn.addClass(op.selectedClass).addClass("btn-icon-selected")}tr.append($("").append(btn))}tbody.append(tr)}},Iconpicker.prototype.updateIconsCount=function(){var op=this.options;if(op.footer===!0){var icons_count=["",' ',' '," ",""];op.table.find("tfoot").empty().append(icons_count.join(""))}},Iconpicker.prototype.updateLabels=function(page){var op=this.options,total_icons=this.totalIcons(),total_pages=this.totalPages();op.table.find(".page-count").html(op.labelHeader.replace("{0}",0===total_pages?0:page).replace("{1}",total_pages));var offset=(page-1)*this.totalIconsPerPage(),total=page*this.totalIconsPerPage();op.table.find(".icons-count").html(op.labelFooter.replace("{0}",total_icons?offset+1:0).replace("{1}",total_icons>total?total:total_icons).replace("{2}",total_icons)),this.updateArrows(page)},Iconpicker.prototype.updatePagesCount=function(){var op=this.options;if(op.header===!0){for(var tr=$(""),i=0;i');if(0===i||i===op.cols-1){var arrow=['"];td.append(arrow.join("")),tr.append(td)}else 0===tr.find(".page-count").length&&(td.attr("colspan",op.cols-2).append(''),tr.append(td))}op.table.find("thead").empty().append(tr)}},Iconpicker.prototype.updatePicker=function(){var op=this.options;if(op.cols<4)throw"Iconpicker => The number of columns must be greater than or equal to 4. [option.cols = "+op.cols+"]";if(op.rows<0)throw"Iconpicker => The number of rows must be greater than or equal to 0. [option.rows = "+op.rows+"]";this.updatePagesCount(),this.updateSearch(),this.updateIconsCount()},Iconpicker.prototype.updateSearch=function(){var op=this.options,search=["",' ',' '," ",""];search=$(search.join("")),op.search===!0?search.show():search.hide(),op.table.find("thead").append(search)},Iconpicker.prototype.setAlign=function(value){this.$element.removeClass(this.options.align).addClass(value),this.options.align=value},Iconpicker.prototype.setArrowClass=function(value){this.options.arrowClass=this.removeAddClass(".btn-arrow",this.options.arrowClass,value)},Iconpicker.prototype.setArrowNextIconClass=function(value){this.options.arrowNextIconClass=this.removeAddClass(".btn-next > span",this.options.arrowNextIconClass,value)},Iconpicker.prototype.setArrowPrevIconClass=function(value){this.options.arrowPrevIconClass=this.removeAddClass(".btn-previous > span",this.options.arrowPrevIconClass,value)},Iconpicker.prototype.setCols=function(value){this.options.cols=value,this.reset()},Iconpicker.prototype.setFooter=function(value){var footer=this.options.table.find("tfoot");value===!0?footer.show():footer.hide(),this.options.footer=value},Iconpicker.prototype.setHeader=function(value){var header=this.options.table.find("thead");value===!0?header.show():header.hide(),this.options.header=value},Iconpicker.prototype.setIcon=function(value){this.select(value)},Iconpicker.prototype.setIconset=function(value){var op=this.options;$.isPlainObject(value)?(Iconpicker.ICONSET._custom=$.extend(Iconpicker.ICONSET_EMPTY,value),op.iconset="_custom"):Iconpicker.ICONSET.hasOwnProperty(value)?op.iconset=value:op.iconset=Iconpicker.DEFAULTS.iconset,op=$.extend(op,Iconpicker.ICONSET[op.iconset]),this.reset(),this.select(op.icon)},Iconpicker.prototype.setLabelHeader=function(value){this.options.labelHeader=value,this.updateLabels(this.options.page)},Iconpicker.prototype.setLabelFooter=function(value){this.options.labelFooter=value,this.updateLabels(this.options.page)},Iconpicker.prototype.setPlacement=function(value){this.options.placement=value},Iconpicker.prototype.setRows=function(value){this.options.rows=value,this.reset()},Iconpicker.prototype.setSearch=function(value){var search=this.options.table.find(".search-control");value===!0?search.show():search.hide(),search.val(""),this.changeList(1),this.options.search=value},Iconpicker.prototype.setSearchText=function(value){this.options.table.find(".search-control").attr("placeholder",value),this.options.searchText=value},Iconpicker.prototype.setSelectedClass=function(value){this.options.selectedClass=this.removeAddClass(".btn-icon-selected",this.options.selectedClass,value)},Iconpicker.prototype.setUnselectedClass=function(value){this.options.unselectedClass=this.removeAddClass(".btn-icon",this.options.unselectedClass,value)};var old=$.fn.iconpicker;$.fn.iconpicker=function(option,params){return this.each(function(){var $this=$(this),data=$this.data("bs.iconpicker"),options="object"==typeof option&&option;if(data||$this.data("bs.iconpicker",data=new Iconpicker(this,options)),"string"==typeof option){if("undefined"==typeof data[option])throw'Iconpicker => The "'+option+'" method does not exists.';data[option](params)}else{var op=data.options;op=$.extend(op,{inline:!1,page:1,selected:-1,table:$('
')});var name="undefined"!=typeof $this.attr("name")?'name="'+$this.attr("name")+'"':"";"BUTTON"===$this.prop("tagName")?($this.empty().append("").append('").append('').addClass("iconpicker "+("3.x"===$.fn.bsVersion()?"":"dropdown-toggle")),data.setIconset(op.iconset),$this.on("click",function(e){e.preventDefault(),$this.popover({animation:!1,trigger:"manual",html:!0,content:op.table,container:"body",placement:op.placement}).on("inserted.bs.popover",function(){var el=$this.data("bs.popover"),tip="3.x"===$.fn.bsVersion()?el.tip():$(el.getTipElement());tip.addClass("iconpicker-popover")}).on("shown.bs.popover",function(){data.switchPage(op.icon),data.bindEvents()}),$this.popover("show")})):(op.inline=!0,data.setIconset(op.iconset),$this.empty().append('").append(op.table).addClass("iconpicker").addClass(op.align),data.switchPage(op.icon),data.bindEvents())}})},$.fn.iconpicker.Constructor=Iconpicker,$.fn.iconpicker.noConflict=function(){return $.fn.iconpicker=old,this},$.fn.bsVersion=function(){return $.fn.popover.Constructor.VERSION.substr(0,2)+"x"},$(document).on("click","body",function(e){$(".iconpicker").each(function(){$(this).is(e.target)||0!==$(this).has(e.target).length||0!==$(".popover").has(e.target).length||$(this).popover("3.x"===$.fn.bsVersion()?"destroy":"dispose")})}),$('button[role="iconpicker"],div[role="iconpicker"]').iconpicker()}(jQuery); \ No newline at end of file diff --git a/public/bower_components/menu-editor/jquery-menu-editor-copy.jsxx b/public/bower_components/menu-editor/jquery-menu-editor-copy.jsxx new file mode 100644 index 000000000..1764bf11a --- /dev/null +++ b/public/bower_components/menu-editor/jquery-menu-editor-copy.jsxx @@ -0,0 +1,571 @@ +function MenuEditor(e, s) { + var t = $("#" + e).data("level", "0"), + l = { + labelEdit: '', + labelRemove: '', + textConfirmDelete: "Item ini akan dihapus, apakah anda yakin ?", + iconPicker: { + cols: 4, + rows: 4, + footer: !1, + iconset: "fontawesome5" + }, + maxLevel: -1, + listOptions: { + hintCss: { + border: "1px dashed #13981D" + }, + opener: { + as: "html", + close: '', + open: '', + openerCss: { + "margin-right": "10px", + float: "none" + }, + openerClass: "btn btn-success btn-xs" + }, + placeholderCss: { + "background-color": "gray" + }, + ignoreClass: "clickable", + listsClass: "pl-0", + listsCss: { + "padding-top": "10px" + }, + complete: function (e) { + return MenuEditor.updateButtons(t), t.updateLevels(0), !0 + }, + isAllowed: function (e, s, t) { + return v(e, t) + } + } + }; + $.extend(!0, l, s); + var n = null, + o = !0, + i = null, + r = null, + a = l.iconPicker, + c = (s = l.listOptions, $("#" + e + "_icon").iconpicker(a)); + + function d() { + i[0].reset(), (c = c.iconpicker(a)).iconpicker("setIcon", "empty"), r.attr("disabled", !0), n = null + } + + function p(e) { + return $("").addClass(e.classCss).addClass("clickable").attr("href", "#").html(e.text) + } + + function u() { + var e = $("
").addClass("btn-group pull-right"), + s = p({ + classCss: "btn btn-primary btn-xs btnEdit", // 'btn-sm' diubah menjadi 'btn-xs' untuk Bootstrap 3 + text: l.labelEdit + }), + t = p({ + classCss: "btn btn-danger btn-xs btnRemove", + text: l.labelRemove + }), + n = p({ + classCss: "btn btn-default btn-xs btnUp btnMove", + text: '' + }), + o = p({ + classCss: "btn btn-default btn-xs btnDown btnMove", + text: '' + }), + i = p({ + classCss: "btn btn-default btn-xs btnOut btnMove", + text: '' + }), + r = p({ + classCss: "btn btn-default btn-xs btnIn btnMove", + text: '' + }); + return e.append(n).append(o).append(r).append(i).append(s).append(t), e; +} + + + function f(e, s) { + var l = void 0 === s ? 0 : s, + n = 0 === l ? t : $("