aboutsummaryrefslogtreecommitdiff
path: root/src/routes
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes')
-rw-r--r--src/routes/NavigationBar.tsx75
-rw-r--r--src/routes/OnboardingStack.tsx57
-rw-r--r--src/routes/Routes.tsx44
-rw-r--r--src/routes/authentication/AuthProvider.tsx122
-rw-r--r--src/routes/authentication/index.ts2
-rw-r--r--src/routes/index.ts10
-rw-r--r--src/routes/onboarding/Onboarding.tsx43
-rw-r--r--src/routes/onboarding/OnboardingStack.tsx13
-rw-r--r--src/routes/onboarding/index.ts2
-rw-r--r--src/routes/tabs/NavigationBar.tsx73
-rw-r--r--src/routes/tabs/index.ts1
11 files changed, 268 insertions, 174 deletions
diff --git a/src/routes/NavigationBar.tsx b/src/routes/NavigationBar.tsx
deleted file mode 100644
index 84c18e00..00000000
--- a/src/routes/NavigationBar.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-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
deleted file mode 100644
index 5e91fe9f..00000000
--- a/src/routes/OnboardingStack.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-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 43a51b90..92cd3dd2 100644
--- a/src/routes/Routes.tsx
+++ b/src/routes/Routes.tsx
@@ -1,42 +1,14 @@
import React from 'react';
-import {OnboardingStack, NavigationBar} from './';
-interface RoutesProps {}
-interface AuthProviderProps {}
+import {AuthContext} from './authentication';
+import NavigationBar from './tabs';
+import Onboarding from './onboarding';
-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 (
- <AuthContext.Provider
- value={{
- user: loggedIn,
- login: () => {
- setLoggedIn(true);
- },
- logout: () => {
- setLoggedIn(false);
- },
- }}>
- {children}
- </AuthContext.Provider>
- );
-};
-
-const Routes: React.FC<RoutesProps> = ({}) => {
- const {user} = React.useContext(AuthContext);
- return user ? <NavigationBar /> : <OnboardingStack />;
+const Routes: React.FC = () => {
+ const {
+ user: {userId},
+ } = React.useContext(AuthContext);
+ return userId ? <NavigationBar /> : <Onboarding />;
};
export default Routes;
diff --git a/src/routes/authentication/AuthProvider.tsx b/src/routes/authentication/AuthProvider.tsx
new file mode 100644
index 00000000..bd5706f3
--- /dev/null
+++ b/src/routes/authentication/AuthProvider.tsx
@@ -0,0 +1,122 @@
+import React, {useEffect} from 'react';
+import {createContext, useState} from 'react';
+import RNFetchBlob from 'rn-fetch-blob';
+import {UserType, ProfileType} from '../../types';
+import {
+ PROFILE_INFO_ENDPOINT,
+ AVATAR_PHOTO_ENDPOINT,
+ COVER_PHOTO_ENDPOINT,
+} from '../../constants';
+
+interface AuthContextProps {
+ user: UserType;
+ profile: ProfileType;
+ login: (userId: string, username: string) => void;
+ logout: () => void;
+ avatar: string | null;
+ cover: string | null;
+}
+const NO_USER: UserType = {
+ userId: '',
+ username: '',
+};
+const NO_PROFILE: ProfileType = {
+ biography: '',
+ website: '',
+ name: '',
+};
+export const AuthContext = createContext<AuthContextProps>({
+ user: NO_USER,
+ profile: NO_PROFILE,
+ login: () => {},
+ logout: () => {},
+ avatar: null,
+ cover: null,
+});
+
+/**
+ * Authentication provider for the application.
+ */
+const AuthProvider: React.FC = ({children}) => {
+ const [user, setUser] = useState<UserType>(NO_USER);
+ const [profile, setProfile] = useState<ProfileType>(NO_PROFILE);
+ const [avatar, setAvatar] = useState<string | null>(null);
+ const [cover, setCover] = useState<string | null>(null);
+
+ const {userId} = user;
+ useEffect(() => {
+ if (!userId) {
+ return;
+ }
+ const loadProfileInfo = async () => {
+ try {
+ const response = await fetch(PROFILE_INFO_ENDPOINT + `${userId}/`, {
+ method: 'GET',
+ });
+ const status = response.status;
+ if (status === 200) {
+ const info = await response.json();
+ let {name, biography, website} = info;
+ setProfile({name, biography, website});
+ }
+ } catch (error) {
+ console.log(error);
+ }
+ };
+ const loadAvatar = async () => {
+ try {
+ const response = await RNFetchBlob.config({
+ fileCache: true,
+ appendExt: 'jpg',
+ }).fetch('GET', AVATAR_PHOTO_ENDPOINT + `${userId}/`);
+ const status = response.info().status;
+ if (status === 200) {
+ setAvatar(response.path());
+ } else {
+ setAvatar('');
+ }
+ } catch (error) {
+ console.log(error);
+ }
+ };
+ const loadCover = async () => {
+ try {
+ let response = await RNFetchBlob.config({
+ fileCache: true,
+ appendExt: 'jpg',
+ }).fetch('GET', COVER_PHOTO_ENDPOINT + `${userId}/`);
+ const status = response.info().status;
+ if (status === 200) {
+ setCover(response.path());
+ } else {
+ setCover('');
+ }
+ } catch (error) {
+ console.log(error);
+ }
+ };
+ loadProfileInfo();
+ loadAvatar();
+ loadCover();
+ }, [userId]);
+
+ return (
+ <AuthContext.Provider
+ value={{
+ user,
+ profile,
+ avatar,
+ cover,
+ login: (id, username) => {
+ setUser({...user, userId: id, username});
+ },
+ logout: () => {
+ setUser(NO_USER);
+ },
+ }}>
+ {children}
+ </AuthContext.Provider>
+ );
+};
+
+export default AuthProvider;
diff --git a/src/routes/authentication/index.ts b/src/routes/authentication/index.ts
new file mode 100644
index 00000000..9968ae93
--- /dev/null
+++ b/src/routes/authentication/index.ts
@@ -0,0 +1,2 @@
+export * from './AuthProvider';
+export {default} from './AuthProvider';
diff --git a/src/routes/index.ts b/src/routes/index.ts
index 054a25c3..69697b20 100644
--- a/src/routes/index.ts
+++ b/src/routes/index.ts
@@ -1,6 +1,4 @@
-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';
+export {default as AuthProvider} from './authentication';
+export * from './authentication';
+export * from './onboarding';
+export {default} from './Routes';
diff --git a/src/routes/onboarding/Onboarding.tsx b/src/routes/onboarding/Onboarding.tsx
new file mode 100644
index 00000000..d2bfbfd6
--- /dev/null
+++ b/src/routes/onboarding/Onboarding.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import {OnboardingStack} from './OnboardingStack';
+import {
+ Login,
+ RegistrationOne,
+ RegistrationTwo,
+ Verification,
+ ProfileOnboarding,
+} from '../../screens';
+
+const Onboarding: React.FC = () => {
+ return (
+ <OnboardingStack.Navigator initialRouteName="Login">
+ <OnboardingStack.Screen
+ name="Login"
+ component={Login}
+ options={{headerShown: false}}
+ />
+ <OnboardingStack.Screen
+ name="RegistrationOne"
+ component={RegistrationOne}
+ options={{headerShown: false}}
+ />
+ <OnboardingStack.Screen
+ name="RegistrationTwo"
+ component={RegistrationTwo}
+ options={{headerShown: false}}
+ />
+ <OnboardingStack.Screen
+ name="Verification"
+ component={Verification}
+ options={{headerShown: false}}
+ />
+ <OnboardingStack.Screen
+ name="ProfileOnboarding"
+ component={ProfileOnboarding}
+ options={{headerShown: false}}
+ />
+ </OnboardingStack.Navigator>
+ );
+};
+
+export default Onboarding;
diff --git a/src/routes/onboarding/OnboardingStack.tsx b/src/routes/onboarding/OnboardingStack.tsx
new file mode 100644
index 00000000..f9722d46
--- /dev/null
+++ b/src/routes/onboarding/OnboardingStack.tsx
@@ -0,0 +1,13 @@
+import {createStackNavigator} from '@react-navigation/stack';
+
+export type OnboardingStackParams = {
+ Login: undefined;
+ RegistrationOne: undefined;
+ RegistrationTwo:
+ | {firstName: string; lastName: string; email: string}
+ | undefined;
+ Verification: {username: string; email: string; userId: string};
+ ProfileOnboarding: {username: string; userId: string};
+};
+
+export const OnboardingStack = createStackNavigator<OnboardingStackParams>();
diff --git a/src/routes/onboarding/index.ts b/src/routes/onboarding/index.ts
new file mode 100644
index 00000000..66b0f3f4
--- /dev/null
+++ b/src/routes/onboarding/index.ts
@@ -0,0 +1,2 @@
+export * from './OnboardingStack';
+export {default} from './Onboarding';
diff --git a/src/routes/tabs/NavigationBar.tsx b/src/routes/tabs/NavigationBar.tsx
new file mode 100644
index 00000000..aca968c2
--- /dev/null
+++ b/src/routes/tabs/NavigationBar.tsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
+import {NavigationIcon} from '../../components';
+import {
+ ProfileScreen,
+ Home,
+ Notifications,
+ Search,
+ Upload,
+} from '../../screens';
+
+const Tabs = createBottomTabNavigator();
+
+const NavigationBar: React.FC = () => {
+ return (
+ <Tabs.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="Profile"
+ tabBarOptions={{
+ showLabel: false,
+ style: {
+ backgroundColor: 'transparent',
+ position: 'absolute',
+ borderTopWidth: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ },
+ }}>
+ <Tabs.Screen name="Home" component={Home} />
+ <Tabs.Screen name="Search" component={Search} />
+ <Tabs.Screen name="Upload" component={Upload} />
+ <Tabs.Screen name="Notifications" component={Notifications} />
+ <Tabs.Screen name="Profile" component={ProfileScreen} />
+ </Tabs.Navigator>
+ );
+};
+
+export default NavigationBar;
diff --git a/src/routes/tabs/index.ts b/src/routes/tabs/index.ts
new file mode 100644
index 00000000..8ea77e8f
--- /dev/null
+++ b/src/routes/tabs/index.ts
@@ -0,0 +1 @@
+export {default} from './NavigationBar';