diff options
author | meganhong <34787696+meganhong@users.noreply.github.com> | 2020-07-30 13:28:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-30 16:28:56 -0400 |
commit | f9cf9b5d89d5e25b227814f0fc759257564cea89 (patch) | |
tree | d45b6f8378acb5bccb4ff06363ccad98bcb579dd /src | |
parent | 20b0ca39b333e0e3687f25347431643b5b2a95ef (diff) |
TMA-168: Add Gradient to Navigation Bar (#26)
* 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
* added gradient and changed screens to transparent
* renamed Routes to OnboardingStack
* rerouting navigation
* pulling from master
* merge conflicts
* added entryway to home on profileonboarding
* changed gradient into custom component
* removed a method that i had commented out
Co-authored-by: Megan Hong <meganhong31@g.ucla.edu>
Diffstat (limited to 'src')
-rw-r--r-- | src/App.tsx | 10 | ||||
-rw-r--r-- | src/components/common/GradientBackground.tsx | 34 | ||||
-rw-r--r-- | src/components/common/index.ts | 1 | ||||
-rw-r--r-- | src/routes/NavigationBar.tsx | 75 | ||||
-rw-r--r-- | src/routes/OnboardingStack.tsx | 57 | ||||
-rw-r--r-- | src/routes/Routes.tsx | 149 | ||||
-rw-r--r-- | src/routes/index.ts | 6 | ||||
-rw-r--r-- | src/screens/main/Home.tsx | 25 | ||||
-rw-r--r-- | src/screens/main/Notifications.tsx | 31 | ||||
-rw-r--r-- | src/screens/main/Profile.tsx | 28 | ||||
-rw-r--r-- | src/screens/main/Search.tsx | 28 | ||||
-rw-r--r-- | src/screens/main/Upload.tsx | 29 | ||||
-rw-r--r-- | src/screens/onboarding/Login.tsx | 6 | ||||
-rw-r--r-- | src/screens/onboarding/ProfileOnboarding.tsx | 13 |
14 files changed, 256 insertions, 236 deletions
diff --git a/src/App.tsx b/src/App.tsx index f4dea5bf..5abf1ff4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,14 @@ import React from 'react'; -import Routes from './routes'; import {NavigationContainer} from '@react-navigation/native'; +import {Routes, AuthContextProvider} from './routes'; const App = () => { return ( - <NavigationContainer> - <Routes /> - </NavigationContainer> + <AuthContextProvider> + <NavigationContainer> + <Routes /> + </NavigationContainer> + </AuthContextProvider> ); }; diff --git a/src/components/common/GradientBackground.tsx b/src/components/common/GradientBackground.tsx new file mode 100644 index 00000000..f363bd61 --- /dev/null +++ b/src/components/common/GradientBackground.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import LinearGradient from 'react-native-linear-gradient'; +import { + StyleSheet, + TouchableWithoutFeedback, + Keyboard, + ViewProps, + SafeAreaView, +} from 'react-native'; + +interface GradientBackgroundProps extends ViewProps {} +const GradientBackground: React.FC<GradientBackgroundProps> = (props) => { + return ( + <LinearGradient + locations={[0.89, 1]} + colors={['transparent', 'rgba(0, 0, 0, 0.6)']} + style={styles.container}> + <TouchableWithoutFeedback accessible={false} onPress={Keyboard.dismiss}> + <SafeAreaView {...props}>{props.children}</SafeAreaView> + </TouchableWithoutFeedback> + </LinearGradient> + ); +}; + +const styles = StyleSheet.create({ + container: { + justifyContent: 'center', + alignItems: 'center', + backgroundColor: 'transparent', + flex: 1, + }, +}); + +export default GradientBackground; diff --git a/src/components/common/index.ts b/src/components/common/index.ts index d7778f95..a1bcc558 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -3,3 +3,4 @@ export {default as OverlayView} from './OverlayView'; export {default as RadioCheckbox} from './RadioCheckbox'; export {default as TaggInput} from './TaggInput'; export {default as NavigationIcon} from './NavigationIcon'; +export {default as GradientBackground} from './GradientBackground'; diff --git a/src/routes/NavigationBar.tsx b/src/routes/NavigationBar.tsx new file mode 100644 index 00000000..84c18e00 --- /dev/null +++ b/src/routes/NavigationBar.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import {ViewProps} from 'react-native'; +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; +import {Fragment} from 'react'; +import {NavigationIcon} from '../components'; +import {Home, Notifications, Profile, Search, Upload} from '../screens/main'; + +interface NavigationBarProps extends ViewProps { + centered?: boolean; +} + +const Tab = createBottomTabNavigator(); + +const NavigationBar: React.FC<NavigationBarProps> = () => { + return ( + <Fragment> + <Tab.Navigator + screenOptions={({route}) => ({ + tabBarIcon: ({focused}) => { + if (route.name === 'Home') { + return focused ? ( + <NavigationIcon tab="Home" disabled={false} /> + ) : ( + <NavigationIcon tab="Home" disabled={true} /> + ); + } else if (route.name === 'Search') { + return focused ? ( + <NavigationIcon tab="Search" disabled={false} /> + ) : ( + <NavigationIcon tab="Search" disabled={true} /> + ); + } else if (route.name === 'Upload') { + return focused ? ( + <NavigationIcon tab="Upload" disabled={false} /> + ) : ( + <NavigationIcon tab="Upload" disabled={true} /> + ); + } else if (route.name === 'Notifications') { + return focused ? ( + <NavigationIcon tab="Notifications" disabled={false} /> + ) : ( + <NavigationIcon tab="Notifications" disabled={true} /> + ); + } else if (route.name === 'Profile') { + return focused ? ( + <NavigationIcon tab="Profile" disabled={false} /> + ) : ( + <NavigationIcon tab="Profile" disabled={true} /> + ); + } + }, + })} + initialRouteName="Home" + tabBarOptions={{ + showLabel: false, + style: { + backgroundColor: 'transparent', + position: 'absolute', + borderTopWidth: 0, + left: 0, + right: 0, + bottom: 0, + }, + }}> + <Tab.Screen name="Home" component={Home} /> + <Tab.Screen name="Search" component={Search} /> + <Tab.Screen name="Upload" component={Upload} /> + <Tab.Screen name="Notifications" component={Notifications} /> + <Tab.Screen name="Profile" component={Profile} /> + </Tab.Navigator> + </Fragment> + ); +}; + +export default NavigationBar; diff --git a/src/routes/OnboardingStack.tsx b/src/routes/OnboardingStack.tsx new file mode 100644 index 00000000..5e91fe9f --- /dev/null +++ b/src/routes/OnboardingStack.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import {createStackNavigator} from '@react-navigation/stack'; +import { + Login, + RegistrationOne, + RegistrationTwo, + Verification, + ProfileOnboarding, +} from '../screens/onboarding'; + +export type RootStackParamList = { + Login: undefined; + RegistrationOne: undefined; + RegistrationTwo: + | {firstName: string; lastName: string; email: string} + | undefined; + Verification: {username: string; email: string; userId: string}; + ProfileOnboarding: {username: string; userId: string}; +}; + +const RootStack = createStackNavigator<RootStackParamList>(); + +interface OnboardingStackProps {} + +const OnboardingStack: React.FC<OnboardingStackProps> = ({}) => { + return ( + <RootStack.Navigator initialRouteName="Login"> + <RootStack.Screen + name="Login" + component={Login} + options={{headerShown: false}} + /> + <RootStack.Screen + name="RegistrationOne" + component={RegistrationOne} + options={{headerShown: false}} + /> + <RootStack.Screen + name="RegistrationTwo" + component={RegistrationTwo} + options={{headerShown: false}} + /> + <RootStack.Screen + name="Verification" + component={Verification} + options={{headerShown: false}} + /> + <RootStack.Screen + name="ProfileOnboarding" + component={ProfileOnboarding} + options={{headerShown: false}} + /> + </RootStack.Navigator> + ); +}; + +export default OnboardingStack; diff --git a/src/routes/Routes.tsx b/src/routes/Routes.tsx index 5d69b38b..43a51b90 100644 --- a/src/routes/Routes.tsx +++ b/src/routes/Routes.tsx @@ -1,131 +1,42 @@ import React from 'react'; -import {createStackNavigator} from '@react-navigation/stack'; -import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; +import {OnboardingStack, NavigationBar} from './'; -import { - Login, - RegistrationOne, - RegistrationTwo, - Verification, - 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}; - ProfileOnboarding: {username: string; userId: string}; - - // Main Screens - Home: undefined; - Notifications: undefined; - Profile: undefined; - Search: undefined; - Upload: undefined; -}; - -const RootStack = createStackNavigator<RootStackParamList>(); - -const Tab = createBottomTabNavigator(); - -function MainTabNavigator() { +interface RoutesProps {} +interface AuthProviderProps {} + +export const AuthContext = React.createContext<{ + user: boolean; + login: () => void; + logout: () => void; +}>({ + user: false, + login: () => {}, + logout: () => {}, +}); + +export const AuthContextProvider: React.FC<AuthProviderProps> = ({ + children, +}) => { + const [loggedIn, setLoggedIn] = React.useState(false); // renders onboarding stack return ( - <Tab.Navigator - screenOptions={({route}) => ({ - tabBarIcon: ({focused}) => { - if (route.name === 'Home') { - return focused ? ( - <NavigationIcon tab="Home" disabled={false} /> - ) : ( - <NavigationIcon tab="Home" disabled={true} /> - ); - } else if (route.name === 'Search') { - return focused ? ( - <NavigationIcon tab="Search" disabled={false} /> - ) : ( - <NavigationIcon tab="Search" disabled={true} /> - ); - } else if (route.name === 'Upload') { - return focused ? ( - <NavigationIcon tab="Upload" disabled={false} /> - ) : ( - <NavigationIcon tab="Upload" disabled={true} /> - ); - } else if (route.name === 'Notifications') { - return focused ? ( - <NavigationIcon tab="Notifications" disabled={false} /> - ) : ( - <NavigationIcon tab="Notifications" disabled={true} /> - ); - } else if (route.name === 'Profile') { - return focused ? ( - <NavigationIcon tab="Profile" disabled={false} /> - ) : ( - <NavigationIcon tab="Profile" disabled={true} /> - ); - } + <AuthContext.Provider + value={{ + user: loggedIn, + login: () => { + setLoggedIn(true); }, - })} - tabBarOptions={{ - showLabel: false, - style: { - backgroundColor: 'transparent', - position: 'absolute', - borderTopWidth: 0, + logout: () => { + setLoggedIn(false); }, }}> - <Tab.Screen name="Home" component={Home} /> - <Tab.Screen name="Search" component={Search} /> - <Tab.Screen name="Upload" component={Upload} /> - <Tab.Screen name="Notifications" component={Notifications} /> - <Tab.Screen name="Profile" component={Profile} /> - </Tab.Navigator> + {children} + </AuthContext.Provider> ); -} - -interface RoutesProps {} +}; const Routes: React.FC<RoutesProps> = ({}) => { - return ( - <RootStack.Navigator initialRouteName="Login"> - <RootStack.Screen - name="Login" - component={Login} - options={{headerShown: false}} - /> - <RootStack.Screen - name="RegistrationOne" - component={RegistrationOne} - options={{headerShown: false}} - /> - <RootStack.Screen - name="RegistrationTwo" - component={RegistrationTwo} - options={{headerShown: false}} - /> - <RootStack.Screen - name="Verification" - component={Verification} - options={{headerShown: false}} - /> - <RootStack.Screen - name="ProfileOnboarding" - component={ProfileOnboarding} - options={{headerShown: false}} - /> - <RootStack.Screen - name="Home" - component={MainTabNavigator} - options={{headerShown: false}} - /> - </RootStack.Navigator> - ); + const {user} = React.useContext(AuthContext); + return user ? <NavigationBar /> : <OnboardingStack />; }; export default Routes; diff --git a/src/routes/index.ts b/src/routes/index.ts index cfa05fcb..054a25c3 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,2 +1,6 @@ -export {default} from './Routes'; +export {default as OnboardingStack} from './OnboardingStack'; +export * from './OnboardingStack'; +export {default as NavigationBar} from './NavigationBar'; +export * from './NavigationBar'; +export {default as Routes} from './Routes'; export * from './Routes'; diff --git a/src/screens/main/Home.tsx b/src/screens/main/Home.tsx index cd2c418a..86f9b2ba 100644 --- a/src/screens/main/Home.tsx +++ b/src/screens/main/Home.tsx @@ -1,35 +1,24 @@ 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<RootStackParamList, 'Home'>; -type HomeScreenNavigationProp = StackNavigationProp<RootStackParamList, 'Home'>; -interface HomeProps { - route: HomeScreenRouteProp; - navigation: HomeScreenNavigationProp; -} +import {GradientBackground} from '../../components'; /** * Home Screen for displaying Tagg post suggestions * for users to discover and browse */ -const Home: React.FC<HomeProps> = () => { +const Home: React.FC = () => { return ( - <Background centered style={styles.container}> - <Text> Tagg Home Screen 🏠 </Text> - </Background> + <GradientBackground> + <Text style={styles.text}> Tagg Home Screen 🏠 </Text> + </GradientBackground> ); }; const styles = StyleSheet.create({ - container: { - flex: 1, + text: { justifyContent: 'center', - alignItems: 'center', + backgroundColor: 'transparent', }, }); export default Home; diff --git a/src/screens/main/Notifications.tsx b/src/screens/main/Notifications.tsx index ec881c8e..db89d7f9 100644 --- a/src/screens/main/Notifications.tsx +++ b/src/screens/main/Notifications.tsx @@ -1,41 +1,24 @@ 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; -} +import {GradientBackground} from '../../components'; /** * Navigation Screen for displaying other users' * actions on the logged in user's posts */ -const Notifications: React.FC<NotificationsProps> = () => { +const Notifications: React.FC = () => { return ( - <Background centered style={styles.container}> - <Text> Notifications will go here 🔔 </Text> - </Background> + <GradientBackground> + <Text style={styles.text}> Notifications will go here 🔔 </Text> + </GradientBackground> ); }; const styles = StyleSheet.create({ - container: { - flex: 1, + text: { justifyContent: 'center', - alignItems: 'center', + backgroundColor: 'transparent', }, }); export default Notifications; diff --git a/src/screens/main/Profile.tsx b/src/screens/main/Profile.tsx index a40a9cef..3a6536e4 100644 --- a/src/screens/main/Profile.tsx +++ b/src/screens/main/Profile.tsx @@ -1,38 +1,24 @@ 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<RootStackParamList, 'Home'>; -type ProfileScreenNavigationProp = StackNavigationProp< - RootStackParamList, - 'Profile' ->; -interface ProfileProps { - route: ProfileScreenRouteProp; - navigation: ProfileScreenNavigationProp; -} +import {GradientBackground} from '../../components'; /** * Profile Screen for a user's logged in profile * including posts, messaging, and settings */ -const Profile: React.FC<ProfileProps> = () => { +const Profile: React.FC = () => { return ( - <Background centered style={styles.container}> - <Text> Profile Screen 🤩 </Text> - </Background> + <GradientBackground> + <Text style={styles.text}> Profile Screen 🤩 </Text> + </GradientBackground> ); }; const styles = StyleSheet.create({ - container: { - flex: 1, + text: { justifyContent: 'center', - alignItems: 'center', + backgroundColor: 'transparent', }, }); export default Profile; diff --git a/src/screens/main/Search.tsx b/src/screens/main/Search.tsx index caa5d205..19e35d04 100644 --- a/src/screens/main/Search.tsx +++ b/src/screens/main/Search.tsx @@ -1,38 +1,24 @@ 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<RootStackParamList, 'Search'>; -type SearchScreenNavigationProp = StackNavigationProp< - RootStackParamList, - 'Search' ->; -interface SearchProps { - route: SearchScreenRouteProp; - navigation: SearchScreenNavigationProp; -} +import {GradientBackground} from '../../components'; /** * Search Screen for user recommendations and a search * tool to allow user to find other users */ -const Search: React.FC<SearchProps> = () => { +const Search: React.FC = () => { return ( - <Background centered style={styles.container}> - <Text> Search for people here 👀 </Text> - </Background> + <GradientBackground> + <Text style={styles.text}> Search for people here 👀 </Text> + </GradientBackground> ); }; const styles = StyleSheet.create({ - container: { - flex: 1, + text: { justifyContent: 'center', - alignItems: 'center', + backgroundColor: 'transparent', }, }); export default Search; diff --git a/src/screens/main/Upload.tsx b/src/screens/main/Upload.tsx index 4bbe2d0a..d91af1f5 100644 --- a/src/screens/main/Upload.tsx +++ b/src/screens/main/Upload.tsx @@ -1,37 +1,24 @@ 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<RootStackParamList, 'Upload'>; -type UploadScreenNavigationProp = StackNavigationProp< - RootStackParamList, - 'Upload' ->; -interface UploadProps { - route: UploadScreenRouteProp; - navigation: UploadScreenNavigationProp; -} +import {GradientBackground} from '../../components'; /** * Upload Screen to allow users to upload posts to Tagg */ -const Upload: React.FC<UploadProps> = () => { +const Upload: React.FC = () => { return ( - <Background centered style={styles.container}> - <Text> Upload pics ⬆ </Text> - </Background> + <GradientBackground> + <Text style={styles.text}> Upload pics ⬆ </Text> + </GradientBackground> ); }; const styles = StyleSheet.create({ - container: { - flex: 1, + text: { justifyContent: 'center', - alignItems: 'center', + backgroundColor: 'transparent', }, }); + export default Upload; diff --git a/src/screens/onboarding/Login.tsx b/src/screens/onboarding/Login.tsx index 537ce868..7b76e97c 100644 --- a/src/screens/onboarding/Login.tsx +++ b/src/screens/onboarding/Login.tsx @@ -13,7 +13,7 @@ import { Platform, } from 'react-native'; -import {RootStackParamList} from '../../routes'; +import {RootStackParamList, AuthContext} from '../../routes'; import {Background, TaggInput, SubmitButton} from '../../components'; import {usernameRegex, LOGIN_ENDPOINT} from '../../constants'; @@ -41,6 +41,8 @@ const Login: React.FC<LoginProps> = ({navigation}: LoginProps) => { isValidPassword: false, attemptedSubmit: false, }); + // determines if user is logged in + const {login} = React.useContext(AuthContext); /** * Updates the state of username. Also verifies the input of the username field by ensuring proper length and appropriate characters. @@ -118,7 +120,7 @@ const Login: React.FC<LoginProps> = ({navigation}: LoginProps) => { let statusCode = response.status; if (statusCode === 200) { - navigation.navigate('Home'); + login(); } else if (statusCode === 401) { Alert.alert( 'Login failed 😔', diff --git a/src/screens/onboarding/ProfileOnboarding.tsx b/src/screens/onboarding/ProfileOnboarding.tsx index 191d62b2..6ce1ff80 100644 --- a/src/screens/onboarding/ProfileOnboarding.tsx +++ b/src/screens/onboarding/ProfileOnboarding.tsx @@ -10,7 +10,7 @@ import { Alert, View, } from 'react-native'; -import {RootStackParamList} from '../../routes'; +import {RootStackParamList, AuthContext} from '../../routes'; import {Background} from '../../components'; import ImagePicker from 'react-native-image-crop-picker'; import {REGISTER_ENDPOINT} from '../../constants'; @@ -39,6 +39,12 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { const [smallPic, setSmallPic] = React.useState(''); /** + * login: determines if user successully created an account to + * navigate to home and display main tab navigation bar + */ + const {login} = React.useContext(AuthContext); + + /** * Profile screen "Add Large Profile Pic Here" button */ const LargeProfilePic = () => ( @@ -147,10 +153,7 @@ const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { let data = await response.json(); let statusCode = response.status; if (statusCode === 200) { - Alert.alert( - 'Profile successfully created! 🥳', - `Welcome to Tagg, ${username}!`, - ); + login(); } else if (statusCode === 400) { Alert.alert('Profile update failed. 😔', `${data}`); } else { |