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 { TouchableOpacity, View } from 'react-native';
|
||||||
import MenuView from './Views/Menu.js';
|
import MenuView from './Views/Menu.js';
|
||||||
import ProfileSettings from './Views/ProfileSettings.js';
|
import ProfileSettings from './Views/ProfileSettings.js';
|
||||||
|
import InviteView from './Views/Invite.js';
|
||||||
|
|
||||||
|
|
||||||
const Tab = createBottomTabNavigator();
|
const Tab = createBottomTabNavigator();
|
||||||
@@ -255,6 +256,10 @@ export default function App() {
|
|||||||
name="ProfileSettings"
|
name="ProfileSettings"
|
||||||
component={ProfileSettings}
|
component={ProfileSettings}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Invite"
|
||||||
|
component={InviteView}
|
||||||
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="Notifications"
|
name="Notifications"
|
||||||
component={NotificationsView}
|
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 React from "react";
|
||||||
import { View } from "react-native";
|
import { View, ImageBackground } from "react-native";
|
||||||
import { Text, List, RadioButton } from "react-native-paper";
|
import { Text, List, RadioButton } from "react-native-paper";
|
||||||
import i18n from "../i18nMessages.js";
|
import i18n from "../i18nMessages.js";
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
@@ -18,12 +18,17 @@ let MenuView = ({navigation})=>{
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
|
<ImageBackground source={require("../assets/settings.png")}
|
||||||
|
style={{paddingTop:10}}
|
||||||
|
imageStyle={{resizeMode:"contain", opacity: 0.05}}
|
||||||
|
>
|
||||||
<List.Section title="User Actions">
|
<List.Section title="User Actions">
|
||||||
<List.Item title="Profile" onPress={()=>{navigation.navigate("ProfileSettings")}} left={props => <List.Icon {...props} icon="person" />} />
|
<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="Settings" left={props => <List.Icon {...props} icon="settings" />} />
|
||||||
<List.Item title="Sign out" left={props => <List.Icon {...props} icon="logout" />} />
|
<List.Item title="Sign out" left={props => <List.Icon {...props} icon="logout" />} />
|
||||||
</List.Section>
|
</List.Section>
|
||||||
<List.Section title="Fellowship App">
|
<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.Item title="About" left={props => <List.Icon {...props} icon="more" />} />
|
||||||
</List.Section>
|
</List.Section>
|
||||||
<View style={{padding: 10}}>
|
<View style={{padding: 10}}>
|
||||||
@@ -33,6 +38,7 @@ let MenuView = ({navigation})=>{
|
|||||||
<RadioButton.Item value="en" label="English"/>
|
<RadioButton.Item value="en" label="English"/>
|
||||||
</RadioButton.Group>
|
</RadioButton.Group>
|
||||||
</View>
|
</View>
|
||||||
|
</ImageBackground>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { View } from "react-native";
|
import { View, ImageBackground, ScrollView } from "react-native";
|
||||||
import { Text, TextInput, RadioButton, Divider } from "react-native-paper";
|
import { Text, TextInput, Button, Divider } from "react-native-paper";
|
||||||
import i18n from "../i18nMessages.js";
|
import i18n from "../i18nMessages.js";
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
import 'moment/min/locales';
|
import 'moment/min/locales';
|
||||||
@@ -8,43 +8,126 @@ import ProfileCardHorizontal from "../components/ProfileCardHorizontal.js";
|
|||||||
Moment.locale(i18n.locale);
|
Moment.locale(i18n.locale);
|
||||||
import { useSnapshot } from 'valtio';
|
import { useSnapshot } from 'valtio';
|
||||||
import GlobalState from '../contexts/GlobalState.js';
|
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 = ()=>{
|
let ProfileSettings = ()=>{
|
||||||
const gState = useSnapshot(GlobalState);
|
const gState = useSnapshot(GlobalState);
|
||||||
const viewer = gState.me;
|
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 (
|
return (
|
||||||
<View style={{
|
<ScrollView style={{
|
||||||
padding: 10
|
padding: 10,
|
||||||
}}>
|
}}>
|
||||||
<Text style={{marginBottom:10, fontSize:20}}>Profile Settings</Text>
|
<ImageBackground source={require("../assets/settings.png")}
|
||||||
<View style={{flexDirection:"row", justifyContent:"space-between"}}>
|
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={i18n.t("message.name")}
|
||||||
|
style={{width:"48%", backgroundColor:"rgba(0,0,0,0)"}}
|
||||||
|
value={name}
|
||||||
|
onChangeText={text => setName(text)}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label={i18n.t("message.lastName")}
|
||||||
|
style={{width:"48%", backgroundColor:"rgba(0,0,0,0)"}}
|
||||||
|
value={lastName}
|
||||||
|
onChangeText={text => setLastName(text)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
<TextInput
|
<TextInput
|
||||||
label="First Name"
|
label={i18n.t("message.description")}
|
||||||
style={{width:"48%", backgroundColor:"rgba(0,0,0,0)"}}
|
style={{backgroundColor:"rgba(0,0,0,0)", marginBottom:5}}
|
||||||
value={gState.me.profile.firstName}
|
multiline={true}
|
||||||
//onChangeText={text => setText(text)}
|
numberOfLines={3}
|
||||||
|
value={description}
|
||||||
|
onChangeText={text => setDescription(text)}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<Button icon="photo" mode="outlined" onPress={pickImage} >Update Photo</Button>
|
||||||
label="Last Name"
|
<Divider />
|
||||||
style={{width:"48%", backgroundColor:"rgba(0,0,0,0)"}}
|
<View style={{paddingTop: 10}}>
|
||||||
value={gState.me.profile.lastName}
|
<Text style={{fontSize:20, padding: 5, color:"#666"}}>Preview:</Text>
|
||||||
//onChangeText={text => setText(text)}
|
<ProfileCardHorizontal profileObj={GlobalState.me} skipFollow={true} skiptOnPress={true} key={updateKey} />
|
||||||
/>
|
</View>
|
||||||
</View>
|
<Button mode="outlined" onPress={updateProfile}>{i18n.t("message.update")}</Button>
|
||||||
<TextInput
|
</ImageBackground>
|
||||||
label="Description"
|
</ScrollView>
|
||||||
style={{backgroundColor:"rgba(0,0,0,0)"}}
|
|
||||||
multiline={true}
|
|
||||||
numberOfLines={3}
|
|
||||||
value={gState.me.profile.description}
|
|
||||||
//onChangeText={text => setText(text)}
|
|
||||||
/>
|
|
||||||
<Divider />
|
|
||||||
<View style={{paddingTop: 10}}>
|
|
||||||
<ProfileCardHorizontal profileObj={gState.me} skipFollow={true} skiptOnPress={true} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import API from "../API";
|
|||||||
import ProfileCardHorizontal from "../components/ProfileCardHorizontal";
|
import ProfileCardHorizontal from "../components/ProfileCardHorizontal";
|
||||||
import { useSnapshot } from 'valtio';
|
import { useSnapshot } from 'valtio';
|
||||||
import GlobalState from '../contexts/GlobalState.js';
|
import GlobalState from '../contexts/GlobalState.js';
|
||||||
|
import ProfileHeader from "../components/ProfileHeader";
|
||||||
|
|
||||||
const Search = () => {
|
const Search = () => {
|
||||||
const viewer = useSnapshot(GlobalState).me;
|
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 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 { Avatar, Button, Card, Title, Paragraph } from 'react-native-paper';
|
||||||
import UserName from './UserName';
|
import UserName from './UserName';
|
||||||
import FollowButton from './basics/FollowButton';
|
import FollowButton from './basics/FollowButton';
|
||||||
@@ -13,11 +13,22 @@ const ProfileHeader = ({ profileObj }) => {
|
|||||||
<Card elevation={3}>
|
<Card elevation={3}>
|
||||||
<Card.Cover source={{ uri: photoUrl, cache: 'force-cache' }} />
|
<Card.Cover source={{ uri: photoUrl, cache: 'force-cache' }} />
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<Title>
|
<Title style={{position: "absolute", top: -60, left: 10, backgroundColor: "rgba(255,255,255,0.4)", padding: 10}}>
|
||||||
<UserName profileid={profileObj._id} />
|
<UserName profileid={profileObj._id} />
|
||||||
</Title>
|
</Title>
|
||||||
<Paragraph>{profileObj.profile.description}</Paragraph>
|
<Paragraph style={{paddingTop:10}}>{profileObj.profile.description}</Paragraph>
|
||||||
<FollowButton profile={profileObj} />
|
<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.Content>
|
||||||
</Card>
|
</Card>
|
||||||
{/*
|
{/*
|
||||||
|
|||||||
@@ -60,7 +60,10 @@ const messages = {
|
|||||||
searchCourses: "Search Courses",
|
searchCourses: "Search Courses",
|
||||||
news: "News",
|
news: "News",
|
||||||
wrongInformation: "Please review the information.",
|
wrongInformation: "Please review the information.",
|
||||||
submit: "Submit"
|
submit: "Submit",
|
||||||
|
IKnowThisPerson: "I know this person",
|
||||||
|
update: "Update",
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
es: {
|
es: {
|
||||||
@@ -120,6 +123,8 @@ const messages = {
|
|||||||
news: "Noticias",
|
news: "Noticias",
|
||||||
wrongInformation: "Por favor revisa la información introducida.",
|
wrongInformation: "Por favor revisa la información introducida.",
|
||||||
submit: "Ingresar",
|
submit: "Ingresar",
|
||||||
|
IKnowThisPerson: "Conozco a esta persona",
|
||||||
|
update: "Actualizar",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user