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:
parent
fafc765b3f
commit
0e35047375
@ -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;
|
||||||
|
type: 'income' | 'expense';
|
||||||
|
category: string;
|
||||||
|
date: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Cara Menggunakan
|
**Poin pembelajaran:**
|
||||||
|
- Interface adalah "blueprint" untuk object
|
||||||
|
- Tipe data yang tersedia: string, number, boolean
|
||||||
|
|
||||||
1. Clone repository
|
---
|
||||||
2. Ikuti commit satu per satu:
|
|
||||||
|
#### 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
|
```bash
|
||||||
git log --oneline # Lihat semua commits
|
git clone <repo-url>
|
||||||
git checkout <commit-hash> # Pindah ke commit tertentu
|
cd duit
|
||||||
```
|
```
|
||||||
3. Run `npm install` dan `npx expo start`
|
|
||||||
|
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! 🚀**
|
||||||
Loading…
Reference in New Issue
Block a user