230 lines
8 KiB
TypeScript
230 lines
8 KiB
TypeScript
import {
|
|
StyleSheet,
|
|
ScrollView,
|
|
SafeAreaView,
|
|
StatusBar,
|
|
Image,
|
|
TouchableOpacity,
|
|
View,
|
|
} 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 { ThemedText } from '@/lib/components/ThemedText';
|
|
import { ThemedView } from '@/lib/components/ThemedView';
|
|
import { Colors } from '@/lib/constants/Colors';
|
|
import { useColorScheme } from '@/lib/hooks/useColorScheme';
|
|
import { Request } from '@/lib/services/request';
|
|
import List from '@/lib/components/List';
|
|
import { store } from '@/lib/store/store';
|
|
import { setViewCategory } from '@/lib/store/dataStore';
|
|
|
|
export default function ExploreScreen() {
|
|
const colorScheme = useColorScheme() ?? 'light';
|
|
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">Wat moet waar?</ThemedText>
|
|
</ThemedView>
|
|
|
|
<ThemedView style={styles.titleContainer}>
|
|
<ThemedText type="title" style={{ color: Colors[ colorScheme ].tint }}>en waarom?</ThemedText>
|
|
</ThemedView>
|
|
|
|
<ThemedView style={styles.searchContainer}>
|
|
<ThemedText type="defaultSemiBold">Wat wilt u scheiden?</ThemedText>
|
|
<AutocompleteDropdown
|
|
ref={searchRef}
|
|
controller={controller => {
|
|
dropdownController.current = controller
|
|
}}
|
|
textInputProps={{
|
|
placeholder: 'Wat wilt u scheiden?',
|
|
autoCorrect: false,
|
|
autoCapitalize: 'none',
|
|
}}
|
|
clearOnFocus={false}
|
|
closeOnBlur={false}
|
|
closeOnSubmit={false}
|
|
emptyResultText={'Niks gevonden'}
|
|
onSelectItem={selectItem}
|
|
dataSet={categories}
|
|
showClear={false}
|
|
/>
|
|
</ThemedView>
|
|
|
|
<ThemedView style={styles.categoriesContainer}>
|
|
<ThemedText type="defaultSemiBold">Of kies een categorie:</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">Beschrijving:</ThemedText>
|
|
<ThemedText>{activeCategory?.description}</ThemedText>
|
|
</ThemedView>
|
|
|
|
<TouchableOpacity
|
|
onPress={() => setActiveCategory( null )}
|
|
style={{ ...styles.modalClose, backgroundColor: Colors[ colorScheme ].tint }}>
|
|
<ThemedText style={{ color: '#fff' }}>Sluiten</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,
|
|
},
|
|
} );
|