From 6b786d7983638688aa22c6a1c32bb4289231603f Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Mon, 6 Apr 2026 11:20:20 +0800 Subject: [PATCH] refactor: Migrate Portofolio & Maps screens to NewWrapper_V2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 3 Migration - Fix keyboard handling issues across 8 screens Portofolio Screens (5): - portofolio/[id]/edit-social-media.tsx: ViewWrapper → NewWrapper_V2 - portofolio/[id]/edit-logo.tsx: ViewWrapper → NewWrapper_V2 - portofolio/[id]/edit.tsx: NewWrapper → NewWrapper_V2 + fix React error - portofolio/[id]/index.tsx: ViewWrapper → NewWrapper_V2 - screens/Portofolio/ScreenPortofolioCreate.tsx: NewWrapper → NewWrapper_V2 Maps Screens (3): - screens/Maps/ScreenMapsCreate.tsx: NewWrapper → NewWrapper_V2 - screens/Maps/ScreenMapsEdit.tsx: ViewWrapper → NewWrapper_V2 - app/(application)/(user)/maps/[id]/custom-pin.tsx: ViewWrapper → NewWrapper_V2 Changes: - Add enableKeyboardHandling to all form screens - Wrap TextInputCustom/SelectCustom/TextAreaCustom with View onStartShouldSetResponder - Fix React static flag error in portofolio edit loading state - Update TASK-004 migration task file Co-authored-by: Qwen-Coder --- .../(user)/maps/[id]/custom-pin.tsx | 10 +- .../(user)/portofolio/[id]/edit-logo.tsx | 9 +- .../portofolio/[id]/edit-social-media.tsx | 81 +++-- .../(user)/portofolio/[id]/edit.tsx | 336 ++++++++++-------- .../(user)/portofolio/[id]/index.tsx | 6 +- screens/Maps/ScreenMapsCreate.tsx | 29 +- screens/Maps/ScreenMapsEdit.tsx | 27 +- screens/Portofolio/ScreenPortofolioCreate.tsx | 231 ++++++------ tasks/TASK-004-newwrapper-migration.md | 133 +++++-- 9 files changed, 504 insertions(+), 358 deletions(-) diff --git a/app/(application)/(user)/maps/[id]/custom-pin.tsx b/app/(application)/(user)/maps/[id]/custom-pin.tsx index 8ea9893..cc12799 100644 --- a/app/(application)/(user)/maps/[id]/custom-pin.tsx +++ b/app/(application)/(user)/maps/[id]/custom-pin.tsx @@ -8,7 +8,7 @@ import { MapCustom, Spacing, StackCustom, - ViewWrapper, + NewWrapper_V2, } from "@/components"; import CenterCustom from "@/components/Center/CenterCustom"; import { router, useLocalSearchParams } from "expo-router"; @@ -30,7 +30,11 @@ export default function MapsCustomPin() { ); return ( <> - + @@ -49,7 +53,7 @@ export default function MapsCustomPin() { - + ); } diff --git a/app/(application)/(user)/portofolio/[id]/edit-logo.tsx b/app/(application)/(user)/portofolio/[id]/edit-logo.tsx index 9845fb4..c23fdcf 100644 --- a/app/(application)/(user)/portofolio/[id]/edit-logo.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit-logo.tsx @@ -3,7 +3,7 @@ import { BoxButtonOnFooter, ButtonCenteredOnly, ButtonCustom, - ViewWrapper + NewWrapper_V2 } from "@/components"; import API_STRORAGE from "@/constants/base-url-api-strorage"; import DIRECTORY_ID from "@/constants/directory-id"; @@ -126,7 +126,10 @@ export default function PortofolioEditLogo() { return ( <> - + Upload - + ); } diff --git a/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx b/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx index 1770c3f..f04e288 100644 --- a/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit-social-media.tsx @@ -1,8 +1,8 @@ import { BoxButtonOnFooter, ButtonCustom, + NewWrapper_V2, TextInputCustom, - ViewWrapper, } from "@/components"; import { apiGetOnePortofolio, @@ -10,6 +10,7 @@ import { } from "@/service/api-client/api-portofolio"; import { useLocalSearchParams, router } from "expo-router"; import { useEffect, useState } from "react"; +import { View } from "react-native"; import Toast from "react-native-toast-message"; export default function PortofolioEditSocialMedia() { @@ -91,38 +92,52 @@ export default function PortofolioEditSocialMedia() { return ( <> - - setData({ ...data, tiktok: value })} - label="Tiktok" - placeholder="Masukkan tiktok" - /> - setData({ ...data, instagram: value })} - label="Instagram" - placeholder="Masukkan instagram" - /> - setData({ ...data, facebook: value })} - label="Facebook" - placeholder="Masukkan facebook" - /> - setData({ ...data, twitter: value })} - label="Twitter" - placeholder="Masukkan twitter" - /> - setData({ ...data, youtube: value })} - label="Youtube" - placeholder="Masukkan youtube" - /> - + + true}> + setData({ ...data, tiktok: value })} + label="Tiktok" + placeholder="Masukkan tiktok" + /> + + true}> + setData({ ...data, instagram: value })} + label="Instagram" + placeholder="Masukkan instagram" + /> + + true}> + setData({ ...data, facebook: value })} + label="Facebook" + placeholder="Masukkan facebook" + /> + + true}> + setData({ ...data, twitter: value })} + label="Twitter" + placeholder="Masukkan twitter" + /> + + true}> + setData({ ...data, youtube: value })} + label="Youtube" + placeholder="Masukkan youtube" + /> + + ); } diff --git a/app/(application)/(user)/portofolio/[id]/edit.tsx b/app/(application)/(user)/portofolio/[id]/edit.tsx index b1dbfad..764f219 100644 --- a/app/(application)/(user)/portofolio/[id]/edit.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit.tsx @@ -4,7 +4,7 @@ import { BoxButtonOnFooter, ButtonCustom, CenterCustom, - NewWrapper, + NewWrapper_V2, PhoneInputCustom, SelectCustom, Spacing, @@ -16,7 +16,11 @@ import { import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent"; import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_XLARGE } from "@/constants/constans-value"; -import { DEFAULT_COUNTRY, type CountryData, COUNTRIES } from "@/constants/countries"; +import { + DEFAULT_COUNTRY, + type CountryData, + COUNTRIES, +} from "@/constants/countries"; import { apiMasterBidangBisnis, apiMasterSubBidangBisnis, @@ -61,7 +65,8 @@ export default function PortofolioEdit() { const [isLoading, setIsLoading] = useState(false); const [data, setData] = useState({}); const [phoneNumber, setPhoneNumber] = useState(""); - const [selectedCountry, setSelectedCountry] = useState(DEFAULT_COUNTRY); + const [selectedCountry, setSelectedCountry] = + useState(DEFAULT_COUNTRY); const [bidangBisnis, setBidangBisnis] = useState< IMasterBidangBisnis[] | null >(null); @@ -75,38 +80,38 @@ export default function PortofolioEdit() { function handlePhoneChange(phone: string) { setPhoneNumber(phone); - + // Format phone number for API const callingCode = selectedCountry.callingCode; let fixNumber = phone.replace(/\s+/g, "").replace(/^0+/, ""); - + // Remove country code if already present if (fixNumber.startsWith(callingCode)) { fixNumber = fixNumber.substring(callingCode.length); } - + // Remove leading zero fixNumber = fixNumber.replace(/^0+/, ""); - + const realNumber = callingCode + fixNumber; setData({ ...data, tlpn: realNumber }); } function handleCountryChange(country: CountryData) { setSelectedCountry(country); - + // Re-format with new country code const callingCode = country.callingCode; let fixNumber = phoneNumber.replace(/\s+/g, "").replace(/^0+/, ""); - + // Remove country code if already present if (fixNumber.startsWith(callingCode)) { fixNumber = fixNumber.substring(callingCode.length); } - + // Remove leading zero fixNumber = fixNumber.replace(/^0+/, ""); - + const realNumber = callingCode + fixNumber; setData({ ...data, tlpn: realNumber }); } @@ -157,7 +162,7 @@ export default function PortofolioEdit() { const fullNumber = response.data.tlpn; let displayNumber = fullNumber; let detectedCountry = DEFAULT_COUNTRY; - + // Try to detect country from calling code for (const country of COUNTRIES) { if (fullNumber.startsWith(country.callingCode)) { @@ -166,12 +171,12 @@ export default function PortofolioEdit() { break; } } - + setSelectedCountry(detectedCountry); - + // Remove leading zero if present displayNumber = displayNumber.replace(/^0+/, ""); - + setPhoneNumber(displayNumber); setData({ ...response.data, tlpn: displayNumber }); @@ -363,161 +368,176 @@ export default function PortofolioEdit() { ); - if (!bidangBisnis || !subBidangBisnis) { - return ( - <> - - - - - ); - } + // if (!bidangBisnis || !subBidangBisnis) { + // return ( + // + // + // + // ); + // } return ( <> - - - - setData({ ...data, namaBisnis: value }) - } - /> - - ({ - label: item.name, - value: item.id, - }))} - value={data.masterBidangBisnisId} - onChange={(value: any) => { - handleBidangBisnisChange(value); - }} - /> - - {listSubBidangSelected.map((item, index) => { - // Filter data untuk select sub bidang, menghilangkan yang sudah dipilih kecuali untuk item ini sendiri - const selectedIds = listSubBidangSelected - .filter((_, i) => i !== index) - .map((s) => s.MasterSubBidangBisnis?.id) - .filter((id) => id); // Filter hanya yang memiliki id (tidak kosong) - - const availableSubBidangOptions = (selectedSubBidang || []) - .filter((sub: any) => { - // Tampilkan jika ini adalah opsi yang dipilih saat ini atau belum dipilih di sub bidang lainnya - - return ( - sub.id === item.MasterSubBidangBisnis?.id || - !selectedIds.includes(sub.id) - ); - }) - .map((sub: any) => ({ - value: sub.id, - label: sub.name, - })); - - return ( - + {!bidangBisnis || !subBidangBisnis ? ( + + ) : ( + + true}> + + setData({ ...data, namaBisnis: value }) + } + /> + + + true}> + ({ + label: item.name, + value: item.id, + }))} + value={data.masterBidangBisnisId} onChange={(value: any) => { - handleSubBidangChange(value, index); + handleBidangBisnisChange(value); }} /> - ); - })} - - - - { - handleAddSubBidang(); - }} - icon={ - - } - size="xl" - /> - { - handleRemoveSubBidang(listSubBidangSelected.length - 1); - }} - icon={ - - } - size="xl" - /> - - - - - - Nomor Telepon - - * + {listSubBidangSelected.map((item, index) => { + // Filter data untuk select sub bidang, menghilangkan yang sudah dipilih kecuali untuk item ini sendiri + const selectedIds = listSubBidangSelected + .filter((_, i) => i !== index) + .map((s) => s.MasterSubBidangBisnis?.id) + .filter((id) => id); // Filter hanya yang memiliki id (tidak kosong) + + const availableSubBidangOptions = (selectedSubBidang || []) + .filter((sub: any) => { + // Tampilkan jika ini adalah opsi yang dipilih saat ini atau belum dipilih di sub bidang lainnya + + return ( + sub.id === item.MasterSubBidangBisnis?.id || + !selectedIds.includes(sub.id) + ); + }) + .map((sub: any) => ({ + value: sub.id, + label: sub.name, + })); + + return ( + true} key={index}> + { + handleSubBidangChange(value, index); + }} + /> + + ); + })} + + + + { + handleAddSubBidang(); + }} + icon={ + + } + size="xl" + /> + { + handleRemoveSubBidang(listSubBidangSelected.length - 1); + }} + icon={ + + } + size="xl" + /> + + + + + + + + Nomor Telepon + + * + + + - - - - + - - setData({ ...data, alamatKantor: value }) - } - /> + true}> + + setData({ ...data, alamatKantor: value }) + } + /> + - - setData({ ...data, deskripsi: value }) - } - autosize - minRows={2} - maxRows={5} - required - showCount - maxLength={1000} - /> - - - + true}> + + setData({ ...data, deskripsi: value }) + } + autosize + minRows={2} + maxRows={5} + required + showCount + maxLength={1000} + /> + + + + )} + ); } diff --git a/app/(application)/(user)/portofolio/[id]/index.tsx b/app/(application)/(user)/portofolio/[id]/index.tsx index ed2c2d3..4c55489 100644 --- a/app/(application)/(user)/portofolio/[id]/index.tsx +++ b/app/(application)/(user)/portofolio/[id]/index.tsx @@ -4,6 +4,7 @@ import { DrawerCustom, DummyLandscapeImage, LoaderCustom, + NewWrapper_V2, Spacing, StackCustom, TextCustom, @@ -12,7 +13,6 @@ import AppHeader from "@/components/_ShareComponent/AppHeader"; import LeftButtonCustom from "@/components/Button/BackButton"; import GridTwoView from "@/components/_ShareComponent/GridTwoView"; import CustomSkeleton from "@/components/_ShareComponent/SkeletonCustom"; -import ViewWrapper from "@/components/_ShareComponent/ViewWrapper"; import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_SMALL } from "@/constants/constans-value"; import { useAuth } from "@/hooks/use-auth"; @@ -92,7 +92,7 @@ export default function Portofolio() { ), }} /> - + {!data || !profileId ? ( @@ -125,7 +125,7 @@ export default function Portofolio() { )} - + {/* Drawer Komponen Eksternal */} + @@ -160,13 +165,15 @@ export function Maps_ScreenMapsCreate() { /> - + true}> + + @@ -179,7 +186,7 @@ export function Maps_ScreenMapsCreate() { - + ); } diff --git a/screens/Maps/ScreenMapsEdit.tsx b/screens/Maps/ScreenMapsEdit.tsx index deee80f..7319fd7 100644 --- a/screens/Maps/ScreenMapsEdit.tsx +++ b/screens/Maps/ScreenMapsEdit.tsx @@ -7,7 +7,7 @@ import { LandscapeFrameUploaded, Spacing, TextInputCustom, - ViewWrapper, + NewWrapper_V2, } from "@/components"; import CustomSkeleton from "@/components/_ShareComponent/SkeletonCustom"; import { MapSelectedPlatform } from "@/components/Map/MapSelectedPlatform"; @@ -19,6 +19,7 @@ import { uploadFileService } from "@/service/upload-service"; import pickFile, { IFileData } from "@/utils/pickFile"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import { useCallback, useState } from "react"; +import { View } from "react-native"; import { LatLng } from "react-native-maps"; import Toast from "react-native-toast-message"; @@ -166,7 +167,11 @@ export function Maps_ScreenMapsEdit() { : defaultRegion; return ( - + {/* )} - setData({ ...data, namePin: value })} - /> + true}> + setData({ ...data, namePin: value })} + /> + @@ -223,6 +230,6 @@ export function Maps_ScreenMapsEdit() { Upload - + ); } diff --git a/screens/Portofolio/ScreenPortofolioCreate.tsx b/screens/Portofolio/ScreenPortofolioCreate.tsx index 6547b7b..583ad21 100644 --- a/screens/Portofolio/ScreenPortofolioCreate.tsx +++ b/screens/Portofolio/ScreenPortofolioCreate.tsx @@ -4,7 +4,7 @@ import { ButtonCenteredOnly, CenterCustom, InformationBox, - NewWrapper, + NewWrapper_V2, PhoneInputCustom, SelectCustom, Spacing, @@ -142,7 +142,9 @@ export function ScreenPortofolioCreate() { }; return ( - - setData({ ...data, namaBisnis: value })} - /> - - ({ - label: item.name, - value: item.id, - }))} - value={data.masterBidangBisnisId} - onChange={(value) => { - const isSameBidang = data.masterBidangBisnisId === value; - - if (!isSameBidang) { - setListSubBidangSelected([{ id: "" }]); - } - - setData({ ...(data as any), masterBidangBisnisId: value }); - handlerSelectedSubBidang({ id: value as string }); - }} - /> - - {listSubBidangSelected.map((item, index) => ( - true}> + { - const selectedValues = listSubBidangSelected.map((s) => s.id); - return ( - option.id === item.id || !selectedValues.includes(option.id) - ); - }) - .map((e: any) => ({ - value: e.id, - label: e.name, - }))} - value={item.id || null} + label="Nama Bisnis" + placeholder="Masukkan nama bisnis" + onChangeText={(value: any) => setData({ ...data, namaBisnis: value })} + /> + + + true}> + ({ + label: item.name, + value: item.id, + }))} + value={data.masterBidangBisnisId} onChange={(value) => { - const list = _.clone(listSubBidangSelected); - list[index].id = value as any; - setListSubBidangSelected(list); + const isSameBidang = data.masterBidangBisnisId === value; + + if (!isSameBidang) { + setListSubBidangSelected([{ id: "" }]); + } + + setData({ ...(data as any), masterBidangBisnisId: value }); + handlerSelectedSubBidang({ id: value as string }); }} /> + + + {listSubBidangSelected.map((item, index) => ( + true} key={index}> + { + const selectedValues = listSubBidangSelected.map((s) => s.id); + return ( + option.id === item.id || !selectedValues.includes(option.id) + ); + }) + .map((e: any) => ({ + value: e.id, + label: e.name, + }))} + value={item.id || null} + onChange={(value) => { + const list = _.clone(listSubBidangSelected); + list[index].id = value as any; + setListSubBidangSelected(list); + }} + /> + ))} @@ -272,27 +279,31 @@ export function ScreenPortofolioCreate() { - - setData({ ...data, alamatKantor: value }) - } - /> + true}> + + setData({ ...data, alamatKantor: value }) + } + /> + - setData({ ...data, deskripsi: value })} - autosize - minRows={2} - maxRows={5} - required - showCount - maxLength={1000} - /> + true}> + setData({ ...data, deskripsi: value })} + autosize + minRows={2} + maxRows={5} + required + showCount + maxLength={1000} + /> + @@ -322,46 +333,56 @@ export function ScreenPortofolioCreate() { - - setDataMedsos({ ...dataMedsos, tiktok: value }) - } - /> + true}> + + setDataMedsos({ ...dataMedsos, tiktok: value }) + } + /> + - - setDataMedsos({ ...dataMedsos, facebook: value }) - } - /> + true}> + + setDataMedsos({ ...dataMedsos, facebook: value }) + } + /> + - - setDataMedsos({ ...dataMedsos, instagram: value }) - } - /> + true}> + + setDataMedsos({ ...dataMedsos, instagram: value }) + } + /> + - - setDataMedsos({ ...dataMedsos, twitter: value }) - } - /> + true}> + + setDataMedsos({ ...dataMedsos, twitter: value }) + } + /> + - - setDataMedsos({ ...dataMedsos, youtube: value }) - } - /> + true}> + + setDataMedsos({ ...dataMedsos, youtube: value }) + } + /> + - + ); } diff --git a/tasks/TASK-004-newwrapper-migration.md b/tasks/TASK-004-newwrapper-migration.md index dcf4778..863fee2 100644 --- a/tasks/TASK-004-newwrapper-migration.md +++ b/tasks/TASK-004-newwrapper-migration.md @@ -15,29 +15,47 @@ Migrasi bertahap dari `NewWrapper` ke `NewWrapper_V2` untuk memperbaiki bug keyb ## 📊 Migration Priority -### **Phase 1: Job Screens** (Week 1) - CURRENT +### **Phase 1: Job Screens** (Week 1) ✅ COMPLETED - [x] `screens/Job/ScreenJobCreate2.tsx` → Already using keyboard handling -- [ ] `screens/Job/ScreenJobCreate.tsx` → Migrate to NewWrapper_V2 -- [ ] `screens/Job/ScreenJobEdit.tsx` → Migrate to NewWrapper_V2 -- [ ] Delete test files after migration +- [x] `screens/Job/ScreenJobCreate.tsx` → Migrate to NewWrapper_V2 +- [x] `screens/Job/ScreenJobEdit.tsx` → Migrate to NewWrapper_V2 +- [x] Delete test files after migration -### **Phase 2: Event & Profile Screens** (Week 2) +### **Phase 2: Profile Screens** (Week 2) ✅ COMPLETED +- [x] `app/(application)/(user)/profile/create.tsx` → Migrate to NewWrapper_V2 +- [x] `app/(application)/(user)/profile/[id]/edit.tsx` → Migrate to NewWrapper_V2 +- [x] `app/(application)/(user)/profile/[id]/index.tsx` → Migrate to NewWrapper_V2 +- [x] `app/(application)/(user)/profile/[id]/detail-blocked.tsx` → Migrate to NewWrapper_V2 +- [x] `app/(application)/(user)/profile/[id]/blocked-list.tsx` → Migrate to NewWrapper_V2 +- [x] `app/(application)/(user)/profile/[id]/update-photo.tsx` → Migrate to NewWrapper_V2 +- [x] `app/(application)/(user)/profile/[id]/update-background.tsx` → Migrate to NewWrapper_V2 + +### **Phase 3: Portofolio & Maps Screens** (Week 3) - NEXT +- [ ] `app/(application)/(user)/portofolio/[id]/create.tsx` +- [ ] `app/(application)/(user)/portofolio/[id]/edit.tsx` +- [ ] `app/(application)/(user)/portofolio/[id]/edit-logo.tsx` +- [ ] `app/(application)/(user)/portofolio/[id]/edit-social-media.tsx` +- [ ] `app/(application)/(user)/portofolio/[id]/index.tsx` +- [ ] `app/(application)/(user)/portofolio/[id]/list.tsx` +- [ ] `screens/Maps/ScreenMapsCreate.tsx` +- [ ] `screens/Maps/ScreenMapsEdit.tsx` +- [ ] `app/(application)/(user)/maps/[id]/custom-pin.tsx` + +### **Phase 4: Event Screens** (Week 4) - [ ] `screens/Event/ScreenEventCreate.tsx` - [ ] `screens/Event/ScreenEventEdit.tsx` -- [ ] `screens/Profile/ScreenProfileCreate.tsx` -- [ ] `screens/Profile/ScreenProfileEdit.tsx` -### **Phase 3: Other Form Screens** (Week 3) +### **Phase 5: Other Form Screens** (Week 5) - [ ] `screens/Donation/` - All create/edit screens - [ ] `screens/Investment/` - All create/edit screens - [ ] `screens/Voting/` - All create/edit screens -### **Phase 4: Complex Screens** (Week 4) +### **Phase 6: Complex Screens** (Week 6) - [ ] `screens/Forum/` - Create/edit with rich text - [ ] `screens/Collaboration/` - Complex forms - [ ] Other complex forms -### **Phase 5: Cleanup** (Week 5) +### **Phase 7: Cleanup** (Week 7) - [ ] Remove old `NewWrapper.tsx` (or deprecate) - [ ] Rename `NewWrapper_V2.tsx` → `NewWrapper.tsx` - [ ] Update documentation @@ -214,10 +232,12 @@ import { View } from "react-native"; | Phase | Screens | Status | Completed Date | |-------|---------|--------|----------------| | **Phase 1: Job** | 6 screens | ✅ COMPLETED | 2026-04-01 | -| **Phase 2: Event & Profile** | 4 screens | ⏳ Pending | - | -| **Phase 3: Forms** | 6-8 screens | ⏳ Pending | - | -| **Phase 4: Complex** | 4-6 screens | ⏳ Pending | - | -| **Phase 5: Cleanup** | Cleanup | ⏳ Pending | - | +| **Phase 2: Profile** | 7 screens | ✅ COMPLETED | 2026-04-04 | +| **Phase 3: Portofolio & Maps** | 9 screens | ⏳ Pending | - | +| **Phase 4: Event** | 2 screens | ⏳ Pending | - | +| **Phase 5: Forms** | 6-8 screens | ⏳ Pending | - | +| **Phase 6: Complex** | 4-6 screens | ⏳ Pending | - | +| **Phase 7: Cleanup** | Cleanup | ⏳ Pending | - | --- @@ -256,30 +276,63 @@ import { View } from "react-native"; --- +## ✅ Phase 2: COMPLETED! + +**Migrated Screens:** +1. ✅ `app/(application)/(user)/profile/create.tsx` - Form with keyboard handling +2. ✅ `app/(application)/(user)/profile/[id]/edit.tsx` - Form with keyboard handling +3. ✅ `app/(application)/(user)/profile/[id]/index.tsx` - Profile detail (list, no keyboard handling) +4. ✅ `app/(application)/(user)/profile/[id]/detail-blocked.tsx` - Blocked detail with keyboard handling +5. ✅ `app/(application)/(user)/profile/[id]/blocked-list.tsx` - Blocked list (list, no keyboard handling) +6. ✅ `app/(application)/(user)/profile/[id]/update-photo.tsx` - Photo update screen +7. ✅ `app/(application)/(user)/profile/[id]/update-background.tsx` - Background update screen + +**Changes Applied:** +- Replaced `ViewWrapper`/`NewWrapper` → `NewWrapper_V2` +- Added `enableKeyboardHandling` prop to form screens +- Added `keyboardScrollOffset={100}` to form screens +- Wrapped all `TextInputCustom`/`SelectCustom` with ` true}>` +- Fixed keyboard handling issues (footer lift, white area, input cutoff) + +**Commits:** +- `3382c16` - refactor: Migrate Profile screens to NewWrapper_V2 +- `76759cc` - chore: Update layout headers and iOS build config + +**Total:** 7 screens migrated, 2 commits pushed to branch `qc/4-apr-26` + +--- + ## 🚀 Current Status **Status**: 🟡 IN PROGRESS -**Current Phase**: Phase 1 - Job Screens +**Current Phase**: Phase 2 - Profile Screens ✅ COMPLETED +**Next Phase**: Phase 3 - Portofolio & Maps Screens **Started**: 2026-04-01 -**ETA**: 2026-04-07 (Phase 1 complete) +**Last Updated**: 2026-04-04 +**Overall Progress**: 13/34+ screens completed (38%) --- ## 📞 Next Actions 1. **Immediate** (Today): - - [ ] Migrate `ScreenJobCreate.tsx` - - [ ] Migrate `ScreenJobEdit.tsx` - - [ ] Test both screens + - [ ] Migrate `app/(application)/(user)/portofolio/[id]/create.tsx` + - [ ] Migrate `app/(application)/(user)/portofolio/[id]/edit.tsx` + - [ ] Migrate `app/(application)/(user)/portofolio/[id]/edit-logo.tsx` + - [ ] Migrate `app/(application)/(user)/portofolio/[id]/edit-social-media.tsx` + - [ ] Migrate `screens/Maps/ScreenMapsCreate.tsx` + - [ ] Migrate `screens/Maps/ScreenMapsEdit.tsx` + - [ ] Migrate `app/(application)/(user)/maps/[id]/custom-pin.tsx` + - [ ] Test all Portofolio & Maps screens 2. **This Week**: - - [ ] Delete test files + - [ ] Complete Phase 3 (Portofolio & Maps screens) - [ ] Document any issues - - [ ] Prepare Phase 2 + - [ ] Prepare Phase 4 3. **Next Week**: - - [ ] Start Phase 2 (Event & Profile) - - [ ] Review Phase 1 results + - [ ] Start Phase 4 (Event screens) + - [ ] Review Phase 2-3 results - [ ] Adjust migration guide if needed --- @@ -297,8 +350,13 @@ import { View } from "react-native"; - `tasks/TASK-004-newwrapper-migration.md` (This file) **Screens to Migrate:** -- `screens/Job/ScreenJobCreate.tsx` -- `screens/Job/ScreenJobEdit.tsx` +- `app/(application)/(user)/portofolio/[id]/create.tsx` (Phase 3) +- `app/(application)/(user)/portofolio/[id]/edit.tsx` (Phase 3) +- `app/(application)/(user)/portofolio/[id]/edit-logo.tsx` (Phase 3) +- `app/(application)/(user)/portofolio/[id]/edit-social-media.tsx` (Phase 3) +- `screens/Maps/ScreenMapsCreate.tsx` (Phase 3) +- `screens/Maps/ScreenMapsEdit.tsx` (Phase 3) +- `app/(application)/(user)/maps/[id]/custom-pin.tsx` (Phase 3) - (More in subsequent phases) --- @@ -322,12 +380,23 @@ import { View } from "react-native"; ## ✅ Success Criteria -**Phase 1 Complete when:** -- [ ] Job Create migrated -- [ ] Job Edit migrated -- [ ] Both screens tested on iOS & Android +**Phase 2 Complete when:** ✅ +- [x] Profile Create migrated +- [x] Profile Edit migrated +- [x] Profile detail screens migrated +- [x] All screens tested +- [x] Commits pushed to branch + +**Phase 3 Complete when:** +- [ ] Portofolio Create migrated +- [ ] Portofolio Edit migrated +- [ ] Portofolio edit-logo migrated +- [ ] Portofolio edit-social-media migrated +- [ ] Maps Create migrated +- [ ] Maps Edit migrated +- [ ] Maps custom-pin migrated +- [ ] All Portofolio & Maps screens tested on iOS & Android - [ ] No critical bugs -- [ ] Test files deleted - [ ] Documentation updated **Overall Migration Complete when:** @@ -339,6 +408,6 @@ import { View } from "react-native"; --- -**Last Updated**: 2026-04-01 +**Last Updated**: 2026-04-04 **Created by**: AI Assistant -**Status**: 🟡 IN PROGRESS +**Status**: 🟡 IN PROGRESS - Phase 2 Complete, Ready for Phase 3 (Portofolio & Maps)