feat: Plan 5 — Ekspor PDF + Ekspor per Radius + Cetak Laporan

- Add ExportController: allMiskinPDF (all data) + radiusMiskinPDF
  (server-side Haversine filtering per ibadah radius)
- Add two table-based PDF Blade views (dompdf-compatible, no flexbox/grid)
- Add export routes (/export/pdf, /export/pdf/radius/{id}/{radius})
  with numeric route constraints
- Add "Ekspor PDF" button to data tabular view
- Add CSV + PDF radius export buttons to map analysis panel;
  exportRadiusCSV() reuses existing isInside(); PDF href synced on
  ibadah click and radius slider change
- 5 new tests: access control, PDF content-type, 404 + param validation
- Mark K-04 and Section 5 (Cetak & Ekspor) complete in missing_features.md
- Update README with export features

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
GuavaPopper
2026-06-03 20:44:10 +07:00
parent 4649a983ef
commit 1fcad7d9b2
9 changed files with 327 additions and 9 deletions
+7
View File
@@ -2,6 +2,7 @@
use App\Http\Controllers\AdminUserController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ExportController;
use App\Http\Controllers\IbadahController;
use App\Http\Controllers\MiskinController;
use Illuminate\Support\Facades\Route;
@@ -20,6 +21,12 @@ Route::middleware('auth')->group(function () {
Route::get('/data', fn() => view('data'));
Route::get('/dashboard', fn() => view('dashboard'))->name('dashboard');
// Export routes — semua role authenticated bisa ekspor
Route::get('/export/pdf', [ExportController::class, 'allMiskinPDF'])->name('export.pdf.all');
Route::get('/export/pdf/radius/{ibadahId}/{radius}', [ExportController::class, 'radiusMiskinPDF'])
->name('export.pdf.radius')
->where(['ibadahId' => '[0-9]+', 'radius' => '[0-9]+']);
// API routes moved here for session + CSRF middleware
Route::prefix('api')->group(function () {