# Finance Tracker - Materi Pembelajaran React Native Project ini adalah aplikasi penghitung income dan expense keuangan untuk pembelajaran React Native. Setiap commit merepresentasikan satu tahap pembelajaran yang dapat diikuti oleh murid dan pengajar. --- ## Prerequisites Sebelum memulai, pastikan komputer Anda sudah terinstall: 1. **Node.js** (versi 18 atau terbaru) - Download: https://nodejs.org - Cek: `node --version` 2. **Expo CLI** ```bash npm install -g expo-cli ``` 3. **Code Editor** (VS Code direkomendasikan) - Download: https://code.visualstudio.com 4. **Untuk Running di Android:** - Android Studio (dengan SDK) - Atau gunakan Expo Go di smartphone --- ## Struktur Folder Project ``` duit/ ├── app/ # File routing (expo-router) │ ├── _layout.tsx # Root layout │ └── (tabs)/ # Tab navigation │ ├── _layout.tsx # Tab config │ ├── index.tsx # Home screen │ └── explore.tsx # Stats screen ├── components/ # Komponen React Native │ ├── Header.tsx # Header component │ ├── BalanceCard.tsx # Balance display │ ├── TransactionForm.tsx # Input form │ └── TransactionList.tsx # Transaction list ├── hooks/ # Custom hooks │ └── useTransactions.ts # Data management hook ├── types/ # TypeScript types │ └── index.ts # Transaction interface ├── utils/ # Utility functions │ └── helpers.ts # Helper functions ├── constants/ # Konstanta │ └── theme.ts # Colors & fonts ├── package.json └── LEARNING_MATERIALS.md ``` --- ## Daftar Commit Pembelajaran ### Fase 1: Setup & Types (Commit 1-3) #### Commit 1: Setup Project **Topik:** Install dependencies, TypeScript interfaces **Materi yang dipelajari:** - Cara install package dengan npm - TypeScript interface untuk mendefinisikan bentuk data - Export/import module **Code penting:** ```typescript // types/index.ts export interface Transaction { id: string; amount: number; description: string; type: 'income' | 'expense'; category: string; date: string; } ``` **Poin pembelajaran:** - Interface adalah "blueprint" untuk object - Tipe data yang tersedia: string, number, boolean --- #### Commit 2: Theme Constants **Topik:** Konstanta warna dan font **Materi yang dipelajari:** - Mendefinisikan konstanta di React Native - Konfigurasi tema aplikasi **Code penting:** ```typescript // constants/theme.ts export const COLORS = { income: '#4CAF50', expense: '#F44336', background: '#F5F5F5', card: '#FFFFFF', text: '#333333', primary: '#2196F3', } as const; ``` **Poin pembelajaran:** - `as const` membuat object jadi readonly - Gunakan konsistensi warna di seluruh app --- #### Commit 3: Helper Functions **Topik:** Fungsi utility **Materi yang dipelajari:** - Membuat fungsi helper yang reusable - Formatting angka dan tanggal - Array reduce untuk kalkulasi **Code penting:** ```typescript // utils/helpers.ts export const formatRupiah = (amount: number): string => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', }).format(amount); }; export const calculateBalance = (transactions: Transaction[]): BalanceInfo => { const income = transactions .filter((t) => t.type === 'income') .reduce((sum, t) => sum + t.amount, 0); // ... }; ``` **Poin pembelajaran:** - `Intl.NumberFormat` untuk mata uang Indonesia - `reduce` untuk menjumlahkan array - `filter` untuk menyaring array --- ### Fase 2: Components (Commit 4-7) #### Commit 4: Header Component **Topik:** Komponen Pertama **Materi yang dipelajari:** - Cara membuat komponen React Native - View, Text, StyleSheet - Interface props **Code penting:** ```typescript // components/Header.tsx interface HeaderProps { title: string; } export const Header: React.FC = ({ title }) => { return ( {title} ); }; ``` **Poin pembelajaran:** - Komponen adalah fungsi yang return JSX - Props digunakan untuk data dinamis - `React.FC` adalah type untuk functional component --- #### Commit 5: BalanceCard Component **Topik:** Props dan conditional styling **Materi yang dipelajari:** - Menerima object sebagai props - Conditional styling (warna berbeda untuk income/expense) **Code penting:** ```typescript interface BalanceCardProps { balance: BalanceInfo; } export const BalanceCard: React.FC = ({ balance }) => { return ( +{formatRupiah(balance.income)} ); }; ``` **Poin pembelajaran:** - Destructure props dengan `{ balance }` - Conditional class dengan array `[styles.base, isActive && styles.active]` --- #### Commit 6: TransactionForm Component **Topik:** Form input dengan useState **Materi yang dipelajari:** - useState untuk form inputs - TextInput component - TouchableOpacity untuk button - ScrollView horizontal **Code penting:** ```typescript // components/TransactionForm.tsx const [amount, setAmount] = useState(''); const [description, setDescription] = useState(''); const [type, setType] = useState<'income' | 'expense'>('expense'); setType('expense')}> Pengeluaran ``` **Poin pembelajaran:** - `useState` menyimpan state komponen - `onChangeText` menangkap input teks - `keyboardType="numeric"` untuk number only - TouchableOpacity = button yang bisa ditekan --- #### Commit 7: TransactionList Component **Topik:** FlatList dan rendering **Materi yang dipelajari:** - FlatList untuk list panjang - renderItem function - Empty state handling **Code penting:** ```typescript // components/TransactionList.tsx item.id} renderItem={renderItem} scrollEnabled={false} /> if (transactions.length === 0) { return ...; } ``` **Poin pembelajaran:** - FlatList lebih efficient dari map - `keyExtractor` untuk key unik - `renderItem` menerima object `{ item }` --- ### Fase 3: State Management (Commit 8-10) #### Commit 8: useTransactions Hook **Topik:** Custom hooks **Materi yang dipelajari:** - Membuat custom hook - useState dan useEffect - Load data dari AsyncStorage **Code penting:** ```typescript // hooks/useTransactions.ts export const useTransactions = () => { const [transactions, setTransactions] = useState([]); const [loading, setLoading] = useState(true); const loadTransactions = async () => { const stored = await AsyncStorage.getItem(STORAGE_KEY); if (stored) setTransactions(JSON.parse(stored)); }; useEffect(() => { loadTransactions(); }, []); return { transactions, loading }; }; ``` **Poin pembelajaran:** - Hook adalah fungsi dengan "use" prefix - useEffect untuk side effects (API calls) - AsyncStorage untuk persistence lokal --- #### Commit 9: addTransaction **Topik:** State update dengan callback **Materi yang dipelajari:** - Menambah item ke state - Callback function - useCallback untuk optimisasi **Code penting:** ```typescript const addTransaction = useCallback((transaction: Transaction) => { setTransactions((prev) => { const updated = [transaction, ...prev]; AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); return updated; }); }, []); ``` **Poin pembelajaran:** - Gunakan functional update `setTransactions(prev => ...)` - Selalu simpan ke storage setelah update --- #### Commit 10: deleteTransaction **Topik:** Hapus item dari state **Materi yang dipelajari:** - Filter untuk hapus item - Update berdasarkan id **Code penting:** ```typescript const deleteTransaction = useCallback((id: string) => { setTransactions((prev) => { const updated = prev.filter((t) => t.id !== id); AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); return updated; }); }, []); ``` **Poin pembelajaran:** - `filter` mengembalikan array baru (tidak mutate) - Compare dengan `!==` untuk hapus berdasarkan id --- ### Fase 4: Screen Integration (Commit 11-15) #### Commit 11: HomeScreen **Topik:** Menggabungkan komponen **Materi yang dipelajari:** - Import dan gunakan komponen - Loading state - ScrollView **Code penting:** ```typescript // screens/HomeScreen.tsx export default function HomeScreen() { const { transactions, loading, addTransaction, deleteTransaction } = useTransactions(); const balance = calculateBalance(transactions); if (loading) { return ; } return (
); } ``` **Poin pembelajaran:** - Custom hook return multiple values dengan destructuring - ActivityIndicator untuk loading state - ScrollView untuk konten panjang --- #### Commit 12-15: App Integration **Topik:** Expo Router & Navigation **Materi yang dipelajari:** - File-based routing dengan expo-router - Tab navigation - Layout configuration --- ### Fase 5: Enhancements (Commit 16-21) Topics tambahan: - Categories management - Form validation - Code refactoring --- ## Cara Menggunakan untuk Pembelajaran ### Cara 1: Ikuti Commit Satu per Satu 1. **Clone repository:** ```bash git clone cd duit ``` 2. **Lihat semua commits:** ```bash git log --oneline ``` 3. **Pergi ke commit tertentu:** ```bash git checkout ``` 4. **Install dan run:** ```bash npm install npx expo start ``` **⚠️ PENTING: Urutan Commit yang harus Diperhatikan** Beberapa commit memiliki dependensi. Berikut urutannya: | Jika ingin belajar | Pastikan sudah checkout ke commit | |-----------------|------------------------------| | Commit 4-7 (Components) | Setelah commit 3 | | Commit 11+ (HomeScreen) | Setelah commit 10 (useTransactions) | | Commit 14 (Stats Screen) | Setelah commit 10 (useTransactions) | | Commit 18+ (Categories) | Setelah commit 17 | **Jangan langsung checkout ke commit tinggi** tanpa mengikuti urutan, karena akan terjadi error (beberapa komponen/hooks belum tersedia). ### Cara 2: Belajar dari Kode 1. Clone repository di commit terakhir 2. Baca kode di setiap file 3. Pahami hubungan antar komponen 4. Modifikasi untuk latihan ### Cara 3: Latihan Pengembangan 1. Di commit terakhir, tambahkan fitur: - Filter transaksi per kategori - Edit transaksi yang sudah ada - Export data ke CSV - Dark mode --- ## Cara Run Aplikasi ### Di Emulator Android ```bash npx expo start --android ``` ### Di Emulator iOS (Mac only) ```bash npx expo start --ios ``` ### Di Browser (Web) ```bash npx expo start --web ``` ### Di Smartphone 1. Install "Expo Go" dari App Store/Play Store 2. Scan QR code dari terminal --- ## Debugging Tips 1. **React Native Debugger** - iOS: `Cmd + D` - Android: `Cmd + M` atau `Ctrl + M` - Enable "Debug JS Remotely" 2. **Console.log** ```typescript console.log('Data:', transactions); ``` 3. **Error Boundary** - Perhatikan error merah di emulator - Check terminal untuk stack trace --- ## Fitur Aplikasi - ✅ Tambah income/pengeluaran - ✅ Lihat saldo total - ✅ Riwayat transaksi - ✅ Hapus transaksi - ✅ Kategori transaksi - ✅ Simpan data lokal (AsyncStorage) - ✅ Tab navigation (Keuangan & Statistik) - ✅ Ringkasan bulanan - ✅ Kategori pengeluaran terbesar --- ## Daftar Commit Lengkap | # | Commit Hash | Deskripsi | |---|------------|----------| | 1 | feat: setup project and add types | Install AsyncStorage, Transaction interface | | 2 | feat: add theme constants | COLORS, FONTS | | 3 | feat: add helper utility functions | formatRupiah, calculateBalance | | 4 | feat: create Header component | Komponen title | | 5 | feat: create BalanceCard component | Tampilan saldo | | 6 | feat: create TransactionForm component | Form input | | 7 | feat: create TransactionList component | List riwayat | | 8 | feat: create useTransactions hook | Load data | | 9 | feat: add addTransaction function | Tambah transaksi | | 10 | feat: add deleteTransaction function | Hapus transaksi | | 11 | feat: create HomeScreen | Gabung komponen | | 12 | feat: update index to use HomeScreen | Entry point | | 13 | feat: configure tab navigation | Tab config | | 14 | feat: create Explore/StatsScreen | Statistik | | 15 | feat: simplify root layout | Layout utama | | 16 | docs: add learning materials | Dokumentasi | | 17 | feat: add CATEGORIES constant | Categories array | | 18 | refactor: use CATEGORIES from types | Import categories | | 19 | refactor: add getCategoryLabel helper | Helper function | | 20 | feat: add form validation | Alert, validation | --- ## Referensi - [React Native Docs](https://reactnative.dev/docs/getting-started) - [Expo Docs](https://docs.expo.dev) - [TypeScript Handbook](https://www.typescriptlang.org/docs/) --- **Happy Learning! 🚀**