Finish update profile view
This commit is contained in:
5
App.js
5
App.js
@@ -21,6 +21,7 @@ import NewPostView from './Views/NewPost.js';
|
||||
import { TouchableOpacity, View } from 'react-native';
|
||||
import MenuView from './Views/Menu.js';
|
||||
import ProfileSettings from './Views/ProfileSettings.js';
|
||||
import InviteView from './Views/Invite.js';
|
||||
|
||||
|
||||
const Tab = createBottomTabNavigator();
|
||||
@@ -255,6 +256,10 @@ export default function App() {
|
||||
name="ProfileSettings"
|
||||
component={ProfileSettings}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="Invite"
|
||||
component={InviteView}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="Notifications"
|
||||
component={NotificationsView}
|
||||
|
||||
42
Views/Invite.js
Normal file
42
Views/Invite.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import React from "react";
|
||||
import { View, ImageBackground } from "react-native";
|
||||
import { Text, TextInput, Button, Divider, Checkbox } from "react-native-paper";
|
||||
import i18n from "../i18nMessages.js";
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
|
||||
|
||||
let InviteView = ()=>{
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const viewer = gState.me;
|
||||
return (
|
||||
<View style={{
|
||||
padding: 10,
|
||||
height: "100%"
|
||||
}}>
|
||||
<ImageBackground source={require("../assets/Invite.png")}
|
||||
style={{paddingTop:10, flex:1, opacity:1}}
|
||||
imageStyle={{resizeMode:"contain", opacity: 0.05}}
|
||||
>
|
||||
<Text style={{marginBottom:10, fontSize:20}}>{i18n.t("message.invite")}</Text>
|
||||
<TextInput
|
||||
label={i18n.t("message.name")}
|
||||
style={{backgroundColor:"rgba(0,0,0,0)"}}
|
||||
value={''}
|
||||
//onChangeText={text => setText(text)}
|
||||
/>
|
||||
<TextInput
|
||||
label={i18n.t("message.email")}
|
||||
style={{backgroundColor:"rgba(0,0,0,0)"}}
|
||||
value={''}
|
||||
//onChangeText={text => setText(text)}
|
||||
/>
|
||||
<Checkbox.Item label={i18n.t("message.IKnowThisPerson")} status="checked" />
|
||||
<Divider />
|
||||
<Button mode="outlined">Invite</Button>
|
||||
</ImageBackground>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default InviteView;
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { View, ImageBackground } from "react-native";
|
||||
import { Text, List, RadioButton } from "react-native-paper";
|
||||
import i18n from "../i18nMessages.js";
|
||||
import Moment from 'moment';
|
||||
@@ -18,12 +18,17 @@ let MenuView = ({navigation})=>{
|
||||
|
||||
return (
|
||||
<View>
|
||||
<ImageBackground source={require("../assets/settings.png")}
|
||||
style={{paddingTop:10}}
|
||||
imageStyle={{resizeMode:"contain", opacity: 0.05}}
|
||||
>
|
||||
<List.Section title="User Actions">
|
||||
<List.Item title="Profile" onPress={()=>{navigation.navigate("ProfileSettings")}} left={props => <List.Icon {...props} icon="person" />} />
|
||||
<List.Item title="Settings" left={props => <List.Icon {...props} icon="settings" />} />
|
||||
<List.Item title="Sign out" left={props => <List.Icon {...props} icon="logout" />} />
|
||||
</List.Section>
|
||||
<List.Section title="Fellowship App">
|
||||
<List.Item title="Invite" onPress={()=>{navigation.navigate("Invite")}} left={props => <List.Icon {...props} icon="person-add" />} />
|
||||
<List.Item title="About" left={props => <List.Icon {...props} icon="more" />} />
|
||||
</List.Section>
|
||||
<View style={{padding: 10}}>
|
||||
@@ -33,6 +38,7 @@ let MenuView = ({navigation})=>{
|
||||
<RadioButton.Item value="en" label="English"/>
|
||||
</RadioButton.Group>
|
||||
</View>
|
||||
</ImageBackground>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { Text, TextInput, RadioButton, Divider } from "react-native-paper";
|
||||
import { View, ImageBackground, ScrollView } from "react-native";
|
||||
import { Text, TextInput, Button, Divider } from "react-native-paper";
|
||||
import i18n from "../i18nMessages.js";
|
||||
import Moment from 'moment';
|
||||
import 'moment/min/locales';
|
||||
@@ -8,43 +8,126 @@ import ProfileCardHorizontal from "../components/ProfileCardHorizontal.js";
|
||||
Moment.locale(i18n.locale);
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
import API from "../API.js";
|
||||
import ProfileHeader from "../components/ProfileHeader.js";
|
||||
import * as ImagePicker from 'expo-image-picker';
|
||||
|
||||
|
||||
|
||||
let ProfileSettings = ()=>{
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const viewer = gState.me;
|
||||
const [photo, setPhoto] = React.useState(null);
|
||||
const [name, setName] = React.useState(viewer.profile.firstName);
|
||||
const [lastName, setLastName] = React.useState(viewer.profile.lastName);
|
||||
const [photoUrl, setphotoUrl] = React.useState(viewer.profile.photo);
|
||||
const [updateKey, setUpdateKey] = React.useState(0);
|
||||
const [description, setDescription] = React.useState(viewer.profile.description);
|
||||
|
||||
const pickImage = async () => {
|
||||
// No permissions request is necessary for launching the image library
|
||||
let result = await ImagePicker.launchImageLibraryAsync({
|
||||
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||
allowsEditing: true,
|
||||
aspect: [4, 3],
|
||||
quality: 0.7,
|
||||
//allowsMultipleSelection: true,
|
||||
});
|
||||
if (!result.cancelled) {
|
||||
setPhoto(result);
|
||||
let newPhotoURL = await handleUploadPhoto(result);
|
||||
if(newPhotoURL !== ""){
|
||||
setphotoUrl(newPhotoURL);
|
||||
GlobalState.me.profile.photo = newPhotoURL;
|
||||
setUpdateKey(updateKey+1);
|
||||
}
|
||||
setPhoto(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUploadPhoto = async (photo) => {
|
||||
if (!photo) return;
|
||||
const uri =
|
||||
Platform.OS === "android"
|
||||
? photo.uri
|
||||
: photo.uri.replace("file://", "");
|
||||
const filename = photo.uri.split("/").pop();
|
||||
const match = /\.(\w+)$/.exec(filename);
|
||||
const ext = match?.[1];
|
||||
const type = match ? `image/${match[1]}` : `image`;
|
||||
const formData = new FormData();
|
||||
formData.append("banner", {
|
||||
uri,
|
||||
name: `image.${ext}`,
|
||||
type,
|
||||
});
|
||||
let uploadedFile = '';
|
||||
try {
|
||||
uploadedFile = await fetch("https://social.emmint.com/upload.php", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: { "Content-Type": "multipart/form-data" }
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
return data.fileName;
|
||||
})
|
||||
.catch((err) => console.error(err));
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
alert("Something went wrong");
|
||||
}
|
||||
return uploadedFile;
|
||||
};
|
||||
|
||||
let updateProfile = () => {
|
||||
GlobalState.me.profile.firstName = name;
|
||||
GlobalState.me.profile.lastName = lastName;
|
||||
GlobalState.me.profile.description = description;
|
||||
API.updateMyProfile(viewer.profile, viewer.data);
|
||||
setUpdateKey(updateKey+1);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{
|
||||
padding: 10
|
||||
<ScrollView style={{
|
||||
padding: 10,
|
||||
}}>
|
||||
<ImageBackground source={require("../assets/settings.png")}
|
||||
imageStyle={{resizeMode:"contain", opacity: 0.05}}
|
||||
style={{paddingBottom: 50}}
|
||||
>
|
||||
<Text style={{marginBottom:10, fontSize:20}}>Profile Settings</Text>
|
||||
<View style={{flexDirection:"row", justifyContent:"space-between"}}>
|
||||
<TextInput
|
||||
label="First Name"
|
||||
label={i18n.t("message.name")}
|
||||
style={{width:"48%", backgroundColor:"rgba(0,0,0,0)"}}
|
||||
value={gState.me.profile.firstName}
|
||||
//onChangeText={text => setText(text)}
|
||||
value={name}
|
||||
onChangeText={text => setName(text)}
|
||||
/>
|
||||
<TextInput
|
||||
label="Last Name"
|
||||
label={i18n.t("message.lastName")}
|
||||
style={{width:"48%", backgroundColor:"rgba(0,0,0,0)"}}
|
||||
value={gState.me.profile.lastName}
|
||||
//onChangeText={text => setText(text)}
|
||||
value={lastName}
|
||||
onChangeText={text => setLastName(text)}
|
||||
/>
|
||||
</View>
|
||||
<TextInput
|
||||
label="Description"
|
||||
style={{backgroundColor:"rgba(0,0,0,0)"}}
|
||||
label={i18n.t("message.description")}
|
||||
style={{backgroundColor:"rgba(0,0,0,0)", marginBottom:5}}
|
||||
multiline={true}
|
||||
numberOfLines={3}
|
||||
value={gState.me.profile.description}
|
||||
//onChangeText={text => setText(text)}
|
||||
value={description}
|
||||
onChangeText={text => setDescription(text)}
|
||||
/>
|
||||
<Button icon="photo" mode="outlined" onPress={pickImage} >Update Photo</Button>
|
||||
<Divider />
|
||||
<View style={{paddingTop: 10}}>
|
||||
<ProfileCardHorizontal profileObj={gState.me} skipFollow={true} skiptOnPress={true} />
|
||||
</View>
|
||||
<Text style={{fontSize:20, padding: 5, color:"#666"}}>Preview:</Text>
|
||||
<ProfileCardHorizontal profileObj={GlobalState.me} skipFollow={true} skiptOnPress={true} key={updateKey} />
|
||||
</View>
|
||||
<Button mode="outlined" onPress={updateProfile}>{i18n.t("message.update")}</Button>
|
||||
</ImageBackground>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import API from "../API";
|
||||
import ProfileCardHorizontal from "../components/ProfileCardHorizontal";
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
import ProfileHeader from "../components/ProfileHeader";
|
||||
|
||||
const Search = () => {
|
||||
const viewer = useSnapshot(GlobalState).me;
|
||||
|
||||
BIN
assets/Invite.png
Normal file
BIN
assets/Invite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
BIN
assets/settings.png
Normal file
BIN
assets/settings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { Avatar, Button, Card, Title, Paragraph } from 'react-native-paper';
|
||||
import UserName from './UserName';
|
||||
import FollowButton from './basics/FollowButton';
|
||||
@@ -13,11 +13,22 @@ const ProfileHeader = ({ profileObj }) => {
|
||||
<Card elevation={3}>
|
||||
<Card.Cover source={{ uri: photoUrl, cache: 'force-cache' }} />
|
||||
<Card.Content>
|
||||
<Title>
|
||||
<Title style={{position: "absolute", top: -60, left: 10, backgroundColor: "rgba(255,255,255,0.4)", padding: 10}}>
|
||||
<UserName profileid={profileObj._id} />
|
||||
</Title>
|
||||
<Paragraph>{profileObj.profile.description}</Paragraph>
|
||||
<Paragraph style={{paddingTop:10}}>{profileObj.profile.description}</Paragraph>
|
||||
<View style={{
|
||||
position: "absolute",
|
||||
top: -190,
|
||||
right: 10,
|
||||
width: 50,
|
||||
height: 50,
|
||||
backgroundColor: "#ddd",
|
||||
borderRadius: 25,
|
||||
opacity: 0.7
|
||||
}}>
|
||||
<FollowButton profile={profileObj} />
|
||||
</View>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
{/*
|
||||
|
||||
@@ -60,7 +60,10 @@ const messages = {
|
||||
searchCourses: "Search Courses",
|
||||
news: "News",
|
||||
wrongInformation: "Please review the information.",
|
||||
submit: "Submit"
|
||||
submit: "Submit",
|
||||
IKnowThisPerson: "I know this person",
|
||||
update: "Update",
|
||||
|
||||
},
|
||||
},
|
||||
es: {
|
||||
@@ -120,6 +123,8 @@ const messages = {
|
||||
news: "Noticias",
|
||||
wrongInformation: "Por favor revisa la información introducida.",
|
||||
submit: "Ingresar",
|
||||
IKnowThisPerson: "Conozco a esta persona",
|
||||
update: "Actualizar",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user