import { FontAwesome } from "@expo/vector-icons";
import React, { memo, useEffect, useState } from "react";
import { ActivityIndicator, Dimensions, Image, Keyboard, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { TouchableWithoutFeedback } from "react-native-gesture-handler";
import Picker from 'react-native-picker-select';
import { colors, Icons, IconStrings } from "../globals";
import { Landmark, useLandmarks } from "../hooks/useLandmarks";
import { SecondaryButton } from "./Auth/Buttons";
/**
* Props for the {@link AddLandmark} component.
*/
export interface AddLandmarkProps {
/**
* The {@link landmark} object to be added.
*/
landmark?: Landmark;
/**
* A call back that toggles the visibility state of the {@link AddLandmark} modal. Passed down from {@link AddLandmark}.
*/
setVisible: (state: boolean) => void;
}
/**
* Component that renders a form for adding a new {@link Landmark}. Contained within a [react-native-modal]{@link https://github.com/react-native-modal/react-native-modal}.
* @component
* @category Map
*/
const AddLandmark: React.FC<AddLandmarkProps> = ({landmark, setVisible}) => {
const {
addLandmarkAsync,
resetAddLm,
addLandmarkStatus,
newLandmark,
getLandmarksStatus
} = useLandmarks(undefined);
/**
* Holds the state of the landmark object to be added.
*/
const currentLandmarkState = undefined;
const [currentLandmark, setLandmark] = useState<Landmark | undefined>(currentLandmarkState);
useEffect(() => {
/**
* Updates this component's {@linkcode currentLandmarkState} when the {@linkcode landmark} prop passed down from the parent {@link Map}'s {@linkcode newLandmark} is changed.
* Embedded in a useEffect that listens to the {@linkcode landmark} prop.
* @memberOf AddLandmark
*/
const updateLandmarkStateFromParent = () => {
setLandmark(landmark), [landmark]
}
})
useEffect(() => {
/**
* Resets the {@link addLandmarkAsync} mutation on successful add.
* Embedded in a useEffect that listens to the {@link addLandmarkStatus} value from the {@link useLandmarks} hook.
* @memberOf AddLandmark
*/
const resetAddMutationOnSuccess = () => {
if (addLandmarkStatus == 'success') {
resetAddLm();
}
}
resetAddMutationOnSuccess();
}, [addLandmarkStatus]);
/**
* Calls {@link addLandmarkAsync} from {@link useLandmarks} to initate the process of adding a landmark, then closes the modal.
*/
const submit = async () => {
await addLandmarkAsync(currentLandmark)
setVisible(false);
}
/**
* Closes the modal.
*/
const close = () => {
setVisible(false)
}
return (
<View style={{backgroundColor: colors.red, paddingBottom: 20, height: Dimensions.get("window").height * .6, }}>
{addLandmarkStatus == 'idle' ?
<>
<View style={{
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: "row",
marginBottom: 15,
borderBottomWidth: 1,
borderBottomColor: 'white',
paddingHorizontal: 20,
paddingVertical: 10}}>
<Text style={{color: 'white', fontSize: 15}}>Add landmark here?</Text>
<FontAwesome name="times" color='white' size={25} onPress={close} />
</View>
<View style={{paddingHorizontal: 20, paddingBottom: 20 }}>
<TextInput
multiline={true}
style={{backgroundColor: 'white', paddingHorizontal: 10, paddingTop: 10, paddingBottom: 10, marginBottom: 20, height: 150}}
placeholder="Description"
onChangeText={value => setLandmark({...currentLandmark, description: value})}>
{currentLandmark?.description}
</TextInput>
<View style={{flexDirection: 'row'}}>
<Picker
style={{
inputIOS: {color: 'white'},
inputAndroid: {color: 'white'},
viewContainer: {marginVertical: 10, flex: 1}, placeholder: {color: 'white'}}}
textInputProps={{placeholderTextColor: 'white', selectionColor: 'white'}}
Icon={() => <FontAwesome name="chevron-down" color='white' size={20} />}
placeholder={{label: "Select a landmark type...", value: 0}}
value={currentLandmark?.landmark_type}
onValueChange={(value) => {
setLandmark({...currentLandmark, landmark_type: value, title: IconStrings[value]})
console.log(value)
}}
useNativeAndroidPickerStyle={true}
items={Object.keys(Icons)?.map(icon => {
return (
{label: IconStrings[parseInt(icon)].toUpperCase(), value: icon, key: icon}
)})}
/>
{currentLandmark?.landmark_type ? <Image style={{marginLeft: 20}} source={Icons[currentLandmark.landmark_type]}/>
: null}
</View>
</View>
{currentLandmark?.landmark_type ?
<View style={{justifyContent: 'flex-end', flexDirection: 'row', paddingHorizontal: 20}}>
{currentLandmark.description && currentLandmark.title ?
<View style={{flexDirection: 'row' }}>
<TouchableOpacity onPress={async () => submit()}><Text style={{color: 'white', marginRight: 20}}>Add</Text></TouchableOpacity>
<TouchableOpacity onPress={close}><Text style={{color: 'white'}}>Cancel</Text></TouchableOpacity>
</View> : null}
</View> : null}
<TouchableWithoutFeedback style={{height: '100%'}} onPress={() => Keyboard.dismiss()}><Text></Text></TouchableWithoutFeedback>
</> :
<View style={{height: '100%', justifyContent: "space-evenly", alignItems: "center"}}>
<Text style={{color: 'white', fontSize: 20}}>{
addLandmarkStatus == "loading" ? 'Uploading landmark...' :
addLandmarkStatus == "error" ? 'Something went wrong when trying to upload the landmark.' : null }
</Text>
{
addLandmarkStatus == "loading" ? <ActivityIndicator color='white' size="large"/> :
addLandmarkStatus == "error" ? <SecondaryButton text="Okay" onPress={close}/> : null
}
</View> }
</View>
)
}
export default memo(AddLandmark);
Source