Skip to content

Latest commit

 

History

History
585 lines (465 loc) · 11.2 KB

File metadata and controls

585 lines (465 loc) · 11.2 KB

Ercode CLI - New Features Guide

🎉 New Features

Ercode CLI telah di-upgrade dengan 2 fitur baru yang sangat powerful:

1. Cubit State Management

Alternative modern dari StatefulWidget menggunakan Flutter Bloc

2. Offline-First Support

Local caching dengan Hive untuk aplikasi yang bisa bekerja offline


🎯 Cubit State Management

Apa itu Cubit?

Cubit adalah state management yang lebih ringan dari Bloc, cocok untuk aplikasi dengan state yang tidak terlalu kompleks. Keuntungan menggunakan Cubit:

  • Reactive: UI update otomatis saat state berubah
  • Testable: Mudah untuk unit testing
  • Predictable: State flow yang jelas
  • Scalable: Cocok untuk project besar

Cara Menggunakan

Tambahkan parameter stateManagement di JSON config:

{
  "name": "product",
  "stateManagement": "cubit",
  "fields": [...]
}

Options:

  • "stateful" (default) - Menggunakan StatefulWidget
  • "cubit" - Menggunakan Flutter Bloc Cubit

Contoh Lengkap

Config: generator/book.json

{
  "name": "book",
  "stateManagement": "cubit",
  "fields": [
    {
      "name": "id",
      "type": "int",
      "primary": true,
      "hidden": true
    },
    {
      "name": "title",
      "type": "String",
      "list": true
    },
    {
      "name": "author",
      "type": "String",
      "list": true
    }
  ]
}

Generate:

ercode generate generator/book.json

Generated Structure:

lib/modules/book/
├── cubit/
│   ├── book_cubit.dart       # Cubit logic
│   └── book_state.dart       # State definitions
├── data/
│   ├── book.dart
│   └── book_repository.dart
└── views/
    ├── book_view.dart        # BlocBuilder UI
    └── book_view_item.dart

Generated Cubit States

Untuk List View, akan ada states:

  • BookInitial - State awal
  • BookLoading - Sedang loading data
  • BookLoaded - Data berhasil dimuat
  • BookEmpty - Data kosong
  • BookError - Terjadi error

Contoh Penggunaan di Code

// Di view, otomatis menggunakan BlocBuilder
BlocBuilder<BookCubit, BookState>(
  builder: (context, state) {
    if (state is BookLoading) {
      return CircularProgressIndicator();
    }
    
    if (state is BookLoaded) {
      return ListView.builder(
        itemCount: state.data.length,
        itemBuilder: (context, index) {
          return BookItem(item: state.data[index]);
        },
      );
    }
    
    return SizedBox();
  },
)

💾 Offline-First Support

Apa itu Offline-First?

Offline-first adalah pendekatan dimana aplikasi:

  • Menyimpan data di local storage (Hive)
  • Menampilkan data cache saat offline
  • Sync dengan server saat online
  • User tetap bisa pakai app tanpa internet

Cara Menggunakan

Tambahkan parameter offlineFirst di JSON config:

{
  "name": "product",
  "stateManagement": "cubit",
  "offlineFirst": true,
  "fields": [...]
}

Note: Offline-first requires Cubit state management

Contoh Lengkap

Config: generator/product.json

{
  "name": "product",
  "stateManagement": "cubit",
  "offlineFirst": true,
  "fields": [
    {
      "name": "id",
      "type": "int",
      "primary": true,
      "hidden": true
    },
    {
      "name": "image",
      "type": "String",
      "input": "image",
      "list": true
    },
    {
      "name": "name",
      "type": "String",
      "list": true
    },
    {
      "name": "price",
      "type": "int",
      "list": true
    },
    {
      "name": "description",
      "type": "String"
    }
  ]
}

Fitur Offline-First

Dengan offlineFirst: true, generated code akan:

  1. Auto-cache data setelah fetch dari API
  2. Load dari cache saat app dibuka (instant loading)
  3. Fallback ke cache jika API error (no internet)
  4. Refresh dari server saat pull-to-refresh
  5. Track last sync time

Alur Kerja

App Start
    ↓
Load from Cache (instant) ← User sees data immediately
    ↓
Fetch from API
    ↓
Save to Cache ← Update cache
    ↓
Update UI

Jika Offline:

App Start
    ↓
Load from Cache
    ↓
Try Fetch from API → Failed
    ↓
Show Cached Data (with offline indicator)

Generated LocalDb Helper

File lib/helpers/local_db.dart akan di-generate dengan methods:

// Save list
await LocalDb.saveList<Product>(
  boxName: 'product',
  key: 'list',
  data: products,
  toJson: (item) => item.toMap(),
);

// Get list
final products = await LocalDb.getList<Product>(
  boxName: 'product',
  key: 'list',
  fromJson: (json) => Product.fromMap(json),
);

// Get last sync time
final lastSync = await LocalDb.getLastSync(boxName: 'product');

🔄 Kombinasi Fitur

Cubit + Offline-First (Recommended)

Kombinasi terbaik untuk aplikasi modern:

{
  "name": "product",
  "stateManagement": "cubit",
  "offlineFirst": true,
  "fields": [...]
}

Benefits:

  • ✅ Reactive UI dengan Cubit
  • ✅ Instant loading dari cache
  • ✅ Bekerja tanpa internet
  • ✅ Auto sync saat online

StatefulWidget + Offline-First

Not Supported: Offline-first hanya tersedia untuk Cubit

Jika Anda butuh offline-first, harus pakai Cubit:

{
  "stateManagement": "cubit",
  "offlineFirst": true
}

📋 Configuration Parameters (Updated)

Module Parameters

Parameter Type Required Default Values Description
name String - - Module name
api String = name - API endpoint
modelName String = name - Model class name
stateManagement String stateful stateful, cubit State management type
offlineFirst Boolean false true, false Enable offline-first
only Array [] - Generate specific modules
fields Array - - Field definitions

🚀 Quick Start Examples

Example 1: Simple List with Cubit

Config:

{
  "name": "note",
  "stateManagement": "cubit",
  "fields": [
    {"name": "id", "type": "int", "primary": true, "hidden": true},
    {"name": "title", "list": true},
    {"name": "content"}
  ]
}

Generate:

ercode generate generator/note.json

Example 2: E-commerce Product with Offline

Config:

{
  "name": "product",
  "stateManagement": "cubit",
  "offlineFirst": true,
  "fields": [
    {"name": "id", "type": "int", "primary": true, "hidden": true},
    {"name": "image", "input": "image", "list": true},
    {"name": "name", "list": true},
    {"name": "price", "type": "int", "list": true},
    {"name": "stock", "type": "int"},
    {"name": "description"}
  ]
}

Generate:

ercode generate generator/product.json

Example 3: News App with Offline

Config:

{
  "name": "article",
  "stateManagement": "cubit",
  "offlineFirst": true,
  "fields": [
    {"name": "id", "type": "int", "primary": true, "hidden": true},
    {"name": "featured_image", "input": "image", "list": true},
    {"name": "title", "list": true},
    {"name": "summary", "list": true},
    {"name": "content"},
    {"name": "author"},
    {"name": "published_at", "list": true}
  ]
}

Example 4: Todo App (Cubit Only)

Config:

{
  "name": "todo",
  "stateManagement": "cubit",
  "fields": [
    {"name": "id", "type": "int", "primary": true, "hidden": true},
    {"name": "title", "list": true},
    {"name": "completed", "type": "bool", "list": true},
    {"name": "description"}
  ]
}

🔧 Migration Guide

From StatefulWidget to Cubit

Jika Anda sudah punya module dengan StatefulWidget:

Before:

{
  "name": "product",
  "fields": [...]
}

After:

{
  "name": "product", 
  "stateManagement": "cubit",
  "fields": [...]
}

Steps:

  1. Backup existing module
  2. Update JSON config
  3. Generate with force flag:
    ercode generate generator/product.json force
  4. Update navigation calls jika ada

Adding Offline-First

Before (Cubit Only):

{
  "name": "product",
  "stateManagement": "cubit",
  "fields": [...]
}

After (Cubit + Offline):

{
  "name": "product",
  "stateManagement": "cubit",
  "offlineFirst": true,
  "fields": [...]
}

Steps:

  1. Update JSON config
  2. Re-generate:
    ercode generate generator/product.json force
  3. Hive akan otomatis handle caching

📦 New Dependencies

ercode init sekarang otomatis install:

dependencies:
  # Existing
  dio: ^4.0.6
  cached_network_image: ^3.2.3
  # ... other deps
  
  # NEW
  flutter_bloc: ^8.1.3     # For Cubit
  hive: ^2.2.3             # For offline storage
  hive_flutter: ^1.1.0     # Hive Flutter adapter

🎓 Best Practices

When to Use Cubit?

Use Cubit when:

  • Building new modules
  • Need reactive UI
  • Want testable code
  • Building medium-large apps

Use StatefulWidget when:

  • Very simple UI
  • Prototype/POC
  • Familiar with StatefulWidget only

When to Use Offline-First?

Use Offline-First when:

  • App needs to work offline
  • Poor network conditions
  • Cache for better UX
  • News, articles, products apps

Skip Offline-First when:

  • Real-time data only
  • Always-online apps
  • Simple CRUD without cache

Recommended Combinations

Use Case State Management Offline-First
News App cubit true
E-commerce cubit true
Social Media Feed cubit true
Simple Admin stateful false
Real-time Chat cubit false
Todo App cubit true

🐛 Troubleshooting

Error: "Cubit not found"

Solution:

  1. Run flutter pub get
  2. Check if flutter_bloc installed
  3. Re-run ercode init

Error: "Hive box not found"

Solution: Add init to main.dart:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await LocalDb.init();  // Add this
  runApp(MyApp());
}

Offline mode not working

Solution:

  1. Check offlineFirst: true in JSON
  2. Check stateManagement: "cubit" is set
  3. Verify Hive initialized
  4. Check console for cache errors

BlocProvider error

Solution: Make sure you're using the generated view correctly:

// Correct
Get.to(BookView());

// Wrong - don't create Cubit manually
Get.to(BlocProvider(create: ...));

📚 Learn More


🎉 Summary

New features available:

  1. Cubit State Management

    • Add "stateManagement": "cubit" to JSON
    • Modern, reactive, testable code
  2. Offline-First Support

    • Add "offlineFirst": true to JSON (requires Cubit)
    • Auto caching with Hive
    • Works without internet

Migration:

  • Existing modules still work (backward compatible)
  • New modules can use Cubit
  • Offline-first is optional

Next Steps:

  1. Run ercode init to install new dependencies
  2. Update JSON configs with new parameters
  3. Generate modules with ercode generate

Happy Coding! 🚀