From d5634c1f67bdce4caa331939901a9c1780345590 Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Tue, 28 Apr 2026 12:10:27 +0800 Subject: [PATCH] chore: reorganize docs folder + add CLAUDE.md - Kelompokkan docs/ ke subfolder: architecture/, testing/, notes/, ai/, tasks/ - Pindahkan tasks/ (root) ke docs/tasks/ - Tambah docs/README.md sebagai index navigasi - Tambah CLAUDE.md (project instructions) - Hapus .qwen/settings.json Co-Authored-By: Claude Sonnet 4.6 --- .qwen/settings.json | 22 -- .qwen/settings.json.orig | 7 - CLAUDE.md | 273 ++++++++++++++++++ docs/README.md | 17 ++ docs/{ => ai}/prompt-for-qwen-code.md | 0 .../NEWWRAPPER-KEYBOARD-IMPLEMENTATION.md | 0 .../OS-Wrapper-Quick-Reference.md | 0 .../admin-folder-structure.md | 0 docs/{ => notes}/CHANGE_LOG.md | 0 docs/{ => notes}/hipmi-note.md | 0 {tasks => docs/tasks}/README.md | 0 .../TASK-001-footer-tabs-consistency.md | 0 .../TASK-002-expo-router-tabs-safe-area.md | 0 ...ASK-003-footer-terangkat-keyboard-close.md | 0 .../tasks}/TASK-004-newwrapper-migration.md | 0 .../TASK-005-OS-Wrapper-Implementation.md | 0 docs/{ => testing}/KEYBOARD-BUG-TEST.md | 0 docs/{ => testing}/QR_CODE_TESTING.md | 0 18 files changed, 290 insertions(+), 29 deletions(-) delete mode 100644 .qwen/settings.json delete mode 100644 .qwen/settings.json.orig create mode 100644 CLAUDE.md create mode 100644 docs/README.md rename docs/{ => ai}/prompt-for-qwen-code.md (100%) rename docs/{ => architecture}/NEWWRAPPER-KEYBOARD-IMPLEMENTATION.md (100%) rename docs/{ => architecture}/OS-Wrapper-Quick-Reference.md (100%) rename docs/{ => architecture}/admin-folder-structure.md (100%) rename docs/{ => notes}/CHANGE_LOG.md (100%) rename docs/{ => notes}/hipmi-note.md (100%) rename {tasks => docs/tasks}/README.md (100%) rename {tasks => docs/tasks}/TASK-001-footer-tabs-consistency.md (100%) rename {tasks => docs/tasks}/TASK-002-expo-router-tabs-safe-area.md (100%) rename {tasks => docs/tasks}/TASK-003-footer-terangkat-keyboard-close.md (100%) rename {tasks => docs/tasks}/TASK-004-newwrapper-migration.md (100%) rename {tasks => docs/tasks}/TASK-005-OS-Wrapper-Implementation.md (100%) rename docs/{ => testing}/KEYBOARD-BUG-TEST.md (100%) rename docs/{ => testing}/QR_CODE_TESTING.md (100%) diff --git a/.qwen/settings.json b/.qwen/settings.json deleted file mode 100644 index 1e1ec9f..0000000 --- a/.qwen/settings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "security": { - "auth": { - "selectedType": "openai" - } - }, - "env": { - "OPENAI_BASE_URL": "https://claude-local.wibudev.com/v1", - "OPENAI_API_KEY": "sk-T8mDcFAe83WWOQsHGx0JxvTmgBVdTQ2uFKzIRjZpwrh0H4Bg", - "OPENAI_MODEL": "claude-sonnet-4-6" - }, - "projectContext": { - "enabled": false - }, - "agent": { - "enabled": false - }, - "permissions": { - "allow": [] - }, - "$version": 3 -} \ No newline at end of file diff --git a/.qwen/settings.json.orig b/.qwen/settings.json.orig deleted file mode 100644 index 322d785..0000000 --- a/.qwen/settings.json.orig +++ /dev/null @@ -1,7 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(git add *)" - ] - } -} \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a6ed30f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,273 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +--- + +## Project + +**HIPMI Badung Connect** — Cross-platform mobile app (iOS, Android, Web) for HIPMI (Himpunan Pengusaha Muda Indonesia) chapter Badung members. + +- Framework: Expo v54 + React Native v0.81.5, TypeScript strict +- Routing: Expo Router v6 (file-based) +- Package manager: Bun + +--- + +## Commands + +```bash +bun install # install dependencies +bunx expo start # dev server +bunx expo start --ios # iOS simulator +bunx expo start --android # Android emulator +bunx expo start -c # clear cache +bun run lint # expo lint + +# Build (EAS) +eas build --profile production +eas build --profile preview +eas build --profile development + +# Troubleshooting +rm -rf node_modules && bun install +bunx expo start --clear +``` + +--- + +## Architecture + +### Route → Screen separation (strict) + +`app/` contains **route files only** (max 5 lines). All business logic lives in `screens/`. + +```typescript +// app/(application)/admin/feature/screen-name.tsx +import { Admin_ScreenXXX } from "@/screens/Admin/Feature/ScreenXXX"; +export default function AdminScreenXXX() { return ; } +``` + +```typescript +// screens/Admin/Feature/ScreenXXX.tsx — ALL logic here +export function Admin_ScreenXXX() { + // hooks, state, handlers, render + return ; +} +``` + +### Naming conventions + +| Item | Convention | Example | +|---|---|---| +| Admin screen | `Admin_ScreenXXX` | `Admin_ScreenDonationList` | +| User screen | PascalCase | `ScreenDonationDetail` | +| Admin card | `Admin_BoxXXX` | `Admin_BoxDonation` | +| Path alias | `@/*` | `@/components/...` | + +--- + +## Key Components + +### OS_Wrapper — always use as root wrapper + +Automatically selects iOS/Android layout. Two modes: + +```typescript +// List screen +} +/> + +// Form screen (with TextInput / TextArea) + + + +``` + +- `contentPaddingBottom={100}` — default for list screens +- `contentPaddingBottom={250}` — **only** for screens with TextInput/TextArea +- `enableKeyboardHandling` — Android keyboard auto-scroll (ignored on iOS) + +### AdminBasicBox + GridSpan_4_8 + +```typescript + router.push(`/path/${item.id}`)} style={{ marginHorizontal: 10, marginVertical: 5 }}> + + {item.name}} /> + + +``` + +--- + +## Pagination Pattern + +```typescript +import { usePagination } from "@/hooks/use-pagination"; +import { createPaginationComponents } from "@/helpers/paginationHelpers"; +import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value"; + +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, +}); +``` + +`usePagination` returns: `listData`, `loading`, `refreshing`, `hasMore`, `page`, `onRefresh`, `loadMore`, `reset`, `setListData`, `isInitialLoad` + +--- + +## API Service Pattern + +Always use `apiConfig` (not `axios` directly) — auth token injected automatically via request interceptor from `AsyncStorage.getItem("authToken")`. + +```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; + } +} +``` + +- All list endpoints require `page` param (default `"1"` as string) +- Response shape: `{ success: boolean, data: T[], message?: string }` +- Admin APIs: `service/api-admin/` +- Client APIs: `service/api-client/` + +--- + +## Authentication + +```typescript +// context/AuthContext.tsx — access via useAuth() +const { user, token, isAdmin, isUserActive, loginWithNomor, validateOtp, logout } = useAuth(); + +// Role check +const isAdmin = user?.masterUserRoleId !== "1"; // "1" = regular user + +// Post-login routing +// active user → /(application)/(user)/home +// inactive user → /(application)/(user)/waiting-room +``` + +AsyncStorage keys: `"authToken"`, `"userData"` + +--- + +## File Upload + +```typescript +import { uploadFileService, deleteFileService } from "@/service/upload-service"; +import { API_IMAGE } from "@/constants/api-storage"; + +const result = await uploadFileService({ dirId: "folder-name", imageUri: localUri }); +// result.data.id → save this ID to backend + +await deleteFileService({ id: fileId }); + +const imageUrl = API_IMAGE.GET({ fileId: "xxx", size: 200 }); // wibu-storage CDN +``` + +--- + +## Constants (`constants/constans-value.ts`) + +```typescript +PADDING_INLINE = 16 // use selectively, not on every screen by default +PADDING_EXTRA_SMALL = 10 +PADDING_SMALL = 12 +PADDING_MEDIUM = 16 +PADDING_LARGE = 20 + +OS_ANDROID_HEIGHT = 60 / OS_IOS_HEIGHT = 80 +OS_ANDROID_PADDING_TOP = 6 / OS_IOS_PADDING_TOP = 12 + +TEXT_SIZE_SMALL = 12 / MEDIUM = 14 / LARGE = 16 / XLARGE = 18 +PAGINATION_DEFAULT_TAKE = 10 +DRAWER_HEIGHT = 500 +RADIUS_BUTTON = 50 +``` + +```typescript +// constants/color-palet.ts +MainColor.darkblue = "#001D3D" // user app primary +AdminColor.bgAdmin = "#182c47" // admin panel background +``` + +--- + +## Known Issues + +### iOS Maplibre crash — "Attempt to recycle a mounted view" + +Never conditionally render `PointAnnotation`. Control visibility via opacity instead: + +```typescript +// ✅ correct + + + + + + +// ❌ crashes iOS +{selectedLocation && } +``` + +--- + +## Known Typos — Do NOT fix unless asked + +| Path | Typo | +|---|---| +| `constants/constans-value.ts` | `constans` | +| `constants/base-url-api-strorage.ts` | `strorage` | +| `screens/Invesment/` | `Invesment` | +| `screens/Portofolio/` | `Portofolio` | +| `screens/UserSeach/` | `UserSeach` | + +--- + +## Environment Variables (`.env`) + +```env +API_BASE_URL=https://your-api-url.com +BASE_URL=https://your-app-url.com +DEEP_LINK_URL=hipmimobile:// +``` + +Accessed via: `Constants.expoConfig?.extra?.API_BASE_URL` + +--- + +## New Screen Checklist + +1. `service/api-admin/api-xxx.ts` — API function with `page` param +2. `screens/Admin/Feature/ScreenXXX.tsx` — screen with `usePagination` + `OS_Wrapper` +3. `screens/Admin/Feature/BoxXXX.tsx` — card component (optional) +4. `app/(application)/admin/feature/index.tsx` — thin route file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..1edfaae --- /dev/null +++ b/docs/README.md @@ -0,0 +1,17 @@ +# Dokumentasi HIPMI Mobile + +## Struktur Folder + +| Folder | Isi | +|---|---| +| [architecture/](./architecture/) | Referensi arsitektur, komponen, dan implementasi | +| [testing/](./testing/) | Panduan dan catatan testing fitur | +| [notes/](./notes/) | Catatan development dan changelog | +| [ai/](./ai/) | Prompt dan konfigurasi AI tools | +| [tasks/](./tasks/) | Task list development | + +## Referensi Cepat + +- [OS_Wrapper Quick Reference](./architecture/OS-Wrapper-Quick-Reference.md) +- [Admin Folder Structure](./architecture/admin-folder-structure.md) +- [Change Log](./notes/CHANGE_LOG.md) diff --git a/docs/prompt-for-qwen-code.md b/docs/ai/prompt-for-qwen-code.md similarity index 100% rename from docs/prompt-for-qwen-code.md rename to docs/ai/prompt-for-qwen-code.md diff --git a/docs/NEWWRAPPER-KEYBOARD-IMPLEMENTATION.md b/docs/architecture/NEWWRAPPER-KEYBOARD-IMPLEMENTATION.md similarity index 100% rename from docs/NEWWRAPPER-KEYBOARD-IMPLEMENTATION.md rename to docs/architecture/NEWWRAPPER-KEYBOARD-IMPLEMENTATION.md diff --git a/docs/OS-Wrapper-Quick-Reference.md b/docs/architecture/OS-Wrapper-Quick-Reference.md similarity index 100% rename from docs/OS-Wrapper-Quick-Reference.md rename to docs/architecture/OS-Wrapper-Quick-Reference.md diff --git a/docs/admin-folder-structure.md b/docs/architecture/admin-folder-structure.md similarity index 100% rename from docs/admin-folder-structure.md rename to docs/architecture/admin-folder-structure.md diff --git a/docs/CHANGE_LOG.md b/docs/notes/CHANGE_LOG.md similarity index 100% rename from docs/CHANGE_LOG.md rename to docs/notes/CHANGE_LOG.md diff --git a/docs/hipmi-note.md b/docs/notes/hipmi-note.md similarity index 100% rename from docs/hipmi-note.md rename to docs/notes/hipmi-note.md diff --git a/tasks/README.md b/docs/tasks/README.md similarity index 100% rename from tasks/README.md rename to docs/tasks/README.md diff --git a/tasks/TASK-001-footer-tabs-consistency.md b/docs/tasks/TASK-001-footer-tabs-consistency.md similarity index 100% rename from tasks/TASK-001-footer-tabs-consistency.md rename to docs/tasks/TASK-001-footer-tabs-consistency.md diff --git a/tasks/TASK-002-expo-router-tabs-safe-area.md b/docs/tasks/TASK-002-expo-router-tabs-safe-area.md similarity index 100% rename from tasks/TASK-002-expo-router-tabs-safe-area.md rename to docs/tasks/TASK-002-expo-router-tabs-safe-area.md diff --git a/tasks/TASK-003-footer-terangkat-keyboard-close.md b/docs/tasks/TASK-003-footer-terangkat-keyboard-close.md similarity index 100% rename from tasks/TASK-003-footer-terangkat-keyboard-close.md rename to docs/tasks/TASK-003-footer-terangkat-keyboard-close.md diff --git a/tasks/TASK-004-newwrapper-migration.md b/docs/tasks/TASK-004-newwrapper-migration.md similarity index 100% rename from tasks/TASK-004-newwrapper-migration.md rename to docs/tasks/TASK-004-newwrapper-migration.md diff --git a/tasks/TASK-005-OS-Wrapper-Implementation.md b/docs/tasks/TASK-005-OS-Wrapper-Implementation.md similarity index 100% rename from tasks/TASK-005-OS-Wrapper-Implementation.md rename to docs/tasks/TASK-005-OS-Wrapper-Implementation.md diff --git a/docs/KEYBOARD-BUG-TEST.md b/docs/testing/KEYBOARD-BUG-TEST.md similarity index 100% rename from docs/KEYBOARD-BUG-TEST.md rename to docs/testing/KEYBOARD-BUG-TEST.md diff --git a/docs/QR_CODE_TESTING.md b/docs/testing/QR_CODE_TESTING.md similarity index 100% rename from docs/QR_CODE_TESTING.md rename to docs/testing/QR_CODE_TESTING.md