Fakultas Ilmu Komputer UI

Commit 9374fa4f authored by Zafir Rasyidi Taufik's avatar Zafir Rasyidi Taufik
Browse files

[GREEN]Connect GoogleSignin with backend

parent c0537f8f
Pipeline #79221 failed with stage
in 14 minutes and 8 seconds
......@@ -28,6 +28,7 @@ import initialCacheState, {
} from 'contexts/AppContext/cache';
import { useMainService } from 'services'
import { Box, Text, Button, Gap } from 'components';
import OfficerSignupFormGoogleSignin from 'scenes/OfficerSignupFormGoogleSignin';
const StyledApp = styled.SafeAreaView`
height: 100%;
......@@ -309,6 +310,10 @@ const App = () => {
name="officer-signup-form"
component={OfficerSignupForm}
/>
<Stack.Screen
name="officer-signup-form-google-signin"
component={OfficerSignupFormGoogleSignin}
/>
<Stack.Screen
name="officer-signup-finish"
component={OfficerSignupFormFinishPage}
......
......@@ -11,6 +11,14 @@ import {useNavigation} from '@react-navigation/native';
import WaveBackground from 'assets/arts/background-wave.png';
import WonderingIllustration from 'assets/illustrations/wondering.png';
import { GoogleSignin, GoogleSigninButton, statusCodes } from '@react-native-google-signin/google-signin';
import {GOOGLE_CLIENT_ID} from "react-native-dotenv"
GoogleSignin.configure(
{webClientId: GOOGLE_CLIENT_ID, offlineAccess: true}
);
enum LoginResponse {
InvalidCredential = 'Username atau Password Salah.',
UnknownServerError = 'Unknown Server Error',
......@@ -30,6 +38,27 @@ const LoginPage = () => {
type: 'ANY',
},
});
const [userInfo, setUserInfo] = useState<any>();
const signIn = async () => {
try {
await GoogleSignin.hasPlayServices();
const tempUserInfo = await GoogleSignin.signIn();
setUserInfo(tempUserInfo);
navigation.navigate('officer-signup-form-google-signin', {idToken: tempUserInfo.idToken});
} catch (error) {
console.log(error)
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
// user cancelled the login flow
} else if (error.code === statusCodes.IN_PROGRESS) {
// operation (e.g. sign in) is in progress already
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// play services not available or outdated
} else {
}
}
};
return (
<Box
......@@ -143,6 +172,17 @@ const LoginPage = () => {
Ajukan Akun Kader
</Button>
</Box>
<Gap gap={24} axis={Gap.Axis.Vertical} />
<Box
mainAxis="center"
>
<GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={() => signIn()}
/>
</Box>
</Action>
</Box>
);
......
const KECAMATAN_VALUES: {label: string; value: string}[] = [
{ label: 'Beji', value: 'Beji' },
{ label: 'Bojongsari', value: 'Bojongsari' },
{ label: 'Cilodong', value: 'Cilodong' },
{ label: 'Cimanggis', value: 'Cimanggis' },
{ label: 'Cinere', value: 'Cinere' },
{ label: 'Cipayung', value: 'Cipayung' },
{ label: 'Limo', value: 'Limo' },
{ label: 'Pancoran Mas', value: 'Pancoran Mas' },
{ label: 'Sawangan', value: 'Sawangan' },
{ label: 'Sukmajaya', value: 'Sukmajaya' },
{ label: 'Tapos', value: 'Tapos' },
];
const KELURAHAN_VALUES: { [key: string]: {label: string; value: string}[] } = {
'Beji': [
{ label: 'Beji', value: 'Beji' },
{ label: 'Beji Timur', value: 'Beji Timur' },
{ label: 'Kemirimuka', value: 'Kemirimuka' },
{ label: 'Kukusan', value: 'Kukusan' },
{ label: 'Pondok Cina', value: 'Pondok Cina' },
{ label: 'Tanah Baru', value: 'Tanah Baru' },
],
'Bojongsari': [
{ label: 'Bojongsari Baru', value: 'Bojongsari Baru' },
{ label: 'Bojongsari Lama', value: 'Bojongsari Lama' },
{ label: 'Curug', value: 'Curug' },
{ label: 'Duren Mekar', value: 'Duren Mekar' },
{ label: 'Duren Seribu', value: 'Duren Seribu' },
{ label: 'Pondok Petir', value: 'Pondok Petir' },
{ label: 'Serua', value: 'Serua' },
],
'Cilodong': [
{ label: 'Cilodong', value: 'Cilodong' },
{ label: 'Jatimulya', value: 'Jatimulya' },
{ label: 'Kalibaru', value: 'Kalibaru' },
{ label: 'Kalimulya', value: 'Kalimulya' },
{ label: 'Sukamaju', value: 'Sukamaju' },
],
'Cimanggis': [
{ label: 'Cisalak Pasar', value: 'Cisalak Pasar' },
{ label: 'Curug', value: 'Curug' },
{ label: 'Harjamukti', value: 'Harjamukti' },
{ label: 'Mekarsari', value: 'Mekarsari' },
{ label: 'Pasir Gunung Selatan', value: 'Pasir Gunung Selatan' },
{ label: 'Tugu', value: 'Tugu' },
],
'Cinere': [
{ label: 'Cinere', value: 'Cinere' },
{ label: 'Gandul', value: 'Gandul' },
{ label: 'Pangkalan Jati', value: 'Pangkalan Jati' },
{ label: 'Pangkalan Jati Baru', value: 'Pangkalan Jati Baru' },
],
'Cipayung': [
{ label: 'Bojong Pondok Terong', value: 'Bojong Pondok Terong' },
{ label: 'Cipayung', value: 'Cipayung' },
{ label: 'Cipayung Jaya', value: 'Cipayung Jaya' },
{ label: 'Pondok Jaya', value: 'Pondok Jaya' },
{ label: 'Ratujaya', value: 'Ratujaya' },
],
'Limo': [
{ label: 'Grogol', value: 'Grogol' },
{ label: 'Krukut', value: 'Krukut' },
{ label: 'Limo', value: 'Limo' },
{ label: 'Meruyung', value: 'Meruyung' },
],
'Pancoran Mas': [
{ label: 'Depok', value: 'Depok' },
{ label: 'Depok Jaya', value: 'Depok Jaya' },
{ label: 'Mampang', value: 'Mampang' },
{ label: 'Pancoran Mas', value: 'Pancoran Mas' },
{ label: 'Rangkapan Jaya', value: 'Rangkapan Jaya' },
{ label: 'Rangkapan Jaya Baru', value: 'Rangkapan Jaya Baru' },
],
'Sawangan': [
{ label: 'Bedahan', value: 'Bedahan' },
{ label: 'Cinangka', value: 'Cinangka' },
{ label: 'Kedaung', value: 'Kedaung' },
{ label: 'Pasir Putih', value: 'Pasir Putih' },
{ label: 'Pengasinan', value: 'Pengasinan' },
{ label: 'Sawangan Baru', value: 'Sawangan Baru' },
{ label: 'Sawangan Lama', value: 'Sawangan Lama' },
],
'Sukmajaya': [
{ label: 'Abadijaya', value: 'Abadijaya' },
{ label: 'Bakti Jaya', value: 'Bakti Jaya' },
{ label: 'Cisalak', value: 'Cisalak' },
{ label: 'Mekar Jaya', value: 'Mekar Jaya' },
{ label: 'Sukmajaya', value: 'Sukmajaya' },
{ label: 'Tirtajaya', value: 'Tirtajaya' },
],
'Tapos': [
{ label: 'Cilangkap', value: 'Cilangkap' },
{ label: 'Cimpaeun', value: 'Cimpaeun' },
{ label: 'Jatijajar', value: 'Jatijajar' },
{ label: 'Leuwinanggung', value: 'Leuwinanggung' },
{ label: 'Sukamaju Baru', value: 'Sukamaju Baru' },
{ label: 'Sukatani', value: 'Sukatani' },
{ label: 'Tapos', value: 'Tapos' },
],
};
export {KECAMATAN_VALUES};
export {KELURAHAN_VALUES};
import React, {useState, useContext} from 'react';
import styled from 'styled-components/native';
import {ActivityIndicator, ScrollView, View, Modal, Image} from 'react-native';
import {Header, Field, Button, Text} from '../../components';
import error_img from '../OfficerSignupForm/img/folder.png';
import {useFormState} from 'helpers';
import {KECAMATAN_VALUES, KELURAHAN_VALUES} from './constants';
import {useNavigation, useRoute} from '@react-navigation/native';
import {AppContext} from 'contexts';
import translateError from '../OfficerSignupForm/utilities';
const OfficerSignupFormGoogleSignin = () => {
const navigation = useNavigation();
const global = useContext(AppContext);
const headingSize = 0.028 * global.vh;
const imageSize = 0.15 * global.vh;
const route = useRoute();
const [form, setField] = useFormState({
name: {type: 'text'},
username: {type: 'any'},
password: {type: 'password'},
email: {type: 'email'},
phone_number: {type: 'phone'},
district: {type: 'any'},
sub_district: {type: 'any'},
});
const [serverHasError, setServerHasError] = useState(false);
const [messageErrors, setMessageErrors] = useState<any>({
name: '',
username: '',
password: '',
email: '',
phoneNumber: '',
district: '',
sub_district: '',
})
const [modalVisible, setModalVisible] = useState(false);
const [isLoading, setIsLoading] = useState(false);
return (
<View>
<ScrollView>
<Header headerText="Ajukan Akun Kader" />
<ContainerContent>
<Modal animationType="fade" transparent={true} visible={isLoading}>
<ModalContainer>
<ActivityIndicator
animating={isLoading}
size="large"
color="#fff"
/>
</ModalContainer>
</Modal>
<Modal
id="errorModal"
animationType="fade"
transparent={true}
visible={modalVisible}
onDismiss={() => setServerHasError(false)}>
<ModalContainer>
<ModalInner>
<Image
style={{width: imageSize, height: imageSize}}
source={error_img}
/>
<HeadingField>
{serverHasError ? (
<>
<Text isBold={true} fontSize={headingSize}>
Unknown Server Error
</Text>
</>
) : (
<>
<Text isBold={true} fontSize={headingSize}>
Akun sudah terdaftar
</Text>
<Text isBold={true} fontSize={headingSize}>
atau
</Text>
<Text isBold={true} fontSize={headingSize}>
sudah pernah diajukan
</Text>
</>
)}
</HeadingField>
<Button id="modalBack" type={2} onPress={() => setModalVisible(false)}>
Kembali
</Button>
</ModalInner>
</ModalContainer>
</Modal>
<InputField>
<Field
id="phone"
name="Nomor Handphone"
placeholder="No HP Anda"
isRequired={true}
information={messageErrors.phoneNumber}
value={form.fields.phone_number.value}
updateValue={val => setField('phone_number', val)}
/>
</InputField>
<InputField>
<Field
id="district"
type={3}
name="Kecamatan"
placeholder="Pilih Kecamatan"
isRequired={true}
information={messageErrors.district}
value={form.fields.district.value || KECAMATAN_VALUES[0].value}
updateValue={val => setField('district', val)}
values={KECAMATAN_VALUES}
/>
</InputField>
<InputField>
<Field
id="sub_district"
type={3}
name="Kelurahan"
placeholder="Pilih Kelurahan"
isRequired={true}
information={messageErrors.sub_district}
value={form.fields.sub_district.value || KELURAHAN_VALUES[KECAMATAN_VALUES[0].value][0].value}
updateValue={val => setField('sub_district', val)}
values={(form.fields.district.value) ? KELURAHAN_VALUES[form.fields.district.value] : KELURAHAN_VALUES[KECAMATAN_VALUES[0].value]}
/>
</InputField>
<Button
id="submit"
type={1}
onPress={async () => {
setIsLoading(true)
const response = await global.services.main.createUserGoogleSignin({
idToken: route.params.idToken,
phone_number: form.fields.phone_number.value,
district: form.fields.district.value,
sub_district: form.fields.sub_district.value
})
if (response.status === 201) {
setIsLoading(false);
navigation.reset({
index: 0,
routes: [{name: "officer-signup-finish"}],
});
} else if (response.status === 400) {
const errors = {
phoneNumber: response.data.phone_number || [],
district: response.data.district || [],
sub_district: response.data.sub_district || [],
}
setMessageErrors({
phoneNumber: translateError(errors.phoneNumber[0] || ""),
district: translateError(errors.district[0] || ""),
sub_district: translateError(errors.sub_district[0] || ""),
})
} else if (response.status === 500) {
if (response.data.includes("IntegrityError")) {
setServerHasError(false);
} else {
setServerHasError(true);
}
setModalVisible(true);
}
setIsLoading(false);
}}>
Ajukan Akun
</Button>
</ContainerContent>
</ScrollView>
</View>
);
};
const ContainerContent = styled.View`
padding: 5%;
background-color: white;
`;
const InputField = styled.View`
margin-bottom: 5%;
`;
const ModalContainer = styled.View`
flex: 1;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #00000080;
`;
const HeadingField = styled.View`
margin: 10% 0;
align-items: center;
`;
const ModalInner = styled.View`
align-items: center;
background-color: #fff;
padding: 15%;
height: ${props => props.theme.vh * 0.55};
`;
export default OfficerSignupFormGoogleSignin;
......@@ -21,7 +21,7 @@ enum Method {
PUT = 'PUT',
}
export default function useMainService(token: string) {
export default function useMainService(idToken: string) {
// Private functions
async function fetchWithoutAuthentication(
endpoint: string,
......@@ -44,7 +44,7 @@ export default function useMainService(token: string) {
) {
return await axios.request({
headers: {
Authorization: `Token ${token}`,
Authorization: `idToken ${idToken}`,
},
url: API_MAIN_URL + endpoint,
method: method,
......@@ -88,6 +88,20 @@ export default function useMainService(token: string) {
return fetchWithoutAuthentication(endPoint, Method.POST, body);
}
interface UserFormTypeGoogleSignin {
idToken: string
phone_number: string;
district: string;
sub_district: string;
}
async function createUserGoogleSignin(body: UserFormTypeGoogleSignin) {
const endPoint = END_POINTS.ACCOUNTS([
"google",
])
return fetchWithoutAuthentication(endPoint, Method.POST, body);
}
async function createCaseSubject(body: object) {
const endPoint = END_POINTS.CASE_SUBJECTS([
null,
......@@ -260,6 +274,7 @@ export default function useMainService(token: string) {
// Authentication
login,
createUser,
createUserGoogleSignin,
me,
// Contact Investigation Form
createCaseSubject,
......
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