// @/components/NewWrapper.tsx import { MainColor } from "@/constants/color-palet"; import { OS_HEIGHT } from "@/constants/constans-value"; import { GStyles } from "@/styles/global-styles"; import { ImageBackground, Keyboard, KeyboardAvoidingView, Platform, ScrollView, FlatList, TouchableWithoutFeedback, View, StyleProp, ViewStyle, } from "react-native"; import { NativeSafeAreaViewProps, SafeAreaView, } from "react-native-safe-area-context"; import type { ScrollViewProps, FlatListProps } from "react-native"; // --- ✅ Tambahkan refreshControl ke BaseProps --- interface BaseProps { withBackground?: boolean; headerComponent?: React.ReactNode; footerComponent?: React.ReactNode; floatingButton?: React.ReactNode; hideFooter?: boolean; edgesFooter?: NativeSafeAreaViewProps["edges"]; style?: StyleProp; refreshControl?: ScrollViewProps["refreshControl"]; // ✅ dipakai di kedua mode } interface StaticModeProps extends BaseProps { children: React.ReactNode; listData?: never; renderItem?: never; } interface ListModeProps extends BaseProps { children?: never; listData?: any[]; renderItem?: FlatListProps["renderItem"]; onEndReached?: () => void; // ✅ Gunakan tipe yang kompatibel dengan FlatList ListHeaderComponent?: React.ReactElement | null; ListFooterComponent?: React.ReactElement | null; ListEmptyComponent?: React.ReactElement | null; keyExtractor?: FlatListProps["keyExtractor"]; } type NewWrapperProps = StaticModeProps | ListModeProps; const NewWrapper = (props: NewWrapperProps) => { const { withBackground = false, headerComponent, footerComponent, floatingButton, hideFooter = false, edgesFooter = [], style, refreshControl, // ✅ sekarang ada di BaseProps } = props; const assetBackground = require("../../assets/images/main-background.png"); const renderContainer = (content: React.ReactNode) => { if (withBackground) { return ( {content} ); } return {content}; }; // 🔹 Mode Dinamis if ("listData" in props) { const listProps = props as ListModeProps; return ( {headerComponent && ( {headerComponent} )} { if (item.id == null) { console.warn("Item tanpa 'id':", item); return `fallback-${index}-${JSON.stringify(item)}`; } // Gabungkan ID dengan indeks untuk mencegah duplikasi return `${String(item.id)}-${index}`; }) } refreshControl={refreshControl} // ✅ dari BaseProps onEndReached={listProps.onEndReached} onEndReachedThreshold={0.5} ListHeaderComponent={listProps.ListHeaderComponent} ListFooterComponent={listProps.ListFooterComponent} ListEmptyComponent={listProps.ListEmptyComponent} contentContainerStyle={{ flexGrow: 1 }} keyboardShouldPersistTaps="handled" /> {footerComponent ? ( {footerComponent} ) : hideFooter ? null : ( )} {floatingButton && ( {floatingButton} )} ); } // 🔹 Mode Statis const staticProps = props as StaticModeProps; return ( {headerComponent && ( {headerComponent} )} {renderContainer(staticProps.children)} {footerComponent ? ( {footerComponent} ) : hideFooter ? null : ( )} {floatingButton && ( {floatingButton} )} ); }; export default NewWrapper;