All Projects
WebIn Progress
E-Plantation Web — Dashboard & Manajemen Operasional Perkebunan
Juni 2025 — On Going

Overview
E-Plantation Web adalah antarmuka utama sistem E-Plantation. Dibangun dengan pendekatan component-based menggunakan Next.js sebagai SSR framework, Redux Toolkit untuk global state, dan Material-UI sebagai design system. Mencakup 50+ halaman aplikasi, 200+ komponen UI reusable, dan 30+ Redux module yang masing-masing mengatur state per fitur domain bisnis. Terintegrasi dengan Metabase untuk embedded analytics dashboard dan mendukun operasi file seperti upload, download Excel, serta cetak PDF langsung dari browser.
Key Features
- Dashboard Analitik — Overview KPI perkebunan dengan chart dan summary cards
- Manajemen SPB — CRUD Surat Pengantar Buah dengan cetak PDF langsung dari browser
- Tonase Kebun & PKS — Input dan tracking data panen per blok
- Perencanaan Kerja — Form RKT/RKB/RKH dengan validasi dan approval flow
- Approval Workflow UI — Interface untuk submit, approve, reject dokumen dengan history
- Pemeliharaan — Pemupukan, checkup item, maintenance tracking
- Manajemen Keuangan — Budgeting, cost, perpajakan dengan tabel interaktif
- Master Data — CRUD organisasi, divisi, blok, user, role berbasis permission
- Laporan & Analytics — Performance report, budget vs realisasi, BJR dashboard via Metabase
- Role-based UI — Komponen dan menu yang tampil dinamis sesuai permission user
- Export/Import Excel — Bulk upload data dengan template Excel terstandarisasi
- Responsive Design — Mobile-first layout dengan breakpoint MUI
Challenges
- State management yang kompleks — 30+ Redux module dengan interdependensi antar domain (contoh: filter organisasi memengaruhi data di puluhan halaman berbeda)
- Metabase embedding — JWT-signed URL untuk iframe Metabase harus di-generate server-side, sementara frontend Next.js perlu handle refresh token dan resolusi hostname (localhost vs container name)
- Permission-based rendering — Ratusan komponen dan menu harus dirender kondisional berdasarkan role + module permission, tanpa performa degradasi.
- Form kompleks dengan data relasional — Form RKH misalnya menghubungkan blok, sub-aktivitas, karyawan, dan biaya dalam satu transaksi
- Konsistensi tipe data — Puluhan interface TypeScript harus sinkron dengan response API backend yang terus berkembang
Solutions
- Feature-based Redux slices — setiap domain punya slice sendiri (rkt/, spb/, gardenTonnage/), dan filter global disimpan di shared state yang di-subscribe per module
- Custom metabase.ts util — men-generate JWT-signed URL di sisi backend, kemudian dikirim ke frontend sebagai signed token; hostname-nya di-resolve via environment variable
- accesses.ts utility — centralized permission check function yang digunakan di seluruh komponen untuk konsistensi guard logic
- Print-specific CSS + isolated print component — PrintSuratJalanButton.tsx menggunakan window.print() dengan stylesheet terpisah yang di-inject hanya saat print mode
- Formik + Yup schema — validasi multi-level field dengan schema terpisah per form kompleks; nested field array menggunakan FieldArray
- Centralized model types (src/model/) — 50+ TypeScript interface yang menjadi single source of truth untuk semua response shape dari API
Lessons Learned
- Redux terlalu granular bisa jadi overhead — 30+ slice untuk project ini cukup manage, tapi untuk feature baru yang kecil, React local state + SWR/React Query lebih ringan
- Metabase iframe lebih mudah dari custom chart — untuk analytics kompleks seperti BJR, menggunakan Metabase embedded jauh lebih cepat daripada rebuild chart dari scratch
- Design system dari awal menghemat waktu — konsistensi MUI theme + custom component library (src/presentation/components/) membuat development page baru jauh lebih cepat
- Type-safety antara FE dan BE perlu dijaga aktif — tanpa contract testing atau shared types, perubahan response API backend sering menyebabkan runtime error di FE yang baru ketahuan saat testing
- Next.js SSR + Redux perlu setup hydration yang benar — state yang diinisialisasi di server harus match di client untuk menghindari hydration mismatch error yang susah di-debug