Tujuan:
i. Mendefinisikan gaya teks yang konsisten di seluruh aplikasi.
ii. Memudahkan dalam mengubah gaya teks secara global.
iii. Meningkatkan keterbacaan dan estetika aplikasi.
Langkah-langkah:
i. Buat widgetTextComponent: Widget ini menerima parameter seperti teks, ukuran font, warna, dan weight.
ii. Definisikan style: Buat TextStyle yang berbeda-beda untuk judul, subjudul, dan teks biasa.
iii. GunakanTextwidget: Gunakan Text widget dengan TextStyle yang sesuai berdasarkan parameter yang diberikan.
Contoh:
TextComponent(
text: 'Ini adalah judul utama',
style: Theme.of(context).textTheme.headline1,
)
ButtonComponent
Tujuan:
i. Mendefinisikan tampilan tombol yang konsisten.
ii. Memudahkan dalam membuat tombol dengan berbagai gaya.
iii. Meningkatkan interaksi pengguna.
Langkah-langkah:
i. Buat widgetButtonComponent: Widget ini menerima parameter seperti teks tombol, fungsi yang akan dijalankan saat tombol ditekan, warna, dan lebar.
ii. GunakanElevatedButtonatauOutlinedButton: Pilih jenis tombol yang sesuai dengan desain.
iii. Sesuaikan tampilan: Atur borderRadius, padding, dan properti lainnya sesuai kebutuhan.
Contoh Penggunaan:
ButtonComponent(
text: 'Beli Sekarang',
onPressed: () {
// Lakukan sesuatu saat tombol ditekan
},
color: Colors.blue,
)
ProgressBarComponent:
Tujuan:
i. Menampilkan indikator progres suatu proses.
ii. Memberikan umpan balik visual kepada pengguna.
Langkah-langkah:
i. Buat widget ProgressBarComponent: Widget ini menerima parameter seperti nilai progres (antara 0-1).
ii. Gunakan LinearProgressIndicator atau CircularProgressIndicator: Pilih jenis progress bar yang sesuai dengan desain.
iii. Sesuaikan tampilan: Atur warna, lebar, dan gaya lainnya.
Tujuan:
i. Menampilkan gambar profil pengguna.
ii. Memberikan identitas visual kepada pengguna.
Langkah-langkah:
i. Buat widgetAvatarComponent: Widget ini menerima parameter seperti URL gambar, ukuran, dan fungsi yang akan dijalankan saat avatar ditekan.
ii. GunakanCircleAvatar: Untuk membuat avatar berbentuk lingkaran.
iii. GunakanNetworkImage: Untuk memuat gambar dari URL.
iv. Tambahkan fitur opsional: Seperti border, shadow, atau inisial jika gambar tidak tersedia.
Contoh Penggunaan:
AvatarComponent(
imageUrl: 'https://example.com/avatar.jpg',
size: 50,
onTap: () {
// Navigasi ke profil pengguna
},
)
NetworkImageLoader:
Tujuan:
i. Memudahkan dalam memuat gambar dari jaringan.
ii. Menangani error dan loading state.
Langkah-langkah:
i. Buat fungsiNetworkImageLoader: Fungsi ini menerima URL gambar sebagai parameter.
ii. GunakanImage.network: Untuk memuat gambar dari URL.
iii. TambahkanerrorBuilderdanloadingBuilder: Untuk menampilkan pesan error atau indikator loading saat gambar sedang dimuat atau gagal dimuat.
Tujuan
i. Titik Masuk Aplikasi: File ini adalah titik awal eksekusi aplikasi Flutter Anda.
ii. Inisialisasi Aplikasi: Melakukan konfigurasi awal aplikasi, seperti tema, rute navigasi, dan pengaturan lainnya.
iii. Menampilkan Widget Utama: Menentukan widget yang akan ditampilkan pertama kali saat aplikasi dijalankan.
Langkah-langkah:
i. Import Library: Impor library yang diperlukan, terutama material.dart atau cupertino.dart.
ii. Buat Fungsi main: Fungsi utama untuk menjalankan aplikasi.
iii. Buat Widget Utama: Buat widget StatelessWidget atau StatefulWidget sebagai akar aplikasi.
iv. KonfigurasiMaterialAppatauCupertinoApp: Atur judul aplikasi (title).Tentukan tema (theme). Tentukan layar awal (home). Konfigurasi rute navigasi (routes, onGenerateRoute).
v. Jalankan Aplikasi: Panggil runApp dengan widget utama sebagai argumen.
Tujuan
i. Membungkus Logika Navigasi: Menyembunyikan kompleksitas navigasi di balik fungsi-fungsi yang mudah digunakan.
ii. Meningkatkan Reusabilitas: Fungsi-fungsi navigasi dapat digunakan di berbagai bagian aplikasi tanpa perlu menulis ulang kode.
iii. Meningkatkan Keterbacaan: Membuat kode lebih mudah dipahami dengan menggunakan nama fungsi yang jelas.
Langkah-langkah Implementasi
i. Buat Enum untuk Rute
ii. Definisikan fungsi navigasi
iii. Konfigurasi Rute di main.dart
Contoh Penggunaan:
// Di suatu widget
ElevatedButton(
onPressed: () {
push(context, AppRoutes.profile);
},
child: Text('Profil'),
)
date_utils.dart:
Tujuan:
i. Menyediakan fungsi-fungsi untuk memanipulasi dan memformat tanggal dan waktu.
ii. Membuat tampilan tanggal dan waktu menjadi lebih konsisten dan sesuai dengan kebutuhan aplikasi.
iii. Memudahkan dalam melakukan perhitungan terkait tanggal dan waktu.
Langkah-langkah:
i. Import Library: Library intl menyediakan berbagai format tanggal dan waktu yang bisa disesuaikan.
ii. Definisikan Fungsi-fungsi: Memformat tanggal, memformat waktu, mendapatkan selisih waktu, Mengecek apakah tanggal sudah lewat, dll.
Contoh Penggunaan:
// Mendapatkan tanggal hari ini dalam format "dd MMMM yyyy"
String today = formatDate(DateTime.now(), format: 'dd MMMM yyyy');
// Menghitung selisih waktu antara dua tanggal
Duration difference = calculateTimeDifference(DateTime(2023, 1, 1), DateTime.now());
device_utils.dart:
Tujuan:
i. Menyediakan fungsi-fungsi untuk memanipulasi dan memformat tanggal dan waktu.
ii. Membuat tampilan tanggal dan waktu menjadi lebih konsisten dan sesuai dengan kebutuhan aplikasi.
iii. Memudahkan dalam melakukan perhitungan terkait tanggal dan waktu.
Langkah-langkah:
i. Import Library: Library device_info_plus digunakan untuk mendapatkan informasi spesifik perangkat.
ii. Definisikan Fungsi-fungsi: Mendapatkan informasi perangkat, Mengecek orientasi layar, Mendapatkan ukuran layar, dll
Contoh Penggunaan:
// Mendapatkan model perangkat
String deviceModel = await getDeviceModel();
// Mengecek apakah layar dalam mode landscape
bool isLandscapeMode = isLandscape(context);
4. Constants (core/constants)
strings.dart:
Tujuan:
i. Memusatkan Teks Statis: Mengumpulkan semua teks statis yang digunakan dalam aplikasi ke dalam satu tempat.
ii. Meningkatkan Keterbacaan Kode: Memudahkan dalam mengubah teks tanpa perlu mencari-cari di seluruh kode.
iii. Memudahkan Terjemahan: Memudahkan proses terjemahan jika aplikasi ingin mendukung beberapa bahasa.
iv. Menghindari Hardcoding: Mencegah terjadinya kesalahan pengetikan dan mempermudah pengelolaan teks.
Langkah-langkah:
i. Buat File: Buat file strings.dart di dalam direktori constants.
ii. Definisikan Konstanta seperti label tombol, pesan error, dan placeholder.
Tujuan:
i. Membangun Sistem Warna yang Konsisten: Mendefinisikan palet warna yang akan digunakan di seluruh aplikasi.
ii. Memudahkan Perubahan Tema: Memudahkan dalam mengubah tampilan keseluruhan aplikasi dengan mengubah nilai konstanta warna.
iii. Meningkatkan Keterbacaan Kode: Membuat kode lebih mudah dibaca dengan menggunakan nama warna yang jelas.
Langkah-langkah:
i. Buat File: Buat file colors.dart di dalam direktori constants.
ii. Definisikan Warna: seperti primaryColor, secondaryColor, dan warna latar belakang.
Tujuan:
i. Membuat Tampilan Responsif: Mendefinisikan ukuran dimensi yang dapat disesuaikan dengan berbagai ukuran layar.
ii. Meningkatkan Keterbacaan Kode: Membuat kode lebih mudah dibaca dengan menggunakan nama dimensi yang jelas.
iii. Memudahkan Perubahan Desain: Memudahkan dalam mengubah ukuran elemen-elemen UI.
Langkah-langkah:
i. Buat File: Buat file dimens.dart di dalam direktori constants.
ii. Definisikan Dimensi: seperti padding, margin, dan radius.
Contoh Penggunaan:
import 'package:flutter/material.dart';
import 'constants/dimens.dart';
class MyCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.all(defaultPadding),
child: Text('Ini adalah sebuah card'),
),
);
}
}
assets.dart:
Tujuan:
i. Memusatkan Path Aset: Mengumpulkan semua path ke aset (gambar, ikon, font) dalam satu tempat.
ii. Meningkatkan Keterbacaan Kode: Memudahkan dalam mengelola dan mengubah path aset.
iii. Mencegah Kesalahan Path: Mencegah kesalahan pengetikan path aset.
Langkah-langkah:
i. Buat File: Buat file assets.dart di dalam direktori constants.
ii. Definisikan Path: seperti gambar, ikon, dan font.
Tujuan:
i. Merepresentasikan data produk secara rinci.
ii. Mendefinisikan atribut-atribut yang dimiliki oleh sebuah produk, seperti nama, harga, deskripsi, gambar, dll.
Langkah-langkah:
i. Definisi Kelas: Buat kelas Product dengan atribut-atribut yang sesuai.
ii. Tipe Data: Tentukan tipe data yang tepat untuk setiap atribut (misalnya, String untuk nama, double untuk harga).
iii. Constructor: Buat constructor untuk menginisialisasi objek Product.
iv. Getter dan Setter: Tambahkan getter dan setter untuk mengakses dan memodifikasi nilai atribut.
Tujuan:
i. Merepresentasikan keranjang belanja pengguna.
ii. Mendefinisikan atribut-atribut yang terkait dengan keranjang belanja, seperti daftar produk, total harga, dll.
Langkah-langkah:
i. Definisi Kelas: Buat kelas Cart dengan atribut-atribut yang sesuai.
ii. Tipe Data: Gunakan List untuk menyimpan daftar produk dalam keranjang.
iii. Metode: Tambahkan metode untuk menambahkan produk ke keranjang, menghapus produk dari keranjang, menghitung total harga, dll.
Contoh Penggunaan:
class Cart {
List<Product> items = [];
void addItem(Product product) {
items.add(product);
}
double getTotalPrice() {
// Hitung total harga berdasarkan daftar produk
}
}
ProductRepository.dart
Tujuan:
i. Mengabstraksikan logika akses data untuk produk.
ii. Memisahkan logika bisnis terkait produk dari ViewModel.
iii. Menyediakan metode untuk mengambil, menambahkan, memperbarui, dan menghapus data produk dari sumber data (misalnya, database, API).
Langkah-langkah:
i. Definisi Kelas: Buat kelas ProductRepository dengan metode-metode yang sesuai untuk operasi CRUD (Create, Read, Update, Delete) pada data produk.
ii. Implementasi Metode:
getProducts(): Mengambil daftar semua produk dari sumber data.
getProductById(id): Mengambil detail produk berdasarkan ID.
addProduct(product): Menambahkan produk baru ke sumber data.
updateProduct(product): Memperbarui data produk yang sudah ada.
deleteProduct(id): Menghapus produk berdasarkan ID.
iii. Penggunaan Sumber Data:
Gunakan library atau framework yang sesuai untuk berinteraksi dengan sumber data (misalnya, SQLite, Firebase, REST API).
Implementasikan logika untuk memetakan data dari sumber data ke objek Product.
Contoh Penggunaan:
class ProductRepository {
Future<List<Product>> getProducts() async {
// Implementasi untuk mengambil data produk dari database atau API
// ...
return products;
}
Future<Product?> getProductById(String id) async {
// Implementasi untuk mengambil detail produk berdasarkan ID
// ...
return product;
}
Future<void> addProduct(Product product) async {
// Implementasi untuk menambahkan produk baru ke database
// ...
}
// ...
}
CartRepository.dart
Tujuan:
i. Mengabstraksikan logika akses data untuk keranjang belanja.
ii. Memisahkan logika bisnis terkait keranjang belanja dari ViewModel.
iii. Menyediakan metode untuk mengambil, menambahkan, menghapus produk dari keranjang belanja, dan menyimpan status keranjang.
Langkah-langkah:
i. Definisi Kelas: Buat kelas CartRepository dengan metode-metode yang sesuai untuk operasi pada keranjang belanja.
ii. Implementasi Metode:
getCart(): Mengambil data keranjang belanja dari penyimpanan lokal (misalnya, SharedPreferences).
addItemToCart(product): Menambahkan produk ke keranjang belanja.
removeItemFromCart(product): Menghapus produk dari keranjang belanja.
clearCart(): Mengosongkan keranjang belanja.
saveCart(cart): Menyimpan data keranjang belanja ke penyimpanan lokal.
iii. Penggunaan Penyimpanan Lokal: Gunakan library atau framework yang sesuai untuk menyimpan data keranjang belanja secara lokal (misalnya, SharedPreferences, SQLite).
Contoh Penggunaan:
class CartRepository {
Future<Cart> getCart() async {
// Implementasi untuk mengambil data keranjang dari SharedPreferences
// ...
return cart;
}
Future<void> addItemToCart(Product product) async {
// Implementasi untuk menambahkan produk ke keranjang dan menyimpan ke SharedPreferences
// ...
}
// ...
}
2. Profile
User.dart
Tujuan:
i. Merepresentasikan data pengguna secara rinci.
ii. Mendefinisikan atribut-atribut yang dimiliki oleh seorang pengguna, seperti nama, email, alamat, nomor telepon, dan lain-lain.
Langkah-langkah:
i. Definisi Kelas: Buat kelas User dengan atribut-atribut yang sesuai.
ii. Tipe Data: Tentukan tipe data yang tepat untuk setiap atribut (misalnya, String untuk nama, String untuk email).
iii. Constructor: Buat constructor untuk menginisialisasi objek User.
iv. Getter dan Setter: Tambahkan getter dan setter untuk mengakses dan memodifikasi nilai atribut.
Contoh Penggunaan:
class User {
String name;
String email;
String address;
String phoneNumber;
User({required this.name, required this.email, required this.address, required this.phoneNumber});
}
UserRepository.dart
Tujuan:
i. Mengabstraksikan logika akses data untuk pengguna.
ii. Memisahkan logika bisnis terkait pengguna dari ViewModel.
iii. Menyediakan metode untuk mengambil, menambahkan, memperbarui, dan menghapus data pengguna dari sumber data (misalnya, database, API).
Langkah-langkah:
i. Definisi Kelas: Buat kelas UserRepository dengan metode-metode yang sesuai untuk operasi CRUD (Create, Read, Update, Delete) pada data pengguna.
ii. Implementasi Metode:
getUser(): Mengambil data pengguna yang sedang login.
updateUser(user): Memperbarui data pengguna yang sudah ada.
registerUser(user): Mendaftarkan pengguna baru.
iii. Penggunaan Sumber Data:
Gunakan library atau framework yang sesuai untuk berinteraksi dengan sumber data (misalnya, Firebase, Supabase, REST API).
Contoh Penggunaan:
class UserRepository {
Future<User> getUser() async {
// Implementasi untuk mengambil data pengguna dari database atau API
// ...
return user;
}
Future<void> updateUser(User user) async {
// Implementasi untuk memperbarui data pengguna di database
// ...
}
}
ProfileViewModel.dart
Tujuan:
i. Mengelola logika bisnis terkait profil pengguna.
ii. Menyediakan data untuk tampilan profil pengguna.
iii. Menangani interaksi pengguna pada tampilan profil (misalnya, mengedit profil).
Langkah-langkah:
i. Definisi Kelas: Buat kelas ProfileViewModel yang extends ChangeNotifier.
ii. Variabel: Simpan objek User yang sedang aktif.
iii. Metode:
getUser(): Memanggil UserRepository untuk mengambil data pengguna.
updateUser(user): Memanggil UserRepository untuk memperbarui data pengguna.
notifyListeners(): Memberitahu widget yang mendengarkan perubahan data untuk memperbarui tampilan.
Contoh Penggunaan:
class ProfileViewModel extends ChangeNotifier {
final UserRepository _userRepository = UserRepository();
User _user = User(name: '', email: '', address: '', phoneNumber: '');
User get user => _user;
Future<void> getUserData() async {
_user = await _userRepository.getUser();
notifyListeners();
}
Future<void> updateUser(User newUser) async {
await _userRepository.updateUser(newUser);
_user = newUser;
notifyListeners();
}
}
3. Quizzes
Quiz.dart, Question.dart, Answer.dart
Tujuan:
i. Quiz.dart: Merepresentasikan sebuah kuis secara keseluruhan, termasuk daftar pertanyaan, kategori, tingkat kesulitan, dan lain-lain.
ii. Question.dart: Merepresentasikan satu pertanyaan dalam sebuah kuis, termasuk pertanyaannya, pilihan jawaban, dan jawaban yang benar.
iii. Answer.dart: Merepresentasikan satu pilihan jawaban untuk sebuah pertanyaan.
Langkah-langkah:
i. Definisi Kelas: Buat kelas-kelas Quiz, Question, dan Answer dengan atribut-atribut yang sesuai.
ii. Hubungan: Buat hubungan antara kelas-kelas tersebut. Misalnya, kelas Quiz memiliki list dari objek Question, dan kelas Question memiliki list dari objek Answer.
Tujuan:
i. Mengabstraksikan logika akses data untuk kuis.
ii. Menyediakan metode untuk mengambil, menambahkan, memperbarui, dan menghapus data kuis dari sumber data.
Langkah-langkah:
i. Definisi Kelas: Buat kelas QuizRepository dengan metode-metode yang sesuai untuk operasi CRUD (Create, Read, Update, Delete) pada data kuis.
ii. Implementasi Metode:
getQuizzes(): Mengambil semua kuis.
getQuizById(id): Mengambil kuis berdasarkan ID.
addQuiz(quiz): Menambahkan kuis baru.
updateQuiz(quiz): Memperbarui kuis yang sudah ada.
Contoh Penggunaan:
class QuizRepository {
Future<List<Quiz>> getQuizzes() async {
// Implementasi untuk mengambil data kuis dari database atau API
// ...
return quizzes;
}
Future<Quiz> getQuizById(String id) async {
// Implementasi untuk mengambil kuis berdasarkan ID
// ...
return quiz;
}
}
api_service.dart
Tujuan:
i. Berinteraksi dengan API untuk mengambil data kuis.
Langkah-langkah:
i. Definisi Kelas: Buat kelas ApiService dengan metode-metode untuk melakukan request ke API.
ii. Implementasi Metode:
fetchQuizzes(): Mengirim request ke API untuk mendapatkan daftar kuis.
fetchQuizById(id): Mengirim request ke API untuk mendapatkan detail kuis berdasarkan ID.
iii. Penggunaan HTTP Client: Gunakan package seperti http atau dio untuk melakukan request HTTP.
Contoh Penggunaan:
class ApiService {
Future<List<Quiz>> fetchQuizzes() async {
final response = await http.get(Uri.parse('https://api.example.com/quizzes'));
// ...
return quizzes;
}
}
Fitur
1. Tampilan Khusus & Antar Muka
HomeScreen.dart
Tujuan: Merupakan halaman utama aplikasi yang biasanya menampilkan daftar produk terbaru, populer, atau kategori tertentu. Halaman ini berfungsi sebagai pintu masuk bagi pengguna untuk menjelajahi aplikasi.
Langkah-langkah:
i. Mendapatkan data produk: Memanggil fungsi dari ProductRepository untuk mengambil data produk dari server atau database.
ii. Menampilkan daftar produk: Menggunakan widget seperti ListView atau GridView untuk menampilkan daftar produk dalam bentuk kartu (card) atau grid. Setiap kartu produk biasanya berisi gambar produk, nama, harga, dan mungkin rating.
iii. Implementasi navigasi: Menambahkan fitur navigasi ke halaman detail produk saat pengguna mengetuk kartu produk tertentu.
ProductDetailScreen.dart
Tujuan: Menampilkan detail lengkap dari sebuah produk yang dipilih oleh pengguna.
Langkah-langkah:
i. Menerima data produk: Menerima data produk yang dipilih dari HomeScreen sebagai argumen.
ii. Menampilkan detail produk: Menampilkan informasi detail produk seperti gambar, nama, deskripsi, harga, dan mungkin ulasan pengguna.
iii. Implementasi keranjang belanja: Menambahkan tombol "Tambahkan ke Keranjang" untuk memungkinkan pengguna menambahkan produk ke keranjang belanja mereka.
CartScreen.dart
Tujuan: Menampilkan daftar produk yang telah ditambahkan oleh pengguna ke keranjang belanja mereka.
Langkah-langkah:
i. Mendapatkan data keranjang: Memanggil fungsi dari CartRepository untuk mengambil data produk yang ada di keranjang belanja.
ii. Menampilkan daftar produk: Menggunakan widget seperti ListView untuk menampilkan daftar produk di dalam keranjang.
iii. Implementasi fitur menghapus produk: Menambahkan fitur untuk menghapus produk dari keranjang.
iv. Implementasi fitur checkout: Menambahkan tombol "Checkout" untuk melanjutkan ke proses pembayaran.
ProfileScreen.dart
Tujuan: Menampilkan informasi profil pengguna, seperti nama, alamat email, riwayat pesanan, dan pengaturan akun.
Langkah-langkah:
i. Mendapatkan data profil: Memanggil fungsi dari UserRepository untuk mengambil data profil pengguna yang sedang login.
ii. Menampilkan informasi profil: Menampilkan informasi profil pengguna dalam bentuk teks atau formulir.
iii. Implementasi fitur edit profil: Menambahkan fitur untuk mengedit informasi profil pengguna.
iv. Implementasi fitur logout: Menambahkan tombol logout untuk mengakhiri sesi pengguna.
2. Onboarding
HomeViewModel.dart
Tujuan
i. Mengatur logika bisnis: ViewModel ini bertanggung jawab atas logika yang berkaitan dengan tampilan HomeScreen. Ini termasuk mengelola data yang akan ditampilkan, menangani interaksi pengguna, dan berkomunikasi dengan lapisan data (repositori) untuk mengambil data yang diperlukan.
ii. Memperbarui tampilan: ViewModel akan memberitahu tampilan (dalam hal ini HomeScreen.dart) kapan harus memperbarui tampilannya, misalnya ketika data baru telah diambil atau ketika pengguna melakukan suatu tindakan.
iii. Menjaga tampilan tetap sederhana: Dengan memindahkan logika bisnis ke ViewModel, tampilan (view) dapat menjadi lebih sederhana dan hanya fokus pada penyajian data.
Langkah-langkah Umum
i. Deklarasi variabel:
Variabel untuk menyimpan data yang akan ditampilkan, misalnya List<Product> products.
Variabel untuk melacak status loading, error, atau idle.
ii. Fungsi untuk mengambil data:
Memanggil ProductRepository untuk mengambil data produk dari server atau database.
Mengatur status loading selama proses pengambilan data.
Memperbarui variabel products setelah data berhasil diambil.
Mengatur status error jika terjadi kesalahan saat mengambil data.
iii. Fungsi untuk menangani interaksi pengguna:
Menangani event-event dari tampilan, misalnya ketika pengguna mengklik sebuah produk.
Memanggil fungsi-fungsi yang sesuai, misalnya untuk navigasi ke halaman detail produk.
iv. Notifier atau Provider:
Menggunakan Notifier atau Provider untuk memberitahu tampilan ketika ada perubahan data.
https://dribbble.com/shots/15475209-Coffee-Shop-Mobile-Apps-Dark-Mode
lib/ ├── core/ │ ├── utils/ │ ├── constants/ │ ├── data/ │ ├── models/ │ │ ├── Product.dart │ │ ├── Cart.dart │ │ ├── User.dart │ ├── repositories/ │ │ ├── ProductRepository.dart │ │ ├── CartRepository.dart │ │ ├── UserRepository.dart │ ├── features/ │ ├── home/ │ │ ├── viewmodels/ │ │ │ ├── HomeViewModel.dart │ │ ├── screens/ │ │ │ ├── HomeScreen.dart │ │ ├── widgets/ │ │ │ ├── ProductCard.dart │ ├── product_detail/ │ ├── viewmodels/ │ │ ├── ProductDetailViewModel.dart │ ├── screens/ │ │ ├── ProductDetailScreen.dart │ ├── cart/ │ ├── viewmodels/ │ │ ├── CartViewModel.dart │ ├── screens/ │ │ ├── CartScreen.dart │ ├── profile/ │ ├── viewmodels/ │ │ ├── ProfileViewModel.dart │ ├── screens/ │ │ ├── ProfileScreen.dart │ ├── services/ │ ├── api_service.dart │ ├── main.dart
Core
1. Komponen Global (core/global_components)
Typography.dart
Tujuan: i. Mendefinisikan gaya teks yang konsisten di seluruh aplikasi. ii. Memudahkan dalam mengubah gaya teks secara global. iii. Meningkatkan keterbacaan dan estetika aplikasi.
Langkah-langkah: i. Buat widget
TextComponent
: Widget ini menerima parameter seperti teks, ukuran font, warna, dan weight. ii. Definisikan style: BuatTextStyle
yang berbeda-beda untuk judul, subjudul, dan teks biasa. iii. GunakanText
widget: GunakanText
widget denganTextStyle
yang sesuai berdasarkan parameter yang diberikan.Contoh:
ButtonComponent
Tujuan: i. Mendefinisikan tampilan tombol yang konsisten. ii. Memudahkan dalam membuat tombol dengan berbagai gaya. iii. Meningkatkan interaksi pengguna.
Langkah-langkah: i. Buat widget
ButtonComponent
: Widget ini menerima parameter seperti teks tombol, fungsi yang akan dijalankan saat tombol ditekan, warna, dan lebar. ii. GunakanElevatedButton
atauOutlinedButton
: Pilih jenis tombol yang sesuai dengan desain. iii. Sesuaikan tampilan: AturborderRadius
,padding
, dan properti lainnya sesuai kebutuhan.Contoh Penggunaan:
ProgressBarComponent
:Tujuan: i. Menampilkan indikator progres suatu proses. ii. Memberikan umpan balik visual kepada pengguna.
Langkah-langkah: i. Buat widget ProgressBarComponent: Widget ini menerima parameter seperti nilai progres (antara 0-1). ii. Gunakan LinearProgressIndicator atau CircularProgressIndicator: Pilih jenis progress bar yang sesuai dengan desain. iii. Sesuaikan tampilan: Atur warna, lebar, dan gaya lainnya.
Contoh Penggunaan:
AvatarComponent
:Tujuan: i. Menampilkan gambar profil pengguna. ii. Memberikan identitas visual kepada pengguna.
Langkah-langkah: i. Buat widget
AvatarComponent
: Widget ini menerima parameter seperti URL gambar, ukuran, dan fungsi yang akan dijalankan saat avatar ditekan. ii. GunakanCircleAvatar
: Untuk membuat avatar berbentuk lingkaran. iii. GunakanNetworkImage
: Untuk memuat gambar dari URL. iv. Tambahkan fitur opsional: Seperti border, shadow, atau inisial jika gambar tidak tersedia.Contoh Penggunaan:
NetworkImageLoader
:Tujuan: i. Memudahkan dalam memuat gambar dari jaringan. ii. Menangani error dan loading state.
Langkah-langkah: i. Buat fungsi
NetworkImageLoader
: Fungsi ini menerima URL gambar sebagai parameter. ii. GunakanImage.network
: Untuk memuat gambar dari URL. iii. TambahkanerrorBuilder
danloadingBuilder
: Untuk menampilkan pesan error atau indikator loading saat gambar sedang dimuat atau gagal dimuat.Contoh Penggunaan:
2. Config (core/config)
main_app.dart
:Tujuan i. Titik Masuk Aplikasi: File ini adalah titik awal eksekusi aplikasi Flutter Anda. ii. Inisialisasi Aplikasi: Melakukan konfigurasi awal aplikasi, seperti tema, rute navigasi, dan pengaturan lainnya. iii. Menampilkan Widget Utama: Menentukan widget yang akan ditampilkan pertama kali saat aplikasi dijalankan.
Langkah-langkah: i. Import Library: Impor library yang diperlukan, terutama
material.dart
ataucupertino.dart
. ii. Buat Fungsi main: Fungsi utama untuk menjalankan aplikasi. iii. Buat Widget Utama: Buat widgetStatelessWidget
atauStatefulWidget
sebagai akar aplikasi. iv. KonfigurasiMaterialApp
atauCupertinoApp
: Atur judul aplikasi (title
).Tentukan tema (theme
). Tentukan layar awal (home
). Konfigurasi rute navigasi (routes
,onGenerateRoute
). v. Jalankan Aplikasi: PanggilrunApp
dengan widget utama sebagai argumen.Contoh Penggunaan:
3. Utils (core/utils)
route_utils.dart
:Tujuan i. Membungkus Logika Navigasi: Menyembunyikan kompleksitas navigasi di balik fungsi-fungsi yang mudah digunakan. ii. Meningkatkan Reusabilitas: Fungsi-fungsi navigasi dapat digunakan di berbagai bagian aplikasi tanpa perlu menulis ulang kode. iii. Meningkatkan Keterbacaan: Membuat kode lebih mudah dipahami dengan menggunakan nama fungsi yang jelas.
Langkah-langkah Implementasi i. Buat Enum untuk Rute ii. Definisikan fungsi navigasi iii. Konfigurasi Rute di
main.dart
Contoh Penggunaan:
date_utils.dart
:Tujuan: i. Menyediakan fungsi-fungsi untuk memanipulasi dan memformat tanggal dan waktu. ii. Membuat tampilan tanggal dan waktu menjadi lebih konsisten dan sesuai dengan kebutuhan aplikasi. iii. Memudahkan dalam melakukan perhitungan terkait tanggal dan waktu.
Langkah-langkah: i. Import Library: Library intl menyediakan berbagai format tanggal dan waktu yang bisa disesuaikan. ii. Definisikan Fungsi-fungsi: Memformat tanggal, memformat waktu, mendapatkan selisih waktu, Mengecek apakah tanggal sudah lewat, dll.
Contoh Penggunaan:
device_utils.dart
:Tujuan: i. Menyediakan fungsi-fungsi untuk memanipulasi dan memformat tanggal dan waktu. ii. Membuat tampilan tanggal dan waktu menjadi lebih konsisten dan sesuai dengan kebutuhan aplikasi. iii. Memudahkan dalam melakukan perhitungan terkait tanggal dan waktu.
Langkah-langkah: i. Import Library: Library device_info_plus digunakan untuk mendapatkan informasi spesifik perangkat. ii. Definisikan Fungsi-fungsi: Mendapatkan informasi perangkat, Mengecek orientasi layar, Mendapatkan ukuran layar, dll
Contoh Penggunaan:
4. Constants (core/constants)
strings.dart
:Tujuan: i. Memusatkan Teks Statis: Mengumpulkan semua teks statis yang digunakan dalam aplikasi ke dalam satu tempat. ii. Meningkatkan Keterbacaan Kode: Memudahkan dalam mengubah teks tanpa perlu mencari-cari di seluruh kode. iii. Memudahkan Terjemahan: Memudahkan proses terjemahan jika aplikasi ingin mendukung beberapa bahasa. iv. Menghindari Hardcoding: Mencegah terjadinya kesalahan pengetikan dan mempermudah pengelolaan teks.
Langkah-langkah: i. Buat File: Buat file strings.dart di dalam direktori constants. ii. Definisikan Konstanta seperti label tombol, pesan error, dan placeholder.
Contoh Penggunaan:
colors.dart
:Tujuan: i. Membangun Sistem Warna yang Konsisten: Mendefinisikan palet warna yang akan digunakan di seluruh aplikasi. ii. Memudahkan Perubahan Tema: Memudahkan dalam mengubah tampilan keseluruhan aplikasi dengan mengubah nilai konstanta warna. iii. Meningkatkan Keterbacaan Kode: Membuat kode lebih mudah dibaca dengan menggunakan nama warna yang jelas.
Langkah-langkah: i. Buat File: Buat file
colors.dart
di dalam direktori constants. ii. Definisikan Warna: sepertiprimaryColor
,secondaryColor
, dan warna latar belakang.Contoh Penggunaan:
dimens.dart
:Tujuan: i. Membuat Tampilan Responsif: Mendefinisikan ukuran dimensi yang dapat disesuaikan dengan berbagai ukuran layar. ii. Meningkatkan Keterbacaan Kode: Membuat kode lebih mudah dibaca dengan menggunakan nama dimensi yang jelas. iii. Memudahkan Perubahan Desain: Memudahkan dalam mengubah ukuran elemen-elemen UI.
Langkah-langkah: i. Buat File: Buat file dimens.dart di dalam direktori constants. ii. Definisikan Dimensi: seperti padding, margin, dan radius.
Contoh Penggunaan:
assets.dart
:Tujuan: i. Memusatkan Path Aset: Mengumpulkan semua path ke aset (gambar, ikon, font) dalam satu tempat. ii. Meningkatkan Keterbacaan Kode: Memudahkan dalam mengelola dan mengubah path aset. iii. Mencegah Kesalahan Path: Mencegah kesalahan pengetikan path aset.
Langkah-langkah: i. Buat File: Buat file
assets.dart
di dalam direktori constants. ii. Definisikan Path: seperti gambar, ikon, dan font.Cotoh Penggunaan:
Data
1. Course
Product.dart
Tujuan: i. Merepresentasikan data produk secara rinci. ii. Mendefinisikan atribut-atribut yang dimiliki oleh sebuah produk, seperti nama, harga, deskripsi, gambar, dll.
Langkah-langkah: i. Definisi Kelas: Buat kelas Product dengan atribut-atribut yang sesuai. ii. Tipe Data: Tentukan tipe data yang tepat untuk setiap atribut (misalnya, String untuk nama, double untuk harga). iii. Constructor: Buat constructor untuk menginisialisasi objek Product. iv. Getter dan Setter: Tambahkan getter dan setter untuk mengakses dan memodifikasi nilai atribut.
Contoh Penggunaan:
Cart.dart
Tujuan: i. Merepresentasikan keranjang belanja pengguna. ii. Mendefinisikan atribut-atribut yang terkait dengan keranjang belanja, seperti daftar produk, total harga, dll.
Langkah-langkah: i. Definisi Kelas: Buat kelas Cart dengan atribut-atribut yang sesuai. ii. Tipe Data: Gunakan List untuk menyimpan daftar produk dalam keranjang.
iii. Metode: Tambahkan metode untuk menambahkan produk ke keranjang, menghapus produk dari keranjang, menghitung total harga, dll.
Contoh Penggunaan:
ProductRepository.dart
Tujuan: i. Mengabstraksikan logika akses data untuk produk. ii. Memisahkan logika bisnis terkait produk dari ViewModel. iii. Menyediakan metode untuk mengambil, menambahkan, memperbarui, dan menghapus data produk dari sumber data (misalnya, database, API).
Langkah-langkah: i. Definisi Kelas: Buat kelas
ProductRepository
dengan metode-metode yang sesuai untuk operasi CRUD (Create, Read, Update, Delete) pada data produk. ii. Implementasi Metode:getProducts()
: Mengambil daftar semua produk dari sumber data.getProductById(id)
: Mengambil detail produk berdasarkan ID.addProduct(product)
: Menambahkan produk baru ke sumber data.updateProduct(product)
: Memperbarui data produk yang sudah ada.deleteProduct(id)
: Menghapus produk berdasarkan ID. iii. Penggunaan Sumber Data: Gunakan library atau framework yang sesuai untuk berinteraksi dengan sumber data (misalnya, SQLite, Firebase, REST API). Implementasikan logika untuk memetakan data dari sumber data ke objekProduct
.Contoh Penggunaan:
CartRepository.dart
Tujuan: i. Mengabstraksikan logika akses data untuk keranjang belanja. ii. Memisahkan logika bisnis terkait keranjang belanja dari ViewModel. iii. Menyediakan metode untuk mengambil, menambahkan, menghapus produk dari keranjang belanja, dan menyimpan status keranjang.
Langkah-langkah: i. Definisi Kelas: Buat kelas
CartRepository
dengan metode-metode yang sesuai untuk operasi pada keranjang belanja. ii. Implementasi Metode:getCart()
: Mengambil data keranjang belanja dari penyimpanan lokal (misalnya, SharedPreferences).addItemToCart(product)
: Menambahkan produk ke keranjang belanja.removeItemFromCart(product)
: Menghapus produk dari keranjang belanja.clearCart()
: Mengosongkan keranjang belanja.saveCart(cart)
: Menyimpan data keranjang belanja ke penyimpanan lokal. iii. Penggunaan Penyimpanan Lokal: Gunakan library atau framework yang sesuai untuk menyimpan data keranjang belanja secara lokal (misalnya, SharedPreferences, SQLite).Contoh Penggunaan:
2. Profile
User.dart
Tujuan: i. Merepresentasikan data pengguna secara rinci. ii. Mendefinisikan atribut-atribut yang dimiliki oleh seorang pengguna, seperti nama, email, alamat, nomor telepon, dan lain-lain.
Langkah-langkah: i. Definisi Kelas: Buat kelas User dengan atribut-atribut yang sesuai. ii. Tipe Data: Tentukan tipe data yang tepat untuk setiap atribut (misalnya,
String
untuk nama,String
untuk email). iii. Constructor: Buat constructor untuk menginisialisasi objek User. iv. Getter dan Setter: Tambahkan getter dan setter untuk mengakses dan memodifikasi nilai atribut.Contoh Penggunaan:
UserRepository.dart
Tujuan: i. Mengabstraksikan logika akses data untuk pengguna. ii. Memisahkan logika bisnis terkait pengguna dari ViewModel. iii. Menyediakan metode untuk mengambil, menambahkan, memperbarui, dan menghapus data pengguna dari sumber data (misalnya, database, API).
Langkah-langkah: i. Definisi Kelas: Buat kelas UserRepository dengan metode-metode yang sesuai untuk operasi CRUD (Create, Read, Update, Delete) pada data pengguna. ii. Implementasi Metode:
getUser()
: Mengambil data pengguna yang sedang login.updateUser(user)
: Memperbarui data pengguna yang sudah ada.registerUser(user)
: Mendaftarkan pengguna baru. iii. Penggunaan Sumber Data: Gunakan library atau framework yang sesuai untuk berinteraksi dengan sumber data (misalnya, Firebase, Supabase, REST API).Contoh Penggunaan:
ProfileViewModel.dart
Tujuan: i. Mengelola logika bisnis terkait profil pengguna. ii. Menyediakan data untuk tampilan profil pengguna. iii. Menangani interaksi pengguna pada tampilan profil (misalnya, mengedit profil).
Langkah-langkah: i. Definisi Kelas: Buat kelas ProfileViewModel yang extends ChangeNotifier. ii. Variabel: Simpan objek User yang sedang aktif. iii. Metode:
getUser()
: Memanggil UserRepository untuk mengambil data pengguna.updateUser(user)
: Memanggil UserRepository untuk memperbarui data pengguna.notifyListeners()
: Memberitahu widget yang mendengarkan perubahan data untuk memperbarui tampilan.Contoh Penggunaan:
3. Quizzes
Quiz.dart
,Question.dart
,Answer.dart
Tujuan: i.
Quiz.dart
: Merepresentasikan sebuah kuis secara keseluruhan, termasuk daftar pertanyaan, kategori, tingkat kesulitan, dan lain-lain. ii.Question.dart
: Merepresentasikan satu pertanyaan dalam sebuah kuis, termasuk pertanyaannya, pilihan jawaban, dan jawaban yang benar. iii.Answer.dart
: Merepresentasikan satu pilihan jawaban untuk sebuah pertanyaan.Langkah-langkah: i. Definisi Kelas: Buat kelas-kelas Quiz, Question, dan Answer dengan atribut-atribut yang sesuai. ii. Hubungan: Buat hubungan antara kelas-kelas tersebut. Misalnya, kelas Quiz memiliki list dari objek Question, dan kelas Question memiliki list dari objek Answer.
Contoh Penggunaan:
QuizRepository.dart
Tujuan: i. Mengabstraksikan logika akses data untuk kuis. ii. Menyediakan metode untuk mengambil, menambahkan, memperbarui, dan menghapus data kuis dari sumber data.
Langkah-langkah: i. Definisi Kelas: Buat kelas QuizRepository dengan metode-metode yang sesuai untuk operasi CRUD (Create, Read, Update, Delete) pada data kuis. ii. Implementasi Metode:
getQuizzes()
: Mengambil semua kuis.getQuizById(id)
: Mengambil kuis berdasarkan ID.addQuiz(quiz)
: Menambahkan kuis baru.updateQuiz(quiz)
: Memperbarui kuis yang sudah ada.Contoh Penggunaan:
api_service.dart
Tujuan: i. Berinteraksi dengan API untuk mengambil data kuis.
Langkah-langkah: i. Definisi Kelas: Buat kelas ApiService dengan metode-metode untuk melakukan request ke API. ii. Implementasi Metode:
fetchQuizzes()
: Mengirim request ke API untuk mendapatkan daftar kuis.fetchQuizById(id)
: Mengirim request ke API untuk mendapatkan detail kuis berdasarkan ID. iii. Penggunaan HTTP Client: Gunakan package seperti http atau dio untuk melakukan request HTTP.Contoh Penggunaan:
Fitur
1. Tampilan Khusus & Antar Muka
HomeScreen.dart
Tujuan: Merupakan halaman utama aplikasi yang biasanya menampilkan daftar produk terbaru, populer, atau kategori tertentu. Halaman ini berfungsi sebagai pintu masuk bagi pengguna untuk menjelajahi aplikasi.
Langkah-langkah: i. Mendapatkan data produk: Memanggil fungsi dari ProductRepository untuk mengambil data produk dari server atau database. ii. Menampilkan daftar produk: Menggunakan widget seperti ListView atau
GridView
untuk menampilkan daftar produk dalam bentuk kartu (card) atau grid. Setiap kartu produk biasanya berisi gambar produk, nama, harga, dan mungkin rating. iii. Implementasi navigasi: Menambahkan fitur navigasi ke halaman detail produk saat pengguna mengetuk kartu produk tertentu.ProductDetailScreen.dart
Tujuan: Menampilkan detail lengkap dari sebuah produk yang dipilih oleh pengguna.
Langkah-langkah: i. Menerima data produk: Menerima data produk yang dipilih dari HomeScreen sebagai argumen. ii. Menampilkan detail produk: Menampilkan informasi detail produk seperti gambar, nama, deskripsi, harga, dan mungkin ulasan pengguna. iii. Implementasi keranjang belanja: Menambahkan tombol "Tambahkan ke Keranjang" untuk memungkinkan pengguna menambahkan produk ke keranjang belanja mereka.
CartScreen.dart
Tujuan: Menampilkan daftar produk yang telah ditambahkan oleh pengguna ke keranjang belanja mereka.
Langkah-langkah: i. Mendapatkan data keranjang: Memanggil fungsi dari CartRepository untuk mengambil data produk yang ada di keranjang belanja. ii. Menampilkan daftar produk: Menggunakan widget seperti ListView untuk menampilkan daftar produk di dalam keranjang. iii. Implementasi fitur menghapus produk: Menambahkan fitur untuk menghapus produk dari keranjang. iv. Implementasi fitur checkout: Menambahkan tombol "Checkout" untuk melanjutkan ke proses pembayaran.
ProfileScreen.dart
Tujuan: Menampilkan informasi profil pengguna, seperti nama, alamat email, riwayat pesanan, dan pengaturan akun.
Langkah-langkah: i. Mendapatkan data profil: Memanggil fungsi dari UserRepository untuk mengambil data profil pengguna yang sedang login. ii. Menampilkan informasi profil: Menampilkan informasi profil pengguna dalam bentuk teks atau formulir. iii. Implementasi fitur edit profil: Menambahkan fitur untuk mengedit informasi profil pengguna. iv. Implementasi fitur logout: Menambahkan tombol logout untuk mengakhiri sesi pengguna.
2. Onboarding
HomeViewModel.dart
Tujuan i. Mengatur logika bisnis: ViewModel ini bertanggung jawab atas logika yang berkaitan dengan tampilan HomeScreen. Ini termasuk mengelola data yang akan ditampilkan, menangani interaksi pengguna, dan berkomunikasi dengan lapisan data (repositori) untuk mengambil data yang diperlukan. ii. Memperbarui tampilan: ViewModel akan memberitahu tampilan (dalam hal ini HomeScreen.dart) kapan harus memperbarui tampilannya, misalnya ketika data baru telah diambil atau ketika pengguna melakukan suatu tindakan. iii. Menjaga tampilan tetap sederhana: Dengan memindahkan logika bisnis ke ViewModel, tampilan (view) dapat menjadi lebih sederhana dan hanya fokus pada penyajian data.
Langkah-langkah Umum i. Deklarasi variabel: Variabel untuk menyimpan data yang akan ditampilkan, misalnya
List<Product> product
s. Variabel untuk melacak status loading, error, atau idle. ii. Fungsi untuk mengambil data: MemanggilProductRepository
untuk mengambil data produk dari server atau database. Mengatur status loading selama proses pengambilan data. Memperbarui variabelproducts
setelah data berhasil diambil. Mengatur status error jika terjadi kesalahan saat mengambil data. iii. Fungsi untuk menangani interaksi pengguna: Menangani event-event dari tampilan, misalnya ketika pengguna mengklik sebuah produk. Memanggil fungsi-fungsi yang sesuai, misalnya untuk navigasi ke halaman detail produk. iv. Notifier atau Provider: MenggunakanNotifier
atauProvider
untuk memberitahu tampilan ketika ada perubahan data.Contoh Penggunaan