Ubah Sampahmu Jadi GreenCoin β gerakan daur ulang Surabaya berbasis aplikasi mobile.
- Tentang Project
- Fitur Utama
- Tech Stack
- Arsitektur
- Struktur Folder
- Setup & Instalasi
- Akun Demo
- Database & Migration
- Business Rules
- Skrip Penting
- Test
- Roadmap & TODO
- Lisensi
EcoPoin adalah aplikasi mobile Flutter + Supabase yang membantu masyarakat mengelola aktivitas daur ulang sampah menjadi saldo digital bernama GreenCoin (GC). Setiap kilogram sampah yang disetor diubah menjadi GC berdasarkan rate kategori yang ditentukan admin. Saldo GC dapat:
- πΈ Dicairkan ke e-wallet (DANA, GoPay, OVO, ShopeePay) β minimal Rp 10.000.
- π Ditukar di Marketplace dengan barang kebutuhan sehari-hari (beras, minyak, detergen, dll).
Project ini dibangun sebagai tugas akhir UAS dengan fokus pada arsitektur feature-first, RLS Supabase, dan operasi saldo atomik via RPC PostgreSQL.
1 GC = Rp 100 (configurable di core/constants/app_strings.dart)
| Fitur | Deskripsi |
|---|---|
| π Beranda | Dashboard dinamis: saldo, total sampah, total transaksi, CO2 dihemat, grafik aktivitas 7 hari, breakdown kategori, riwayat terbaru. Empty state untuk akun baru. |
| π EcoPick | Pengajuan penjemputan sampah ke lokasi user. Pilih kategori, berat, tanggal, slot waktu, lokasi. Validasi berat β€ 0 β popup. |
| π EcoDrop | Setor mandiri ke Bank Sampah Induk Surabaya. Upload foto bukti, kategori, berat. |
| π° GreenCoin Wallet | Saldo + konversi Rupiah, riwayat transaksi (filter Semua/Masuk/Keluar), tarik dana via bottom sheet. |
| π Marketplace | Tukar GC dengan produk fisik. Setiap produk ada emoji (π π’οΈ π§Ί π§Ό πͺ₯ dst), nama, stok, harga. |
| π Status Transaksi | Daftar semua EcoPick/EcoDrop user dengan status (pending/process/completed/rejected). |
| π€ Profil | Edit nama, telepon, ganti password, logout. |
| πͺ Login Cepat | Chip akun yang pernah login β tap untuk auto-fill + auto-submit (credential disimpan via flutter_secure_storage terenkripsi). |
| Fitur | Deskripsi |
|---|---|
| π Overview Dashboard | Statistik platform: total pengguna, transaksi, sampah terkumpul, GC beredar, log aktivitas terbaru. |
| π₯ Users Management | List semua user, search, lihat detail aktivitas. |
| π EcoPick Management | Pantau permintaan penjemputan, set status completed/rejected. |
| π EcoDrop Management | Verifikasi setor mandiri, set status. |
| πΈ Transactions & GreenCoin | Pantau seluruh transaksi GC, withdraw yang sedang diproses, total beredar/dicairkan. |
| π Marketplace Management | CRUD produk: nama, deskripsi, emoji, harga GC, stok, status aktif. |
| π Master Data | CRUD kategori sampah + rate GC per kg. |
| Layer | Tools |
|---|---|
| Frontend | Flutter 3.41, Dart 3.5+ |
| State | flutter_riverpod 2.5 |
| Routing | go_router 14.2 (ShellRoute untuk bottom nav) |
| Backend | Supabase: PostgreSQL + Auth + Storage + Realtime + Edge Functions |
| Secure storage | flutter_secure_storage 9.2 (untuk Login Cepat) |
| Charts | fl_chart 0.68 |
| i18n & format | intl (Rupiah, tanggal Indonesia) |
| Env config | flutter_dotenv |
| Picker gambar | image_picker (untuk EcoPick/EcoDrop foto bukti) |
| Testing | flutter_test, integration_test, mocktail |
graph TD
A[User Flutter App] --> B[Presentation Layer<br/>Pages & Widgets]
B --> C[State Layer<br/>Riverpod Providers]
C --> D[Service Layer<br/>Pure Dart classes]
D --> E[Supabase Client SDK]
E --> F[Supabase Auth]
E --> G[(PostgreSQL<br/>+ RLS Policies)]
E --> H[Supabase Storage]
E --> I[Supabase Realtime]
J[Admin Flutter Interface] --> B
G --> K[RPC: adjust_balance<br/>atomic balance update]
G --> L[Trigger: handle_new_user<br/>auto-create profile]
Lapisan:
- Presentation β
lib/features/*/presentation/β screens, widgets, bottom sheets. - State β
lib/features/*/providers/β RiverpodProvider/StateNotifierProvider/FutureProvider. - Domain / Models β
lib/features/*/models/β immutable data classes denganfromMap. - Service / Data β
lib/features/*/data/β komunikasi ke Supabase. Tidak ada query DB langsung di widget. - Database β
supabase/migrations/SQL untuk schema +supabase/policies.sqluntuk RLS +supabase/seed.sqluntuk default data.
ecopoin_app/
βββ lib/
β βββ main.dart # Entry point β init Supabase, dotenv, intl
β βββ app.dart # MaterialApp.router dengan AppTheme
β βββ core/
β β βββ config/ # supabase_config.dart (init + isConfigured)
β β βββ constants/ # app_colors, app_sizes, app_strings (enum & const)
β β βββ errors/ # AppException, AuthException, InsufficientBalance
β β βββ routing/ # app_router.dart (ShellRoute + 6 tabs)
β β βββ theme/ # app_theme.dart (Material3, green identity)
β β βββ utils/ # formatters (Rupiah, GC, weight), validators
β βββ shared/
β β βββ widgets/ # Reusable: AppCard, PrimaryButton, StatusBadge,
β β # LabeledField, EcoLogo, MainShell, SuccessHeader,
β β # MotionFadeSlide (animasi entrance)
β βββ features/
β βββ auth/ # Landing, Login (dengan Login Cepat chips), Register
β βββ dashboard/ # User home: metrics, weekly chart, kategori, recent
β βββ ecopick/ # Form penjemputan + success page
β βββ ecodrop/ # Form setor mandiri + success page
β βββ greencoin/ # Wallet + withdraw bottom sheet + success page
β βββ marketplace/ # Katalog produk + exchange flow
β βββ status/ # Daftar status transaksi
β βββ profile/ # Edit profil + ubah password
β βββ admin/ # Admin overview, drawer, master data, marketplace mgmt
βββ supabase/
β βββ migrations/0001_init.sql # Schema: 9 tabel + trigger + RPC
β βββ policies.sql # RLS user/admin policies
β βββ seed.sql # Default kategori sampah + produk
βββ test/widget_test.dart # Unit tests untuk formatters & validators
βββ .env.example # Template β SUPABASE_URL + SUPABASE_ANON_KEY
βββ .gitignore # Termasuk .env, .mcp.json (NEVER commit)
βββ pubspec.yaml
βββ README.md (kamu sedang baca ini)
Feature-first seperti yang disarankan PRD. Setiap fitur self-contained dengan
data/models/providers/presentation.
- Flutter SDK β₯ 3.41 (install guide)
- Dart SDK β₯ 3.5 (ikut dengan Flutter)
- Akun Supabase (daftar gratis)
- Android Studio / Xcode untuk run di emulator/device
git clone https://github.com/BlindCr/EcoPick-UAS.git
cd EcoPick-UASflutter pub geta) Buat project baru di supabase.com/dashboard β ambil URL dan anon key dari Settings β API.
b) Salin .env.example ke .env:
cp .env.example .envc) Isi .env:
SUPABASE_URL=https://xxxx.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOi...Penting:
.envsudah ada di.gitignoreβ JANGAN commit. Jika.envbelum diisi (masih placeholder), aplikasi otomatis jalan dalam demo mode dengan data dummy.
d) Jalankan SQL berurutan di Supabase SQL Editor:
| Step | File | Fungsi |
|---|---|---|
| 1 | supabase/migrations/0001_init.sql |
Schema 9 tabel + trigger updated_at + trigger handle_new_user + RPC adjust_balance |
| 2 | supabase/policies.sql |
RLS policy: user akses data sendiri, admin akses lintas-user |
| 3 | supabase/seed.sql |
7 kategori sampah + 4 produk marketplace default |
e) (Opsional) Promote user pertama jadi admin (setelah register lewat app):
update public.profiles set role = 'admin' where email = 'email-anda@example.com';# Android emulator / device
flutter run
# iOS Simulator
flutter run -d iPhoneSetelah migration + seed dijalankan, akun admin sudah otomatis ter-setup:
| Role | Password | |
|---|---|---|
| Admin | admin@ecopoin.id |
admin12345 |
Login sebagai admin β otomatis redirect ke /admin.
Login sebagai user biasa β otomatis ke /home (Beranda).
User baru dapat register lewat halaman Daftar Akun Baru β trigger handle_new_user otomatis bikin row di profiles dengan role user dan saldo 0 GC.
Demo Mode: Kalau
.envbelum diisi (placeholder), aplikasi pakai user dummyAlexa M.untuk preview UI tanpa setup backend.
| Tabel | Deskripsi |
|---|---|
profiles |
Data user publik (linked ke auth.users.id) + saldo + role |
waste_categories |
Kategori sampah + rate GC per kg + flag aktif |
ecopick_requests |
Permintaan penjemputan sampah |
ecodrop_requests |
Setor sampah mandiri |
greencoin_transactions |
Ledger semua transaksi GC (immutable history) |
withdraw_requests |
Permintaan pencairan ke e-wallet |
marketplace_products |
Katalog produk + harga GC + emoji |
marketplace_orders |
Order penukaran GC β produk |
platform_logs |
Audit log admin actions |
Setiap tabel user-facing punya RLS aktif. Pattern:
- User:
auth.uid() = user_idβ bisa read/insert data sendiri. - Admin:
public.is_admin(auth.uid())β bisa read/write lintas user.
Operasi saldo wajib lewat fungsi ini agar atomic:
select public.adjust_balance(
p_user_id => 'uuid',
p_amount => 150, -- positif = earn, negatif = withdraw/exchange
p_source_type => 'ecopick',
p_source_id => 'tx-uuid',
p_transaction_type => 'earn',
p_description => 'EcoPick β 2 kg plastik'
);Function:
- Update
profiles.green_coin_balance. - Raise exception jika saldo jadi negatif.
- Insert ledger row di
greencoin_transactions.
| Rule | Implementasi |
|---|---|
GC bertambah saat EcoPick/EcoDrop completed |
EcoPickService.submit() & EcoDropService.submit() panggil adjust_balance |
| GC berkurang saat withdraw / marketplace order | Sama via adjust_balance dengan amount negatif |
| Withdraw minimal Rp 10.000 | Validasi di WithdrawBottomSheet |
| Berat sampah β€ 0 β popup tidak valid | EcoPick & EcoDrop validate sebelum submit |
| Stok marketplace β produk habis tidak bisa ditukar | MarketplaceService.exchange() cek stok terbaru di DB sebelum order |
| Saldo dikembalikan jika order dibatalkan | TODO (currently soft-delete only) |
| Admin tidak bisa di-edit jadi role user dari client | RLS policy block update role pada profiles |
| Estimasi CO2 dihemat | kg sampah Γ 0.34 (kg CO2 saved per kg recycled) |
# Run di device
flutter run
# Run dengan device tertentu
flutter devices
flutter run -d <device-id>
# Test
flutter test
# Analyze (lint + type check)
flutter analyze
# Build APK Android release
flutter build apk --release
# Build iOS (perlu Mac + Xcode)
flutter build ios --release
# Generate icon launcher (jika setup flutter_launcher_icons)
flutter pub run flutter_launcher_icons
# Clean & rebuild
flutter clean && flutter pub getflutter testYang sudah ada di test/widget_test.dart:
- β
Formattersβ konversi GC β Rupiah, format berat, format GreenCoin - β
Validatorsβ email valid, password β₯ 8 char, format telepon Indonesia
Hasil: 6/6 passing. flutter analyze 0 errors.
- Auth Supabase (signup/signin/signout) + auto-create profile via trigger
- Login Cepat (chip akun yang pernah login dengan secure storage)
- Role-based routing (admin β /admin, user β /home)
- Dashboard real-time dari Supabase (empty state untuk akun baru)
- EcoPick + EcoDrop dengan validasi berat + save atomik
- GreenCoin wallet + withdraw flow + success page
- Marketplace dengan emoji + exchange (decrement stok + balance)
- Admin: overview, master data (kategori), marketplace management
- RLS Policies + RPC adjust_balance
- Theme hijau konsisten dengan animasi entrance (MotionFadeSlide)
- Integrasi
google_maps_flutteruntuk picker lokasi EcoPick (saat ini placeholder) - Upload foto bukti EcoDrop ke Supabase Storage
- Realtime subscription untuk status update (notif user saat admin approve)
- Withdraw oleh user yang ditolak β refund saldo otomatis (saat ini perlu manual)
- Admin sub-pages: detail user, detail EcoPick/EcoDrop dengan tombol approve/reject
- Refactor admin_dashboard_page.dart (2543 baris) menjadi file per-section
- Push notification via FCM
- CI/CD pipeline (GitHub Actions: lint + test on PR)
Tambahkan screenshot di sini setelah build:
docs/screenshots/ βββ landing.png βββ dashboard.png βββ ecopick.png βββ greencoin.png βββ marketplace.png βββ admin-overview.png
Hariz β UAS Mobile Programming
- GitHub: @BlindCr
Project akademik EcoPoin UAS. Bebas untuk pembelajaran & referensi. Tidak untuk komersial tanpa izin.