mirror of
https://bitbucket.org/tagfer_team/tagfer-app.git
synced 2025-12-25 03:37:41 +00:00
UPS8-View own profile
This commit is contained in:
parent
6fd3cc46de
commit
f30b457e48
@ -21,7 +21,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3</string>
|
||||
<string>5</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
"dependencies": {
|
||||
"acorn": "^6.0.4",
|
||||
"i18n-js": "^3.1.0",
|
||||
"moment": "^2.24.0",
|
||||
"react": "16.6.3",
|
||||
"react-native": "0.57.8",
|
||||
"react-native-app-settings": "^2.0.1",
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import EventsScreen from '../../screens/events/EventsScreen';
|
||||
import ConnectScreen from '../../screens/connections/ConnectScreen';
|
||||
import MessagesScreen from '../../screens/messages/MessagesScreen';
|
||||
import ProfileScreen from '../../screens/profile/ProfileScreen';
|
||||
|
||||
import BottomTabNavigator from './BottomTabNavigator';
|
||||
import TopStackNavigator from './TopStackNavigator';
|
||||
import ContactsTabNavigator from './ContactsTabNavigator';
|
||||
import ProfileTabNavigator from './ProfileTabNavigator';
|
||||
|
||||
const ConnectionsStack = TopStackNavigator({
|
||||
connect: ConnectScreen
|
||||
@ -15,10 +15,14 @@ const ContactsStack = TopStackNavigator({
|
||||
contcats: ContactsTabNavigator
|
||||
});
|
||||
|
||||
const ProfileStack = TopStackNavigator({
|
||||
profile: ProfileTabNavigator
|
||||
});
|
||||
|
||||
export default BottomTabNavigator({
|
||||
Events: EventsScreen,
|
||||
Contacts: ContactsStack,
|
||||
Connections: ConnectionsStack,
|
||||
Messages: MessagesScreen,
|
||||
Profile: ProfileScreen
|
||||
Profile: ProfileStack
|
||||
});
|
||||
|
||||
37
src/components/navigators/ProfileTabNavigator.js
Normal file
37
src/components/navigators/ProfileTabNavigator.js
Normal file
@ -0,0 +1,37 @@
|
||||
import { createMaterialTopTabNavigator } from 'react-navigation';
|
||||
|
||||
import ProfileScreen from '../../screens/profile/ProfileScreen';
|
||||
import EventsScreen from '../../screens/profile/EventsScreen';
|
||||
|
||||
const profileTabBarOptions = {
|
||||
upperCaseLabel: false,
|
||||
activeTintColor: 'white',
|
||||
inactiveTintColor: '#53ACF0',
|
||||
lazy: true,
|
||||
labelStyle: {
|
||||
margin: 1,
|
||||
fontSize: 13,
|
||||
},
|
||||
tabStyle: {
|
||||
borderColor: '#53ACF0',
|
||||
borderWidth: 1,
|
||||
padding: 5
|
||||
},
|
||||
indicatorStyle: {
|
||||
backgroundColor: '#53ACF0',
|
||||
bottom: 0,
|
||||
height: 50,
|
||||
},
|
||||
style: {
|
||||
backgroundColor: 'transparent',
|
||||
}
|
||||
};
|
||||
|
||||
export default createMaterialTopTabNavigator(
|
||||
{
|
||||
'Basic Info': ProfileScreen,
|
||||
Events: EventsScreen
|
||||
},
|
||||
{
|
||||
tabBarOptions: profileTabBarOptions
|
||||
});
|
||||
84
src/components/profile/ActionBar.js
Normal file
84
src/components/profile/ActionBar.js
Normal file
@ -0,0 +1,84 @@
|
||||
import React from 'react';
|
||||
import { View, Text, TouchableOpacity } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
|
||||
const ActionBar = ({ status, isSelf }) => {
|
||||
if (isSelf) { return null; }
|
||||
if (status === 'connected') { return <ConnectedBar />; }
|
||||
if (status === 'pending') { return <NotConnectedBar isPending />; }
|
||||
|
||||
return <NotConnectedBar />;
|
||||
};
|
||||
|
||||
const NotConnectedBar = ({ isPending }) => (
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-around', marginTop: 20, backgroundColor: '#F5F8FA' }}>
|
||||
<TouchableOpacity style={styles.actionBtn}>
|
||||
<Icon type='material-community' name='share' color='#53ACF0' />
|
||||
<Text style={styles.actionBtnTitle}>Share</Text>
|
||||
</TouchableOpacity>
|
||||
{isPending ? <PendingBtn /> : <ConnectBtn />}
|
||||
<TouchableOpacity style={styles.actionBtn}>
|
||||
<Icon type='material-community' name='qrcode' color='#53ACF0' />
|
||||
<Text style={styles.actionBtnTitle}>QR Code</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const ConnectedBar = () => (
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'center', marginTop: 20, borderWidth: 0.5, borderColor: '#E0E3EF' }}>
|
||||
<TouchableOpacity style={styles.connectedBtns}>
|
||||
<Icon type='material' name='call' color='#008A1C' size={32} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.connectedBtns}>
|
||||
<Icon type='material-community' name='share' color='#53ACF0' size={32} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.connectedBtns}>
|
||||
<Icon type='material-community' name='message-text' color='#0462AA' size={32} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.connectedBtns}>
|
||||
<Icon type='material-community' name='file-document' color='#F3DD0F' size={32} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const PendingBtn = () => (
|
||||
<TouchableOpacity style={styles.actionBtn}>
|
||||
<Icon type='material' name='person-add' color='#008A1C' />
|
||||
<Text style={styles.pedningBtnTitle}>Pending</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
const ConnectBtn = () => (
|
||||
<TouchableOpacity style={styles.actionBtn}>
|
||||
<Icon type='material' name='person-add' color='#53ACF0' />
|
||||
<Text style={styles.actionBtnTitle}>Connect</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
const styles = {
|
||||
actionBtn: {
|
||||
flex: 1,
|
||||
paddingVertical: 6,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderWidth: 0.5,
|
||||
borderColor: '#E0E3EF',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
actionBtnTitle: {
|
||||
marginLeft: 7,
|
||||
color: '#53ACF0',
|
||||
fontSize: 14
|
||||
},
|
||||
pedningBtnTitle: {
|
||||
marginLeft: 7,
|
||||
color: '#008A1C',
|
||||
fontSize: 14
|
||||
},
|
||||
connectedBtns: {
|
||||
marginHorizontal: 15,
|
||||
marginVertical: 5
|
||||
}
|
||||
};
|
||||
|
||||
export default ActionBar;
|
||||
11
src/components/profile/EditButton.js
Normal file
11
src/components/profile/EditButton.js
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { TouchableOpacity } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
|
||||
const EditButton = ({ size }) => (
|
||||
<TouchableOpacity style={{ alignItems: 'flex-end' }}>
|
||||
<Icon name='mode-edit' color='#2B3550' size={size || 20} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
export default EditButton;
|
||||
25
src/components/profile/InfoBar.js
Normal file
25
src/components/profile/InfoBar.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
|
||||
const InfoBar = ({ numOfContacts, numOfRecs }) => (
|
||||
<View style={{ flexDirection: 'row', borderWidth: 0.5, borderColor: '#E0E3EF' }}>
|
||||
<View style={{ flex: 2, alignItems: 'flex-start', paddingVertical: 10, paddingLeft: 5, borderWidth: 0.5, borderColor: '#E0E3EF' }}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Icon name='star-circle' type='material-community' color='#FFD166' size={17} />
|
||||
<Text style={{ marginLeft: 3 }}>Tagfer Top Networker</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Icon name='md-ribbon' type='ionicon' color='#36CCDA' size={20} />
|
||||
<Text style={{ marginLeft: 5 }}>{numOfRecs} Recommendations</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', borderWidth: 0.5, borderColor: '#E0E3EF', paddingVertical: 10 }}>
|
||||
<Text style={{ fontSize: 18, fontWeight: '600' }}>{numOfContacts}</Text>
|
||||
<Text style={{ fontSize: 15, color: '#535353' }}>Contacts</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default InfoBar;
|
||||
196
src/components/profile/MainContent.js
Normal file
196
src/components/profile/MainContent.js
Normal file
@ -0,0 +1,196 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { View, Text, Linking, Platform } from 'react-native';
|
||||
import { Icon, Divider } from 'react-native-elements';
|
||||
import EditButton from './EditButton';
|
||||
|
||||
const MainContent = ({ about, help, need, experienceList, educationList, contact, canEdit }) => {
|
||||
const contactsList = createContactsList(contact);
|
||||
|
||||
return (
|
||||
<View style={{ height: '100%', backgroundColor: '#F5F8FA', alignItems: 'center', paddingVertical: 15 }}>
|
||||
{/* ABOUT SECTION */}
|
||||
{renderSingleSection('About', about, canEdit)}
|
||||
|
||||
{/* HELP SECTION */}
|
||||
{renderSingleSection('How can you help your contacts?', help, canEdit)}
|
||||
|
||||
{/* NEED SECTION */}
|
||||
{renderSingleSection('What do you need?', need, canEdit)}
|
||||
|
||||
{/* EXPERIENCE SECTION */}
|
||||
{renderMultipleSections('Experience', experienceList, (e) => <ExperienceBody experience={e} />, canEdit)}
|
||||
|
||||
{/* EDUCATION SECTION */}
|
||||
{renderMultipleSections('Education', educationList, (e) => <EducationBody education={e} />, canEdit)}
|
||||
|
||||
{/* CONTACT SECTION */}
|
||||
{renderMultipleSections('Contact', contactsList, (c) => <ContactBody contact={c} />, canEdit)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
function renderSingleSection(title, body, canEdit) {
|
||||
if (body) {
|
||||
return (
|
||||
<Card title={title}>
|
||||
<Section addEdit={canEdit}>
|
||||
<Text>{body}</Text>
|
||||
</Section>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderMultipleSections(title, list, renderBody, canEdit) {
|
||||
const length = list.length;
|
||||
if (length === 0) { return null; }
|
||||
|
||||
const sections = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
const addDivider = i !== length - 1;
|
||||
const section = (
|
||||
<Section key={i} addEdit={canEdit} addDivider={addDivider}>
|
||||
{renderBody(list[i])}
|
||||
</Section>
|
||||
);
|
||||
sections.push(section);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card title={title}>
|
||||
{sections}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
const ExperienceBody = ({ experience }) => {
|
||||
const { jobTitle, companyName, companyLocation, startDate, endDate, summary } = experience;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text>{jobTitle} at {companyName}</Text>
|
||||
<Text>{companyLocation}</Text>
|
||||
<Duration startDate={startDate} endDate={endDate} />
|
||||
<Text style={{ marginTop: 10 }}>{summary}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const EducationBody = ({ education }) => {
|
||||
const { school, degree, study, startDate, endDate, summary } = education;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text>{degree} at {school}</Text>
|
||||
<Text>{study}</Text>
|
||||
<Duration startDate={startDate} endDate={endDate} />
|
||||
<Text style={{ marginTop: 10 }}>{summary}</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const ContactBody = ({ contact }) => {
|
||||
const { iconName, contactType, contactValue, linkTo } = contact;
|
||||
|
||||
return (
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Icon name={iconName} />
|
||||
<View style={{ flexDirection: 'column', marginLeft: 15 }}>
|
||||
<Text style={{ fontSize: 15, marginBottom: 3 }}>{contactType}</Text>
|
||||
<Text style={{ color: '#0462AA' }} onPress={() => linkTo(contactValue)} >{contactValue}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const Duration = ({ startDate, endDate }) => {
|
||||
if (!startDate && !endDate) { return null; }
|
||||
const start = moment(startDate).format('MMMM YYYY');
|
||||
const end = endDate === -1 ? 'Present' : moment(endDate).format('MMMM YYYY');
|
||||
|
||||
return (
|
||||
<Text style={{ color: '#535353' }}>{start} - {end}</Text>
|
||||
);
|
||||
};
|
||||
|
||||
const Card = ({ title, children }) => (
|
||||
<View style={styles.card}>
|
||||
<Text style={{ color: '#2B3550', fontSize: 17, fontWeight: '500' }}>{title}</Text>
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
const Section = ({ children, addDivider, addEdit }) => (
|
||||
<View>
|
||||
{addEdit ? <EditButton /> : <View style={{ marginTop: 10 }} />}
|
||||
{children}
|
||||
{addDivider ? <Divider style={{ marginVertical: 10 }} /> : null}
|
||||
</View>
|
||||
);
|
||||
|
||||
function openEmail(email) {
|
||||
return Linking.canOpenURL(`mailto:${email}`).then(supported => {
|
||||
if (supported) {
|
||||
Linking.openURL(`mailto:${email}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openPhone(phoneNumber) {
|
||||
return Linking.canOpenURL(`tel:${phoneNumber}`).then(supported => {
|
||||
if (supported) {
|
||||
Linking.openURL(`tel:${phoneNumber}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createContactsList(contact = {}) {
|
||||
const phoneNumber = {
|
||||
iconName: 'phone',
|
||||
contactType: 'Phone Number',
|
||||
contactValue: contact.phoneNumber,
|
||||
linkTo: openPhone
|
||||
};
|
||||
const email = {
|
||||
iconName: 'email',
|
||||
contactType: 'Email',
|
||||
contactValue: contact.email,
|
||||
linkTo: openEmail
|
||||
};
|
||||
const contacts = [];
|
||||
if (contact.email) {
|
||||
contacts.push(email);
|
||||
}
|
||||
|
||||
if (contact.phoneNumber) {
|
||||
contacts.push(phoneNumber);
|
||||
}
|
||||
|
||||
return contacts;
|
||||
}
|
||||
|
||||
const styles = {
|
||||
card: {
|
||||
width: '95%',
|
||||
padding: 10,
|
||||
margin: 5,
|
||||
borderWidth: 0.3,
|
||||
borderColor: '#e1e8ee',
|
||||
...Platform.select({
|
||||
android: {
|
||||
elevation: 1,
|
||||
},
|
||||
default: {
|
||||
shadowColor: 'rgba(0,0,0, .2)',
|
||||
shadowOffset: { height: 0, width: 0 },
|
||||
shadowOpacity: 1,
|
||||
shadowRadius: 1,
|
||||
},
|
||||
}),
|
||||
backgroundColor: 'white'
|
||||
}
|
||||
};
|
||||
|
||||
export default MainContent;
|
||||
28
src/components/profile/OptionsMenu.js
Normal file
28
src/components/profile/OptionsMenu.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { View, TouchableOpacity } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
import Menu, { MenuItem, MenuDivider } from 'react-native-material-menu';
|
||||
|
||||
const OptionsButton = ({ onPress }) => (
|
||||
<TouchableOpacity onPress={onPress} >
|
||||
<Icon type='entypo' name='dots-three-vertical' size={24} iconStyle={{ textAlign: 'left' }} color='#535353' />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
const OptionsMenu = ({ setMenu, showMenu, onPress }) => (
|
||||
<View style={styles.optionsMenu}>
|
||||
<Menu ref={setMenu} button={<OptionsButton onPress={showMenu} />}>
|
||||
<MenuItem onPress={onPress} style={{ height: 50 }}>Show QR Code</MenuItem>
|
||||
<MenuDivider />
|
||||
<MenuItem onPress={onPress} style={{ height: 50 }}>Share Profile</MenuItem>
|
||||
</Menu>
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = {
|
||||
optionsMenu: {
|
||||
marginTop: 10
|
||||
}
|
||||
};
|
||||
|
||||
export default OptionsMenu;
|
||||
82
src/components/profile/ProfileHeader.js
Normal file
82
src/components/profile/ProfileHeader.js
Normal file
@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import { View, ScrollView, Text, Animated, Dimensions } from 'react-native';
|
||||
import { Icon } from 'react-native-elements';
|
||||
|
||||
import TagferAvatar from '../new/TagferAvatar';
|
||||
import EditButton from './EditButton';
|
||||
import OptionsMenu from './OptionsMenu';
|
||||
|
||||
const SCREEN_WIDTH = Dimensions.get('window').width;
|
||||
const SCROLL_X = new Animated.Value(0);
|
||||
|
||||
const ProfileHeader = ({ photoURL, fullName, tagferId, jobTitle, companyName, companyLocation, setOptionsMenu, showOptionsMenu }) => {
|
||||
const onScroll = Animated.event(
|
||||
[{ nativeEvent: { contentOffset: { x: SCROLL_X } } }]
|
||||
);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<ScrollView
|
||||
horizontal
|
||||
pagingEnabled
|
||||
showsHorizontalScrollIndicator={false}
|
||||
onScroll={onScroll}
|
||||
scrollEventThrottle={16}
|
||||
>
|
||||
{/* SWIPE SCREEN 1 */}
|
||||
<View style={{ width: SCREEN_WIDTH }}>
|
||||
{/* BUTTONS SECTION */}
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
||||
<OptionsMenu
|
||||
setMenu={setOptionsMenu}
|
||||
showMenu={showOptionsMenu}
|
||||
/>
|
||||
<View style={{ marginTop: 8, marginRight: 5 }}>
|
||||
<EditButton size={24} />
|
||||
</View>
|
||||
</View>
|
||||
{/* PROFILE CONTENT SECTION */}
|
||||
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<TagferAvatar size='large' color='#53ACF060' photoURL={photoURL} />
|
||||
<Text style={{ fontSize: 22, fontWeight: '600', marginTop: 5 }}>{fullName}</Text>
|
||||
<Text style={{ fontSize: 18, marginBottom: 8, fontWeight: '400' }}>@{tagferId}</Text>
|
||||
<Text style={{ fontSize: 14 }}>{jobTitle} at {companyName}</Text>
|
||||
<Text style={{ fontSize: 14, marginBottom: 20, color: '#535353' }}>{companyLocation}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* SWIPE SCREEN 2 */}
|
||||
<View style={{ width: SCREEN_WIDTH, alignItems: 'center', marginVertical: 10 }}>
|
||||
<Icon type='font-awesome' name='id-card' size={180} color='#53ACF040' />
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
<SwiperDots />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const SwiperDots = () => {
|
||||
const position = Animated.divide(SCROLL_X, SCREEN_WIDTH);
|
||||
const opacity = (i) => position.interpolate({
|
||||
inputRange: [i - 1, i, i + 1],
|
||||
outputRange: [0.3, 1, 0.3],
|
||||
extrapolate: 'clamp'
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}>
|
||||
<Animated.View
|
||||
key={'swiperDot0'}
|
||||
style={{ opacity: opacity(0), height: 7, width: 7, backgroundColor: '#595959', margin: 3, borderRadius: 3 }}
|
||||
/>
|
||||
|
||||
<Animated.View
|
||||
key={'swiperDot1'}
|
||||
style={{ opacity: opacity(1), height: 7, width: 7, backgroundColor: '#595959', margin: 3, borderRadius: 3 }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProfileHeader;
|
||||
@ -1,4 +1,4 @@
|
||||
const baseurl = 'http://localhost:3000';
|
||||
const baseurl = 'https://us-central1-tagfer-inc.cloudfunctions.net/api';
|
||||
const endpoints = {
|
||||
login: {
|
||||
method: 'POST',
|
||||
@ -59,7 +59,23 @@ const endpoints = {
|
||||
getAllConnections: {
|
||||
method: 'GET',
|
||||
url: `${baseurl}/connections/me`
|
||||
}
|
||||
},
|
||||
getProfileSelf: (profileN) => ({
|
||||
method: 'GET',
|
||||
url: `${baseurl}/profiles/me/${profileN}`
|
||||
}),
|
||||
getProfile: (tagferId) => ({
|
||||
method: 'GET',
|
||||
url: `${baseurl}/profiles/${tagferId}`
|
||||
}),
|
||||
getConnectionCountSelf: {
|
||||
method: 'GET',
|
||||
url: `${baseurl}/connections/me/count`
|
||||
},
|
||||
getConnectionCount: (tagferId) => ({
|
||||
method: 'GET',
|
||||
url: `${baseurl}/connections/${tagferId}/count`
|
||||
})
|
||||
};
|
||||
|
||||
export default endpoints;
|
||||
|
||||
21
src/screens/profile/EventsScreen.js
Normal file
21
src/screens/profile/EventsScreen.js
Normal file
@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
export default class AllConnectionsScreen extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Events</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}
|
||||
};
|
||||
@ -1,21 +1,135 @@
|
||||
import React from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import { ScrollView } from 'react-native';
|
||||
|
||||
import ProfileHeader from '../../components/profile/ProfileHeader';
|
||||
import MainContent from '../../components/profile/MainContent';
|
||||
import ActionBar from '../../components/profile/ActionBar';
|
||||
import InfoBar from '../../components/profile/InfoBar';
|
||||
|
||||
import endpoints from '../../config/apiEndpoints';
|
||||
|
||||
import { fetchTagferApi } from '../../utils/fetch';
|
||||
import { showFlashErrorMessage } from '../../utils/errorHandler';
|
||||
|
||||
export default class ProfileScreen extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
// FIXME: Hardcoded data needs to be removed
|
||||
this.state = {
|
||||
profile: {
|
||||
fullName: 'Ruth Ougston',
|
||||
tagferId: 'ruthoug',
|
||||
experience: [{
|
||||
jobTitle: 'CTO',
|
||||
companyName: 'Square',
|
||||
companyLocation: 'California, USA',
|
||||
startDate: 1488904944000,
|
||||
endDate: -1,
|
||||
summary: 'Company name is a duis nec sapien convallis, tincidunt orci sed, ultrices augue. Quisque ornare non erat vitae eleifend. '
|
||||
},
|
||||
{
|
||||
jobTitle: 'Software Engineer',
|
||||
companyName: 'Google',
|
||||
companyLocation: 'California, USA',
|
||||
startDate: 1446914544000,
|
||||
endDate: 1399477344000,
|
||||
summary: 'Company name is a duis nec sapien convallis, tincidunt orci sed, ultrices augue. Quisque ornare non erat vitae eleifend. '
|
||||
}],
|
||||
education: [{
|
||||
degree: 'Bachelor\'s Degree',
|
||||
school: 'Harvard',
|
||||
study: 'Computer Engineering',
|
||||
startDate: 1283874144000,
|
||||
endDate: 1399477344000,
|
||||
summary: 'Harvard is a duis nec sapien convallis, tincidunt orci sed, ultrices augue. Quisque ornare non erat vitae eleifend. '
|
||||
}],
|
||||
contact: {
|
||||
email: 'ruthoug@google.com',
|
||||
phoneNumber: '+1 404 569-(9123)'
|
||||
}
|
||||
},
|
||||
numOfRecs: 12,
|
||||
numOfContacts: 500
|
||||
};
|
||||
|
||||
this.setOptionsMenu = this.setOptionsMenu.bind(this);
|
||||
this.showOptionsMenu = this.showOptionsMenu.bind(this);
|
||||
this.tagferId = this.props.navigation.getParam('tagferId');
|
||||
this.profileN = 1;
|
||||
this.isSelf = !this.tagferId;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.onLoad1();
|
||||
// this.onLoad2();
|
||||
}
|
||||
|
||||
async onLoad1() {
|
||||
const endpoint = this.isSelf ? endpoints.getProfileSelf(this.profileN) : endpoints.getProfile(this.tagferId);
|
||||
const response = await fetchTagferApi(endpoint);
|
||||
if (response.error) {
|
||||
return showFlashErrorMessage(response.error);
|
||||
}
|
||||
|
||||
// FIXME: Make the backend aggregate the data in the same format as the state at the top, this requires a model change.
|
||||
// FIXME: Need to change the behaviour of how information is saved.
|
||||
const { profile } = response;
|
||||
|
||||
this.setState({ profile });
|
||||
}
|
||||
|
||||
async onLoad2() {
|
||||
const endpoint = this.isSelf ? endpoints.getConnectionCountSelf : endpoints.getConnectionCount(this.tagferId);
|
||||
const response = await fetchTagferApi(endpoint);
|
||||
if (response.error) {
|
||||
return showFlashErrorMessage(response.error);
|
||||
}
|
||||
|
||||
this.setState({ numOfContacts: response.count });
|
||||
}
|
||||
|
||||
getExperience(attribute) {
|
||||
if (this.state.profile.experience.length !== 0) {
|
||||
return this.state.profile.experience[0][attribute];
|
||||
}
|
||||
}
|
||||
|
||||
setOptionsMenu(ref) {
|
||||
this.sortMenu = ref;
|
||||
}
|
||||
|
||||
showOptionsMenu() {
|
||||
this.sortMenu.show();
|
||||
}
|
||||
|
||||
export default class AllConnectionsScreen extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Profile</Text>
|
||||
</View>
|
||||
<ScrollView style={{ flex: 1 }}>
|
||||
<ProfileHeader
|
||||
fullName={this.state.profile.fullName}
|
||||
tagferId={this.state.profile.tagferId}
|
||||
photoURL={this.state.profile.photoURL}
|
||||
jobTitle={this.getExperience('jobTitle')}
|
||||
companyName={this.getExperience('companyName')}
|
||||
companyLocation={this.getExperience('companyLocation') || 'USA'}
|
||||
setOptionsMenu={this.setOptionsMenu}
|
||||
showOptionsMenu={this.showOptionsMenu}
|
||||
canEdit={this.isSelf}
|
||||
/>
|
||||
|
||||
<ActionBar isSelf={this.isSelf} />
|
||||
<InfoBar numOfRecs={this.state.numOfRecs} numOfContacts={this.state.numOfContacts} />
|
||||
<MainContent
|
||||
need={this.state.profile.need}
|
||||
help={this.state.profile.help}
|
||||
about={this.state.profile.about}
|
||||
experienceList={this.state.profile.experience}
|
||||
educationList={this.state.profile.education}
|
||||
contact={this.state.profile.contact}
|
||||
canEdit={this.isSelf}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user