From 20b0ca39b333e0e3687f25347431643b5b2a95ef Mon Sep 17 00:00:00 2001 From: meganhong <34787696+meganhong@users.noreply.github.com> Date: Mon, 27 Jul 2020 13:05:03 -0700 Subject: TMA-167: Create Navigation Bar (#25) * Renamed Profile in Onboarding and added dummy main screens * Comments for new screens created * change navigation in verification to profileonboarding * added icons and tab navigation * added icons to navigation bar * add clicked icons * added 2x and 3x icon sizes * rename for resizing to work * remove upload clicked as informed by design * changed initialRouteName back to Login * created NavigationIcon component to hold all the nav icons * added default case * changed intialRouteName back to Login * fixed icon names * fixed icon names * add navigation to home page after login Co-authored-by: Megan Hong --- src/App.tsx | 10 - src/assets/navigationIcons/home-clicked.png | Bin 0 -> 1577 bytes src/assets/navigationIcons/home-clicked@2x.png | Bin 0 -> 17970 bytes src/assets/navigationIcons/home-clicked@3x.png | Bin 0 -> 28722 bytes src/assets/navigationIcons/home.png | Bin 0 -> 1745 bytes src/assets/navigationIcons/home@2x.png | Bin 0 -> 32014 bytes src/assets/navigationIcons/home@3x.png | Bin 0 -> 53505 bytes .../navigationIcons/notifications-clicked.png | Bin 0 -> 962 bytes .../navigationIcons/notifications-clicked@2x.png | Bin 0 -> 10995 bytes .../navigationIcons/notifications-clicked@3x.png | Bin 0 -> 17720 bytes src/assets/navigationIcons/notifications.png | Bin 0 -> 1324 bytes src/assets/navigationIcons/notifications@2x.png | Bin 0 -> 19051 bytes src/assets/navigationIcons/notifications@3x.png | Bin 0 -> 30496 bytes src/assets/navigationIcons/profile-clicked.png | Bin 0 -> 958 bytes src/assets/navigationIcons/profile-clicked@2x.png | Bin 0 -> 12204 bytes src/assets/navigationIcons/profile-clicked@3x.png | Bin 0 -> 19693 bytes src/assets/navigationIcons/profile.png | Bin 0 -> 1251 bytes src/assets/navigationIcons/search-clicked.png | Bin 0 -> 941 bytes src/assets/navigationIcons/search-clicked3x.png | Bin 0 -> 19433 bytes src/assets/navigationIcons/search-clicked@2x.png | Bin 0 -> 12517 bytes src/assets/navigationIcons/search.png | Bin 0 -> 1278 bytes src/assets/navigationIcons/search@2x.png | Bin 0 -> 20905 bytes src/assets/navigationIcons/search@3x.png | Bin 0 -> 33147 bytes src/assets/navigationIcons/upload.png | Bin 0 -> 982 bytes src/assets/navigationIcons/upload@2x.png | Bin 0 -> 13483 bytes src/assets/navigationIcons/upload@3x.png | Bin 0 -> 21684 bytes src/components/common/NavigationIcon.tsx | 69 ++++++ src/components/common/index.ts | 1 + src/routes/Routes.tsx | 81 ++++++- src/screens/main/Home.tsx | 35 +++ src/screens/main/Notifications.tsx | 41 ++++ src/screens/main/Profile.tsx | 38 +++ src/screens/main/Search.tsx | 38 +++ src/screens/main/Upload.tsx | 37 +++ src/screens/main/index.ts | 5 + src/screens/onboarding/Login.tsx | 2 +- src/screens/onboarding/Profile.tsx | 253 -------------------- src/screens/onboarding/ProfileOnboarding.tsx | 256 +++++++++++++++++++++ src/screens/onboarding/Verification.tsx | 2 +- src/screens/onboarding/index.ts | 2 +- 40 files changed, 600 insertions(+), 270 deletions(-) create mode 100644 src/assets/navigationIcons/home-clicked.png create mode 100644 src/assets/navigationIcons/home-clicked@2x.png create mode 100644 src/assets/navigationIcons/home-clicked@3x.png create mode 100644 src/assets/navigationIcons/home.png create mode 100644 src/assets/navigationIcons/home@2x.png create mode 100644 src/assets/navigationIcons/home@3x.png create mode 100644 src/assets/navigationIcons/notifications-clicked.png create mode 100644 src/assets/navigationIcons/notifications-clicked@2x.png create mode 100644 src/assets/navigationIcons/notifications-clicked@3x.png create mode 100644 src/assets/navigationIcons/notifications.png create mode 100644 src/assets/navigationIcons/notifications@2x.png create mode 100644 src/assets/navigationIcons/notifications@3x.png create mode 100644 src/assets/navigationIcons/profile-clicked.png create mode 100644 src/assets/navigationIcons/profile-clicked@2x.png create mode 100644 src/assets/navigationIcons/profile-clicked@3x.png create mode 100644 src/assets/navigationIcons/profile.png create mode 100644 src/assets/navigationIcons/search-clicked.png create mode 100644 src/assets/navigationIcons/search-clicked3x.png create mode 100644 src/assets/navigationIcons/search-clicked@2x.png create mode 100644 src/assets/navigationIcons/search.png create mode 100644 src/assets/navigationIcons/search@2x.png create mode 100644 src/assets/navigationIcons/search@3x.png create mode 100644 src/assets/navigationIcons/upload.png create mode 100644 src/assets/navigationIcons/upload@2x.png create mode 100644 src/assets/navigationIcons/upload@3x.png create mode 100644 src/components/common/NavigationIcon.tsx create mode 100644 src/screens/main/Home.tsx create mode 100644 src/screens/main/Notifications.tsx create mode 100644 src/screens/main/Profile.tsx create mode 100644 src/screens/main/Search.tsx create mode 100644 src/screens/main/Upload.tsx create mode 100644 src/screens/main/index.ts delete mode 100644 src/screens/onboarding/Profile.tsx create mode 100644 src/screens/onboarding/ProfileOnboarding.tsx (limited to 'src') diff --git a/src/App.tsx b/src/App.tsx index 6c247f7c..f4dea5bf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,3 @@ -/** - * Sample React Native App - * https://github.com/facebook/react-native - * - * Generated with the TypeScript template - * https://github.com/react-native-community/react-native-template-typescript - * - * @format - */ - import React from 'react'; import Routes from './routes'; import {NavigationContainer} from '@react-navigation/native'; diff --git a/src/assets/navigationIcons/home-clicked.png b/src/assets/navigationIcons/home-clicked.png new file mode 100644 index 00000000..8b6e9766 Binary files /dev/null and b/src/assets/navigationIcons/home-clicked.png differ diff --git a/src/assets/navigationIcons/home-clicked@2x.png b/src/assets/navigationIcons/home-clicked@2x.png new file mode 100644 index 00000000..51a80de7 Binary files /dev/null and b/src/assets/navigationIcons/home-clicked@2x.png differ diff --git a/src/assets/navigationIcons/home-clicked@3x.png b/src/assets/navigationIcons/home-clicked@3x.png new file mode 100644 index 00000000..17010413 Binary files /dev/null and b/src/assets/navigationIcons/home-clicked@3x.png differ diff --git a/src/assets/navigationIcons/home.png b/src/assets/navigationIcons/home.png new file mode 100644 index 00000000..ac20c3c1 Binary files /dev/null and b/src/assets/navigationIcons/home.png differ diff --git a/src/assets/navigationIcons/home@2x.png b/src/assets/navigationIcons/home@2x.png new file mode 100644 index 00000000..02564b85 Binary files /dev/null and b/src/assets/navigationIcons/home@2x.png differ diff --git a/src/assets/navigationIcons/home@3x.png b/src/assets/navigationIcons/home@3x.png new file mode 100644 index 00000000..4a6c9cba Binary files /dev/null and b/src/assets/navigationIcons/home@3x.png differ diff --git a/src/assets/navigationIcons/notifications-clicked.png b/src/assets/navigationIcons/notifications-clicked.png new file mode 100644 index 00000000..0e72b0d5 Binary files /dev/null and b/src/assets/navigationIcons/notifications-clicked.png differ diff --git a/src/assets/navigationIcons/notifications-clicked@2x.png b/src/assets/navigationIcons/notifications-clicked@2x.png new file mode 100644 index 00000000..29ce7fbf Binary files /dev/null and b/src/assets/navigationIcons/notifications-clicked@2x.png differ diff --git a/src/assets/navigationIcons/notifications-clicked@3x.png b/src/assets/navigationIcons/notifications-clicked@3x.png new file mode 100644 index 00000000..611f3221 Binary files /dev/null and b/src/assets/navigationIcons/notifications-clicked@3x.png differ diff --git a/src/assets/navigationIcons/notifications.png b/src/assets/navigationIcons/notifications.png new file mode 100644 index 00000000..5dd46fba Binary files /dev/null and b/src/assets/navigationIcons/notifications.png differ diff --git a/src/assets/navigationIcons/notifications@2x.png b/src/assets/navigationIcons/notifications@2x.png new file mode 100644 index 00000000..85760ebb Binary files /dev/null and b/src/assets/navigationIcons/notifications@2x.png differ diff --git a/src/assets/navigationIcons/notifications@3x.png b/src/assets/navigationIcons/notifications@3x.png new file mode 100644 index 00000000..101c7f8a Binary files /dev/null and b/src/assets/navigationIcons/notifications@3x.png differ diff --git a/src/assets/navigationIcons/profile-clicked.png b/src/assets/navigationIcons/profile-clicked.png new file mode 100644 index 00000000..add50faf Binary files /dev/null and b/src/assets/navigationIcons/profile-clicked.png differ diff --git a/src/assets/navigationIcons/profile-clicked@2x.png b/src/assets/navigationIcons/profile-clicked@2x.png new file mode 100644 index 00000000..7c1fc99d Binary files /dev/null and b/src/assets/navigationIcons/profile-clicked@2x.png differ diff --git a/src/assets/navigationIcons/profile-clicked@3x.png b/src/assets/navigationIcons/profile-clicked@3x.png new file mode 100644 index 00000000..ab0d194f Binary files /dev/null and b/src/assets/navigationIcons/profile-clicked@3x.png differ diff --git a/src/assets/navigationIcons/profile.png b/src/assets/navigationIcons/profile.png new file mode 100644 index 00000000..e79b8547 Binary files /dev/null and b/src/assets/navigationIcons/profile.png differ diff --git a/src/assets/navigationIcons/search-clicked.png b/src/assets/navigationIcons/search-clicked.png new file mode 100644 index 00000000..8fc8fa5a Binary files /dev/null and b/src/assets/navigationIcons/search-clicked.png differ diff --git a/src/assets/navigationIcons/search-clicked3x.png b/src/assets/navigationIcons/search-clicked3x.png new file mode 100644 index 00000000..54290168 Binary files /dev/null and b/src/assets/navigationIcons/search-clicked3x.png differ diff --git a/src/assets/navigationIcons/search-clicked@2x.png b/src/assets/navigationIcons/search-clicked@2x.png new file mode 100644 index 00000000..56b5cb6b Binary files /dev/null and b/src/assets/navigationIcons/search-clicked@2x.png differ diff --git a/src/assets/navigationIcons/search.png b/src/assets/navigationIcons/search.png new file mode 100644 index 00000000..bf02835d Binary files /dev/null and b/src/assets/navigationIcons/search.png differ diff --git a/src/assets/navigationIcons/search@2x.png b/src/assets/navigationIcons/search@2x.png new file mode 100644 index 00000000..d079844c Binary files /dev/null and b/src/assets/navigationIcons/search@2x.png differ diff --git a/src/assets/navigationIcons/search@3x.png b/src/assets/navigationIcons/search@3x.png new file mode 100644 index 00000000..73453cad Binary files /dev/null and b/src/assets/navigationIcons/search@3x.png differ diff --git a/src/assets/navigationIcons/upload.png b/src/assets/navigationIcons/upload.png new file mode 100644 index 00000000..ec8c685f Binary files /dev/null and b/src/assets/navigationIcons/upload.png differ diff --git a/src/assets/navigationIcons/upload@2x.png b/src/assets/navigationIcons/upload@2x.png new file mode 100644 index 00000000..66ab56b5 Binary files /dev/null and b/src/assets/navigationIcons/upload@2x.png differ diff --git a/src/assets/navigationIcons/upload@3x.png b/src/assets/navigationIcons/upload@3x.png new file mode 100644 index 00000000..ca51c710 Binary files /dev/null and b/src/assets/navigationIcons/upload@3x.png differ diff --git a/src/components/common/NavigationIcon.tsx b/src/components/common/NavigationIcon.tsx new file mode 100644 index 00000000..9497566b --- /dev/null +++ b/src/components/common/NavigationIcon.tsx @@ -0,0 +1,69 @@ +import React from 'react'; +import { + View, + Image, + StyleSheet, + TouchableOpacity, + TouchableOpacityProps, +} from 'react-native'; + +interface NavigationIconProps extends TouchableOpacityProps { + tab: 'Home' | 'Search' | 'Upload' | 'Notifications' | 'Profile'; + disabled?: boolean; +} + +const NavigationIcon = (props: NavigationIconProps) => { + let imgSrc; + switch (props.tab) { + case 'Home': + imgSrc = props.disabled + ? require('../../assets/navigationIcons/home.png') + : require('../../assets/navigationIcons/home-clicked.png'); + break; + case 'Search': + imgSrc = props.disabled + ? require('../../assets/navigationIcons/search.png') + : require('../../assets/navigationIcons/search-clicked.png'); + break; + case 'Upload': + imgSrc = props.disabled + ? require('../../assets/navigationIcons/upload.png') + : require('../../assets/navigationIcons/upload.png'); + break; + case 'Notifications': + imgSrc = props.disabled + ? require('../../assets/navigationIcons/notifications.png') + : require('../../assets/navigationIcons/notifications-clicked.png'); + break; + case 'Profile': + imgSrc = props.disabled + ? require('../../assets/navigationIcons/profile.png') + : require('../../assets/navigationIcons/profile-clicked.png'); + break; + default: + imgSrc = null; + } + return ( + + + + + + ); +}; + +const styles = StyleSheet.create({ + icon: { + flex: 1, + justifyContent: 'center', + shadowColor: '#000000', + shadowOffset: { + width: 0, + height: 2, + }, + shadowRadius: 2, + shadowOpacity: 0.4, + }, +}); + +export default NavigationIcon; diff --git a/src/components/common/index.ts b/src/components/common/index.ts index b7041b6d..d7778f95 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -2,3 +2,4 @@ export {default as CenteredView} from './CenteredView'; export {default as OverlayView} from './OverlayView'; export {default as RadioCheckbox} from './RadioCheckbox'; export {default as TaggInput} from './TaggInput'; +export {default as NavigationIcon} from './NavigationIcon'; diff --git a/src/routes/Routes.tsx b/src/routes/Routes.tsx index 7379c2c2..5d69b38b 100644 --- a/src/routes/Routes.tsx +++ b/src/routes/Routes.tsx @@ -1,26 +1,94 @@ import React from 'react'; import {createStackNavigator} from '@react-navigation/stack'; +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import { Login, RegistrationOne, RegistrationTwo, Verification, - Profile, + ProfileOnboarding, } from '../screens/onboarding'; +import {Home, Notifications, Profile, Search, Upload} from '../screens/main'; +import {NavigationIcon} from '../components'; export type RootStackParamList = { + // Onboarding Screens Login: undefined; RegistrationOne: undefined; RegistrationTwo: | {firstName: string; lastName: string; email: string} | undefined; Verification: {username: string; email: string; userId: string}; - Profile: {username: string; userId: string}; + ProfileOnboarding: {username: string; userId: string}; + + // Main Screens + Home: undefined; + Notifications: undefined; + Profile: undefined; + Search: undefined; + Upload: undefined; }; const RootStack = createStackNavigator(); +const Tab = createBottomTabNavigator(); + +function MainTabNavigator() { + return ( + ({ + tabBarIcon: ({focused}) => { + if (route.name === 'Home') { + return focused ? ( + + ) : ( + + ); + } else if (route.name === 'Search') { + return focused ? ( + + ) : ( + + ); + } else if (route.name === 'Upload') { + return focused ? ( + + ) : ( + + ); + } else if (route.name === 'Notifications') { + return focused ? ( + + ) : ( + + ); + } else if (route.name === 'Profile') { + return focused ? ( + + ) : ( + + ); + } + }, + })} + tabBarOptions={{ + showLabel: false, + style: { + backgroundColor: 'transparent', + position: 'absolute', + borderTopWidth: 0, + }, + }}> + + + + + + + ); +} + interface RoutesProps {} const Routes: React.FC = ({}) => { @@ -47,8 +115,13 @@ const Routes: React.FC = ({}) => { options={{headerShown: false}} /> + diff --git a/src/screens/main/Home.tsx b/src/screens/main/Home.tsx new file mode 100644 index 00000000..cd2c418a --- /dev/null +++ b/src/screens/main/Home.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import {RootStackParamList} from '../../routes'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import {Background} from '../../components'; +import {Text} from 'react-native-animatable'; +import {StyleSheet} from 'react-native'; + +type HomeScreenRouteProp = RouteProp; +type HomeScreenNavigationProp = StackNavigationProp; +interface HomeProps { + route: HomeScreenRouteProp; + navigation: HomeScreenNavigationProp; +} + +/** + * Home Screen for displaying Tagg post suggestions + * for users to discover and browse + */ + +const Home: React.FC = () => { + return ( + + Tagg Home Screen 🏠 + + ); +}; +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, +}); +export default Home; diff --git a/src/screens/main/Notifications.tsx b/src/screens/main/Notifications.tsx new file mode 100644 index 00000000..ec881c8e --- /dev/null +++ b/src/screens/main/Notifications.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import {RootStackParamList} from '../../routes'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import {Background} from '../../components'; +import {Text} from 'react-native-animatable'; +import {StyleSheet} from 'react-native'; + +type NotificationsScreenRouteProp = RouteProp< + RootStackParamList, + 'Notifications' +>; +type NotificationsScreenNavigationProp = StackNavigationProp< + RootStackParamList, + 'Notifications' +>; +interface NotificationsProps { + route: NotificationsScreenRouteProp; + navigation: NotificationsScreenNavigationProp; +} + +/** + * Navigation Screen for displaying other users' + * actions on the logged in user's posts + */ + +const Notifications: React.FC = () => { + return ( + + Notifications will go here 🔔 + + ); +}; +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, +}); +export default Notifications; diff --git a/src/screens/main/Profile.tsx b/src/screens/main/Profile.tsx new file mode 100644 index 00000000..a40a9cef --- /dev/null +++ b/src/screens/main/Profile.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import {RootStackParamList} from '../../routes'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import {Background} from '../../components'; +import {Text} from 'react-native-animatable'; +import {StyleSheet} from 'react-native'; + +type ProfileScreenRouteProp = RouteProp; +type ProfileScreenNavigationProp = StackNavigationProp< + RootStackParamList, + 'Profile' +>; +interface ProfileProps { + route: ProfileScreenRouteProp; + navigation: ProfileScreenNavigationProp; +} + +/** + * Profile Screen for a user's logged in profile + * including posts, messaging, and settings + */ + +const Profile: React.FC = () => { + return ( + + Profile Screen 🤩 + + ); +}; +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, +}); +export default Profile; diff --git a/src/screens/main/Search.tsx b/src/screens/main/Search.tsx new file mode 100644 index 00000000..caa5d205 --- /dev/null +++ b/src/screens/main/Search.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import {RootStackParamList} from '../../routes'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import {Background} from '../../components'; +import {Text} from 'react-native-animatable'; +import {StyleSheet} from 'react-native'; + +type SearchScreenRouteProp = RouteProp; +type SearchScreenNavigationProp = StackNavigationProp< + RootStackParamList, + 'Search' +>; +interface SearchProps { + route: SearchScreenRouteProp; + navigation: SearchScreenNavigationProp; +} + +/** + * Search Screen for user recommendations and a search + * tool to allow user to find other users + */ + +const Search: React.FC = () => { + return ( + + Search for people here 👀 + + ); +}; +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, +}); +export default Search; diff --git a/src/screens/main/Upload.tsx b/src/screens/main/Upload.tsx new file mode 100644 index 00000000..4bbe2d0a --- /dev/null +++ b/src/screens/main/Upload.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import {RootStackParamList} from '../../routes'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import {Background} from '../../components'; +import {Text} from 'react-native-animatable'; +import {StyleSheet} from 'react-native'; + +type UploadScreenRouteProp = RouteProp; +type UploadScreenNavigationProp = StackNavigationProp< + RootStackParamList, + 'Upload' +>; +interface UploadProps { + route: UploadScreenRouteProp; + navigation: UploadScreenNavigationProp; +} + +/** + * Upload Screen to allow users to upload posts to Tagg + */ + +const Upload: React.FC = () => { + return ( + + Upload pics ⬆ + + ); +}; +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, +}); +export default Upload; diff --git a/src/screens/main/index.ts b/src/screens/main/index.ts new file mode 100644 index 00000000..9bd00c57 --- /dev/null +++ b/src/screens/main/index.ts @@ -0,0 +1,5 @@ +export {default as Home} from './Home'; +export {default as Notifications} from './Notifications'; +export {default as Profile} from './Profile'; +export {default as Search} from './Search'; +export {default as Upload} from './Upload'; diff --git a/src/screens/onboarding/Login.tsx b/src/screens/onboarding/Login.tsx index 971595d3..537ce868 100644 --- a/src/screens/onboarding/Login.tsx +++ b/src/screens/onboarding/Login.tsx @@ -118,7 +118,7 @@ const Login: React.FC = ({navigation}: LoginProps) => { let statusCode = response.status; if (statusCode === 200) { - Alert.alert('Successfully logged in! 🥳', `Welcome ${form.username}`); + navigation.navigate('Home'); } else if (statusCode === 401) { Alert.alert( 'Login failed 😔', diff --git a/src/screens/onboarding/Profile.tsx b/src/screens/onboarding/Profile.tsx deleted file mode 100644 index d42b1185..00000000 --- a/src/screens/onboarding/Profile.tsx +++ /dev/null @@ -1,253 +0,0 @@ -import React from 'react'; -import {RouteProp} from '@react-navigation/native'; -import {StackNavigationProp} from '@react-navigation/stack'; -import { - Text, - StatusBar, - StyleSheet, - Image, - TouchableOpacity, - Alert, - View, -} from 'react-native'; -import {RootStackParamList} from '../../routes'; -import {Background} from '../../components'; -import ImagePicker from 'react-native-image-crop-picker'; -import {REGISTER_ENDPOINT} from '../../constants'; - -type ProfileScreenRouteProp = RouteProp; -type ProfileScreenNavigationProp = StackNavigationProp< - RootStackParamList, - 'Profile' ->; -interface ProfileProps { - route: ProfileScreenRouteProp; - navigation: ProfileScreenNavigationProp; -} - -/** - * Create profile screen for onboarding. - * @param navigation react-navigation navigation object - */ - -const Profile: React.FC = ({route}) => { - const {userId, username} = route.params; - const [largePic, setLargePic] = React.useState(''); - const [smallPic, setSmallPic] = React.useState(''); - - /** - * Profile screen "Add Large Profile Pic Here" button - */ - const LargeProfilePic = () => ( - - {largePic ? ( - - ) : ( - ADD LARGE PROFILE PIC HERE - )} - - ); - - /** - * Profile screen "Add Smaller Profile Pic Here" button - */ - const SmallProfilePic = () => ( - - {smallPic ? ( - - ) : ( - ADD SMALLER PIC - )} - - ); - - /* - * Handles tap on add profile picture buttons by navigating to camera access - * and selecting a picture from gallery for large profile picture - */ - const goToGalleryLargePic = () => { - ImagePicker.openPicker({ - width: 580, - height: 580, - cropping: true, - cropperToolbarTitle: 'Large profile picture', - mediaType: 'photo', - }) - .then((picture) => { - if ('path' in picture) { - setLargePic(picture.path); - } - }) - .catch(() => {}); - }; - - /* - * Handles tap on add profile picture buttons by navigating to camera access - * and selecting a picture from gallery for small profile picture - */ - const goToGallerySmallPic = () => { - ImagePicker.openPicker({ - width: 580, - height: 580, - cropping: true, - cropperToolbarTitle: 'Small profile picture', - mediaType: 'photo', - cropperCircleOverlay: true, - }) - .then((picture) => { - if ('path' in picture) { - setSmallPic(picture.path); - } - }) - .catch(() => {}); - }; - - const handleSubmit = async () => { - const form = new FormData(); - if (largePic) { - form.append('largeProfilePicture', { - uri: largePic, - name: 'large_profile_pic.jpg', - type: 'image/jpg', - }); - } - if (smallPic) { - form.append('smallProfilePicture', { - uri: smallPic, - name: 'small_profile_pic.jpg', - type: 'image/jpg', - }); - } - const endpoint = REGISTER_ENDPOINT + `${userId}/`; - try { - let response = await fetch(endpoint, { - method: 'PATCH', - headers: { - 'Content-Type': 'multipart/form-data', - }, - body: form, - }); - let data = await response.json(); - let statusCode = response.status; - if (statusCode === 200) { - Alert.alert( - 'Profile successfully created! 🥳', - `Welcome to Tagg, ${username}!`, - ); - } else if (statusCode === 400) { - Alert.alert('Profile update failed. 😔', `${data}`); - } else { - Alert.alert( - 'Something went wrong! 😭', - "Would you believe me if I told you that I don't know what happened?", - ); - } - } catch (error) { - Alert.alert( - 'Profile creation failed 😓', - 'Please double-check your network connection and retry.', - ); - return { - name: 'Profile creation error', - description: error, - }; - } - }; - - return ( - - - - - - DUMMY WEBSITE - - - DUMMY BIO - - - Let's start! - - - ); -}; - -const styles = StyleSheet.create({ - largeProfile: { - justifyContent: 'center', - alignItems: 'center', - padding: 15, - height: 230, - width: 230, - borderRadius: 23, - backgroundColor: '#fff', - marginRight: '6%', - }, - largeProfileText: { - textAlign: 'center', - fontSize: 14, - fontWeight: 'bold', - color: '#863FF9', - }, - smallProfile: { - justifyContent: 'center', - alignItems: 'center', - padding: 20, - height: 110, - width: 110, - borderRadius: 55, - backgroundColor: '#E1F0FF', - marginLeft: '45%', - bottom: '7%', - }, - smallProfileText: { - textAlign: 'center', - fontSize: 14, - fontWeight: 'bold', - color: '#806DF4', - }, - profilePic: { - marginRight: 0, - marginLeft: 0, - bottom: 0, - }, - dummyField: { - height: '10%', - width: '80%', - justifyContent: 'center', - alignItems: 'center', - borderColor: '#fff', - borderWidth: 1, - borderRadius: 8, - marginBottom: '10%', - }, - submitBtn: { - backgroundColor: '#8F01FF', - justifyContent: 'center', - alignItems: 'center', - width: 150, - height: 40, - borderRadius: 5, - }, - submitBtnLabel: { - fontSize: 16, - fontWeight: '500', - color: '#fff', - }, -}); - -export default Profile; diff --git a/src/screens/onboarding/ProfileOnboarding.tsx b/src/screens/onboarding/ProfileOnboarding.tsx new file mode 100644 index 00000000..191d62b2 --- /dev/null +++ b/src/screens/onboarding/ProfileOnboarding.tsx @@ -0,0 +1,256 @@ +import React from 'react'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import { + Text, + StatusBar, + StyleSheet, + Image, + TouchableOpacity, + Alert, + View, +} from 'react-native'; +import {RootStackParamList} from '../../routes'; +import {Background} from '../../components'; +import ImagePicker from 'react-native-image-crop-picker'; +import {REGISTER_ENDPOINT} from '../../constants'; + +type ProfileOnboardingScreenRouteProp = RouteProp< + RootStackParamList, + 'ProfileOnboarding' +>; +type ProfileOnboardingScreenNavigationProp = StackNavigationProp< + RootStackParamList, + 'ProfileOnboarding' +>; +interface ProfileOnboardingProps { + route: ProfileOnboardingScreenRouteProp; + navigation: ProfileOnboardingScreenNavigationProp; +} + +/** + * Create profile screen for onboarding. + * @param navigation react-navigation navigation object + */ + +const ProfileOnboarding: React.FC = ({route}) => { + const {userId, username} = route.params; + const [largePic, setLargePic] = React.useState(''); + const [smallPic, setSmallPic] = React.useState(''); + + /** + * Profile screen "Add Large Profile Pic Here" button + */ + const LargeProfilePic = () => ( + + {largePic ? ( + + ) : ( + ADD LARGE PROFILE PIC HERE + )} + + ); + + /** + * Profile screen "Add Smaller Profile Pic Here" button + */ + const SmallProfilePic = () => ( + + {smallPic ? ( + + ) : ( + ADD SMALLER PIC + )} + + ); + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for large profile picture + */ + const goToGalleryLargePic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Large profile picture', + mediaType: 'photo', + }) + .then((picture) => { + if ('path' in picture) { + setLargePic(picture.path); + } + }) + .catch(() => {}); + }; + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for small profile picture + */ + const goToGallerySmallPic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Small profile picture', + mediaType: 'photo', + cropperCircleOverlay: true, + }) + .then((picture) => { + if ('path' in picture) { + setSmallPic(picture.path); + } + }) + .catch(() => {}); + }; + + const handleSubmit = async () => { + const form = new FormData(); + if (largePic) { + form.append('largeProfilePicture', { + uri: largePic, + name: 'large_profile_pic.jpg', + type: 'image/jpg', + }); + } + if (smallPic) { + form.append('smallProfilePicture', { + uri: smallPic, + name: 'small_profile_pic.jpg', + type: 'image/jpg', + }); + } + const endpoint = REGISTER_ENDPOINT + `${userId}/`; + try { + let response = await fetch(endpoint, { + method: 'PATCH', + headers: { + 'Content-Type': 'multipart/form-data', + }, + body: form, + }); + let data = await response.json(); + let statusCode = response.status; + if (statusCode === 200) { + Alert.alert( + 'Profile successfully created! 🥳', + `Welcome to Tagg, ${username}!`, + ); + } else if (statusCode === 400) { + Alert.alert('Profile update failed. 😔', `${data}`); + } else { + Alert.alert( + 'Something went wrong! 😭', + "Would you believe me if I told you that I don't know what happened?", + ); + } + } catch (error) { + Alert.alert( + 'Profile creation failed 😓', + 'Please double-check your network connection and retry.', + ); + return { + name: 'Profile creation error', + description: error, + }; + } + }; + + return ( + + + + + + DUMMY WEBSITE + + + DUMMY BIO + + + Let's start! + + + ); +}; + +const styles = StyleSheet.create({ + largeProfile: { + justifyContent: 'center', + alignItems: 'center', + padding: 15, + height: 230, + width: 230, + borderRadius: 23, + backgroundColor: '#fff', + marginRight: '6%', + }, + largeProfileText: { + textAlign: 'center', + fontSize: 14, + fontWeight: 'bold', + color: '#863FF9', + }, + smallProfile: { + justifyContent: 'center', + alignItems: 'center', + padding: 20, + height: 110, + width: 110, + borderRadius: 55, + backgroundColor: '#E1F0FF', + marginLeft: '45%', + bottom: '7%', + }, + smallProfileText: { + textAlign: 'center', + fontSize: 14, + fontWeight: 'bold', + color: '#806DF4', + }, + profilePic: { + marginRight: 0, + marginLeft: 0, + bottom: 0, + }, + dummyField: { + height: '10%', + width: '80%', + justifyContent: 'center', + alignItems: 'center', + borderColor: '#fff', + borderWidth: 1, + borderRadius: 8, + marginBottom: '10%', + }, + submitBtn: { + backgroundColor: '#8F01FF', + justifyContent: 'center', + alignItems: 'center', + width: 150, + height: 40, + borderRadius: 5, + }, + submitBtnLabel: { + fontSize: 16, + fontWeight: '500', + color: '#fff', + }, +}); + +export default ProfileOnboarding; diff --git a/src/screens/onboarding/Verification.tsx b/src/screens/onboarding/Verification.tsx index 905de276..197bc0ca 100644 --- a/src/screens/onboarding/Verification.tsx +++ b/src/screens/onboarding/Verification.tsx @@ -59,7 +59,7 @@ const Verification: React.FC = ({route, navigation}) => { }); let statusCode = verifyOtpResponse.status; if (statusCode === 200) { - navigation.navigate('Profile', { + navigation.navigate('ProfileOnboarding', { userId: userId, username: username, }); diff --git a/src/screens/onboarding/index.ts b/src/screens/onboarding/index.ts index e89e1d5f..9b2f4cb0 100644 --- a/src/screens/onboarding/index.ts +++ b/src/screens/onboarding/index.ts @@ -2,4 +2,4 @@ export {default as Login} from './Login'; export {default as RegistrationOne} from './RegistrationOne'; export {default as RegistrationTwo} from './RegistrationTwo'; export {default as Verification} from './Verification'; -export {default as Profile} from './Profile'; +export {default as ProfileOnboarding} from './ProfileOnboarding'; -- cgit v1.2.3-70-g09d2