Files
hipmi-mobile/screens/Invesment/ScreenPortofolio.tsx
bagasbanuna eb64c30d49 feat: Complete User Phase 9 Investment screens migration + note known upload issue
- Migrate 24 investment screens to OS_Wrapper (tabs, list, detail, forms, transaction flow)
- Add contentPadding={PADDING_INLINE} to 9 list/tabs screens for consistent spacing
- Add enableKeyboardHandling to 6 form screens
- Fix investment tabs layout height to use OS_IOS_HEIGHT/OS_ANDROID_HEIGHT constants
- Update TASK-005 with known issue: upload image returns 500 error in dev env
- Note: Investment feature not fully complete - upload issue needs investigation tomorrow

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-13 17:56:49 +08:00

104 lines
3.1 KiB
TypeScript

/* eslint-disable react-hooks/exhaustive-deps */
import { OS_Wrapper, ScrollableCustom, TextCustom } from "@/components";
import { PADDING_INLINE } from "@/constants/constans-value";
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
import { createPaginationComponents } from "@/helpers/paginationHelpers";
import { useAuth } from "@/hooks/use-auth";
import { usePagination } from "@/hooks/use-pagination";
import { dummyMasterStatus } from "@/lib/dummy-data/_master/status";
import Investment_StatusBox from "@/screens/Invesment/StatusBox";
import { apiInvestmentGetByStatus } from "@/service/api-client/api-investment";
import { useFocusEffect, useLocalSearchParams } from "expo-router";
import { useCallback, useState } from "react";
import { RefreshControl } from "react-native";
export default function Investment_ScreenPortofolio() {
const { user } = useAuth();
const { status } = useLocalSearchParams<{ status?: string }>();
const [activeCategory, setActiveCategory] = useState<string | null>(
status || "publish",
);
// Setup pagination
const pagination = usePagination({
fetchFunction: async (page) => {
if (!user?.id) return { data: [] };
return await apiInvestmentGetByStatus({
authorId: user.id,
status: activeCategory!,
page: String(page),
});
},
pageSize: PAGINATION_DEFAULT_TAKE,
dependencies: [user?.id, activeCategory],
onError: (error) =>
console.error("[ERROR] Fetch investment by status:", error),
});
// Generate komponen
const { ListEmptyComponent, ListFooterComponent } =
createPaginationComponents({
loading: pagination.loading,
refreshing: pagination.refreshing,
listData: pagination.listData,
emptyMessage: `Tidak ada data ${activeCategory}`,
skeletonCount: PAGINATION_DEFAULT_TAKE,
skeletonHeight: 150,
});
// Render item investment
const renderInvestmentItem = ({ item }: { item: any }) => (
<Investment_StatusBox
key={item.id}
data={item}
status={activeCategory as string}
href={`/investment/${item.id}/${activeCategory}/detail`}
/>
);
const handlePress = (item: any) => {
setActiveCategory(item.value);
// Reset pagination saat kategori berubah
pagination.reset();
};
useFocusEffect(
useCallback(() => {
pagination.onRefresh();
}, [activeCategory]),
);
const tabsComponent = (
<ScrollableCustom
data={dummyMasterStatus.map((e, i) => ({
id: i,
label: e.label,
value: e.value,
}))}
onButtonPress={handlePress}
activeId={activeCategory as any}
/>
);
return (
<OS_Wrapper
contentPadding={PADDING_INLINE}
hideFooter
headerComponent={tabsComponent}
listData={pagination.listData}
renderItem={renderInvestmentItem}
refreshControl={
<RefreshControl
refreshing={pagination.refreshing}
onRefresh={pagination.onRefresh}
/>
}
onEndReached={pagination.loadMore}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
/>
);
}