Untitled
unknown
plain_text
a year ago
7.1 kB
14
Indexable
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;
Editor is loading...
Leave a Comment