query('search', '')); $query = $this->baseQuery(); if ($search !== '') { $query->where(function ($q) use ($search) { $q->where('isi_laporan', 'like', "%{$search}%") ->orWhereHas('kegiatan', function ($kegiatanQuery) use ($search) { $kegiatanQuery->where('nama_kegiatan', 'like', "%{$search}%"); }) ->orWhereHas('kegiatan.organisasi', function ($organisasiQuery) use ($search) { $organisasiQuery->where('nama_organisasi', 'like', "%{$search}%"); }); }); } $laporan = $query->get(); // Get all activities $kegiatanTersedia = Kegiatan::orderByDesc('tanggal_mulai') ->get(['id', 'nama_kegiatan', 'tanggal_mulai']); return view('admin.laporan', compact('laporan', 'search', 'kegiatanTersedia')); } public function store(Request $request): RedirectResponse { $validated = $request->validate([ 'kegiatan_id' => [ 'required', 'integer', 'exists:kegiatan,id', Rule::unique('laporan_kegiatan', 'kegiatan_id') ], 'isi_laporan' => [ 'required', 'string' ], 'file_laporan' => [ 'required', 'file', 'mimes:pdf,doc,docx', 'max:5120' ], ], [ 'kegiatan_id.unique' => 'Kegiatan ini sudah memiliki laporan.', ]); $kegiatan = Kegiatan::findOrFail($validated['kegiatan_id']); $organisasi = $kegiatan->organisasi; $folder = self::REPORT_DIRECTORY . '/' . Str::slug($organisasi->nama_organisasi); $file = $request->file('file_laporan'); $filename = time() . '_' . $file->getClientOriginalName(); $validated['file_laporan'] = $file->storeAs( $folder, $filename, 'public' ); LaporanKegiatan::create([ 'kegiatan_id' => $validated['kegiatan_id'], 'isi_laporan' => $validated['isi_laporan'], 'file_laporan' => $validated['file_laporan'], 'status' => 'disetujui pembina', ]); return redirect() ->route('admin.laporan') ->with('success', 'Laporan kegiatan berhasil ditambahkan.'); } public function update(Request $request, LaporanKegiatan $laporan): RedirectResponse { $validated = $request->validate([ 'isi_laporan' => [ 'required', 'string' ], 'file_laporan' => [ 'nullable', 'file', 'mimes:pdf,doc,docx', 'max:5120' ], ]); if ($request->hasFile('file_laporan')) { if ($laporan->file_laporan && !str_starts_with($laporan->file_laporan, 'http')) { Storage::disk('public')->delete($laporan->file_laporan); } $kegiatan = $laporan->kegiatan; $organisasi = $kegiatan->organisasi; $folder = self::REPORT_DIRECTORY . '/' . Str::slug($organisasi->nama_organisasi); $file = $request->file('file_laporan'); $filename = time() . '_' . $file->getClientOriginalName(); $validated['file_laporan'] = $file->storeAs( $folder, $filename, 'public' ); } $validated['status'] = 'disetujui pembina'; $validated['keterangan'] = null; $laporan->update($validated); return redirect() ->route('admin.laporan') ->with('success', 'Laporan kegiatan berhasil diperbarui.'); } public function destroy(LaporanKegiatan $laporan): RedirectResponse { if ($laporan->file_laporan && !str_starts_with($laporan->file_laporan, 'http')) { Storage::disk('public')->delete($laporan->file_laporan); } $laporan->delete(); return redirect() ->route('admin.laporan') ->with('success', 'Laporan kegiatan berhasil dihapus.'); } public function exportPdf() { $laporan = $this->baseQuery()->get(); $pdf = Pdf::loadView('admin.laporan_pdf', [ 'laporan' => $laporan, ])->setPaper('a4', 'landscape'); return $pdf->download( 'laporan-kegiatan-' . now()->format('YmdHis') . '.pdf' ); } public function download(LaporanKegiatan $laporan): StreamedResponse|RedirectResponse { $file = $laporan->file_laporan; if (! $file) { return back()->with('error', 'File laporan tidak tersedia.'); } if (str_starts_with($file, 'http')) { return redirect()->away($file); } if (! Storage::disk('public')->exists($file)) { return back()->with('error', 'File laporan tidak ditemukan di storage.'); } return Storage::disk('public')->download($file); } private function baseQuery(): Builder { return LaporanKegiatan::with([ 'kegiatan:id,organisasi_id,nama_kegiatan,tanggal_mulai', 'kegiatan.organisasi:id,nama_organisasi', ]) ->where('status', 'disetujui pembina') ->latest('id') ->select([ 'id', 'kegiatan_id', 'isi_laporan', 'file_laporan', 'status', 'keterangan', ]); } }