Skip to content

Commit

Permalink
➕ Add login and private routes
Browse files Browse the repository at this point in the history
  • Loading branch information
djpremier committed Dec 6, 2020
1 parent 00f99ca commit f1fb044
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 33 deletions.
3 changes: 3 additions & 0 deletions classes/level-02/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"dependencies": {
"@react-native-community/async-storage": "^1.12.1",
"@react-native-community/masked-view": "^0.1.10",
"@react-navigation/native": "^5.8.10",
"@react-navigation/stack": "^5.12.8",
"@unform/core": "^2.1.3",
"@unform/mobile": "^2.1.3",
"axios": "^0.21.0",
"react": "17.0.1",
"react-native": "0.63.4",
"react-native-gesture-handler": "^1.9.0",
Expand All @@ -30,6 +32,7 @@
"@babel/core": "^7.8.4",
"@babel/runtime": "^7.8.4",
"@react-native-community/eslint-config": "^2.0.0",
"@types/axios": "^0.14.0",
"@types/jest": "^26.0.16",
"@types/react-native": "^0.63.2",
"@types/react-native-vector-icons": "^6.4.6",
Expand Down
9 changes: 6 additions & 3 deletions classes/level-02/mobile/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import { View, StatusBar } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';

import Routes from './routes';
import AppProvider from './hooks';

const App: FC = () => (
<NavigationContainer>
<StatusBar barStyle="light-content" backgroundColor="#312e38" />
<View style={{ flex: 1, backgroundColor: '#312e38' }}>
<Routes />
</View>
<AppProvider>
<View style={{ flex: 1, backgroundColor: '#312e38' }}>
<Routes />
</View>
</AppProvider>
</NavigationContainer>
);

Expand Down
92 changes: 92 additions & 0 deletions classes/level-02/mobile/src/hooks/auth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import AsyncStorage from '@react-native-community/async-storage';
import React, {
createContext,
useCallback,
FC,
useState,
useContext,
useEffect,
} from 'react';

import api from '../services/api';

interface AuthState {
token: string;
user: Record<string, unknown>;
}

interface SignInCredentials {
email: string;
password: string;
}

interface AuthContextData {
user: Record<string, unknown>;
loading: boolean;
signIn(credentials: SignInCredentials): Promise<void>;
signOut(): void;
}

const AuthContext = createContext<AuthContextData>({} as AuthContextData);

const AuthProvider: FC = ({ children }) => {
const [data, setData] = useState<AuthState>({} as AuthState);
const [loading, setLoading] = useState(true);

useEffect(() => {
const loadStorageData = async (): Promise<void> => {
const [token, user] = await AsyncStorage.multiGet([
'@GoBarber:token',
'@GoBarber:user',
]);

if (token[1] && user[1]) {
setData({ token: token[1], user: JSON.parse(user[1]) });
}

setLoading(false);
};

loadStorageData();
});

const signIn = useCallback(async ({ email, password }) => {
const response = await api.post('sessions', {
email,
password,
});

const { token, user } = response.data;

await AsyncStorage.multiSet([
['@GoBarber:token', token],
['@GoBarber:user', JSON.stringify(user)],
]);

setData({ token, user });
}, []);

const signOut = useCallback(async () => {
await AsyncStorage.multiRemove(['@GoBarber:token', '@GoBarber:user']);

setData({} as AuthState);
}, []);

return (
<AuthContext.Provider value={{ user: data.user, loading, signIn, signOut }}>
{children}
</AuthContext.Provider>
);
};

const useAuth = (): AuthContextData => {
const context = useContext(AuthContext);

if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}

return context;
};

export { AuthProvider, useAuth };
9 changes: 9 additions & 0 deletions classes/level-02/mobile/src/hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, { FC } from 'react';

import { AuthProvider } from './auth';

const AppProvider: FC = ({ children }) => (
<AuthProvider>{children}</AuthProvider>
);

export default AppProvider;
14 changes: 14 additions & 0 deletions classes/level-02/mobile/src/pages/Dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, { FC } from 'react';
import { View, Button } from 'react-native';
import { useAuth } from '../../hooks/auth';

const Dashboard: FC = () => {
const { signOut } = useAuth();
return (
<View style={{ flex: 1, justifyContent: 'center' }}>
<Button title="Sair" onPress={signOut} />
</View>
);
};

export default Dashboard;
14 changes: 7 additions & 7 deletions classes/level-02/mobile/src/pages/SignIn/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
CreateAccountButtonText,
} from './styles';
import getValidationErrors from '../../utils/getValidationErrors';
import { useAuth } from '../../hooks/auth';

interface SignInFormData {
email: string;
Expand All @@ -38,6 +39,7 @@ const SignIn: FC = () => {
const formRef = useRef<FormHandles>(null);
const passwordInputRef = useRef<TextInput>(null);
const navigation = useNavigation();
const { signIn, user } = useAuth();

const handleSignIn = useCallback(
async (data: SignInFormData): Promise<void> => {
Expand All @@ -55,12 +57,10 @@ const SignIn: FC = () => {
abortEarly: false,
});

// await signIn({
// email: data.email,
// password: data.password,
// });

// history.push('/dashboard');
await signIn({
email: data.email,
password: data.password,
});
} catch (err) {
if (err instanceof Yup.ValidationError) {
const errors = getValidationErrors(err);
Expand All @@ -76,7 +76,7 @@ const SignIn: FC = () => {
);
}
},
[],
[signIn],
);

return (
Expand Down
16 changes: 8 additions & 8 deletions classes/level-02/mobile/src/pages/SignUp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import logoImg from '../../assets/logo.png';

import { Container, Title, BackToSignIn, BackToSignInText } from './styles';
import getValidationErrors from '../../utils/getValidationErrors';
import api from '../../services/api';

interface SignUpFormData {
name: string;
Expand Down Expand Up @@ -51,15 +52,14 @@ const SignUp: FC = () => {
abortEarly: false,
});

// await api.post('users', data);
await api.post('users', data);

// addToast({
// type: 'success',
// title: 'Cadastro realizado!',
// description: 'Você já pode fazer seu logon no GoBarber.',
// });
Alert.alert(
'Cadastro realizado!',
'Você já pode fazer seu logon no GoBarber.',
);

// history.push('/');
navigation.goBack();
} catch (err) {
if (err instanceof Yup.ValidationError) {
const errors = getValidationErrors(err);
Expand All @@ -75,7 +75,7 @@ const SignUp: FC = () => {
);
}
},
[],
[navigation],
);

return (
Expand Down
18 changes: 18 additions & 0 deletions classes/level-02/mobile/src/routes/app.routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createStackNavigator } from '@react-navigation/stack';
import React, { FC } from 'react';
import Dashboard from '../pages/Dashboard';

const App = createStackNavigator();

const AppRoutes: FC = () => (
<App.Navigator
screenOptions={{
headerShown: false,
cardStyle: { backgroundColor: '#312e38' },
}}
>
<App.Screen name="Dashboard" component={Dashboard} />
</App.Navigator>
);

export default AppRoutes;
20 changes: 20 additions & 0 deletions classes/level-02/mobile/src/routes/auth.routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createStackNavigator } from '@react-navigation/stack';
import React, { FC } from 'react';
import SignIn from '../pages/SignIn';
import SignUp from '../pages/SignUp';

const Auth = createStackNavigator();

const AuthRoutes: FC = () => (
<Auth.Navigator
screenOptions={{
headerShown: false,
cardStyle: { backgroundColor: '#312e38' }
}}
>
<Auth.Screen name="SignIn" component={SignIn} />
<Auth.Screen name="SignUp" component={SignUp} />
</Auth.Navigator>
)

export default AuthRoutes;
33 changes: 18 additions & 15 deletions classes/level-02/mobile/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { createStackNavigator } from '@react-navigation/stack';
import React, { FC } from 'react';
import SignIn from '../pages/SignIn';
import SignUp from '../pages/SignUp';
import { View, ActivityIndicator } from 'react-native';

const Auth = createStackNavigator();
import AuthRoutes from './auth.routes';
import AppRoutes from './app.routes';

const Routes: FC = () => (
<Auth.Navigator
screenOptions={{
headerShown: false,
cardStyle: { backgroundColor: '#312e38' }
}}
>
<Auth.Screen name="SignIn" component={SignIn} />
<Auth.Screen name="SignUp" component={SignUp} />
</Auth.Navigator>
)
import { useAuth } from '../hooks/auth';

const Routes: FC = () => {
const { user, loading } = useAuth();

if (loading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" color="#999" />
</View>
);
}

return user ? <AppRoutes /> : <AuthRoutes />;
};

export default Routes;
7 changes: 7 additions & 0 deletions classes/level-02/mobile/src/services/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import axios from 'axios';

const api = axios.create({
baseURL: 'http://192.168.1.20:3333',
});

export default api;
Loading

0 comments on commit f1fb044

Please sign in to comment.