Fakultas Ilmu Komputer UI

Commit 6199efa7 authored by Doan Andreas Nathanael's avatar Doan Andreas Nathanael
Browse files

Merge branch 'PBI-5-login_from_signup_page' into 'staging'

Add Logout Button & Login Link in Signup Page

See merge request !33
parents 90a8db7a bc7e4d73
Pipeline #73578 passed with stages
in 46 minutes and 6 seconds
import React from 'react';
import { render, fireEvent, waitFor } from 'utils/testing';
import * as ROUTES from 'constants/routes';
import LogoutButton from '.';
import { UserContext } from 'provider';
describe('LogoutButton', () => {
const initialUser = {
id: null,
email: '',
name: '',
role: null,
};
const userContextMock = {
user: initialUser,
firstAuthenticated: false,
isAuthenticated: true,
isUnpaidClient: false,
isPaidClient: false,
isNutritionist: false,
isAdmin: false,
isLoading: false,
isFirstLoading: false,
signup: jest.fn(),
login: jest.fn(),
loginWithGoogle: jest.fn(),
logout: jest.fn(),
};
it('renders correctly', () => {
render(<LogoutButton />, ROUTES.checkout);
});
it('calls logout and redirects to initial page when clicked', async () => {
const { getByTestId } = render(
<UserContext.Provider value={userContextMock}>
<LogoutButton />
</UserContext.Provider>,
ROUTES.checkout,
);
const logoutButton = getByTestId('logoutButton');
expect(logoutButton).toBeTruthy();
await waitFor(() => fireEvent.press(logoutButton));
expect(userContextMock.logout).toBeCalledTimes(1);
});
});
import React, { FC, useContext } from 'react';
import { UserContext } from 'provider';
import { Button, Icon } from 'react-native-elements';
import { StyleSheet, View } from 'react-native';
import { useNavigation } from '@react-navigation/core';
import * as ROUTES from 'constants/routes';
const LogoutButton: FC = () => {
const { logout, isAuthenticated } = useContext(UserContext);
const navigation = useNavigation();
const handlePress = async () => {
await logout();
navigation.reset({
index: 0,
routes: [{ name: ROUTES.initial }],
});
};
return isAuthenticated ? (
<Button
icon={<Icon name="logout" type="material" />}
buttonStyle={styles.button}
onPress={handlePress}
testID="logoutButton"
/>
) : (
<View />
);
};
const styles = StyleSheet.create({
button: {
backgroundColor: '#fff',
},
});
export default LogoutButton;
......@@ -10,6 +10,7 @@ import ContextProvider from 'provider';
import { theme } from 'styles/theme';
import { screenOptions, toastConfig } from './styles';
import LogoutButton from './LogoutButton';
const Stack = createStackNavigator();
......@@ -29,6 +30,7 @@ const App: FC = () => {
options={{
title: nav.header,
headerShown: Boolean(nav.header),
headerRight: LogoutButton,
}}
/>
))}
......
......@@ -4,14 +4,14 @@ import { UserContext } from 'provider';
import * as ROUTES from 'constants/routes';
const useAuthGuardEffect = (signupFallback?: boolean) => {
const { isAuthenticated } = useContext(UserContext);
const navigation = useNavigation();
const { isAuthenticated, firstAuthenticated } = useContext(UserContext);
const navigation = useNavigation();
useEffect(() => {
if (!isAuthenticated) {
if (!isAuthenticated && firstAuthenticated) {
navigation.navigate(signupFallback ? ROUTES.registration : ROUTES.login);
}
}, [isAuthenticated, signupFallback, navigation]);
}, [isAuthenticated, signupFallback, navigation, firstAuthenticated]);
};
export default useAuthGuardEffect;
......@@ -32,6 +32,7 @@ const initialUser = {
export const UserContext = createContext<iUserContext>({
user: initialUser,
firstAuthenticated: true,
isAuthenticated: false,
isUnpaidClient: false,
isPaidClient: false,
......@@ -49,6 +50,7 @@ export const useUserContext = (): iUserContext => {
const [user, setUser] = useState<User>(initialUser);
const [isLoading, setIsLoading] = useState(false);
const [isFirstLoading, setIsFirstLoading] = useState(false);
const [firstAuth, setFirstAuth] = useState(true);
const [clientHasPaid] = useState(false);
const logout = useCallback(async () => {
......@@ -57,6 +59,7 @@ export const useUserContext = (): iUserContext => {
await removeCache(CACHE_KEYS.refreshToken);
setUser(initialUser);
resetAuthHeader();
setFirstAuth(false);
}, []);
const getUser = useCallback(async () => {
......@@ -164,6 +167,7 @@ export const useUserContext = (): iUserContext => {
return {
user,
firstAuthenticated: firstAuth,
isAuthenticated: user.id !== null,
isUnpaidClient: user.role === UserRole.CLIENT,
isPaidClient: user.role === UserRole.CLIENT && clientHasPaid,
......
......@@ -9,6 +9,7 @@ import {
export interface iUserContext {
user: User;
firstAuthenticated: boolean;
isAuthenticated: boolean;
isUnpaidClient: boolean;
isPaidClient: boolean;
......
......@@ -102,4 +102,15 @@ describe('ManualRegistrationPage', () => {
const nextPageText = queryByText(/Checkout/i);
expect(nextPageText).toBeFalsy();
});
test('has link button that navigates to Login Page', async () => {
const { getByText, queryByText, queryAllByText } = render(
<ManualRegistrationPage />,
ROUTES.registration,
);
expect(queryByText(/Login disini/i)).toBeTruthy();
await waitFor(() => fireEvent.press(getByText(/Login disini/i)));
expect(queryAllByText(/Login/i)).toBeTruthy();
});
});
import React, { FC, useContext } from 'react';
import { useAuthEffect, useForm } from 'hooks';
import { ScrollView } from 'react-native-gesture-handler';
import { useNavigation } from '@react-navigation/core';
import { BigButton, Toast } from 'components/core';
import { BigButton, Link, Toast } from 'components/core';
import { Section } from 'components/layout';
import { TextField } from 'components/form';
import { GoogleLoginButton } from '../components';
......@@ -10,6 +11,7 @@ import { GoogleLoginButton } from '../components';
import { fieldValidation, initialValues, textField } from './schema';
import { generateValidationSchema } from 'utils/form';
import { UserContext } from 'provider';
import * as ROUTES from 'constants/routes';
import { layoutStyles } from 'styles';
......@@ -18,6 +20,7 @@ const isPasswordField = (name: string) =>
const ManualRegistrationPage: FC = () => {
const { signup, loginWithGoogle, isLoading } = useContext(UserContext);
const navigation = useNavigation();
const {
getTextInputProps,
......@@ -70,6 +73,12 @@ const ManualRegistrationPage: FC = () => {
<Section>
<GoogleLoginButton onPress={signupWithGoogle} isLoading={isLoading} />
</Section>
<Section>
<Link
title="Sudah punya akun? Login disini"
onPress={() => navigation.navigate(ROUTES.login)}
/>
</Section>
</ScrollView>
);
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment