middleware('auth'); $this->middleware(function ($request, $next) { $this->user = auth()->user(); return $next($request); }); } /** * Display a listing of the resource. */ public function index() { //$this->authorize('referensi-link.view', $this->user); $data = [ 'title' => 'Referensi Link', 'subtitle' => 'Daftar Referensi Link', 'breadcrumb' => [ ['url' => route('dashboard'), 'text' => 'Dashboard'], ['text' => 'Referensi Link'] ], 'kategoriOptions' => $this->getKategoriOptions(), ]; return view('lpj::referensi_link.index', $data); } /** * Show the form for creating a new resource. */ public function create() { //$this->authorize('referensi-link.create', $this->user); $data = [ 'title' => 'Tambah Referensi Link', 'subtitle' => 'Form Tambah Referensi Link Baru', 'breadcrumb' => [ ['url' => route('dashboard'), 'text' => 'Dashboard'], ['url' => route('basicdata.referensi-link.index'), 'text' => 'Referensi Link'], ['text' => 'Tambah'] ], 'kategoriOptions' => $this->getKategoriOptions(), ]; return view('lpj::referensi_link.create', $data); } /** * Store a newly created resource in storage. */ public function store(ReferensiLinkRequest $request) { //$this->authorize('referensi-link.create', $this->user); try { $validated = $request->validated(); // Set urutan otomatis jika belum diisi if (empty($validated['urutan'])) { $validated['urutan'] = ReferensiLink::max('urutan') + 1; } $referensiLink = ReferensiLink::create($validated); return redirect() ->route('basicdata.referensi-link.index') ->with('success', 'Referensi Link berhasil ditambahkan'); } catch (Exception $e) { return redirect() ->back() ->withInput() ->with('error', 'Gagal menambahkan Referensi Link: ' . $e->getMessage()); } } /** * Show the form for editing the specified resource. */ public function edit($id) { //$this->authorize('referensi-link.update', $this->user); $referensiLink = ReferensiLink::findOrFail($id); $data = [ 'title' => 'Edit Referensi Link', 'subtitle' => 'Form Edit Referensi Link', 'breadcrumb' => [ ['url' => route('dashboard'), 'text' => 'Dashboard'], ['url' => route('basicdata.referensi-link.index'), 'text' => 'Referensi Link'], ['text' => 'Edit'] ], 'referensiLink' => $referensiLink, 'kategoriOptions' => $this->getKategoriOptions(), ]; return view('lpj::referensi_link.create', $data); } /** * Update the specified resource in storage. */ public function update(ReferensiLinkRequest $request, $id) { //$this->authorize('referensi-link.update', $this->user); try { $referensiLink = ReferensiLink::findOrFail($id); $validated = $request->validated(); $referensiLink->update($validated); return redirect() ->route('basicdata.referensi-link.index') ->with('success', 'Referensi Link berhasil diperbarui'); } catch (Exception $e) { return redirect() ->back() ->withInput() ->with('error', 'Gagal memperbarui Referensi Link: ' . $e->getMessage()); } } /** * Remove the specified resource from storage. */ public function destroy($id) { //$this->authorize('referensi-link.delete', $this->user); try { $referensiLink = ReferensiLink::findOrFail($id); $referensiLink->delete(); return response()->json([ 'success' => true, 'message' => 'Referensi Link berhasil dihapus' ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Gagal menghapus Referensi Link: ' . $e->getMessage() ], 500); } } /** * Datatable API for KTDataTable */ public function dataTable(Request $request) { //$this->authorize('referensi-link.view', $this->user); $query = ReferensiLink::with(['createdBy', 'updatedBy']) ->select('referensi_link.*'); // Search $search = $request->input('search'); if (!empty($search)) { $query->where(function ($q) use ($search) { $q->where('name', 'LIKE', "%{$search}%") ->orWhere('link', 'LIKE', "%{$search}%") ->orWhere('kategori', 'LIKE', "%{$search}%"); }); } // Optional filters (support multiple request shapes) $filters = $request->input('filters', []); $kategori = $request->input('kategori', $filters['kategori'] ?? null); if (!empty($kategori)) { if (is_array($kategori)) { $query->whereIn('kategori', $kategori); } else { $values = preg_split('/[,|]/', (string) $kategori, -1, PREG_SPLIT_NO_EMPTY); if (count($values) > 1) { $query->whereIn('kategori', $values); } else { $query->where('kategori', $kategori); } } } $statusRaw = $request->input('status', $filters['status'] ?? $request->input('is_active')); $statusParsed = $this->parseActiveFilter($statusRaw); if ($statusParsed !== null) { $query->where('is_active', $statusParsed); } // Sorting $allowedSortFields = ['id', 'name', 'link', 'kategori', 'urutan', 'is_active', 'created_at', 'updated_at']; $sortField = in_array($request->input('sortField', 'urutan'), $allowedSortFields, true) ? $request->input('sortField', 'urutan') : 'urutan'; $sortOrder = strtolower($request->input('sortOrder', 'asc')); if (in_array($sortOrder, ['asc', 'desc'], true)) { $query->orderBy($sortField, $sortOrder); } // Pagination $page = max((int) $request->input('page', 1), 1); $size = max((int) $request->input('size', 10), 1); $totalRecords = (clone $query)->count(); $offset = ($page - 1) * $size; $items = $query->skip($offset)->take($size)->get(); // Map data rows $data = $items->map(function ($row) { return [ 'id' => $row->id, 'name' => $row->name, 'link' => '' . Str::limit($row->link, 50) . ' ', 'kategori' => $row->kategori, 'status_badge' => $row->status_badge, 'urutan' => $row->urutan, 'actions' => ( (auth()->user()->can('referensi-link.update') ? ' Edit' : '') . (auth()->user()->can('referensi-link.delete') ? ' Hapus' : '') ), ]; }); return response()->json([ 'draw' => (int) $request->input('draw'), 'recordsTotal' => $totalRecords, 'recordsFiltered' => $totalRecords, 'pageCount' => (int) ceil($totalRecords / $size), 'page' => $page, 'totalCount' => $totalRecords, 'data' => $data, ]); } /** * Export data to Excel */ public function export(Request $request) { //$this->authorize('referensi-link.export', $this->user); try { $filename = 'referensi_link_' . date('YmdHis') . '.xlsx'; return Excel::download(new ReferensiLinkExport($request->all()), $filename); } catch (Exception $e) { return redirect() ->back() ->with('error', 'Gagal export data: ' . $e->getMessage()); } } /** * Show import form */ public function import() { //$this->authorize('referensi-link.import', $this->user); $data = [ 'title' => 'Import Referensi Link', 'subtitle' => 'Import data Referensi Link dari Excel', 'breadcrumb' => [ ['url' => route('dashboard'), 'text' => 'Dashboard'], ['url' => route('basicdata.referensi-link.index'), 'text' => 'Referensi Link'], ['text' => 'Import'] ], ]; return view('lpj::referensi_link.import', $data); } /** * Process import */ public function importProcess(Request $request) { //$this->authorize('referensi-link.import', $this->user); $request->validate([ 'file' => 'required|mimes:xlsx,xls|max:10240', // max 10MB ]); try { $import = new ReferensiLinkImport(); Excel::import($import, $request->file('file')); $stats = $import->getImportStats(); $message = "Import berhasil! {$stats['success']} data berhasil diimport"; if ($stats['failed'] > 0) { $message .= ", {$stats['failed']} data gagal diimport"; } return redirect() ->route('basicdata.referensi-link.index') ->with('success', $message); } catch (Exception $e) { Log::error('ReferensiLink import error: ' . $e->getMessage()); return redirect() ->back() ->with('error', 'Gagal import data: ' . $e->getMessage()); } } /** * Toggle status (active/inactive) */ public function toggleStatus($id) { //$this->authorize('referensi-link.update', $this->user); try { $referensiLink = ReferensiLink::findOrFail($id); $referensiLink->is_active = !$referensiLink->is_active; $referensiLink->save(); return response()->json([ 'success' => true, 'message' => 'Status berhasil diubah', 'status' => $referensiLink->is_active ]); } catch (Exception $e) { return response()->json([ 'success' => false, 'message' => 'Gagal mengubah status: ' . $e->getMessage() ], 500); } } /** * Get kategori options for dropdown */ private function getKategoriOptions() { return [ 'regulasi' => 'Regulasi', 'panduan' => 'Panduan', 'prosedur' => 'Prosedur', 'formulir' => 'Formulir', 'laporan' => 'Laporan', 'lainnya' => 'Lainnya' ]; } private function parseActiveFilter($value): ?bool { if ($value === null || $value === '') { return null; } if (is_bool($value)) { return $value; } $val = strtolower(trim((string) $value)); if (in_array($val, ['1', 'true', 'aktif', 'active', 'yes', 'y'], true)) { return true; } if (in_array($val, ['0', 'false', 'tidak', 'inactive', 'nonaktif', 'no', 'n'], true)) { return false; } return null; } /** * Download import template */ public function downloadTemplate() { //$this->authorize('referensi-link.import', $this->user); try { $headers = [ 'Nama', 'Link', 'Kategori', 'Deskripsi', 'Status Aktif', 'Urutan' ]; $filename = 'template_referensi_link_' . date('YmdHis') . '.xlsx'; return Excel::download(new class($headers) implements \Maatwebsite\Excel\Concerns\FromArray, \Maatwebsite\Excel\Concerns\WithHeadings { private $headers; public function __construct($headers) { $this->headers = $headers; } public function array(): array { return [ ['Contoh Referensi', 'https://example.com', 'panduan', 'Deskripsi contoh referensi link', 'aktif', 1], ['Contoh Regulasi', 'https://regulasi.example.com', 'regulasi', 'Deskripsi regulasi', 'aktif', 2], ]; } public function headings(): array { return $this->headers; } }, $filename); } catch (Exception $e) { return redirect() ->back() ->with('error', 'Gagal download template: ' . $e->getMessage()); } } }