CS
This commit is contained in:
parent
fe82b69997
commit
3287b9a3b7
10 changed files with 813 additions and 813 deletions
|
@ -1,65 +1,65 @@
|
||||||
import {
|
import {
|
||||||
SafeAreaView,
|
SafeAreaView,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Dimensions
|
Dimensions
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import {useEffect, useState} from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import RenderHtml from 'react-native-render-html';
|
import RenderHtml from 'react-native-render-html';
|
||||||
import {useNavigation} from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
|
||||||
import {Colors} from '@/constants/Colors';
|
import { Colors } from '@/constants/Colors';
|
||||||
import {useColorScheme} from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
import {ThemedView} from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
|
|
||||||
export default function CategoryScreen() {
|
export default function CategoryScreen() {
|
||||||
const colorScheme = useColorScheme() ?? 'light';
|
const colorScheme = useColorScheme() ?? 'light';
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const [description, setDescription] = useState('');
|
const [ description, setDescription ] = useState( '' );
|
||||||
|
|
||||||
// Load item from storage
|
// Load item from storage
|
||||||
useEffect(() => {
|
useEffect( () => {
|
||||||
AsyncStorage.getItem('activeCategory').then((data) => {
|
AsyncStorage.getItem( 'activeCategory' ).then( (data) => {
|
||||||
const itemData: any = JSON.parse(data ?? '{}');
|
const itemData: any = JSON.parse( data ?? '{}' );
|
||||||
|
|
||||||
if (itemData != null) {
|
if (itemData != null) {
|
||||||
const {name, description} = itemData;
|
const { name, description } = itemData;
|
||||||
|
|
||||||
// Set description
|
// Set description
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
setDescription(description);
|
setDescription( description );
|
||||||
|
|
||||||
// Set page title
|
// Set page title
|
||||||
navigation.setOptions({title: name});
|
navigation.setOptions( { title: name } );
|
||||||
}
|
}
|
||||||
});
|
} );
|
||||||
}, []);
|
}, [] );
|
||||||
|
|
||||||
// HTML render props
|
// HTML render props
|
||||||
const source = {html: description};
|
const source = { html: description };
|
||||||
const width = Dimensions.get('window').width;
|
const width = Dimensions.get( 'window' ).width;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{flex: 1, backgroundColor: Colors[colorScheme].background,}}>
|
<SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background, }}>
|
||||||
<ScrollView style={styles.container}>
|
<ScrollView style={styles.container}>
|
||||||
<ThemedView style={styles.htmlContainer}>
|
<ThemedView style={styles.htmlContainer}>
|
||||||
<RenderHtml
|
<RenderHtml
|
||||||
contentWidth={width}
|
contentWidth={width}
|
||||||
source={source}
|
source={source}
|
||||||
/>
|
/>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create( {
|
||||||
container: {
|
container: {
|
||||||
padding: 25,
|
padding: 25,
|
||||||
},
|
},
|
||||||
htmlContainer: {
|
htmlContainer: {
|
||||||
paddingBottom: 50,
|
paddingBottom: 50,
|
||||||
},
|
},
|
||||||
})
|
} )
|
|
@ -1,128 +1,128 @@
|
||||||
import {Stack} from 'expo-router';
|
import { Stack } from 'expo-router';
|
||||||
import {StyleSheet, TextInput, TouchableOpacity} from 'react-native';
|
import { StyleSheet, TextInput, TouchableOpacity } from 'react-native';
|
||||||
|
|
||||||
import {ThemedText} from '@/components/ThemedText';
|
import { ThemedText } from '@/components/ThemedText';
|
||||||
import {ThemedView} from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
import {useToken} from '@/context/AppProvider';
|
import { useToken } from '@/context/AppProvider';
|
||||||
import {Colors} from '@/constants/Colors';
|
import { Colors } from '@/constants/Colors';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {useColorScheme} from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
import {Message} from '@/services/message';
|
import { Message } from '@/services/message';
|
||||||
import {Request} from '@/services/request';
|
import { Request } from '@/services/request';
|
||||||
import { router } from 'expo-router';
|
import { router } from 'expo-router';
|
||||||
|
|
||||||
export default function OnboardStartScreen() {
|
export default function OnboardStartScreen() {
|
||||||
const colorScheme = useColorScheme() ?? 'light';
|
const colorScheme = useColorScheme() ?? 'light';
|
||||||
const {setToken} = useToken();
|
const { setToken } = useToken();
|
||||||
const [name, setName] = React.useState('Maarten');
|
const [ name, setName ] = React.useState( 'Maarten' );
|
||||||
const [zipcode, setZipcode] = React.useState('6715GA');
|
const [ zipcode, setZipcode ] = React.useState( '6715GA' );
|
||||||
const [houseNumber, setHouseNumber] = React.useState('3');
|
const [ houseNumber, setHouseNumber ] = React.useState( '3' );
|
||||||
|
|
||||||
const start = () => {
|
const start = () => {
|
||||||
if (name === '' || zipcode === '' || houseNumber === '') {
|
if (name === '' || zipcode === '' || houseNumber === '') {
|
||||||
Message.error('Niet alle gegevens zijn ingevuld!');
|
Message.error( 'Niet alle gegevens zijn ingevuld!' );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Get device name
|
||||||
|
const deviceName = 'Test';
|
||||||
|
|
||||||
|
Request
|
||||||
|
.post( 'sessions/create', {
|
||||||
|
name: name,
|
||||||
|
zipcode: zipcode,
|
||||||
|
houseNumber: houseNumber,
|
||||||
|
device: deviceName,
|
||||||
|
} )
|
||||||
|
.then( (response) => {
|
||||||
|
if (!response.success) {
|
||||||
|
Message.error( response.message );
|
||||||
|
} else {
|
||||||
|
const token = response.token;
|
||||||
|
|
||||||
|
setToken( token );
|
||||||
|
router.replace( "/(tabs)" );
|
||||||
|
|
||||||
|
Message.success( response.message );
|
||||||
|
}
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get device name
|
return (
|
||||||
const deviceName = 'Test';
|
<>
|
||||||
|
<Stack.Screen options={{ title: 'Welkom' }}/>
|
||||||
|
<ThemedView style={styles.container}>
|
||||||
|
<ThemedView style={styles.heading}>
|
||||||
|
<ThemedText type="title">Welkom bij </ThemedText>
|
||||||
|
<ThemedText type="title" style={{ color: Colors[ colorScheme ].tint }}>Kliko</ThemedText>
|
||||||
|
</ThemedView>
|
||||||
|
|
||||||
Request
|
<ThemedView style={styles.inputContainer}>
|
||||||
.post('sessions/create', {
|
<ThemedText>Wat is je naam?</ThemedText>
|
||||||
name: name,
|
<TextInput
|
||||||
zipcode: zipcode,
|
style={styles.input}
|
||||||
houseNumber: houseNumber,
|
onChangeText={setName}
|
||||||
device: deviceName,
|
placeholder={'Je naam'}
|
||||||
})
|
value={name}
|
||||||
.then((response) => {
|
/>
|
||||||
if (!response.success) {
|
</ThemedView>
|
||||||
Message.error(response.message);
|
|
||||||
} else {
|
|
||||||
const token = response.token;
|
|
||||||
|
|
||||||
setToken(token);
|
<ThemedView style={styles.inputContainer}>
|
||||||
router.replace("/(tabs)");
|
<ThemedText>Wat is je postcode en huisnummer?</ThemedText>
|
||||||
|
<TextInput
|
||||||
Message.success(response.message);
|
style={styles.input}
|
||||||
}
|
onChangeText={setZipcode}
|
||||||
});
|
placeholder={'Postcode'}
|
||||||
}
|
value={zipcode}
|
||||||
|
/>
|
||||||
return (
|
<TextInput
|
||||||
<>
|
style={styles.input}
|
||||||
<Stack.Screen options={{title: 'Welkom'}}/>
|
onChangeText={setHouseNumber}
|
||||||
<ThemedView style={styles.container}>
|
placeholder={'Huisnummer'}
|
||||||
<ThemedView style={styles.heading}>
|
value={houseNumber}
|
||||||
<ThemedText type="title">Welkom bij </ThemedText>
|
keyboardType="numeric"
|
||||||
<ThemedText type="title" style={{color: Colors[colorScheme].tint}}>Kliko</ThemedText>
|
/>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
|
|
||||||
<ThemedView style={styles.inputContainer}>
|
|
||||||
<ThemedText>Wat is je naam?</ThemedText>
|
|
||||||
<TextInput
|
|
||||||
style={styles.input}
|
|
||||||
onChangeText={setName}
|
|
||||||
placeholder={'Je naam'}
|
|
||||||
value={name}
|
|
||||||
/>
|
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
<ThemedView style={styles.inputContainer}>
|
|
||||||
<ThemedText>Wat is je postcode en huisnummer?</ThemedText>
|
|
||||||
<TextInput
|
|
||||||
style={styles.input}
|
|
||||||
onChangeText={setZipcode}
|
|
||||||
placeholder={'Postcode'}
|
|
||||||
value={zipcode}
|
|
||||||
/>
|
|
||||||
<TextInput
|
|
||||||
style={styles.input}
|
|
||||||
onChangeText={setHouseNumber}
|
|
||||||
placeholder={'Huisnummer'}
|
|
||||||
value={houseNumber}
|
|
||||||
keyboardType="numeric"
|
|
||||||
/>
|
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
|
|
||||||
<TouchableOpacity style={{...styles.button, backgroundColor: Colors[colorScheme].tint}} onPress={start}>
|
<TouchableOpacity style={{ ...styles.button, backgroundColor: Colors[ colorScheme ].tint }} onPress={start}>
|
||||||
<ThemedText style={{color: '#fff'}}>Start</ThemedText>
|
<ThemedText style={{ color: '#fff' }}>Start</ThemedText>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create( {
|
||||||
container: {
|
container: {
|
||||||
padding: 20,
|
padding: 20,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
heading: {
|
heading: {
|
||||||
marginBottom: 30,
|
marginBottom: 30,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
inputContainer: {
|
inputContainer: {
|
||||||
paddingTop: 20,
|
paddingTop: 20,
|
||||||
},
|
},
|
||||||
input: {
|
input: {
|
||||||
width: 250,
|
width: 250,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
padding: 10,
|
padding: 10,
|
||||||
paddingLeft: 20,
|
paddingLeft: 20,
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
paddingTop: 10,
|
paddingTop: 10,
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
paddingLeft: 40,
|
paddingLeft: 40,
|
||||||
paddingRight: 40,
|
paddingRight: 40,
|
||||||
marginTop: 30,
|
marginTop: 30,
|
||||||
},
|
},
|
||||||
});
|
} );
|
||||||
|
|
|
@ -6,55 +6,55 @@ import { Colors } from '@/constants/Colors';
|
||||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
|
|
||||||
export default function TabLayout() {
|
export default function TabLayout() {
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
tabBarActiveTintColor: Colors[ colorScheme ?? 'light' ].tint,
|
||||||
tabBarShowLabel: false,
|
tabBarShowLabel: false,
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
tabBarStyle: {
|
tabBarStyle: {
|
||||||
height: 70,
|
height: 70,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="index"
|
name="index"
|
||||||
options={{
|
options={{
|
||||||
title: 'Home',
|
title: 'Home',
|
||||||
tabBarIcon: ({ color, focused }) => (
|
tabBarIcon: ({ color, focused }) => (
|
||||||
<TabBarIcon name={focused ? 'calendar' : 'calendar-outline'} color={color} />
|
<TabBarIcon name={focused ? 'calendar' : 'calendar-outline'} color={color}/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="map"
|
name="map"
|
||||||
options={{
|
options={{
|
||||||
title: 'Map',
|
title: 'Map',
|
||||||
tabBarIcon: ({ color, focused }) => (
|
tabBarIcon: ({ color, focused }) => (
|
||||||
<TabBarIcon name={focused ? 'map' : 'map-outline'} color={color} />
|
<TabBarIcon name={focused ? 'map' : 'map-outline'} color={color}/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="explore"
|
name="explore"
|
||||||
options={{
|
options={{
|
||||||
title: 'Explore',
|
title: 'Explore',
|
||||||
tabBarIcon: ({ color, focused }) => (
|
tabBarIcon: ({ color, focused }) => (
|
||||||
<TabBarIcon name={focused ? 'trash' : 'trash-outline'} color={color} />
|
<TabBarIcon name={focused ? 'trash' : 'trash-outline'} color={color}/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="settings"
|
name="settings"
|
||||||
options={{
|
options={{
|
||||||
title: 'Settings',
|
title: 'Settings',
|
||||||
tabBarIcon: ({ color, focused }) => (
|
tabBarIcon: ({ color, focused }) => (
|
||||||
<TabBarIcon name={focused ? 'settings' : 'settings-outline'} color={color} />
|
<TabBarIcon name={focused ? 'settings' : 'settings-outline'} color={color}/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,220 +1,220 @@
|
||||||
import {
|
import {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
SafeAreaView,
|
SafeAreaView,
|
||||||
StatusBar,
|
StatusBar,
|
||||||
Image,
|
Image,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import React, {useState, useEffect, useRef} from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import {router} from 'expo-router';
|
import { router } from 'expo-router';
|
||||||
import type {AutocompleteDropdownRef} from 'react-native-autocomplete-dropdown'
|
import type { AutocompleteDropdownRef } from 'react-native-autocomplete-dropdown'
|
||||||
import {AutocompleteDropdown} from 'react-native-autocomplete-dropdown';
|
import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown';
|
||||||
import Modal from "react-native-modal";
|
import Modal from "react-native-modal";
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
|
||||||
import {ThemedText} from '@/components/ThemedText';
|
import { ThemedText } from '@/components/ThemedText';
|
||||||
import {ThemedView} from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
import {Colors} from '@/constants/Colors';
|
import { Colors } from '@/constants/Colors';
|
||||||
import {useColorScheme} from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
import {Request} from '@/services/request';
|
import { Request } from '@/services/request';
|
||||||
import List from '@/components/List';
|
import List from '@/components/List';
|
||||||
|
|
||||||
export default function ExploreScreen() {
|
export default function ExploreScreen() {
|
||||||
const colorScheme = useColorScheme() ?? 'light';
|
const colorScheme = useColorScheme() ?? 'light';
|
||||||
const [categories, setCategories] = useState([]);
|
const [ categories, setCategories ] = useState( [] );
|
||||||
const [types, setTypes] = useState([]);
|
const [ types, setTypes ] = useState( [] );
|
||||||
const [activeCategory, setActiveCategory] = useState<any | null>(null);
|
const [ activeCategory, setActiveCategory ] = useState<any | null>( null );
|
||||||
const searchRef = useRef(null);
|
const searchRef = useRef( null );
|
||||||
const dropdownController = useRef<AutocompleteDropdownRef | null>(null)
|
const dropdownController = useRef<AutocompleteDropdownRef | null>( null )
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect( () => {
|
||||||
// Load categories
|
// Load categories
|
||||||
Request.get('categories').then((response) => {
|
Request.get( 'categories' ).then( (response) => {
|
||||||
const list: any = [];
|
const list: any = [];
|
||||||
|
|
||||||
response.forEach((category: any, index: any) => {
|
response.forEach( (category: any, index: any) => {
|
||||||
list.push({
|
list.push( {
|
||||||
id: index,
|
id: index,
|
||||||
title: category.name,
|
title: category.name,
|
||||||
category: category,
|
category: category,
|
||||||
})
|
} )
|
||||||
});
|
} );
|
||||||
|
|
||||||
setCategories(list);
|
setCategories( list );
|
||||||
})
|
} )
|
||||||
|
|
||||||
// Load waste types
|
// Load waste types
|
||||||
Request.get('waste-types').then((response) => {
|
Request.get( 'waste-types' ).then( (response) => {
|
||||||
setTypes(response);
|
setTypes( response );
|
||||||
});
|
} );
|
||||||
}, []);
|
}, [] );
|
||||||
|
|
||||||
// View selected item in modal
|
// View selected item in modal
|
||||||
const selectItem = (item: any | null) => {
|
const selectItem = (item: any | null) => {
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear select
|
||||||
|
dropdownController.current?.clear()
|
||||||
|
|
||||||
|
const { category } = item;
|
||||||
|
setActiveCategory( category );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear select
|
// View item in sub screen
|
||||||
dropdownController.current?.clear()
|
const viewItem = async (item: any) => {
|
||||||
|
await AsyncStorage.setItem( 'activeCategory', JSON.stringify( item ) );
|
||||||
|
|
||||||
const {category} = item;
|
router.push( '/(explore)/category' );
|
||||||
setActiveCategory(category);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// View item in sub screen
|
return (
|
||||||
const viewItem = async (item: any) => {
|
<SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background }}>
|
||||||
await AsyncStorage.setItem('activeCategory', JSON.stringify(item));
|
<ThemedView>
|
||||||
|
<ScrollView style={styles.container}>
|
||||||
|
<ThemedView style={styles.titleContainer}>
|
||||||
|
<ThemedText type="title">Wat moet waar?</ThemedText>
|
||||||
|
</ThemedView>
|
||||||
|
|
||||||
router.push('/(explore)/category');
|
<ThemedView style={styles.titleContainer}>
|
||||||
};
|
<ThemedText type="title" style={{ color: Colors[ colorScheme ].tint }}>en waarom?</ThemedText>
|
||||||
|
</ThemedView>
|
||||||
|
|
||||||
return (
|
<ThemedView style={styles.searchContainer}>
|
||||||
<SafeAreaView style={{flex: 1, backgroundColor: Colors[colorScheme].background}}>
|
<ThemedText type="defaultSemiBold">Wat wilt u scheiden?</ThemedText>
|
||||||
<ThemedView>
|
<AutocompleteDropdown
|
||||||
<ScrollView style={styles.container}>
|
ref={searchRef}
|
||||||
<ThemedView style={styles.titleContainer}>
|
controller={controller => {
|
||||||
<ThemedText type="title">Wat moet waar?</ThemedText>
|
dropdownController.current = controller
|
||||||
</ThemedView>
|
}}
|
||||||
|
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.titleContainer}>
|
<ThemedView style={styles.categoriesContainer}>
|
||||||
<ThemedText type="title" style={{color: Colors[colorScheme].tint}}>en waarom?</ThemedText>
|
<ThemedText type="defaultSemiBold">Of kies een categorie:</ThemedText>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
|
|
||||||
<ThemedView style={styles.searchContainer}>
|
<ThemedView style={styles.listContainer}>
|
||||||
<ThemedText type="defaultSemiBold">Wat wilt u scheiden?</ThemedText>
|
<List
|
||||||
<AutocompleteDropdown
|
data={types}
|
||||||
ref={searchRef}
|
renderItem={(item: any, index: any) => (
|
||||||
controller={controller => {
|
<TouchableOpacity style={styles.listItem} key={index} onPress={() => viewItem( item )}>
|
||||||
dropdownController.current = controller
|
<Image source={{ uri: item.image }} style={styles.listImage}/>
|
||||||
}}
|
<ThemedText type="default">{item.name}</ThemedText>
|
||||||
textInputProps={{
|
</TouchableOpacity>
|
||||||
placeholder: 'Wat wilt u scheiden?',
|
)}
|
||||||
autoCorrect: false,
|
/>
|
||||||
autoCapitalize: 'none',
|
</ThemedView>
|
||||||
}}
|
</ScrollView>
|
||||||
clearOnFocus={false}
|
</ThemedView>
|
||||||
closeOnBlur={false}
|
|
||||||
closeOnSubmit={false}
|
|
||||||
emptyResultText={'Niks gevonden'}
|
|
||||||
onSelectItem={selectItem}
|
|
||||||
dataSet={categories}
|
|
||||||
showClear={false}
|
|
||||||
/>
|
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
<ThemedView style={styles.categoriesContainer}>
|
<Modal isVisible={activeCategory !== null}>
|
||||||
<ThemedText type="defaultSemiBold">Of kies een categorie:</ThemedText>
|
<ThemedView style={{ ...styles.modalView, backgroundColor: Colors[ colorScheme ].background }}>
|
||||||
</ThemedView>
|
<ThemedText type="subtitle" style={{ marginBottom: 30, textAlign: 'center' }}>{activeCategory?.name}</ThemedText>
|
||||||
|
|
||||||
<ThemedView style={styles.listContainer}>
|
<View style={styles.modalType}>
|
||||||
<List
|
<Image source={{ uri: activeCategory?.type.image }} style={styles.modalTypeImage}/>
|
||||||
data={types}
|
<ThemedText>{activeCategory?.type?.name}</ThemedText>
|
||||||
renderItem={(item: any, index: any) => (
|
</View>
|
||||||
<TouchableOpacity style={styles.listItem} key={index} onPress={() => viewItem(item)}>
|
|
||||||
<Image source={{uri: item.image}} style={styles.listImage}/>
|
|
||||||
<ThemedText type="default">{item.name}</ThemedText>
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</ThemedView>
|
|
||||||
</ScrollView>
|
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
<Modal isVisible={activeCategory !== null}>
|
<View style={{ alignItems: 'center' }}>
|
||||||
<ThemedView style={{...styles.modalView, backgroundColor: Colors[colorScheme].background}}>
|
<ThemedText type="defaultSemiBold">Opmerking:</ThemedText>
|
||||||
<ThemedText type="subtitle" style={{marginBottom: 30, textAlign: 'center'}}>{activeCategory?.name}</ThemedText>
|
<ThemedText>{activeCategory?.description}</ThemedText>
|
||||||
|
</View>
|
||||||
|
|
||||||
<View style={styles.modalType}>
|
<TouchableOpacity
|
||||||
<Image source={{uri: activeCategory?.type.image}} style={styles.modalTypeImage}/>
|
onPress={() => setActiveCategory( null )}
|
||||||
<ThemedText>{activeCategory?.type?.name}</ThemedText>
|
style={{ ...styles.modalClose, backgroundColor: Colors[ colorScheme ].tint }}>
|
||||||
</View>
|
<ThemedText style={{ color: '#fff' }}>Sluiten</ThemedText>
|
||||||
|
</TouchableOpacity>
|
||||||
<View style={{alignItems: 'center'}}>
|
</ThemedView>
|
||||||
<ThemedText type="defaultSemiBold">Opmerking:</ThemedText>
|
</Modal>
|
||||||
<ThemedText>{activeCategory?.description}</ThemedText>
|
</SafeAreaView>
|
||||||
</View>
|
);
|
||||||
|
|
||||||
<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({
|
const styles = StyleSheet.create( {
|
||||||
container: {
|
container: {
|
||||||
marginTop: StatusBar.currentHeight,
|
marginTop: StatusBar.currentHeight,
|
||||||
padding: 25,
|
padding: 25,
|
||||||
},
|
},
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: 8,
|
gap: 8,
|
||||||
paddingBottom: 8,
|
paddingBottom: 8,
|
||||||
},
|
},
|
||||||
searchContainer: {
|
searchContainer: {
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
},
|
},
|
||||||
categoriesContainer: {
|
categoriesContainer: {
|
||||||
marginTop: 25,
|
marginTop: 25,
|
||||||
},
|
},
|
||||||
listContainer: {
|
listContainer: {
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
paddingBottom: 50
|
paddingBottom: 50
|
||||||
},
|
},
|
||||||
listItem: {
|
listItem: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: 8,
|
gap: 8,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderBottomColor: '#f2f2f2',
|
borderBottomColor: '#f2f2f2',
|
||||||
},
|
},
|
||||||
listImage: {
|
listImage: {
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
},
|
},
|
||||||
modalView: {
|
modalView: {
|
||||||
margin: 20,
|
margin: 20,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
padding: 35,
|
padding: 35,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
modalType: {
|
modalType: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: 8,
|
gap: 8,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
marginBottom: 30,
|
marginBottom: 30,
|
||||||
},
|
},
|
||||||
modalTypeImage: {
|
modalTypeImage: {
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
},
|
},
|
||||||
modalClose: {
|
modalClose: {
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
paddingTop: 10,
|
paddingTop: 10,
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
paddingLeft: 40,
|
paddingLeft: 40,
|
||||||
paddingRight: 40,
|
paddingRight: 40,
|
||||||
marginTop: 30,
|
marginTop: 30,
|
||||||
},
|
},
|
||||||
});
|
} );
|
||||||
|
|
|
@ -1,171 +1,171 @@
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {StyleSheet, ScrollView, SafeAreaView, View, StatusBar, TouchableOpacity, Image} from 'react-native';
|
import { StyleSheet, ScrollView, SafeAreaView, View, StatusBar, TouchableOpacity, Image } from 'react-native';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import CalendarPicker from 'react-native-calendar-picker';
|
import CalendarPicker from 'react-native-calendar-picker';
|
||||||
import Ionicons from '@expo/vector-icons/Ionicons';
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
||||||
|
|
||||||
import {ThemedText} from '@/components/ThemedText';
|
import { ThemedText } from '@/components/ThemedText';
|
||||||
import {ThemedView} from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
import {Colors} from '@/constants/Colors';
|
import { Colors } from '@/constants/Colors';
|
||||||
import {useColorScheme} from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
import {useToken} from '@/context/AppProvider';
|
import { useToken } from '@/context/AppProvider';
|
||||||
import {Request} from '@/services/request';
|
import { Request } from '@/services/request';
|
||||||
import List from '@/components/List';
|
import List from '@/components/List';
|
||||||
import { useIsFocused } from '@react-navigation/core';
|
import { useIsFocused } from '@react-navigation/core';
|
||||||
|
|
||||||
export default function HomeScreen() {
|
export default function HomeScreen() {
|
||||||
const colorScheme = useColorScheme() ?? 'light';
|
const colorScheme = useColorScheme() ?? 'light';
|
||||||
const isFocused = useIsFocused();
|
const isFocused = useIsFocused();
|
||||||
const {token, isLoading} = useToken();
|
const { token, isLoading } = useToken();
|
||||||
const [name, setName] = useState(' '); // Default empty space to prevent layout shifting
|
const [ name, setName ] = useState( ' ' ); // Default empty space to prevent layout shifting
|
||||||
const [dates, setDates] = useState<any | null>([]);
|
const [ dates, setDates ] = useState<any | null>( [] );
|
||||||
const [types, setTypes] = useState<any | null>([]);
|
const [ types, setTypes ] = useState<any | null>( [] );
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect( () => {
|
||||||
if (token) {
|
if (token) {
|
||||||
Request.post('calendar', {token: token}).then((response) => {
|
Request.post( 'calendar', { token: token } ).then( (response) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
// Set name
|
// Set name
|
||||||
setName(response.name);
|
setName( response.name );
|
||||||
|
|
||||||
// Set dates
|
// Set dates
|
||||||
let calendarDates: any[] = [];
|
let calendarDates: any[] = [];
|
||||||
response.dates.forEach((date: any) => {
|
response.dates.forEach( (date: any) => {
|
||||||
calendarDates.push({
|
calendarDates.push( {
|
||||||
date: new Date(date.date),
|
date: new Date( date.date ),
|
||||||
style: {backgroundColor: date.color},
|
style: { backgroundColor: date.color },
|
||||||
textStyle: {color: Colors.white},
|
textStyle: { color: Colors.white },
|
||||||
allowDisabled: true,
|
allowDisabled: true,
|
||||||
})
|
} )
|
||||||
})
|
} )
|
||||||
setDates(calendarDates);
|
setDates( calendarDates );
|
||||||
|
|
||||||
// Set types
|
// Set types
|
||||||
setTypes(response.types);
|
setTypes( response.types );
|
||||||
|
}
|
||||||
|
} )
|
||||||
}
|
}
|
||||||
})
|
}, [ isFocused ] );
|
||||||
}
|
|
||||||
}, [isFocused]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{flex: 1, backgroundColor: Colors[colorScheme].background,}}>
|
<SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background, }}>
|
||||||
<ThemedView style={styles.container}>
|
<ThemedView style={styles.container}>
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<ThemedView style={styles.titleContainer}>
|
<ThemedView style={styles.titleContainer}>
|
||||||
<ThemedText type="title">{getGreeting()},</ThemedText>
|
<ThemedText type="title">{getGreeting()},</ThemedText>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
|
|
||||||
<ThemedView style={styles.titleContainer}>
|
<ThemedView style={styles.titleContainer}>
|
||||||
<ThemedText type="title" style={{color: Colors[colorScheme].tint}}>{name}</ThemedText>
|
<ThemedText type="title" style={{ color: Colors[ colorScheme ].tint }}>{name}</ThemedText>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
|
|
||||||
<ThemedView style={styles.calendarContainer}>
|
<ThemedView style={styles.calendarContainer}>
|
||||||
<CalendarPicker
|
<CalendarPicker
|
||||||
showDayStragglers={true}
|
showDayStragglers={true}
|
||||||
enableDateChange={false}
|
enableDateChange={false}
|
||||||
customDatesStyles={dates}
|
customDatesStyles={dates}
|
||||||
todayTextStyle={styles.today}
|
todayTextStyle={styles.today}
|
||||||
previousComponent={
|
previousComponent={
|
||||||
<Ionicons size={28} name="chevron-back"/>
|
<Ionicons size={28} name="chevron-back"/>
|
||||||
}
|
}
|
||||||
nextComponent={
|
nextComponent={
|
||||||
<Ionicons size={28} name="chevron-forward"/>
|
<Ionicons size={28} name="chevron-forward"/>
|
||||||
}
|
}
|
||||||
weekdays={["Zo", "Ma", "Di", "Woe", "Do", "Vrij", "Zat"]}
|
weekdays={[ "Zo", "Ma", "Di", "Woe", "Do", "Vrij", "Zat" ]}
|
||||||
months={[
|
months={[
|
||||||
"Januari",
|
"Januari",
|
||||||
"Februari",
|
"Februari",
|
||||||
"Maart",
|
"Maart",
|
||||||
"April",
|
"April",
|
||||||
"Mei",
|
"Mei",
|
||||||
"Juni",
|
"Juni",
|
||||||
"Juli",
|
"Juli",
|
||||||
"Augustus",
|
"Augustus",
|
||||||
"September",
|
"September",
|
||||||
"Oktober",
|
"Oktober",
|
||||||
"November",
|
"November",
|
||||||
"December",
|
"December",
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
|
|
||||||
<ThemedView style={styles.legendaContainer}>
|
<ThemedView style={styles.legendaContainer}>
|
||||||
<ThemedText type='subtitle'>Legenda:</ThemedText>
|
<ThemedText type='subtitle'>Legenda:</ThemedText>
|
||||||
<List
|
<List
|
||||||
data={types}
|
data={types}
|
||||||
viewStyle={styles.legendaList}
|
viewStyle={styles.legendaList}
|
||||||
renderItem={(type: any, index: any) => (
|
renderItem={(type: any, index: any) => (
|
||||||
<View style={styles.legendaItem} key={index}>
|
<View style={styles.legendaItem} key={index}>
|
||||||
<View style={{...styles.circle, backgroundColor: type.color}}/>
|
<View style={{ ...styles.circle, backgroundColor: type.color }}/>
|
||||||
<ThemedText type="default">{ type.name }</ThemedText>
|
<ThemedText type="default">{type.name}</ThemedText>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGreeting() {
|
function getGreeting() {
|
||||||
const myDate = new Date();
|
const myDate = new Date();
|
||||||
const hours = myDate.getHours();
|
const hours = myDate.getHours();
|
||||||
|
|
||||||
if (hours < 12) {
|
if (hours < 12) {
|
||||||
return 'Goedemorgen';
|
return 'Goedemorgen';
|
||||||
} else if (hours >= 12 && hours <= 17) {
|
} else if (hours >= 12 && hours <= 17) {
|
||||||
return 'Goedemiddag';
|
return 'Goedemiddag';
|
||||||
} else if (hours >= 17 && hours <= 24) {
|
} else if (hours >= 17 && hours <= 24) {
|
||||||
return 'Goedenavond';
|
return 'Goedenavond';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Hallo';
|
return 'Hallo';
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create( {
|
||||||
container: {
|
container: {
|
||||||
padding: 25,
|
padding: 25,
|
||||||
marginTop: StatusBar.currentHeight,
|
marginTop: StatusBar.currentHeight,
|
||||||
},
|
},
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: 8,
|
gap: 8,
|
||||||
paddingBottom: 8,
|
paddingBottom: 8,
|
||||||
},
|
},
|
||||||
calendarContainer: {
|
calendarContainer: {
|
||||||
marginTop: 15,
|
marginTop: 15,
|
||||||
},
|
},
|
||||||
legendaContainer: {
|
legendaContainer: {
|
||||||
marginTop: 40,
|
marginTop: 40,
|
||||||
},
|
},
|
||||||
legendaList: {
|
legendaList: {
|
||||||
marginTop: 15,
|
marginTop: 15,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignContent: 'center',
|
alignContent: 'center',
|
||||||
gap: 15,
|
gap: 15,
|
||||||
},
|
},
|
||||||
legendaItem: {
|
legendaItem: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: 8,
|
gap: 8,
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
},
|
},
|
||||||
circle: {
|
circle: {
|
||||||
width: 25,
|
width: 25,
|
||||||
height: 25,
|
height: 25,
|
||||||
borderRadius: 50,
|
borderRadius: 50,
|
||||||
},
|
},
|
||||||
today: {
|
today: {
|
||||||
borderWidth: 3,
|
borderWidth: 3,
|
||||||
borderColor: Colors.dark.grey,
|
borderColor: Colors.dark.grey,
|
||||||
borderRadius: 25,
|
borderRadius: 25,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
},
|
},
|
||||||
});
|
} );
|
||||||
|
|
|
@ -1,194 +1,194 @@
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {Image, SafeAreaView, ScrollView, StatusBar, StyleSheet, Switch, View, Dimensions} from 'react-native';
|
import { Image, SafeAreaView, ScrollView, StatusBar, StyleSheet, Switch, View, Dimensions } from 'react-native';
|
||||||
import Mapbox, {Callout, Camera, MapView, PointAnnotation} from "@rnmapbox/maps";
|
import Mapbox, { Callout, Camera, MapView, PointAnnotation } from "@rnmapbox/maps";
|
||||||
|
|
||||||
Mapbox.setAccessToken("pk.eyJ1IjoibWFhcnRlbnZyOTgiLCJhIjoiY2x6ZDFqMGp1MGVyejJrczhqcXpvYm9iYiJ9.XvYcL62dWiJQiFmG6mOoug");
|
Mapbox.setAccessToken( "pk.eyJ1IjoibWFhcnRlbnZyOTgiLCJhIjoiY2x6ZDFqMGp1MGVyejJrczhqcXpvYm9iYiJ9.XvYcL62dWiJQiFmG6mOoug" );
|
||||||
|
|
||||||
import {ThemedText} from '@/components/ThemedText';
|
import { ThemedText } from '@/components/ThemedText';
|
||||||
import {ThemedView} from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
import {Colors} from '@/constants/Colors';
|
import { Colors } from '@/constants/Colors';
|
||||||
import {useColorScheme} from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
import List from '@/components/List';
|
import List from '@/components/List';
|
||||||
import {Request} from '@/services/request';
|
import { Request } from '@/services/request';
|
||||||
|
|
||||||
|
|
||||||
export default function MapScreen() {
|
export default function MapScreen() {
|
||||||
const colorScheme = useColorScheme() ?? 'light';
|
const colorScheme = useColorScheme() ?? 'light';
|
||||||
|
|
||||||
const [types, setTypes] = useState<any>([]);
|
const [ types, setTypes ] = useState<any>( [] );
|
||||||
const [markers, setMarkers] = useState<any>([]);
|
const [ markers, setMarkers ] = useState<any>( [] );
|
||||||
|
|
||||||
// Load markers and types
|
// Load markers and types
|
||||||
useEffect(() => {
|
useEffect( () => {
|
||||||
Mapbox.setTelemetryEnabled(false);
|
Mapbox.setTelemetryEnabled( false );
|
||||||
|
|
||||||
Request.get('locations').then((response) => {
|
Request.get( 'locations' ).then( (response) => {
|
||||||
const {locations, types} = response;
|
const { locations, types } = response;
|
||||||
|
|
||||||
// Set types
|
// Set types
|
||||||
const typesList: any[] = [];
|
const typesList: any[] = [];
|
||||||
types.forEach((type: any) => {
|
types.forEach( (type: any) => {
|
||||||
typesList.push({
|
typesList.push( {
|
||||||
name: type.name,
|
name: type.name,
|
||||||
image: type.image,
|
image: type.image,
|
||||||
isEnabled: false,
|
isEnabled: false,
|
||||||
type: type.config_name,
|
type: type.config_name,
|
||||||
});
|
} );
|
||||||
})
|
} )
|
||||||
setTypes(typesList);
|
setTypes( typesList );
|
||||||
|
|
||||||
// Set markers
|
// Set markers
|
||||||
setMarkers(locations);
|
setMarkers( locations );
|
||||||
})
|
} )
|
||||||
}, []);
|
}, [] );
|
||||||
|
|
||||||
// Enable/disable type
|
// Enable/disable type
|
||||||
const toggleSwitch = (index: any) => {
|
const toggleSwitch = (index: any) => {
|
||||||
const newData = types.map((item: any, key: any) =>
|
const newData = types.map( (item: any, key: any) =>
|
||||||
key === index ? {...item, isEnabled: !item.isEnabled} : item
|
key === index ? { ...item, isEnabled: !item.isEnabled } : item
|
||||||
);
|
);
|
||||||
|
|
||||||
setTypes(newData);
|
setTypes( newData );
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get all types that are active
|
// Get all types that are active
|
||||||
const getActiveTypes = (): Array<String> => {
|
const getActiveTypes = (): Array<String> => {
|
||||||
const list: any[] = [];
|
const list: any[] = [];
|
||||||
|
|
||||||
types.forEach((type: any) => {
|
types.forEach( (type: any) => {
|
||||||
if (type.isEnabled) {
|
if (type.isEnabled) {
|
||||||
list.push(type.type);
|
list.push( type.type );
|
||||||
}
|
}
|
||||||
});
|
} );
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all markers that needs to be visible
|
// Get all markers that needs to be visible
|
||||||
const activeMarkers = () => {
|
const activeMarkers = () => {
|
||||||
return markers.filter((marker: any) => {
|
return markers.filter( (marker: any) => {
|
||||||
return getActiveTypes().includes(marker.waste_type);
|
return getActiveTypes().includes( marker.waste_type );
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{flex: 1, backgroundColor: Colors[colorScheme].background}}>
|
<SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background }}>
|
||||||
<ThemedView style={styles.container}>
|
<ThemedView style={styles.container}>
|
||||||
<ThemedView>
|
<ThemedView>
|
||||||
<ThemedView style={styles.titleContainer}>
|
<ThemedView style={styles.titleContainer}>
|
||||||
<ThemedText type="title">Afvalcontainers</ThemedText>
|
<ThemedText type="title">Afvalcontainers</ThemedText>
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
<ThemedView style={styles.titleContainer}>
|
|
||||||
<ThemedText type="title" style={{color: Colors[colorScheme].tint}}>in de buurt</ThemedText>
|
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
<ThemedView style={styles.mapContainer}>
|
|
||||||
<MapView
|
|
||||||
style={styles.map}
|
|
||||||
logoEnabled={false}
|
|
||||||
scaleBarEnabled={false}
|
|
||||||
attributionEnabled={false}
|
|
||||||
>
|
|
||||||
<Camera
|
|
||||||
centerCoordinate={[5.630960, 52.043420]}
|
|
||||||
zoomLevel={13}
|
|
||||||
animationMode={'none'}
|
|
||||||
/>
|
|
||||||
{activeMarkers().map((marker: any, index: any) => (
|
|
||||||
<PointAnnotation
|
|
||||||
key={marker.id.toString()}
|
|
||||||
id={marker.id.toString()}
|
|
||||||
coordinate={marker.coordinate}
|
|
||||||
>
|
|
||||||
<Callout title={marker.number}>
|
|
||||||
<ThemedView style={styles.callout}>
|
|
||||||
<ThemedText>{marker.description + ' - ' + marker.street}</ThemedText>
|
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
</Callout>
|
|
||||||
</PointAnnotation>
|
|
||||||
))}
|
|
||||||
</MapView>
|
|
||||||
</ThemedView>
|
|
||||||
</ThemedView>
|
|
||||||
|
|
||||||
<ScrollView style={styles.listContainer}>
|
<ThemedView style={styles.titleContainer}>
|
||||||
<List
|
<ThemedText type="title" style={{ color: Colors[ colorScheme ].tint }}>in de buurt</ThemedText>
|
||||||
data={types}
|
</ThemedView>
|
||||||
renderItem={(item: any, index: any) => (
|
|
||||||
<ThemedView style={styles.listItem} key={index}>
|
|
||||||
<View style={styles.listItemTitle}>
|
|
||||||
<Image source={{uri: item.image}} style={styles.listImage}/>
|
|
||||||
<ThemedText type="default">{item.name}</ThemedText>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Switch
|
<ThemedView style={styles.mapContainer}>
|
||||||
trackColor={{false: '#767577', true: Colors[colorScheme].tint}}
|
<MapView
|
||||||
thumbColor={'#fff'}
|
style={styles.map}
|
||||||
value={item.isEnabled}
|
logoEnabled={false}
|
||||||
onValueChange={() => toggleSwitch(index)}
|
scaleBarEnabled={false}
|
||||||
/>
|
attributionEnabled={false}
|
||||||
</ThemedView>
|
>
|
||||||
)}/>
|
<Camera
|
||||||
</ScrollView>
|
centerCoordinate={[ 5.630960, 52.043420 ]}
|
||||||
</ThemedView>
|
zoomLevel={13}
|
||||||
</SafeAreaView>
|
animationMode={'none'}
|
||||||
);
|
/>
|
||||||
|
{activeMarkers().map( (marker: any, index: any) => (
|
||||||
|
<PointAnnotation
|
||||||
|
key={marker.id.toString()}
|
||||||
|
id={marker.id.toString()}
|
||||||
|
coordinate={marker.coordinate}
|
||||||
|
>
|
||||||
|
<Callout title={marker.number}>
|
||||||
|
<ThemedView style={styles.callout}>
|
||||||
|
<ThemedText>{marker.description + ' - ' + marker.street}</ThemedText>
|
||||||
|
</ThemedView>
|
||||||
|
</Callout>
|
||||||
|
</PointAnnotation>
|
||||||
|
) )}
|
||||||
|
</MapView>
|
||||||
|
</ThemedView>
|
||||||
|
</ThemedView>
|
||||||
|
|
||||||
|
<ScrollView style={styles.listContainer}>
|
||||||
|
<List
|
||||||
|
data={types}
|
||||||
|
renderItem={(item: any, index: any) => (
|
||||||
|
<ThemedView style={styles.listItem} key={index}>
|
||||||
|
<View style={styles.listItemTitle}>
|
||||||
|
<Image source={{ uri: item.image }} style={styles.listImage}/>
|
||||||
|
<ThemedText type="default">{item.name}</ThemedText>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
trackColor={{ false: '#767577', true: Colors[ colorScheme ].tint }}
|
||||||
|
thumbColor={'#fff'}
|
||||||
|
value={item.isEnabled}
|
||||||
|
onValueChange={() => toggleSwitch( index )}
|
||||||
|
/>
|
||||||
|
</ThemedView>
|
||||||
|
)}/>
|
||||||
|
</ScrollView>
|
||||||
|
</ThemedView>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create( {
|
||||||
container: {
|
container: {
|
||||||
marginTop: StatusBar.currentHeight,
|
marginTop: StatusBar.currentHeight,
|
||||||
paddingTop: 25,
|
paddingTop: 25,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
paddingLeft: 25,
|
paddingLeft: 25,
|
||||||
paddingRight: 25,
|
paddingRight: 25,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: 8,
|
gap: 8,
|
||||||
paddingBottom: 8,
|
paddingBottom: 8,
|
||||||
},
|
},
|
||||||
mapContainer: {
|
mapContainer: {
|
||||||
marginTop: 15,
|
marginTop: 15,
|
||||||
height: 400,
|
height: 400,
|
||||||
},
|
},
|
||||||
map: {
|
map: {
|
||||||
width: Dimensions.get('window').width,
|
width: Dimensions.get( 'window' ).width,
|
||||||
height: 400,
|
height: 400,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
listContainer: {
|
listContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
paddingTop: 20,
|
paddingTop: 20,
|
||||||
paddingLeft: 25,
|
paddingLeft: 25,
|
||||||
paddingRight: 25,
|
paddingRight: 25,
|
||||||
},
|
},
|
||||||
listItem: {
|
listItem: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderBottomColor: '#f2f2f2',
|
borderBottomColor: '#f2f2f2',
|
||||||
},
|
},
|
||||||
listItemTitle: {
|
listItemTitle: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
listImage: {
|
listImage: {
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginRight: 8,
|
marginRight: 8,
|
||||||
},
|
},
|
||||||
callout: {
|
callout: {
|
||||||
width: 200,
|
width: 200,
|
||||||
padding: 5,
|
padding: 5,
|
||||||
},
|
},
|
||||||
});
|
} );
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default function SettingsScreen() {
|
||||||
|
|
||||||
// Handle
|
// Handle
|
||||||
const handleSave = (inputValues: Record<string, string>) => {
|
const handleSave = (inputValues: Record<string, string>) => {
|
||||||
let postData: any = {token: token};
|
let postData: any = { token: token };
|
||||||
|
|
||||||
if (inputValues.name) {
|
if (inputValues.name) {
|
||||||
postData[ 'name' ] = inputValues.name;
|
postData[ 'name' ] = inputValues.name;
|
||||||
|
@ -80,7 +80,7 @@ export default function SettingsScreen() {
|
||||||
|
|
||||||
Request.post( 'sessions/update', postData )
|
Request.post( 'sessions/update', postData )
|
||||||
.then( (response) => {
|
.then( (response) => {
|
||||||
console.log('save', response);
|
console.log( 'save', response );
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setSessionData( response.session );
|
setSessionData( response.session );
|
||||||
|
@ -90,9 +90,9 @@ export default function SettingsScreen() {
|
||||||
Message.error( response.message );
|
Message.error( response.message );
|
||||||
}
|
}
|
||||||
} )
|
} )
|
||||||
.catch((error) => {
|
.catch( (error) => {
|
||||||
console.log('error', error);
|
console.log( 'error', error );
|
||||||
})
|
} )
|
||||||
};
|
};
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
|
|
|
@ -6,26 +6,26 @@ import { type PropsWithChildren } from 'react';
|
||||||
* The contents of this function only run in Node.js environments and do not have access to the DOM or browser APIs.
|
* The contents of this function only run in Node.js environments and do not have access to the DOM or browser APIs.
|
||||||
*/
|
*/
|
||||||
export default function Root({ children }: PropsWithChildren) {
|
export default function Root({ children }: PropsWithChildren) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charSet="utf-8" />
|
<meta charSet="utf-8"/>
|
||||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
<meta httpEquiv="X-UA-Compatible" content="IE=edge"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
|
||||||
|
|
||||||
{/*
|
{/*
|
||||||
Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
|
Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
|
||||||
However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
|
However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
|
||||||
*/}
|
*/}
|
||||||
<ScrollViewStyleReset />
|
<ScrollViewStyleReset/>
|
||||||
|
|
||||||
{/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
|
{/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
|
||||||
<style dangerouslySetInnerHTML={{ __html: responsiveBackground }} />
|
<style dangerouslySetInnerHTML={{ __html: responsiveBackground }}/>
|
||||||
{/* Add any additional <head> elements that you want globally available on web... */}
|
{/* Add any additional <head> elements that you want globally available on web... */}
|
||||||
</head>
|
</head>
|
||||||
<body>{children}</body>
|
<body>{children}</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const responsiveBackground = `
|
const responsiveBackground = `
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
import {useFonts} from 'expo-font';
|
import { useFonts } from 'expo-font';
|
||||||
import {Slot, Stack} from 'expo-router';
|
import { Slot, Stack } from 'expo-router';
|
||||||
import * as SplashScreen from 'expo-splash-screen';
|
import * as SplashScreen from 'expo-splash-screen';
|
||||||
import {useEffect} from 'react';
|
import { useEffect } from 'react';
|
||||||
import 'react-native-reanimated';
|
import 'react-native-reanimated';
|
||||||
|
|
||||||
import {AppProvider} from '@/context/AppProvider';
|
import { AppProvider } from '@/context/AppProvider';
|
||||||
import {DarkTheme, DefaultTheme, ThemeProvider} from '@react-navigation/native';
|
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
||||||
import Toast from 'react-native-toast-message';
|
import Toast from 'react-native-toast-message';
|
||||||
import {AutocompleteDropdownContextProvider} from 'react-native-autocomplete-dropdown';
|
import { AutocompleteDropdownContextProvider } from 'react-native-autocomplete-dropdown';
|
||||||
import {useColorScheme} from '@/hooks/useColorScheme';
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||||
|
|
||||||
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
||||||
// SplashScreen.preventAutoHideAsync();
|
// SplashScreen.preventAutoHideAsync();
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
const [loaded] = useFonts({
|
const [ loaded ] = useFonts( {
|
||||||
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
SpaceMono: require( '../assets/fonts/SpaceMono-Regular.ttf' ),
|
||||||
});
|
} );
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect( () => {
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
// SplashScreen.hideAsync();
|
// SplashScreen.hideAsync();
|
||||||
|
}
|
||||||
|
}, [ loaded ] );
|
||||||
|
|
||||||
|
if (!loaded) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}, [loaded]);
|
|
||||||
|
|
||||||
if (!loaded) {
|
return (
|
||||||
return null;
|
<AppProvider>
|
||||||
}
|
<AutocompleteDropdownContextProvider>
|
||||||
|
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||||
return (
|
<Stack>
|
||||||
<AppProvider>
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }}/>
|
||||||
<AutocompleteDropdownContextProvider>
|
<Stack.Screen name="(onboarding)/start" options={{ headerShown: false }}/>
|
||||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
<Stack.Screen name="index" options={{ headerShown: false }}/>
|
||||||
<Stack>
|
</Stack>
|
||||||
<Stack.Screen name="(tabs)" options={{headerShown: false}}/>
|
<Toast/>
|
||||||
<Stack.Screen name="(onboarding)/start" options={{headerShown: false}}/>
|
</ThemeProvider>
|
||||||
<Stack.Screen name="index" options={{headerShown: false}}/>
|
</AutocompleteDropdownContextProvider>
|
||||||
</Stack>
|
</AppProvider>
|
||||||
<Toast/>
|
);
|
||||||
</ThemeProvider>
|
|
||||||
</AutocompleteDropdownContextProvider>
|
|
||||||
</AppProvider>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
import React, {useEffect} from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import {Redirect, router, useRouter} from 'expo-router';
|
import { Redirect, router, useRouter } from 'expo-router';
|
||||||
|
|
||||||
import {ThemedText} from '@/components/ThemedText';
|
import { ThemedText } from '@/components/ThemedText';
|
||||||
import {ThemedView} from '@/components/ThemedView';
|
import { ThemedView } from '@/components/ThemedView';
|
||||||
import {useToken} from '@/context/AppProvider';
|
import { useToken } from '@/context/AppProvider';
|
||||||
import {Request} from '@/services/request';
|
import { Request } from '@/services/request';
|
||||||
|
|
||||||
|
|
||||||
export default function OnboardStartScreen() {
|
export default function OnboardStartScreen() {
|
||||||
const { token, isLoading } = useToken();
|
const { token, isLoading } = useToken();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const loadingScreen = () => (
|
const loadingScreen = () => (
|
||||||
<ThemedView>
|
<ThemedView>
|
||||||
<ThemedText>Laden...</ThemedText>
|
<ThemedText>Laden...</ThemedText>
|
||||||
</ThemedView>
|
</ThemedView>
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect( () => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const response = await Request.post('sessions/get', { token: token });
|
const response = await Request.post( 'sessions/get', { token: token } );
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
router.replace('/(tabs)/settings');
|
router.replace( '/(tabs)/settings' );
|
||||||
} else {
|
} else {
|
||||||
router.replace('/(onboarding)/start');
|
router.replace( '/(onboarding)/start' );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isLoading && token) {
|
if (!isLoading && token) {
|
||||||
fetchData();
|
fetchData();
|
||||||
|
}
|
||||||
|
}, [ isLoading, token, router ] );
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return loadingScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return <Redirect href="/(onboarding)/start"/>;
|
||||||
}
|
}
|
||||||
}, [isLoading, token, router]);
|
|
||||||
|
|
||||||
if (isLoading) {
|
|
||||||
return loadingScreen();
|
return loadingScreen();
|
||||||
}
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
return <Redirect href="/(onboarding)/start" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return loadingScreen();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue