Untitled
import {CommonText} from 'components/commons/CommonText'; import {mainRoutes} from 'navigation/mainRoutes'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View, FlatList} from 'react-native'; import {navigate} from 'utils/navigation'; import CardItem from './components/CardItem'; import {t} from 'languages/translation'; import HeaderHome from './components/HeaderHome'; import {useListCredentialOfferQuery} from 'app/services/credentialService'; import SortModal from './components/SortModal'; import {Modalize} from 'react-native-modalize'; import useTheme from 'themes/useTheme'; import {ColorProps} from 'themes/ThemeProvider'; import {CredentialData} from 'app/models/credential.model'; import {ScaledSheet} from 'react-native-size-matters'; import ModalController from 'components/modals/ModalController'; import {EdgeInsets, useSafeAreaInsets} from 'react-native-safe-area-context'; import {useGetInfoCurrentUserQuery} from 'app/services/authService'; import {useAppDispatch, useAppSelector} from 'app/hooks'; import {setCurrentUser} from 'futures/auth/authSlice'; function HomeScreen() { const modalizeRef = useRef<Modalize>(null); const [selectedSort, setSelectedSort] = useState<string>('DESC'); const [pageNumber, setPageNumber] = useState<number>(1); const [listCredential, setListCredential] = useState<CredentialData[]>([]); const [itemDetail, setItemDetail] = useState<CredentialData>(); const [indexDetail, setIndexDetail] = useState<number>(0); const dispatch = useAppDispatch(); const currentUser = useAppSelector(state => state.auth.currentUser); const [showSearch, setShowSearch] = useState(false); const [keySearch, setKeySearch] = useState(''); const {data: currentUserData} = useGetInfoCurrentUserQuery(undefined, { skip: currentUser !== null, }); useEffect(() => { if (currentUserData) { dispatch(setCurrentUser(currentUserData.data)); } }, [currentUserData, dispatch]); let limit = 10; const options = [ {label: '発行順(新)', value: 'DESC'}, {label: '発行順(旧)', value: 'ASC'}, ]; const {data, isSuccess, isFetching} = useListCredentialOfferQuery({ page: pageNumber, limit: limit, sortBy: 'createdAt', sortDirection: selectedSort, keyword: keySearch, }); const theme = useTheme(); const inserts = useSafeAreaInsets(); const styles = createStyles(inserts, theme.colors); useEffect(() => { if (data?.data && isSuccess) { const newListCredential = pageNumber !== 1 ? [...listCredential, ...data.data] : data.data; setListCredential(newListCredential); } else { setListCredential([]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [data, isSuccess]); const clearModalData = () => { setItemDetail(undefined); setIndexDetail(0); ModalController.hideCustomModal(); }; useEffect(() => { if (itemDetail) { const isBackground = { hideModal: true, isCallback: () => { setItemDetail(undefined); setIndexDetail(0); }, }; ModalController.showCustomModal( <View style={styles.modalCredential}> <CardItem data={itemDetail} index={indexDetail} showModal={true} handlePressCard={() => { navigate(mainRoutes.CredentialDetailScreen, { itemDetail: itemDetail, }); clearModalData(); }} clearModalData={clearModalData} /> </View>, isBackground, ); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [itemDetail, indexDetail]); const handlePressCard = useCallback((index: number, item: CredentialData) => { setItemDetail(item); setIndexDetail(index); }, []); const renderItem = useCallback( ({item, index}: {item: CredentialData; index: number}) => { return ( <CardItem key={index} data={item} index={index} handlePressCard={() => handlePressCard(index, item)} /> ); }, // eslint-disable-next-line react-hooks/exhaustive-deps [], ); const onEndReached = () => { if (isFetching && listCredential.length === limit * pageNumber) { setPageNumber(preState => preState + 1); } }; const headerList = useMemo(() => { return ( <View> <HeaderHome showSearch={showSearch} setShowSearch={setShowSearch} handleOpenSort={() => modalizeRef.current?.open()} setKeySearch={setKeySearch} /> <CommonText variant="typography16" style={styles.titleList}> {t('HomeScreen.TitleListCard')} </CommonText> </View> ); }, [showSearch, styles.titleList]); const footerList = () => { return ( <View style={styles.bottomList}> {isFetching ? ( <CommonText variant={'typography12'}>Loading...</CommonText> ) : null} </View> ); }; const keyExtractor = useCallback( (_: any, index: {toString: () => any}) => index.toString(), [], ); return ( <View style={styles.container}> <View style={styles.root}> <FlatList nestedScrollEnabled data={listCredential} style={styles.listCredential} renderItem={renderItem} onEndReachedThreshold={0.4} onEndReached={onEndReached} ListHeaderComponent={headerList} ListFooterComponent={footerList} keyExtractor={keyExtractor} initialNumToRender={10} maxToRenderPerBatch={5} windowSize={5} initialScrollIndex={0} removeClippedSubviews={false} /> </View> <SortModal modalizeRef={modalizeRef} onClose={() => modalizeRef?.current?.close()} selectedOption={selectedSort} setSelectedOption={setSelectedSort} options={options} /> </View> ); } const createStyles = (insets: EdgeInsets, colors: ColorProps) => ScaledSheet.create({ container: { flex: 1, }, root: { flex: 1, backgroundColor: colors.background, marginTop: -insets.top, }, titleList: { marginTop: '12@vs', marginBottom: '21@vs', }, itemDetail: { marginBottom: '20@vs', }, listCredential: { paddingHorizontal: '40@ms', flexGrow: 1, }, bottomList: { height: '40@ms', }, modalCredential: { paddingHorizontal: '40@ms', }, itemContainer: { backgroundColor: colors.background, borderRadius: '20@ms', paddingHorizontal: '14@ms', gap: '14@ms', borderColor: colors.input.borderColor, borderWidth: '1@ms', }, }); export default HomeScreen;
Leave a Comment