123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- import React, { useEffect, useRef, useState } from 'react';
- import { ScrollView, View, Text, StyleSheet, TouchableOpacity, Dimensions, Image, Alert} from 'react-native';
- import { TextInput } from 'react-native-paper';
- import { Controller, useForm } from 'react-hook-form';
- import { useMockState } from '../contexts/MockContext';
- import Modal from 'react-native-modalbox';
- import { Icons } from '../globals';
- import Icon from 'react-native-vector-icons/FontAwesome';
- import { v4 as uuidv4 } from 'uuid';
- import { useMemo } from 'react/cjs/react.production.min';
- const editTheme = {
- colors: {
- primary: 'black',
- text: 'black'
- }
- }
- const LandmarkForm = ({navigation}) => {
- const {dispatch, state} = useMockState();
- const { control, isDirty, handleSubmit, setValue, formState } = useForm({
- mode: 'all'
- });
- const [selectedIcon, setIcon] = useState(state.selectedLandmark.icon);
- const iconSelector = useRef();
- useEffect(() => {
- setValue('title', state.selectedLandmark.title);
- setValue('desc', state.selectedLandmark.desc);
- setIcon(state.selectedLandmark.icon)
- }, [state]);
- const saveLandmark = (formData) => {
- let currentLandmark = state.landmarks.filter(l => l.id === state.selectedLandmark.id)[0];
- console.log(currentLandmark)
- if (currentLandmark != null) {
- // we're updating an existing landmark
- dispatch({type: "UPDATE_LANDMARKS", payload: state.landmarks.map(l => {
- if (l.id === state.selectedLandmark.id) {
- currentLandmark = {...l, title: formData.title, desc: formData.desc, icon: selectedIcon};
- dispatch({type: "UPDATE_SELECTED_LANDMARK", payload: currentLandmark});
- return currentLandmark;
- }
- return l;
- })});
- console.log('here')
- navigation.navigate('Map');
- }
-
- else {
- // we're adding a new landmark
- const newLandmark = {
- id: uuidv4(),
- postedBy: 'cdmoss',
- dateAdded: Date.now(),
- title: formData.title,
- desc: formData.desc,
- icon: selectedIcon,
- longitude: state.selectedLandmark.longitude,
- latitude: state.selectedLandmark.latitude,
- comments: []
- };
- dispatch({type: "UPDATE_LANDMARKS", payload: [...state.landmarks, newLandmark]})
- navigation.navigate('Map');
- }
- }
- const openSelector = () => {
- iconSelector.current.open();
- }
- const updateIcon = (icon) => {
- setIcon(icon);
- iconSelector.current.close();
- }
- const closeModal = () => {
- iconSelector.current.close();
- }
- return (
- <View style={styles.container}>
- <View style={styles.inputContainer}>
- <ScrollView>
- <Text style={styles.label}>Title</Text>
- <Controller
- control={control}
- render={({ field: { onBlur, onChange, value }}) => (
- <TextInput
- multiline={true}
- theme={editTheme}
- underlineColor="white"
- style={[styles.title, styles.input]}
- placeholder="Title"
- value={value}
- onBlur={value => onBlur(value)}
- onChangeText={value => onChange(value)}
- ></TextInput>
- )}
- name="title"
- rules={{ required: true, maxLength: 100 }} />
- {formState.errors.title?.type === "required" && <Text style={styles.errorText}>Title is required.</Text>}
- <Controller
- control={control}
- render={({ field: { onChange, onBlur, value }}) => (
- <TextInput
- multiline={true}
- theme={editTheme}
- style={[styles.desc, styles.input]}
- placeholder="Description"
- value={value}
- on={value => onBlur(value)}
- onChangeText={value => onChange(value)}
- ></TextInput>
- )}
- name="desc"
- rules={{ required: true, maxLength: 500 }} />
- {formState.errors.desc?.type === "required" && <Text style={styles.errorText}>Description is required.</Text>}
- {formState.errors.desc?.type === "maxLength" && <Text style={styles.errorText}>Description must be less than 500 characters.</Text>}
- <Text style={styles.label}>Type</Text>
- <TouchableOpacity onPress={openSelector}>
- <View style={styles.selectedIconContainer}>
- <View style={styles.selectedIcon}>
- <Image style={{height: 30, width: 22}} source={Icons[selectedIcon]}/>
- <Text style={{marginLeft: 15, color: 'black'}}>{selectedIcon}</Text>
- </View>
- <Icon style={iconSelector.isOpen ? { transform: [{rotate: '180deg'}] } : null} name="chevron-down" />
- </View>
- </TouchableOpacity>
- </ScrollView>
- </View>
- <TouchableOpacity style={{margin: 20, alignSelf: 'flex-end', zIndex: 5}} onPress={handleSubmit(saveLandmark)}>
- <Text style={{fontSize: 15, color: 'white'}}>Save Changes</Text>
- </TouchableOpacity>
- <Modal position={"bottom"} ref={iconSelector} style={{height: 400}} >
- <TouchableOpacity
- style={{flexDirection: 'row', justifyContent: 'center', paddingVertical: 10}}
- onPress={closeModal}>
- <Icon name="chevron-down"/>
- </TouchableOpacity>
- <ScrollView style={{marginBottom: 100}}>
- {Object.entries(Icons).map(icon => {
- return(
- <TouchableOpacity style={styles.iconChoice} key={icon[0]} onPress={() => updateIcon(icon[0])} >
- <Image style={{height: 30, width: 22}} source={icon[1]}/>
- <Text style={{marginLeft: 15}}>{icon[0]}</Text>
- </TouchableOpacity>)
- })}
- </ScrollView>
- </Modal>
- </View>
- )
- }
- const styles = StyleSheet.create({
- container: {
- position: 'absolute',
- width: Dimensions.get('window').width,
- height: Dimensions.get('window').height,
- flex: 1,
- backgroundColor: '#df3f3f',
- },
- inputContainer: {
- height: 500,
- paddingHorizontal: 20,
- paddingBottom: 20,
- paddingTop: 70,
- },
- label: {
- color: 'white',
- marginTop: 20,
- marginBottom: 8
- },
- title: {
- fontSize: 20,
- marginBottom: 20,
- },
- input: {
- backgroundColor: 'white',
- },
- desc: {
- color: 'white',
- },
- iconPicker: {
- color: 'white',
- },
- selectedIconContainer: {
- backgroundColor: 'white',
- paddingHorizontal: 30,
- padding: 15,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between'
- },
- errorText: {
- alignSelf: 'flex-end',
- color: 'black',
- fontSize: 15
- },
- selectedIcon: {
- backgroundColor: 'white',
- flexDirection: 'row',
- alignItems: 'center',
- },
- iconChoice: {
- marginHorizontal: 30,
- paddingVertical: 10,
- flexDirection: 'row',
-
- alignItems: 'center',
- borderBottomWidth: 1,
- },
- chevronRotate: {
- transform: [{ rotate: '180deg'}]
- }
-
- })
- export default LandmarkForm;
|