Ringkasan Perubahan

File yang Dimodifikasi:
     1. `service/api-admin/api-admin-investment.ts` - Tambah parameter page
        untuk pagination
     2. `app/(application)/admin/investment/[id]/list-of-investor.tsx` - Clean
         route file

    File Baru:
     3. `screens/Admin/Investment/ScreenInvestmentListOfInvestor.tsx` - Screen
         component dengan pagination
     4. `screens/Admin/Investment/BoxInvestmentListOfInvestor.tsx` - Box
        component untuk list item

### No Issue
This commit is contained in:
2026-02-19 14:06:02 +08:00
parent f284e2ec02
commit 4862975402
14 changed files with 789 additions and 508 deletions

518
QWEN.md
View File

@@ -2,56 +2,68 @@
## Project Overview
HIPMI Mobile is a cross-platform mobile application built with Expo and React Native. The application is named "HIPMI Badung Connect" and serves as a platform for the HIPMI (Himpunan Pengusaha dan Pengusaha Indonesia) Badung chapter. It's designed to run on iOS, Android, and web platforms using a single codebase.
HIPMI Mobile is a cross-platform mobile application built with Expo and React Native. The application is named **"HIPMI Badung Connect"** and serves as a platform for the HIPMI (Himpunan Pengusaha dan Pengusaha Indonesia) Badung chapter. It's designed to run on iOS, Android, and web platforms using a single codebase.
### Key Technologies
- **Framework**: Expo (v54.0.0) with React Native (v0.81.4)
- **Framework**: Expo (v54.0.0) with React Native (v0.81.5)
- **Language**: TypeScript
- **Architecture**: File-based routing with Expo Router
- **State Management**: Context API
- **State Management**: Context API (AuthContext)
- **UI Components**: React Native Paper, custom components
- **Maps Integration**: Mapbox Maps for React Native
- **Push Notifications**: React Native Firebase Messaging
- **Build System**: Metro bundler
- **Package Manager**: Bun
### Project Structure
```
hipmi-mobile/
├── app/ # Main application screens and routing
├── app/ # Main application screens and routing (Expo Router)
│ ├── _layout.tsx # Root layout component
│ ├── index.tsx # Entry point (Login screen)
│ └── ...
│ └── (application)/ # Main app screens
│ ├── admin/ # Admin panel screens
│ ├── (user)/ # User screens
│ └── ...
├── components/ # Reusable UI components
│ ├── _ShareComponent/ # Shared components (NewWrapper, Admin components)
│ ├── _Icon/ # Icon components
│ └── ...
├── context/ # State management (AuthContext)
├── screens/ # Screen components organized by feature
│ ├── Admin/ # Admin panel screens
│ │ ├── Donation/ # Donation management screens
│ │ ├── Voting/ # Voting management screens
│ │ ├── Event/ # Event management screens
│ │ └── ...
│ ├── Authentication/ # Login, registration flows
│ ├── Collaboration/ # Collaboration features
│ ├── Event/ # Event management
│ ├── Forum/ # Forum functionality
│ ├── Home/ # Home screen
│ ├── Maps/ # Map integration
│ ├── Profile/ # User profile
│ ├── RootLayout/ # Root layout components
│ └── ...
├── assets/ # Images, icons, and static assets
├── constants/ # Constants and configuration values
├── helpers/ # Helper functions (pagination, etc.)
├── hooks/ # Custom React hooks
├── lib/ # Utility libraries
├── navigation/ # Navigation configuration
├── service/ # API services and business logic
│ ├── api-admin/ # Admin API endpoints
│ ├── api-client/ # Client API endpoints
│ └── api-config.ts # Axios configuration
├── hooks/ # Custom React hooks
│ ├── use-pagination.tsx # Pagination hook
│ └── ...
├── helpers/ # Helper functions
│ ├── paginationHelpers.tsx # Pagination UI helpers
│ └── ...
├── types/ # TypeScript type definitions
── utils/ # Helper functions
── utils/ # Utility functions
├── constants/ # Constants and configuration values
├── styles/ # Global styles
├── assets/ # Images, icons, and static assets
└── docs/ # Documentation files
```
## Building and Running
### Prerequisites
- Node.js (with bun as the package manager)
- Expo CLI
- iOS Simulator or Android Emulator (for native builds)
- Android Studio (for Android builds)
- Xcode (for iOS builds, macOS only)
- **Node.js**: v18+ with Bun package manager
- **Expo CLI**: Installed globally or via npx
- **iOS**: Xcode (macOS only) for iOS simulator/builds
- **Android**: Android Studio for Android emulator/builds
### Setup and Development
@@ -63,16 +75,27 @@ hipmi-mobile/
2. **Run Development Server**
```bash
bun run start
```
Or use the shorthand:
```bash
# or
bunx expo start
```
3. **Platform-Specific Commands**
- iOS: `bun run ios` or `bunx expo start --ios`
- Android: `bun run android` or `bunx expo start --android`
- Web: `bun run web` or `bunx expo start --web`
```bash
# iOS Simulator
bun run ios
# or
bunx expo start --ios
# Android Emulator
bun run android
# or
bunx expo start --android
# Web Browser
bun run web
# or
bunx expo start --web
```
4. **Linting**
```bash
@@ -83,13 +106,13 @@ hipmi-mobile/
#### EAS Build (Production)
```bash
# Production build
# Production build (App Store / Play Store)
eas build --profile production
# Preview build
# Preview build (Internal distribution)
eas build --profile preview
# Development build
# Development build (Development client)
eas build --profile development
```
@@ -100,7 +123,7 @@ npx expo prebuild
# iOS specific
bunx expo prebuild --platform ios
open ios/HIPMIBADUNG.xcworkspace
open ios/HIPMIBadungConnect.xcworkspace
# Android specific
bunx expo prebuild --platform android
@@ -110,6 +133,12 @@ bunx expo prebuild --platform android
```bash
# Patch version update
npm version patch
# Update iOS build number
bunx expo prebuild --platform ios
# Update Android version code
bunx expo prebuild --platform android
```
### Android Debugging
@@ -126,157 +155,336 @@ adb -s <device_id> install android/app/build/outputs/apk/debug/app-debug.apk
## Environment Variables
The application uses environment variables defined in the `app.config.js` file:
- `API_BASE_URL`: Base URL for API endpoints
- `BASE_URL`: Base application URL
- `DEEP_LINK_URL`: URL for deep linking functionality
Create a `.env` file in the project root with:
Create a `.env` file in the project root with these variables.
```env
API_BASE_URL=https://your-api-base-url.com
BASE_URL=https://your-app-url.com
DEEP_LINK_URL=hipmimobile://
```
## EAS Build Configuration
These are loaded in `app.config.js` and accessible via `Constants.expoConfig.extra`.
The project uses Expo Application Services (EAS) for building and deploying:
- **Development**: Development builds with development client
- **Preview**: Internal distribution builds (APK for Android)
- **Production**: App store builds (App Bundle for Android, IPA for iOS)
## Architecture Patterns
Configuration is in `eas.json`.
### 1. Separation of Concerns
## Features and Functionality
**Route Files** (`app/`) should be minimal (max 5 lines):
```typescript
import { Admin_ScreenXXX } from "@/screens/Admin/XXX/ScreenXXX";
The application includes several key modules:
- **Authentication**: Login with phone number, OTP verification, registration, terms acceptance
- **Admin Panel**: Administrative functions for managing content and users
- **Collaboration**: Tools for member collaboration
- **Events**: Event management and calendar
- **Forum**: Discussion forums
- **Maps**: Location-based services with Mapbox integration
- **Donations**: Donation functionality with fund disbursement tracking
- **Job Board**: Employment opportunities
- **Investment**: Investment-related features
- **Voting**: Voting systems
- **Portfolio**: Member portfolio showcase
- **Notifications**: Push notifications via Firebase
export default function AdminXXX() {
return <Admin_ScreenXXX />;
}
```
**Screen Components** (`screens/`) contain all business logic:
```typescript
export function Admin_ScreenXXX() {
// Logic, hooks, state management
return <NewWrapper ... />;
}
```
### 2. Pagination Pattern
Using `usePagination` hook with infinite scroll:
```typescript
const pagination = usePagination({
fetchFunction: async (page, searchQuery) => {
const response = await apiXXX({ page: String(page) });
if (response.success) {
return { data: response.data };
}
return { data: [] };
},
pageSize: PAGINATION_DEFAULT_TAKE, // 10
searchQuery: search,
dependencies: [dependency],
});
const { ListEmptyComponent, ListFooterComponent } =
createPaginationComponents({
loading: pagination.loading,
refreshing: pagination.refreshing,
listData: pagination.listData,
emptyMessage: "Belum ada data",
skeletonCount: PAGINATION_DEFAULT_TAKE,
});
```
### 3. Wrapper Components
**NewWrapper** (preferred for lists):
```typescript
<NewWrapper
listData={pagination.listData}
renderItem={renderItem}
headerComponent={headerComponent}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
onEndReached={pagination.loadMore}
refreshControl={<RefreshControl ... />}
/>
```
**AdminBasicBox** (for card layouts):
```typescript
<AdminBasicBox
onPress={() => router.push(`/path/${item.id}`)}
style={{ marginHorizontal: 10, marginVertical: 5 }}
>
<StackCustom gap={0}>
<GridSpan_4_8 label="Label" value={<TextCustom>Value</TextCustom>} />
</StackCustom>
</AdminBasicBox>
```
### 4. API Service Structure
```typescript
// service/api-admin/api-xxx.ts
export async function apiXXX({ page = "1" }: { page?: string }) {
try {
const response = await apiConfig.get(`/mobile/admin/xxx?page=${page}`);
return response.data;
} catch (error) {
throw error;
}
}
```
**Important**: All list APIs should support pagination with `page` parameter (default: "1").
### 5. Authentication Flow
Managed by `AuthContext`:
- `loginWithNomor()` - Send phone number, receive OTP
- `validateOtp()` - Validate OTP, get token
- `registerUser()` - Register new user
- `logout()` - Clear session and logout
- `userData()` - Fetch user data by token
## Development Conventions
### Coding Standards
- TypeScript is used throughout the project for type safety
- Component-based architecture with reusable components
- Context API for state management (AuthContext)
- File-based routing with Expo Router
- Consistent naming conventions using camelCase for variables and PascalCase for components
- Path aliases: `@/*` maps to project root
- **TypeScript**: Strict mode enabled
- **Naming**:
- Components: PascalCase (`Admin_ScreenDonationStatus`)
- Files: PascalCase for components (`ScreenDonationStatus.tsx`)
- Variables: camelCase
- Constants: UPPER_SNAKE_CASE
- **Path Aliases**: `@/*` maps to project root
- **Imports**: Group imports by type (components, hooks, services, etc.)
### Architecture Patterns
### Component Structure
```typescript
// 1. Imports (grouped)
import { ... } from "@/components";
import { ... } from "@/hooks";
import { ... } from "@/service";
#### Screen Components
- Screen components are stored in `/screens` directory organized by feature
- Route files in `/app` import and use screen components
- Example pattern:
```tsx
// app/some-route.tsx
import SomeScreen from "@/screens/Feature/ScreenSome";
export default function SomeRoute() {
return <SomeScreen />;
}
```
// 2. Types/Interfaces
interface Props { ... }
#### Wrapper Components
- `NewWrapper` component is used for consistent screen layouts
- Located at `components/_ShareComponent/NewWrapper.tsx`
#### Pagination Pattern
- Use `hooks/use-pagination.tsx` and `helpers/paginationHelpers.tsx`
- Helper functions: `createSkeletonList`, `createEmptyState`, `createLoadingFooter`, `createPaginationComponents`
- API functions should accept `page` parameter (default: "1")
### API Service Structure
- Base API configuration: `service/api-config.ts`
- Client APIs: `service/api-client/`
- Admin APIs: `service/api-admin/`
- All API calls use axios with interceptors for auth token injection
// 3. Main Component
export function ComponentName() {
// State
// Hooks
// Functions
// Render
}
```
### Testing
- Linting is configured with ESLint
- Standard Expo linting configuration
- Linting: `bun run lint`
- No formal test suite configured yet
### Security
- Firebase is integrated for authentication and messaging
- Camera and location permissions are properly configured
- Deep linking is secured with app domain associations
- Auth tokens stored in AsyncStorage
### Git Workflow
- Feature branches: `feature/xxx` or `fixed-admin/xxx`
- Commit messages: Clear and descriptive
- Use CHANGE_LOG.md for tracking changes
## Key Dependencies
## Key Features
### Core Dependencies
- `@react-navigation/*`: Navigation solution for React Native
- `@react-native-firebase/*`: Firebase integration for React Native
- `@rnmapbox/maps`: Mapbox integration for React Native
- `expo-router`: File-based routing for Expo applications
- `react-native-paper`: Material Design components for React Native
- `react-native-toast-message`: Toast notifications
- `react-native-otp-entry`: OTP input components
- `react-native-qrcode-svg`: QR code generation
- `axios`: HTTP client for API calls
- `lodash`: Utility library
- `moti`: Animation library
### Authentication
- Phone number login with OTP
- User registration
- Terms & Conditions acceptance
- Session persistence with AsyncStorage
### Development Dependencies
- `@types/*`: TypeScript type definitions
- `eslint-config-expo`: Expo-specific ESLint configuration
- `typescript`: Type checking
### Admin Module
- **Dashboard**: Overview and statistics
- **User Access**: User management
- **Event**: Event CRUD with status management
- **Voting**: Voting management (publish/review/reject)
- **Donation**: Donation management with categories and transaction tracking
- **Collaboration**: Collaboration requests
- **Investment**: Investment management
- **Maps**: Location-based features
- **App Information**: Bank and business field management
## Platform Support
### User Module
- **Home**: Main dashboard
- **Forum**: Discussion forums
- **Profile**: User profile management
- **Portfolio**: Member portfolio
- **Notifications**: Push notifications via Firebase
The application is configured to support:
- **iOS**:
- Bundle identifier: `com.anonymous.hipmi-mobile`
- Supports tablets
- Build number: 21
- Google Services integration
- Associated domains for deep linking
- **Android**:
- Package name: `com.bip.hipmimobileapp`
- Version code: 4
- Adaptive icons
- Edge-to-edge display enabled
- Intent filters for HTTPS deep linking
- **Web**: Static output configuration for web deployment
## API Configuration
## Special Configurations
### Base URLs
```typescript
// From app.config.js extra
API_BASE_URL: process.env.API_BASE_URL
BASE_URL: process.env.BASE_URL
DEEP_LINK_URL: process.env.DEEP_LINK_URL
```
### Axios Interceptor
All API calls use `apiConfig` with automatic token injection:
```typescript
apiConfig.interceptors.request.use(async (config) => {
const token = await AsyncStorage.getItem("authToken");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
```
## Platform Configuration
### iOS
- **Bundle ID**: `com.anonymous.hipmi-mobile`
- **Build Number**: 21
- **Google Services**: Configured
- **Associated Domains**: `applinks:cld-dkr-staging-hipmi.wibudev.com`
- **Tablet Support**: Enabled
### Android
- **Package**: `com.bip.hipmimobileapp`
- **Version Code**: 4
- **Google Services**: Configured (`google-services.json`)
- **Deep Links**: HTTPS intent filters configured
- **Edge-to-Edge**: Enabled
### Web
- **Output**: Static
- **Bundler**: Metro
## Special Integrations
### Firebase
- Authentication
- Push Notifications (FCM)
- Configured for both iOS and Android
### Mapbox
- Map integration via `@rnmapbox/maps`
- Location permissions configured
### Deep Linking
- Scheme: `hipmimobile://`
- Associated domains: `applinks:cld-dkr-staging-hipmi.wibudev.com`
- Configured for both iOS and Android
### Maps Integration
The application uses Mapbox for mapping functionality with the `@rnmapbox/maps` plugin.
### Push Notifications
Firebase Cloud Messaging is integrated for push notifications with proper configuration for both iOS and Android platforms.
- HTTPS: `cld-dkr-staging-hipmi.wibudev.com`
- Configured for both platforms
### Camera
Camera permissions configured for both iOS and Android with microphone access for recording.
- Camera and microphone permissions
- QR code generation support
## Common Development Tasks
### Adding a New Screen
1. Create screen component in appropriate `/screens` subdirectory
2. Add route in `/app` directory if needed
3. Configure navigation in `AppRoot.tsx` if custom header is needed
### Adding a New Admin Screen
### Adding API Endpoint
1. Add function in appropriate service file (`service/api-client/` or `service/api-admin/`)
2. Use `apiConfig` axios instance for requests
3. Include proper error handling
1. **Create Screen Component** (`screens/Admin/Feature/ScreenXXX.tsx`):
```typescript
export function Admin_ScreenXXX() {
const pagination = usePagination({...});
const renderItem = useCallback(...);
const headerComponent = useMemo(...);
return <NewWrapper ... />;
}
```
### Refactoring Pattern (from docs/prompt-for-qwen-code.md)
When moving code from route files to screen components:
1. Create new file in `screens/<Feature>/` directory
2. Rename function with prefix (e.g., `Admin_`, `Donation_`)
3. Use `NewWrapper` component for consistent layout
4. Apply pagination helpers if displaying lists
5. Import and call from original route file
2. **Create Box Component** (optional, for custom item rendering):
```typescript
export default function Admin_BoxXXX({ item }: { item: any }) {
return (
<AdminBasicBox onPress={() => router.push(...)}>
...
</AdminBasicBox>
);
}
```
3. **Update API** (add pagination if needed):
```typescript
export async function apiXXX({ page = "1" }: { page?: string }) {
// ...
}
```
4. **Create Route File** (`app/(application)/admin/feature/xxx.tsx`):
```typescript
import { Admin_ScreenXXX } from "@/screens/Admin/Feature/ScreenXXX";
export default function AdminXXX() {
return <Admin_ScreenXXX />;
}
```
### Updating API Endpoints
1. Add function in appropriate service file
2. Include `page` parameter for list endpoints
3. Use `apiConfig` axios instance
4. Handle errors properly
## Troubleshooting
### Build Issues
```bash
# Clean and rebuild
rm -rf node_modules
bun install
bunx expo prebuild --clean
# iOS specific
cd ios && pod install && cd ..
# Android specific
cd android && ./gradlew clean && cd ..
```
### Cache Issues
```bash
# Clear Expo cache
bunx expo start -c
# Clear Metro cache
bunx expo start --clear
```
### Dependency Issues
```bash
# Reinstall dependencies
rm -rf node_modules bun.lock
bun install
```
## Documentation Files
- `docs/CHANGE_LOG.md` - Change log for recent updates
- `docs/COMMIT_NOTES.md` - Commit notes and guidelines
- `docs/hipmi-note.md` - Build and deployment notes
- `docs/prompt-for-qwen-code.md` - Development prompts and patterns
## Resources
- [Expo Documentation](https://docs.expo.dev/)
- [React Native Documentation](https://reactnative.dev/)
- [Expo Router Documentation](https://docs.expo.dev/router/introduction/)
- [TypeScript Documentation](https://www.typescriptlang.org/docs/)