Fakultas Ilmu Komputer UI

index.ts 5.09 KB
Newer Older
1
2
3
4
5
6
import { createContext, useCallback, useEffect, useState } from 'react';
import { GoogleSignin } from '@react-native-google-signin/google-signin';

import { Toast } from 'components/core';
import CACHE_KEYS from 'constants/cacheKeys';
import { removeCache, getCache, setCache } from 'utils/cache';
7
8
9
10
11
12
13
14

import {
  googleLoginApi,
  loginApi,
  signupApi,
  retrieveUserApi,
  linkUserDataApi,
} from 'services/auth';
15
16
17
18
19
import {
  User,
  RegistrationRequest,
  LoginRequest,
  LoginResponse,
20
  UserRole,
21
} from 'services/auth/models';
22
23
24
import { set401Callback, setAuthHeader, resetAuthHeader } from 'services/api';

import { iUserContext } from './types';
Wulan Mantiri's avatar
Wulan Mantiri committed
25
import { TransactionStatus } from 'services/payment/models';
26
27
28
29
30

const initialUser = {
  id: null,
  email: '',
  name: '',
31
  role: null,
32
33
};

34
35
36
export const UserContext = createContext<iUserContext>({
  user: initialUser,
  isAuthenticated: false,
37
38
39
40
  isUnpaidClient: false,
  isPaidClient: false,
  isNutritionist: false,
  isAdmin: false,
41
  isLoading: false,
42
  isFirstLoading: false,
43
44
45
46
47
48
49
50
51
  signup: () => Promise.reject(),
  login: () => Promise.reject(),
  loginWithGoogle: () => Promise.reject(),
  logout: () => Promise.reject(),
});

export const useUserContext = (): iUserContext => {
  const [user, setUser] = useState<User>(initialUser);
  const [isLoading, setIsLoading] = useState(false);
52
  const [isFirstLoading, setIsFirstLoading] = useState(false);
Wulan Mantiri's avatar
Wulan Mantiri committed
53
54
55
  const [transactionStatus, setTransactionStatus] = useState(
    TransactionStatus.UNPAID,
  );
56
57
58
59
60
61
62
63

  const logout = useCallback(async () => {
    await GoogleSignin.signOut();
    await removeCache(CACHE_KEYS.authToken);
    await removeCache(CACHE_KEYS.refreshToken);
    setUser(initialUser);
    resetAuthHeader();
  }, []);
64
65

  const getUser = useCallback(async () => {
66
    setIsFirstLoading(true);
67
68
69
    const token = await getCache(CACHE_KEYS.authToken);
    if (token) {
      setAuthHeader(token);
70
71
      const response = await retrieveUserApi();
      if (response.success && response.data) {
Wulan Mantiri's avatar
Wulan Mantiri committed
72
73
74
        const { cart, ...userData } = response.data;
        setUser(userData);
        setTransactionStatus(cart.transaction_status);
75
76
77
78
79
80
81
82
      } else {
        await logout();
        Toast.show({
          type: 'error',
          text1: 'Sesi Anda sudah berakhir.',
          text2: 'Silakan coba masuk lagi.',
        });
      }
83
    }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    setIsFirstLoading(false);
  }, [logout]);

  const authSuccess = async (data: LoginResponse) => {
    const accessToken = data.access_token;
    await setCache(CACHE_KEYS.authToken, accessToken);
    await setCache(CACHE_KEYS.refreshToken, data.refresh_token);
    setUser(data.user);
    setAuthHeader(accessToken);
  };

  const linkUserData = async (email: string) => {
    const dietProfileId = await getCache(CACHE_KEYS.dietProfileId);
    const cartId = await getCache(CACHE_KEYS.cartId);
    if (dietProfileId && cartId) {
      const response = await linkUserDataApi({
        email,
        diet_profile_id: parseInt(dietProfileId, 10),
        cart_id: parseInt(cartId, 10),
      });
      return response;
    }
    return {
      success: false,
    };
  };
110

111
112
  const signup = async (registerData: RegistrationRequest) => {
    const response = await signupApi(registerData);
113
114
115
116
    if (response.success && response.data) {
      await authSuccess(response.data);
      return await linkUserData(response.data.user.email);
    }
117
118
    return response;
  };
119

120
121
  const login = async (loginData: LoginRequest) => {
    const response = await loginApi(loginData);
122
123
124
    if (response.success && response.data) {
      await authSuccess(response.data);
    }
125
126
    return response;
  };
127

128
  const loginWithGoogle = async (isLogin: boolean = true) => {
129
130
131
132
133
134
135
136
    try {
      await GoogleSignin.hasPlayServices();
      await GoogleSignin.signIn();
      const tokens = await GoogleSignin.getTokens();
      const response = await googleLoginApi({
        access_token: tokens.accessToken,
      });
      if (response.success && response.data) {
137
        await authSuccess(response.data);
138
139
140
141
142
143
144
145
146
147
148

        if (!isLogin) {
          const linkResponse = await linkUserData(response.data.user.email);
          if (!linkResponse.success) {
            await logout();
            Toast.show({
              type: 'error',
              text1: 'Gagal registrasi dengan Google',
              text2: 'Terjadi kesalahan di sisi kami. Silakan coba lagi',
            });
          }
149
        }
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
      } else {
        await logout();
      }
    } catch (error) {
      console.log(error);
    }
    setIsLoading(false);
  };

  useEffect(() => {
    // TODO: save to .env
    GoogleSignin.configure({
      webClientId:
        '813112248680-ulv0amtocut652j31qbpvubtclbd2c7o.apps.googleusercontent.com',
    });

    getUser();
    set401Callback(logout);
  }, [getUser, logout]);

  return {
    user,
    isAuthenticated: user.id !== null,
Wulan Mantiri's avatar
Wulan Mantiri committed
173
174
175
176
    isUnpaidClient:
      user.role === UserRole.CLIENT &&
      transactionStatus === TransactionStatus.UNPAID,
    isPaidClient: user.role === UserRole.CLIENT,
177
178
    isNutritionist: user.role === UserRole.NUTRITIONIST,
    isAdmin: user.role === UserRole.ADMIN,
179
    isLoading,
180
    isFirstLoading,
181
182
183
184
185
186
    signup,
    login,
    loginWithGoogle,
    logout,
  };
};