Skip to content

Instantly share code, notes, and snippets.

@kevincarpdev
Created April 8, 2023 04:17
Show Gist options
  • Save kevincarpdev/85845ae2cb604a38a30839162c3f942c to your computer and use it in GitHub Desktop.
Save kevincarpdev/85845ae2cb604a38a30839162c3f942c to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, ActivityIndicator } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { BButton, BSeparator, SizedBox, BIcon } from '../../../../../components';
import { useAuthContext } from '../../../../../context/auth/auth.context';
// STYLES
import { CONSTANT_COLOR, CONSTANT_SIZE, GLOBAL_STYLE, icons } from '../../../../../assets';
import { DRAWER_ROUTES_NAMES } from '../../../../../router/DrawerNavigator';
import { ApiClient } from '../../../../../api';
import { useCardAccounts } from '../../../../../hooks/useCardAccounts'
import { useRefetchOnFocus } from '../../../../../hooks/useRefetchOnFocus';
import BouncyCheckbox from 'react-native-bouncy-checkbox';
import {
ConfirmDepositModal,
} from '../../modals';
import WithdrawAmountButton from '../WithdrawTab/WithdrawAmountButton';
import WithdrawAmountInput from '../WithdrawTab/WithdrawAmountInput';
import mobxStore from '../../../../../store/RootStore';
import { formatNumber, webViewUserAgent } from '../../../../../helpers/utils';
import AsyncStorage from '@react-native-async-storage/async-storage';
import WebView from 'react-native-webview';
import { WebViewBModal } from '../../../../../components/Common/BModal';
const CardDepositTab = () => {
const navigation: any = useNavigation();
// get auth context
const {
userInfo
} = useAuthContext();
const [amount, setAmount] = useState(0);
const [depositLimit, setDepositLimit] = useState(0);
const [errorMessage, setErrorMessage] = useState("");
const [helpMessage, setHelpMessage] = useState("");
const [selectedCard, setSelectedCard] = React.useState<any>(-1);
const [showDepositConfirmationModal, setShowDepositConfirmationModal] = useState(false);
const [depositValidationResponse, setDepositValidationResponse] = useState(null);
const [depositResponse, setDepositResponse] = useState(null);
const [isDepositButtonDisabled, setIsDepositButtonDisabled] = useState(true);
const [isContinueButtonPressed, setIsContinueButtonPressed] = useState(false);
const [showBalance, setShowBalance] = useState(mobxStore.showBalance);
const [depositMinValue, setDepositMinValue] = useState(0);
const [depositMaxValue, setDepositMaxValue] = useState(0);
// User Permissions ILNA-442
const [disableContinueButton, setDisableContinueButton] = useState(false);
// New Card
const [paysafeUrl, setPaysafeUrl] = useState('');
const [newCardModalVisible, setNewCardModalVisible] = useState(false);
const [newCardModalUrl, setNewCardModalUrl] = useState('');
const currentWebView = React.useRef<WebView | null>(null);
const [error, setError] = useState(null);
const [saveCard, setSaveCard] = useState(false);
const [newCardToken, setNewCardToken] = useState('');
const [authCookie, setAuthCookie] = useState('');
const depositLimitDepositAmounInputHandler = (_amount: string) => {
setAmount(_amount ? parseInt(_amount) : 0);
};
const withdrawAmountButtonHandler = (changeAmount: number) => {
setAmount(currentAmount => {
return currentAmount < 0 ? 0 : currentAmount + changeAmount;
});
};
// Validate Deposit
useEffect(() => {
const validateDeposit = async () => {
if (depositValidationResponse === null) {
return;
}
if (depositValidationResponse.response.success) {
const playerId = depositValidationResponse.response.response.playerId;
if (playerId) {
setShowDepositConfirmationModal(true);
}
} else {
setErrorMessage(depositValidationResponse.message);
}
};
validateDeposit();
}, [depositValidationResponse]);
// Handle Deposit
const handleDepositButton = async () => {
// Set the deposit button disabled to prevent multiple clicks
setIsDepositButtonDisabled(true);
// Validate transaction
const validateResponse = await ApiClient.validateTransaction({
amount: amount.toString(),
paymentMethodId: 'CARD',
transactionType: 'DEPOSIT',
});
setDepositValidationResponse(validateResponse);
// Re-enable the deposit button
setIsDepositButtonDisabled(false);
};
// /wallet/dep[osit]
const handleDeposit = async () => {
// Deposit
// if token or saveCard is populated, include it and dont include paymentInstrumentId,
var depositResponse = null;
if (newCardToken || saveCard) {
depositResponse = await ApiClient.depositWallet({
amount: amount.toString(),
methodId: "CARD",
token: newCardToken,
saveCard: saveCard ? saveCard : false
});
} else {
depositResponse = await ApiClient.depositWallet({
amount: amount.toString(),
methodId: "CARD",
paymentInstrumentId: selectedCard ? selectedCard : ''
});
}
setDepositResponse(depositResponse);
console.log("depositResponse", depositResponse);
const paymentStatusResponse = depositResponse?.response?.depositTransaction.paymentStatus;
if (paymentStatusResponse == "IN_PROGRESS" || paymentStatusResponse == "COMPLETED" || paymentStatusResponse == "PENDING") {
setShowDepositConfirmationModal(false);
setIsDepositButtonDisabled(false);
setAmount(0);
setIsContinueButtonPressed(false);
navigation.navigate(DRAWER_ROUTES_NAMES.WALLET__DEPOSIT_RESULT as never, {
depositAmount: amount,
transactionState: 'success',
message: depositResponse?.response?.errorMessage,
transactionMethod: 'CARD'
});
}
else {
setIsDepositButtonDisabled(false);
setErrorMessage(depositResponse?.message);
}
};
// if <5 or greater than the player limits,
// disable the withdraw button
useEffect(() => {
if (amount < 5 || amount > depositMaxValue) {
setIsDepositButtonDisabled(true);
setErrorMessage('');
setHelpMessage(`Amount must be between $${depositMinValue} and $${depositMaxValue}`);
} else {
setIsDepositButtonDisabled(false);
setErrorMessage('');
setHelpMessage(`Enter a deposit amount between $${depositMinValue} and $${depositMaxValue}`);
}
}, [amount, depositMaxValue, depositMinValue]);
const {
data: cardAccounts,
fetch: refetchCardAccounts,
isLoading: cardAccountsIsLoading,
} = useCardAccounts({ config: undefined });
useRefetchOnFocus(refetchCardAccounts);
if (!cardAccounts?.response && !cardAccountsIsLoading) {
return <></>;
}
// put const showBalance = mobxStore.showBalance; in a useEffect
useEffect(() => {
setShowBalance(mobxStore.showBalance);
}, [mobxStore.showBalance]);
useEffect(() => {
const fetchData = async () => {
ApiClient.getWalletDepositMethods().then((response) => {
if (response?.response?.addCardWebviewUrl) {
const paysafeUrl = `${response.response.addCardWebviewUrl}`;
setPaysafeUrl(paysafeUrl);
}
// find the depositMethod with id === "CARD"
const cardPaymentMethod = response.response.Deposit.depositMethods.find(
(paymentMethod) => paymentMethod.id === "CARD"
);
// if vipPreferredPaymentMethod exists, set the depositLimit to the maxAllowDeposit
if (cardPaymentMethod) {
setDepositMinValue(cardPaymentMethod.minValue);
setDepositMaxValue(cardPaymentMethod.maxValue);
}
});
};
fetchData();
}, []);
// setDeposit limit to maxAllowDeposit from storage if it exists
useEffect(() => {
const fetchData = async () => {
const maxAllowDeposit = await AsyncStorage.getItem('maxAllowDeposit');
if (maxAllowDeposit) {
setDepositLimit(parseInt(maxAllowDeposit));
}
};
fetchData();
}, []);
const handleError = (syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
console.error('WebView error: ', nativeEvent);
setError(nativeEvent);
};
// useEffect to set auth cookie const authCookie = await AsyncStorage.getItem('user_cookie');
useEffect(() => {
const fetchData = async () => {
const authCookie = await AsyncStorage.getItem('user_cookie');
if (authCookie) {
const cookies = authCookie.split('; ');
let edgeDevelopmentValue;
cookies.forEach(cookie => {
const [name, value] = cookie.split('=');
if (name === 'edge_development') {
edgeDevelopmentValue = value;
}
})
if (edgeDevelopmentValue) {
setAuthCookie(edgeDevelopmentValue);
} else {
console.log('No edge_development cookie found');
}
}
};
fetchData();
}, []);
const handleNewCard = async () => {
// add ?amount to the url from amount state
const newPaysafeUrl = `${paysafeUrl}?amount=${amount}`;
setNewCardModalUrl(newPaysafeUrl);
setNewCardModalVisible(true);
};
React.useEffect(() => {
if (userInfo) {
const blockAllDeposits = userInfo?.userPermissions?.deposit.blockAll;
const blockCardDeposit = userInfo.userPermissions.deposit.blockPaymentMethods.includes('CARD');
setDisableContinueButton(blockAllDeposits || blockCardDeposit)
}
}, [userInfo]);
return (
<View>
{/* If Continue Button has NOT been Pressed */}
{!isContinueButtonPressed && (
<>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
}}>
<Text
style={{
textTransform: 'uppercase',
fontWeight: 'bold',
fontSize: CONSTANT_SIZE.FONT_SIZE_MD,
color: 'white',
}}>
CHOOSE ACCOUNT
</Text>
</View>
<SizedBox height={15} />
<Text
style={{
textTransform: 'uppercase',
fontSize: 12,
lineHeight: 22,
color: 'white',
}}>
Please select the account from which you want to deposit money
</Text>
<BSeparator spaceless />
<View
>
<Text
style={{
textTransform: 'uppercase',
fontWeight: 'bold',
fontSize: CONSTANT_SIZE.FONT_SIZE_MD,
color: 'white',
}}>
From Credit/Debit Card
</Text>
{cardAccountsIsLoading && (
<ActivityIndicator size={20} color={'white'} />
)}
{!cardAccountsIsLoading && cardAccounts?.response && cardAccounts?.response.Deposit.depositMethods.length === 0 && (
<Text
style={{
textTransform: 'uppercase',
fontSize: 15,
color: 'white',
}}>
NONE
</Text>
)}
{!cardAccountsIsLoading && cardAccounts?.response &&
cardAccounts?.response.Deposit.depositMethods.map((entry, entryI) => {
if (entry.paymentInstruments.length > 0 && entry.id === "CARD") {
return entry.paymentInstruments.map((instrument, instrumentI) =>
<View
key={instrument.id}
style={{
flexDirection: 'row',
alignItems: 'center',
width: '100%',
flexWrap: 'wrap',
backgroundColor: 'rgba(255, 255, 255, 0.2)',
borderRadius: 20,
paddingLeft: 15,
paddingVertical: 12,
marginTop: 10,
}}>
<BouncyCheckbox
isChecked={instrument.id === selectedCard}
size={25}
fillColor={'#00ACD4'}
unfillColor={'transparent'}
onPress={(isChecked: boolean) => {
!isChecked && setSelectedCard(-1);
isChecked && setSelectedCard(instrument.id);
}}
/>
<View>
<Text
style={{
textTransform: 'uppercase',
fontFamily: 'Poppins-SemiBold',
fontSize: 14,
color: 'white',
}}>
{instrument.card.type}
</Text>
<Text
style={{
textTransform: 'lowercase',
fontFamily: 'Poppins-SemiBold',
fontSize: 14,
color: 'white',
marginTop: 2,
}}>
{`******` + instrument.card.lastDigits}
</Text>
</View>
</View>
);
}
// if no Card
return null;
})}
</View>
<BSeparator spaceless />
<TouchableOpacity
activeOpacity={0.7}
onPress={() => { setIsContinueButtonPressed(true) }}
>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
justifyContent: 'space-between',
}}>
<Text
style={{
textTransform: 'uppercase',
fontSize: CONSTANT_SIZE.FONT_SIZE,
color: 'white',
}}>
New Account
</Text>
<BIcon
icon={icons.right_arrow}
style={{ height: 12, width: 12, resizeMode: 'contain' }}
/>
</View>
</TouchableOpacity>
<BSeparator spaceless />
<BButton mode="primary" title="CONTINUE"
onPress={() => { setIsContinueButtonPressed(true) }}
disabled={disableContinueButton}
/>
</>
)}
{/* If Continue button has been pressed */}
{isContinueButtonPressed && (
<View>
<Text
style={{
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
}}>
<Text
style={{
...GLOBAL_STYLE.FF_PoppinsSemiBold,
textTransform: 'uppercase',
fontSize: CONSTANT_SIZE.FONT_SIZE_MD,
color: 'white',
}}>
Deposit
</Text>
<SizedBox width={5} />
<Text
style={{
...GLOBAL_STYLE.FF_PoppinsSemiBold,
textTransform: 'uppercase',
fontSize: CONSTANT_SIZE.FONT_SIZE_MD,
color: CONSTANT_COLOR.primary,
}}>
FUNDS
</Text>
</Text>
<Text>
<Text
style={{
textTransform: 'uppercase',
fontSize: 12,
lineHeight: 22,
color: 'white',
}}>
{depositLimit && showBalance ? `Available Amount to Deposit: $${formatNumber(depositLimit)}` : 'Available Amount to Deposit: $****'}
</Text>
</Text>
<View
style={{
flexDirection: 'row',
}}>
<WithdrawAmountButton
amount={15}
onPress={withdrawAmountButtonHandler}
/>
<WithdrawAmountButton
amount={20}
onPress={withdrawAmountButtonHandler}
/>
<WithdrawAmountButton
amount={50}
onPress={withdrawAmountButtonHandler}
/>
<WithdrawAmountButton
amount={100}
onPress={withdrawAmountButtonHandler}
/>
</View>
<SizedBox height={15} />
<Text
style={{
textTransform: 'uppercase',
fontSize: 16,
color: 'white',
}}>
ENTER AMOUNT
</Text>
<SizedBox height={5} />
<WithdrawAmountInput
setAmount={depositLimitDepositAmounInputHandler}
amount={amount}
helpText={helpMessage}
errorText={errorMessage}
/>
<BSeparator spaceless style={{ marginBottom: 25 }} />
<View
style={{
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
justifyContent: 'space-between',
}}>
<Text
style={{
...GLOBAL_STYLE.FF_PoppinsSemiBold,
textTransform: 'uppercase',
fontSize: CONSTANT_SIZE.FONT_SIZE,
color: 'white',
}}>
DEPOSIT AMOUNT
</Text>
<Text
style={{
...GLOBAL_STYLE.FF_PoppinsSemiBold,
textTransform: 'uppercase',
fontSize: CONSTANT_SIZE.FONT_SIZE,
color: 'white',
}}>
${amount}
</Text>
</View>
<SizedBox height={25} />
<BButton
// disabled based on state
disabled={isDepositButtonDisabled}
title="DEPOSIT"
mode="danger"
onPress={handleDepositButton}
/>
{/* Grey cancel button with top margin */}
<BButton
title="CANCEL"
mode="secondary"
onPress={() => {
setIsContinueButtonPressed(false);
}}
style={{ marginTop: 10 }}
/>
{/* Confirm Withdraw Modal */}
<ConfirmDepositModal
disabledButtons={isDepositButtonDisabled}
isVisible={showDepositConfirmationModal}
confirmMessage={`Are you sure you want to deposit $${amount} into your account? Your balance might be subject of bonus forfeit money.`}
confirmTitle={`Are you sure you want to deposit?`}
onConfirm={() => {
setIsDepositButtonDisabled(true)
// if selectedCard is -1, then it's a new card, run handleNewCard function
if (selectedCard === -1) {
handleNewCard();
} else {
handleDeposit();
}
}}
onClose={() => {
setAmount(0);
setShowDepositConfirmationModal(false);
}}
/>
</View>
)}
<WebViewBModal
isVisible={newCardModalVisible}
onClose={() => {
setNewCardModalVisible(false);
}}
>
<React.Fragment>
<View style={{ height: '100%', width: '100%' }}>
{newCardModalUrl && (
<WebView
ref={currentWebView}
source={{
uri: newCardModalUrl,
headers: {
Cookie: `edge_development=${authCookie}`,
'In-Webview': '1',
},
}}
style={{ height: '100%', width: '100%' }}
javaScriptEnabled={true}
domStorageEnabled={true}
thirdPartyCookiesEnabled={true}
sharedCookiesEnabled={true}
onError={handleError}
originWhitelist={['*']}
onNavigationStateChange={(event) => {
const url = event.url;
if (url.includes('ilintlot://cancelAddNewCard')) {
console.log('cancelAddNewCard');
setNewCardModalVisible(false);
}
else if (url.includes('ilintlot://changeAddress')) {
console.log('changeAddress');
setNewCardModalVisible(false);
navigation.navigate(DRAWER_ROUTES_NAMES.ACCOUNT__CHANGE_ADDRESS);
}
else if (url.includes('ilintlot://depositWithNewCardToken')) {
console.log('depositWithNewCardToken');
setNewCardModalVisible(false);
const token = url.split('token=')[1].split('&')[0];
const saveCard = url.split('saveCard=')[1];
setNewCardToken(token);
setSaveCard(saveCard === 'true' ? true : false);
handleDeposit();
}
}}
/>
)}
</View>
</React.Fragment>
</WebViewBModal>
</View>
);
};
export default CardDepositTab;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment