BoilerLiftUp / src / components / profile / EditProfile.jsx
EditProfile.jsx
Raw
import React, { useState, useEffect } from "react";
import { StyleSheet, SafeAreaView, Text, TextInput, View, Image, ScrollView} from "react-native";
import { useTheme } from '@react-navigation/native';
import SelectMultiple from 'react-native-select-multiple';
import { Button} from 'native-base';
import * as ImagePicker from 'expo-image-picker';
import Logo from '../../resources/logo.png';
import axios from 'axios';

function EditProfile({route, navigation}) {
    const { colors } = useTheme();
    const [age, setAge] = useState('');
    const [height, setHeight] = useState('');
    const [weight, setWeight] = useState('');
    const [gender, setGender] = useState('');
    const [levels, setLevels] = useState([]);
    const [selections, setSelections] = useState([]);
    const [photoResult, setPhotoResult] = useState('');
    const [picture, setPicture] = useState('');
    const [picUri, setPicUri] = useState('');
    const [pselections, setPSelections] = useState([]);
    const [settings, setSettings] = useState([]);

    let apiUrl = 'https://api.cloudinary.com/v1_1/boilerliftup/image/upload';

    async function getProfilePicture() {
        await fetch(localhost+'/userprofile/user/'+route.params.username, {
            method: "GET",
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }
        })
        .then(function(response) {
            if (response.status === 200 || response.status === 201) {
                // Successful GET
                // Set Fields to correct values
                response.json().then(function(data) {
                    const imgUrl = data[0].profile_picture;
                    setPicUri(imgUrl);
                })
                console.log("User Profile: Successfully retrived profile picture.");
            } else {
                console.log('issue getProfilePicture. Status Code: ' + response.status);
            }
        })
        .catch(function(err) {
            console.log('Fetch Error :-S', err);
        });
    }

    useEffect(() => {
        setLevels(['Beginner', 'Intermediate', 'Advanced' ]);
        getProfilePicture();
        setSettings(['Can friends see your stats?', 'Can your records be used publicly?' ]);
    }, []);

    const onSelectionsChange = levelSelection => {
        setSelections(levelSelection)
    }


    const selectPicture = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
            mediaTypes: ImagePicker.MediaTypeOptions.All,
            allowsEditing: true,
            aspect: [4, 3],
            quality: 1,
            base64: true
        });

        if (!result.cancelled) {
            setPicture(result.base64);
            setPhotoResult(result);
        }
    };

    const uploadPicture = async () => {
        // certain image sizes are too big - if you get a resource too large error try a different image
        console.log("Photo result", photoResult);
        let base64Img = `data:image/jpeg;base64,${photoResult.base64}`;

        let data = {
            "file": base64Img,
            "upload_preset": "boiler_picture",
        }

        return fetch(apiUrl, {
            body: JSON.stringify(data),
            headers: {
                'content-type': 'application/json'
            },
            method: 'POST',
        }).then(async r => {
            let data = await r.json();
            console.log("Cloudinary data: ", data);
            return data.secure_url;
        }).catch(err => console.log("Cloudinary error: ", err))
    };

    function updateFields(obj) {
        fetch(localhost+'/userprofile/update', {
            method: "PUT",
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(
                {
                    username: route.params.username,
                    update: obj
                })
        })
        .then(
            function(response) {
                if (response.status === 200 || response.status === 201) {
                    // Successful POST
                    console.log('good updateFields');
                    alert("Successfully updated!")
                    navigation.navigate("UserProfile", {
                        username: route.params.username
                    });
                } else {
                    // Examine the text in the response
                    console.log('issue in updateFields. Status code: '+ response.status);
                    alert("Unsuccessful")
                }
            }
        )
        .catch(function(err) {
            console.log('Fetch Error :-S', err);
        });
    }

    const postEditProfile = async () => {
        var obj = {}
        if (height != '') {
            obj["height"] = height
        }
        if (weight != '') {
            obj["weight"] = weight
        }
        if (age != '') {
            obj["age"] = age
        }
        if (gender != '') {
            obj["gender"] = gender
        }
        if (selections.length != 0) {
            var arr = []
            for(i=0; i < selections.length; i++){
                arr.push(selections[i].value)
            }
            obj["level"] = arr
        }
        if (picture != '') {
            await uploadPicture().then((picUrl) => {
                obj["profile_picture"] = picUrl;
                console.log("Put obj: ", obj)
                updateFields(obj).then(function(response) {
                    if (response.status === 200 || response.status === 201) {
                        // Successful POST
                        console.log('good updateFields');
                        alert("Successfully updated!")
                        navigation.navigate("UserProfile", {
                            username: route.params.username
                        });
                    } else {
                        // Examine the text in the response
                        console.log('issue in updateFields. Status code: '+ response.status);
                        alert("Unsuccessful")
                    }
                }).catch(function(err) {
                    console.log('Update Fields Error :-S', err);
                });
            });
        } else {
            updateFields(obj);
        }
    }
    let imageComponent;
    if (picture == '') {
        imageComponent = <Image style={ styles.profileSize } defaultSource={Logo} source={{uri: picUri}}/>
    } else {
        imageComponent = <Image style={ styles.profileSize } defaultSource={Logo} source={{uri: 'data:image/jpeg;base64,' + picture}}/>
    }
    return (
        // added scroll view for device compatability
        <ScrollView scrollEnabled={true}>
        <SafeAreaView style={ [styles.screen, {flexDirection:"column"}] }>
            <Text style={ [styles.title, {color: colors.text}] }>Edit Your Profile</Text>
            <View style={ styles.profilePosition }>
                {imageComponent}
                {/* <Image style={ styles.profileSize } defaultSource={Logo} source={{uri: 'data:image/jpeg;base64,' + picture}} />*/}
            </View>
            <Text style={ [styles.subtitle, {color: colors.text}] }>Age in years:</Text>
            <TextInput placeholder = "20" style={ [styles.input, {color: colors.text}] } onChangeText={(age) => setAge(age)} />
            <Text style={ [styles.subtitle, {color: colors.text}] }>Height in inches:</Text>
            <TextInput placeholder = "71" style={ [styles.input, {color: colors.text}] } onChangeText={(height) => setHeight(height)} />
            <Text style={ [styles.subtitle, {color: colors.text}] }>Weight in pounds:</Text>
            <TextInput placeholder = "150" style={ [styles.input, {color: colors.text}] } onChangeText={(weight) => setWeight(weight)} />
            <Text style={ [styles.subtitle, {color: colors.text}] }>Gender as male, female, or other:</Text>
            <TextInput placeholder = "male" style={ [styles.input, {color: colors.text}] } onChangeText={(gender) => setGender(gender)} />
            <Text style={ [styles.subtitle, {color: colors.text}] }>Enter your Level:</Text>
            <View>
                <SelectMultiple
                    items={levels}
                    selectedItems={selections}
                    onSelectionsChange={onSelectionsChange}
                    labelStyle={{ color: colors.text}}
                    rowStyle={{ backgroundColor: 'white'}}
                    checkboxStyle={{ backgroundColor: "#f0b543", borderRadius: 10 }}
                />
            </View>
            <View style={{flexDirection: "row"}}>
                <Button style={ styles.saveButton } onPress={() =>  selectPicture() }>
                    <Text style={ styles.saveText }>Change Picture</Text>
                </Button>
            </View>
            <Button style={ styles.saveButton } onPress={postEditProfile}>
                    <Text style={ styles.saveText } >Save</Text>
            </Button>
        </SafeAreaView>
        </ScrollView>
    );
}

const styles = StyleSheet.create({
    screen:{
        marginTop: "20%",
        paddingLeft: "5%",
        paddingRight: "5%",
        paddingBottom: "30%",
        marginLeft: "10%",
        marginRight: "10%"
    },
    profilePosition: {
        paddingTop: "12%",
        marginBottom: "5%",
        alignItems: "center"
    },
    profileSize: {
        marginTop: "5%",
        aspectRatio: 1,
        width: 100,
        height: 100,
    },
    title: {
        fontSize: 25,
        fontWeight: "bold",
        marginTop: "10%",
        paddingBottom: "20%",
        textAlign:"center"
    },
    subtitle: {
        fontSize: 16,
        textAlign:"left",
        fontWeight: "bold",
        color: '#5c5a55'
    },
    input: {
        width: "100%",
        height: 40,
        borderBottomWidth: 1
    },
    saveButton: {
        width: '100%',
        justifyContent: 'center',
        backgroundColor: "#d4911c",
        borderRadius: 10,
        alignItems: "center",
        marginBottom: 10,
        marginTop: 50
    },
    saveText: {
        fontSize: 16,
        fontWeight: "bold",
        color: "white"
    },
});

export default EditProfile;