93 lines
No EOL
3 KiB
TypeScript
93 lines
No EOL
3 KiB
TypeScript
import { Modal, NativeSyntheticEvent, StyleSheet, Text, View, FlatList } from 'react-native'
|
|
import React, { useEffect, useMemo, useState } from 'react'
|
|
import { Category } from '../../../types/dbItems';
|
|
import { useTheme } from '../../../app/contexts/ThemeContext';
|
|
import CategoryListItem from '../../common/CategoryListItem';
|
|
import { SIZES } from '../../../constants/theme';
|
|
import useFetch from '../../../hooks/useFetch';
|
|
import TextInputBar from '../../common/TextInputBar';
|
|
|
|
|
|
interface CategorySelectorModalProps{
|
|
visible: boolean;
|
|
onCategoryTap?: (category : Category) => void | undefined;
|
|
selectMulitple?: boolean;
|
|
onRequestClose?: ((event: NativeSyntheticEvent<any>) => void) | undefined;
|
|
}
|
|
|
|
//TODO: select Multiple
|
|
|
|
const CategorySelectorModal: React.FC<CategorySelectorModalProps> = (props : CategorySelectorModalProps) => {
|
|
const {visible, onCategoryTap, selectMulitple} = props;
|
|
const {data, reFetch} = useFetch({sql: "SELECT * FROM category;", args:[]});
|
|
const {colors} = useTheme();
|
|
const [searchtext, setSearchtext] = useState<string>("");
|
|
|
|
const handleSearchText = (text : string) => {
|
|
setSearchtext(text);
|
|
}
|
|
|
|
const categories = useMemo<Category[]>(()=>{
|
|
return data.map((elem) => {
|
|
return {name: elem["name"], color: elem["color"], guid: elem["guid"]}
|
|
})
|
|
}, [data])
|
|
|
|
const filteredCategories = categories.filter((category) => category.name?.toLowerCase().includes(searchtext.toLowerCase()))
|
|
|
|
useEffect(()=>{
|
|
if(visible){
|
|
//reFetch(); Uncomment if newly added categories do not appear
|
|
handleSearchText("");
|
|
}
|
|
}, [visible])
|
|
|
|
return (
|
|
<Modal visible={visible} transparent={true} onRequestClose={props.onRequestClose}>
|
|
<View style={styles.main}>
|
|
<View style={[styles.modal, {backgroundColor: colors.containerColor}]}>
|
|
<View>
|
|
<Text style={[styles.heading, {color: colors.primaryText}]}>{selectMulitple ? "Categories" : "Category"}</Text>
|
|
</View>
|
|
<TextInputBar placeholder='TypeToSearch' value={searchtext} onChangeText={handleSearchText} style={{marginBottom: 10}}></TextInputBar>
|
|
<FlatList
|
|
data={filteredCategories}
|
|
keyExtractor={(item) => item.guid!}
|
|
renderItem={({item})=> <CategoryListItem category={item} onPress={onCategoryTap}/>}
|
|
ItemSeparatorComponent={() => <View style={styles.itemSeperatorStyle}/>}
|
|
ListFooterComponent={() => <View style={styles.itemSeperatorStyle}/>}
|
|
keyboardShouldPersistTaps="always"
|
|
>
|
|
</FlatList>
|
|
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
)
|
|
}
|
|
|
|
export default CategorySelectorModal
|
|
|
|
const styles = StyleSheet.create({
|
|
main: {
|
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
height: "100%",
|
|
width: "100%",
|
|
alignItems: "center",
|
|
},
|
|
modal: {
|
|
height: "70%",
|
|
width: "90%",
|
|
top: "10%",
|
|
borderRadius: 30,
|
|
paddingVertical: 20,
|
|
paddingHorizontal: 20
|
|
},
|
|
heading: {
|
|
fontSize: SIZES.xlarge,
|
|
fontWeight: "bold"
|
|
},
|
|
itemSeperatorStyle: {
|
|
paddingBottom: 10
|
|
}
|
|
}) |