Kliko/app/(tabs)/explore.tsx
2024-08-13 09:22:08 +02:00

231 lines
8.1 KiB
TypeScript

import {
StyleSheet,
ScrollView,
SafeAreaView,
StatusBar,
Image,
TouchableOpacity
} from 'react-native';
import React, { useState, useEffect, useRef } from 'react';
import { router } from 'expo-router';
import type { AutocompleteDropdownRef } from 'react-native-autocomplete-dropdown'
import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown';
import Modal from "react-native-modal";
import { useTranslation } from 'react-i18next';
import { ThemedText } from '@/src/components/themed/ThemedText';
import { ThemedView } from '@/src/components/themed/ThemedView';
import { Colors } from '@/src/constants/Colors';
import { useColorScheme } from '@/src/hooks/useColorScheme';
import { Request } from '@/src/services/request';
import List from '@/src/components/List';
import { store } from '@/src/store/store';
import { setViewCategory } from '@/src/store/dataStore';
export default function ExploreScreen() {
const colorScheme = useColorScheme() ?? 'light';
const { t } = useTranslation();
const [ categories, setCategories ] = useState( [] );
const [ types, setTypes ] = useState( [] );
const [ activeCategory, setActiveCategory ] = useState<any | null>( null );
const searchRef = useRef( null );
const dropdownController = useRef<AutocompleteDropdownRef | null>( null )
useEffect( () => {
// Load categories
Request.get( 'categories' ).then( (response) => {
const list: any = [];
response.forEach( (category: any, index: any) => {
list.push( {
id: index,
title: category.name,
category: category,
} )
} );
setCategories( list );
} )
// Load waste types
Request.get( 'waste-types' ).then( (response) => {
setTypes( response );
} );
}, [] );
// View selected item in modal
const selectItem = (item: any | null) => {
if (item == null) {
return;
}
// Clear select
dropdownController.current?.clear()
const { category } = item;
setActiveCategory( category );
}
// View item in sub screen
const viewItem = async (item: any) => {
store.dispatch( setViewCategory( item ) );
router.push( '/(explore)/category' );
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background }}>
<ThemedView>
<ScrollView style={styles.container}>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">{t( "what-where" )}</ThemedText>
</ThemedView>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title" style={{ color: Colors[ colorScheme ].tint }}>{t( "what-why" )}</ThemedText>
</ThemedView>
<ThemedView style={styles.searchContainer}>
<ThemedText type="defaultSemiBold">{t( "what-separate" )}</ThemedText>
<AutocompleteDropdown
ref={searchRef}
controller={controller => {
dropdownController.current = controller
}}
textInputProps={{
placeholder: t( "what-separate" ),
autoCorrect: false,
autoCapitalize: 'none',
}}
clearOnFocus={false}
closeOnBlur={false}
closeOnSubmit={false}
emptyResultText={t( "nothing-found" )}
onSelectItem={selectItem}
dataSet={categories}
showClear={false}
/>
</ThemedView>
<ThemedView style={styles.categoriesContainer}>
<ThemedText type="defaultSemiBold">{t( "choose-category" )}:</ThemedText>
</ThemedView>
<ThemedView style={styles.listContainer}>
<List
data={types}
renderItem={(item: any, index: any) => (
<TouchableOpacity style={styles.listItem} key={index} onPress={() => viewItem( item )}>
{item.image != null ?
(
<Image source={{ uri: item.image }} style={styles.listImage}/>
) :
(
<ThemedView style={styles.listImage}/>
)
}
<ThemedText type="defaultSemiBold">{item.name}</ThemedText>
</TouchableOpacity>
)}
/>
</ThemedView>
</ScrollView>
</ThemedView>
<Modal isVisible={activeCategory !== null} useNativeDriverForBackdrop={true}>
<ThemedView style={{ ...styles.modalView, backgroundColor: Colors[ colorScheme ].background }}>
<ThemedText type="subtitle" style={{ marginBottom: 30, textAlign: 'center' }}>{activeCategory?.name}</ThemedText>
{activeCategory?.type &&
<ThemedView style={styles.modalType}>
{activeCategory?.type?.image &&
<Image source={{ uri: activeCategory?.type?.image }} style={styles.modalTypeImage}/>
}
<ThemedText type="defaultSemiBold">{activeCategory?.type?.name}</ThemedText>
</ThemedView>
}
<ThemedView style={{ alignItems: 'center' }}>
<ThemedText type="defaultSemiBold">{t( "description" )}:</ThemedText>
<ThemedText>{activeCategory?.description}</ThemedText>
</ThemedView>
<TouchableOpacity
onPress={() => setActiveCategory( null )}
style={{ ...styles.modalClose, backgroundColor: Colors[ colorScheme ].tint }}>
<ThemedText style={{ color: '#fff' }}>{t( "close" )}</ThemedText>
</TouchableOpacity>
</ThemedView>
</Modal>
</SafeAreaView>
);
}
const styles = StyleSheet.create( {
container: {
marginTop: StatusBar.currentHeight,
padding: 25,
},
titleContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
paddingBottom: 8,
},
searchContainer: {
marginTop: 10,
},
categoriesContainer: {
marginTop: 25,
},
listContainer: {
marginTop: 20,
paddingBottom: 50
},
listItem: {
flex: 1,
display: 'flex',
gap: 8,
flexDirection: 'row',
alignItems: 'center',
paddingBottom: 20,
marginBottom: 20,
borderBottomWidth: 1,
borderBottomColor: '#f2f2f2',
},
listImage: {
width: 30,
height: 30,
borderRadius: 5,
marginRight: 8,
},
modalView: {
margin: 20,
borderRadius: 5,
padding: 35,
alignItems: 'center',
textAlign: 'center',
},
modalType: {
gap: 8,
flexDirection: 'row',
alignItems: 'center',
paddingBottom: 10,
marginBottom: 15,
},
modalTypeImage: {
width: 40,
height: 40,
borderRadius: 5,
marginRight: 8,
},
modalClose: {
borderRadius: 5,
paddingTop: 10,
paddingBottom: 10,
paddingLeft: 40,
paddingRight: 40,
marginTop: 30,
},
} );