Kliko/app/(tabs)/map.tsx
2024-08-06 09:41:59 +02:00

194 lines
5.3 KiB
TypeScript

import React, {useEffect, useState} from 'react';
import {Image, SafeAreaView, ScrollView, StatusBar, StyleSheet, Switch, View, Dimensions} from 'react-native';
import Mapbox, {Callout, Camera, MapView, PointAnnotation} from "@rnmapbox/maps";
Mapbox.setAccessToken("pk.eyJ1IjoibWFhcnRlbnZyOTgiLCJhIjoiY2x6ZDFqMGp1MGVyejJrczhqcXpvYm9iYiJ9.XvYcL62dWiJQiFmG6mOoug");
import {ThemedText} from '@/components/ThemedText';
import {ThemedView} from '@/components/ThemedView';
import {Colors} from '@/constants/Colors';
import {useColorScheme} from '@/hooks/useColorScheme';
import List from '@/components/List';
import {Request} from '@/services/request';
export default function MapScreen() {
const colorScheme = useColorScheme() ?? 'light';
const [types, setTypes] = useState<any>([]);
const [markers, setMarkers] = useState<any>([]);
// Load markers and types
useEffect(() => {
Mapbox.setTelemetryEnabled(false);
Request.get('locations').then((response) => {
const {locations, types} = response;
// Set types
const typesList: any[] = [];
types.forEach((type: any) => {
typesList.push({
name: type.name,
image: type.image,
isEnabled: false,
type: type.config_name,
});
})
setTypes(typesList);
// Set markers
setMarkers(locations);
})
}, []);
// Enable/disable type
const toggleSwitch = (index: any) => {
const newData = types.map((item: any, key: any) =>
key === index ? {...item, isEnabled: !item.isEnabled} : item
);
setTypes(newData);
};
// Get all types that are active
const getActiveTypes = (): Array<String> => {
const list: any[] = [];
types.forEach((type: any) => {
if (type.isEnabled) {
list.push(type.type);
}
});
return list;
}
// Get all markers that needs to be visible
const activeMarkers = () => {
return markers.filter((marker: any) => {
return getActiveTypes().includes(marker.waste_type);
});
}
return (
<SafeAreaView style={{flex: 1, backgroundColor: Colors[colorScheme].background}}>
<ThemedView style={styles.container}>
<ThemedView>
<ThemedView style={styles.titleContainer}>
<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>
</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({
container: {
marginTop: StatusBar.currentHeight,
paddingTop: 25,
flex: 1,
},
titleContainer: {
paddingLeft: 25,
paddingRight: 25,
flexDirection: 'row',
alignItems: 'center',
gap: 8,
paddingBottom: 8,
},
mapContainer: {
marginTop: 15,
height: 400,
},
map: {
width: Dimensions.get('window').width,
height: 400,
flex: 1,
},
listContainer: {
flex: 1,
paddingTop: 20,
paddingLeft: 25,
paddingRight: 25,
},
listItem: {
flex: 1,
display: 'flex',
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
paddingBottom: 10,
marginBottom: 10,
borderBottomWidth: 1,
borderBottomColor: '#f2f2f2',
},
listItemTitle: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
},
listImage: {
width: 30,
height: 30,
borderRadius: 5,
marginRight: 8,
},
callout: {
width: 200,
padding: 5,
},
});