docs: comprehensive learning materials

- Prerequisites (Node.js, Expo, VS Code)
- Detailed folder structure explanation
- Materi per commit dengan code snippets
- Cara menggunakan untuk pembelajaran
- Cara run aplikasi (Android, iOS, Web, Smartphone)
- Debugging tips
- Complete commit list
This commit is contained in:
Dita Aji Pratama 2026-04-18 12:30:09 +07:00
parent fafc765b3f
commit 0e35047375

View File

@ -2,46 +2,556 @@
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. 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 ## Daftar Commit Pembelajaran
### Fase 1: Project Setup ### Fase 1: Setup & Types (Commit 1-3)
1. **Setup Project** - Install dependencies, types
2. **Theme Constants** - COLORS, FONTS
3. **Helper Functions** - formatRupiah, calculateBalance
### Fase 2: Components #### Commit 1: Setup Project
4. **Header** - Komponen title **Topik:** Install dependencies, TypeScript interfaces
5. **BalanceCard** - Tampilan saldo
6. **TransactionForm** - Form input transaksi
7. **TransactionList** - List riwayat
### Fase 3: State Management **Materi yang dipelajari:**
8. **useTransactions Hook** - Load data - Cara install package dengan npm
9. **addTransaction** - Tambah transaksi - TypeScript interface untuk mendefinisikan bentuk data
10. **deleteTransaction** - Hapus transaksi - Export/import module
### Fase 4: Screen Integration **Code penting:**
11. **HomeScreen** - Gabung komponen ```typescript
12. **App Index** - Entry point // types/index.ts
13. **Tab Navigation** - Tab navigation export interface Transaction {
14. **Explore/Stats** - Halaman statistik id: string;
15. **Root Layout** - Layout utama amount: number;
description: string;
## Cara Menggunakan type: 'income' | 'expense';
category: string;
1. Clone repository date: string;
2. Ikuti commit satu per satu: }
```bash
git log --oneline # Lihat semua commits
git checkout <commit-hash> # Pindah ke commit tertentu
``` ```
3. Run `npm install` dan `npx expo start`
**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<HeaderProps> = ({ title }) => {
return (
<View style={styles.container}>
<Text style={styles.title}>{title}</Text>
</View>
);
};
```
**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<BalanceCardProps> = ({ balance }) => {
return (
<View>
<Text style={[styles.amount, styles.income]}>
+{formatRupiah(balance.income)}
</Text>
</View>
);
};
```
**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');
<TextInput
style={styles.input}
placeholder="Jumlah (Rp)"
value={amount}
onChangeText={setAmount}
keyboardType="numeric"
/>
<TouchableOpacity onPress={() => setType('expense')}>
<Text>Pengeluaran</Text>
</TouchableOpacity>
```
**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
<FlatList
data={transactions}
keyExtractor={(item) => item.id}
renderItem={renderItem}
scrollEnabled={false}
/>
if (transactions.length === 0) {
return <View style={styles.empty}>...</View>;
}
```
**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<Transaction[]>([]);
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 <ActivityIndicator />;
}
return (
<View>
<Header title="Pengeluaran Kita" />
<ScrollView>
<BalanceCard balance={balance} />
<TransactionForm onAdd={addTransaction} />
<TransactionList transactions={transactions} onDelete={deleteTransaction} />
</ScrollView>
</View>
);
}
```
**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 <repo-url>
cd duit
```
2. **Lihat semua commits:**
```bash
git log --oneline
```
3. **Pergi ke commit tertentu:**
```bash
git checkout <commit-hash>
```
4. **Install dan run:**
```bash
npm install
npx expo start
```
### 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 ## Fitur Aplikasi
- Tambah income/pengeluaran
- Lihat saldo total - ✅ Tambah income/pengeluaran
- Riwayat transaksi - ✅ Lihat saldo total
- Hapus transaksi - ✅ Riwayat transaksi
- Simpan data lokal - ✅ Hapus transaksi
- Statistik bulanan - ✅ Kategori transaksi
- Kategori pengeluaran - ✅ 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! 🚀**