Skip to content

Instantly share code, notes, and snippets.

@kevincarpdev
Created April 11, 2023 06:29
Show Gist options
  • Save kevincarpdev/f811509e5ede05bb4f002376e5f3a3a9 to your computer and use it in GitHub Desktop.
Save kevincarpdev/f811509e5ede05bb4f002376e5f3a3a9 to your computer and use it in GitHub Desktop.
import React from 'react';
import moment from 'moment';
import { ActivityIndicator, View } from 'react-native';
import { Text } from 'react-native-paper';
import { AccountLayout } from '../components';
import {
TitleBanner,
BSeparator,
SizedBox,
BDropdown,
BButton,
} from '../../../../components';
import {
CONSTANT_COLOR as CC,
CONSTANT_SIZE as CS,
GLOBAL_STYLE as GS,
} from '../../../../assets';
import { useTransactions } from '../../../../hooks/useTransactions';
import { useTransactionsFilters } from '../../../../hooks/useTransactionsFilters';
import { useRefetchOnFocus } from '../../../../hooks/useRefetchOnFocus';
import LoadingScreen from '../../../Loading.screen';
import {
IAPIOrderType,
ITransactionsFilters,
Transaction,
} from '../../../../types';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import { useNavigation } from '@react-navigation/native';
import { useAppContext } from '../../../../context/auth/app.context';
import Blank_Screen from '../../../Blank_.screen';
import { formatNumber } from '../../../../helpers/utils';
const TransactionDetail = ({ transaction }: { transaction: Transaction }) => (
<View
style={{
padding: CS.SPACE_MD / 2,
borderRadius: 20,
backgroundColor: 'rgba(0,0,0,0.3)',
flexDirection: 'row',
alignItems: 'center',
marginBottom: CS.SPACE_SM * 1.5,
}}>
<View style={{ flex: 1 }}>
<Text
style={{
textTransform: 'uppercase',
color: CC.primary,
}}>
{transaction?.transaction?.typeName}
</Text>
<View style={{ flexDirection: 'row' }}>
<Text style={{ fontSize: 12, color: 'white' }}>
{moment.unix(transaction?.timestamp).format('MM/DD/yyyy HH:mm:ss ')}
</Text>
</View>
<Text
style={{ fontSize: 12, color: 'white' }}>
TRANSACTION ID: {transaction?.balanceTransaction.id}
</Text>
{/* Show Channel: transaction?.platform */}
{transaction?.platform && (
<Text
style={{ textTransform: 'uppercase', fontSize: 12, color: 'white' }}>
CHANNEL: {transaction?.platform}
</Text>
)}
{/* Show only if type is Winnings/Deposits/Withdraws */}
{transaction?.balanceTransaction?.typeName === 'Winnings' ||
transaction?.balanceTransaction?.typeName === 'Deposit' ||
transaction?.balanceTransaction?.typeName === 'Withdrawal' ? (
<Text
style={{ textTransform: 'uppercase', fontSize: 12, color: 'white' }}>
Status: {transaction?.balanceTransaction?.statusName?.replace(/_/g, ' ')}
</Text>
) : null}
{/* if transaction?.paymentMethod?.displayName exists */}
{transaction?.paymentMethod?.displayName &&
<Text
style={{ textTransform: 'uppercase', fontSize: 12, color: 'white' }}>
PAYMENT INSTRUMENT: {transaction?.paymentMethod?.displayName || 'N/A'}
</Text>
}
</View>
<View>
<Text
style={{
...GS.FF_PoppinsSemiBold,
fontSize: 18,
lineHeight: 26,
textAlign: 'right',
color: 'white',
}}>
{transaction.amount ? (transaction.amount < 0 ? '-$' : '$') : ''}{formatNumber(Math.abs(transaction.amount))}
</Text>
</View>
</View>
);
const TransactionHistoryScreen = () => {
const navigation = useNavigation();
const { appData, isAppDataLoading } = useAppContext();
const [itemsPerPage, setItemsPerPage] = React.useState(10);
const [currentPage, setCurrentPage] = React.useState<number>(1);
const [typeFilter, setTypeFilter] = React.useState<string>(' ');
const [gameFilter, setGameFilter] = React.useState<null | string>('ALL');
const [periodFilter, setPeriodFilter] = React.useState<null | string>(
'User Defined',
);
const [sortBy, setSortBy] = React.useState<string>('timestamp_DESC');
const [pressedButton, setPressedButton] = React.useState<'from' | 'to'>(
'from',
);
const [activityFilter, setActivityFilter] = React.useState<null | string>('ALL');
const [startDateFilter, setStartDateFilter] = React.useState<Date>(
new Date(),
);
const [endDateFilter, setEndDateFilter] = React.useState<Date>(new Date());
const [isDatePickerVisible, setDatePickerVisibility] = React.useState(false);
const [dateResult, setDateResult] = React.useState('');
let transactionHistoryParams: any = {
pagination: {
pageNumber: currentPage,
itemsPerPage: itemsPerPage,
},
dateFrom:
periodFilter === 'User Defined'
? moment(startDateFilter).format('MM/DD/YYYY').toString()
: periodFilter,
dateTo: moment(endDateFilter).format('YYYY-MM-DD').toString(),
// dateFrom: '2013-12-31',
// dateTo: '2032-11-11',
filters: [],
order: [
{
name: 'creationTime',
priority: 0,
order: 'asc',
},
],
};
if (sortBy && sortBy.split('_').length === 2) {
const orderData = sortBy.split('_');
transactionHistoryParams.order = [
{
name: orderData[0] as unknown as ITransactionsFilters,
priority: 1,
order: orderData[1] as unknown as IAPIOrderType,
},
];
}
if (typeFilter && typeFilter !== ' ') {
transactionHistoryParams.filters.push({
name: 'financialTransactionType',
value: [{ condition: 'INCLUDE', logic: 'INCLUDE', value: typeFilter }],
});
}
if (gameFilter && gameFilter !== 'ALL') {
transactionHistoryParams?.filters.push({
name: 'gameId',
value: [
{
condition: 'INCLUDE',
logic: 'INCLUDE',
value: gameFilter,
},
],
});
}
if (activityFilter && activityFilter !== 'ALL') {
transactionHistoryParams?.filters.push({
name: 'financialTransactionActivity',
value: [{ condition: 'INCLUDE', logic: 'INCLUDE', value: activityFilter }],
});
}
const {
data: transactions,
isLoading: transactionsIsLoading,
isError: transactionsIsError,
error: transactionsError,
fetch: refetchTransactions,
} = useTransactions(transactionHistoryParams, { config: { enabled: true } });
const { data: transactionFilters, isLoading: transactionFiltersisLoading } =
useTransactionsFilters({
config: undefined,
});
React.useEffect(() => {
refetchTransactions();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
itemsPerPage,
currentPage,
typeFilter,
gameFilter,
activityFilter,
startDateFilter,
endDateFilter,
sortBy,
periodFilter,
]);
useRefetchOnFocus(refetchTransactions, true);
// this will reset states between navigation in and out
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
setItemsPerPage(10);
});
return unsubscribe;
}, [navigation]);
if (isAppDataLoading || transactionFiltersisLoading) {
return <LoadingScreen />;
}
if (!appData?.response.lotteryGames) {
return <Blank_Screen />;
}
const availableGames = Object.keys(appData?.response?.lotteryGames).map(
(entry) => {
return {
value: entry,
label: appData?.response?.lotteryGames[entry]?.gameName,
};
},
);
const date: Date = new Date();
var lastWeek = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate() - 7,
);
let period = [
{ label: 'Today', value: moment(date).format('MM/DD/YYYY').toString() },
{
label: 'Since Yesterday',
value: moment(date.setDate(date.getDate() - 1))
.format('MM/DD/YYYY')
.toString(),
},
{
label: 'Last week',
value: moment(lastWeek).format('MM/DD/YYYY').toString(),
},
{
label: 'Last month',
value: moment(date.setMonth(date.getMonth() - 1))
.format('MM/DD/YYYY')
.toString(),
},
{
label: 'Last 2 month',
value: moment(date.setMonth(date.getMonth() - 1))
.format('MM/DD/YYYY')
.toString(),
},
{
label: 'Last 6 month',
value: moment(date.setMonth(date.getMonth() - 4))
.format('MM/DD/YYYY')
.toString(),
},
];
const handleConfirm = (date) => {
setDatePickerVisibility(false);
setCurrentPage(1);
if (pressedButton === 'from') {
setStartDateFilter(date);
} else {
setEndDateFilter(date);
}
};
return (
<AccountLayout>
<View style={{ zIndex: 1 }}>
<TitleBanner title="Transaction History" />
{/* */}
<View
style={{
flexDirection: 'row',
alignItems: 'flex-end',
marginTop: 20,
marginBottom: 10,
zIndex: 2,
}}>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
flex: 1,
}}>
<BDropdown
label="Game"
value={gameFilter}
onPress={(entry) => {
setCurrentPage(1);
setGameFilter(entry.value);
}}
listmode="MODAL"
values={[{ value: 'ALL', label: 'All' }].concat(availableGames)}
style={{ flex: 1 }}
/>
<SizedBox width={7.5} />
<BDropdown
label="Type"
value={typeFilter}
values={
transactionFilters?.response?.filters?.financialTransactionType
}
onPress={(entry) => {
setCurrentPage(1);
setTypeFilter(entry.value);
}}
style={{ flex: 1 }}
/>
</View>
</View>
<View
style={{
marginBottom: 15,
position: 'relative',
}}>
{/* TODO */}
<BDropdown
label="ACTIVITY"
value={activityFilter}
values={[{ label: "All", value: "ALL" }, { label: "Bet", value: "placebet" }, { label: "Winnings", value: "settlement" }]}
onPress={(entry) => {
setCurrentPage(1);
setActivityFilter(entry.value);
}}
fullWidth={true}
/>
</View>
{/* */}
<View
style={{
marginTop: 1,
marginBottom: 15,
position: 'relative',
}}>
<BDropdown
label="Time period"
value={periodFilter}
onPress={(entry) => {
setCurrentPage(1);
setPeriodFilter(entry.value);
setDateResult(
entry.label !== ''
? entry.label === 'User Defined'
? ''
: entry.label
: '',
);
}}
listmode="MODAL"
values={[{ value: 'User Defined', label: 'User Defined' }].concat(
period,
)}
fullWidth={true}
/>
</View>
{/* */}
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
marginTop: 15,
}}>
<View style={{ flex: 1 }}>
<Text style={[GS.txtWhite, GS.pl2]}>FROM</Text>
<BButton
selectable
title={
pressedButton !== 'from'
? moment(startDateFilter).format('MM/DD/YYYY').toString()
: periodFilter === 'User Defined'
? moment(startDateFilter).format('MM/DD/YYYY').toString()
: periodFilter
}
onPress={() => {
//setPeriodFilter(moment(startDateFilter).format('MM/DD/YYYY').toString());
setPressedButton('from');
setDatePickerVisibility(true);
setDateResult('IN THE SELECTED TIMEFRAME');
}}
style={{ flex: 1, marginTop: 2 }}
/>
</View>
<SizedBox width={10} />
<View style={{ flex: 1 }}>
<Text style={[GS.txtWhite, GS.pl2]}>TO</Text>
<BButton
selectable
title={moment(endDateFilter).format('MM/DD/YYYY').toString()}
onPress={() => {
setPressedButton('to');
setDatePickerVisibility(true);
}}
style={{ flex: 1, marginTop: 2 }}
/>
</View>
</View>
{/* */}
<View
style={{
marginTop: 15,
marginBottom: 30,
position: 'relative',
}}>
</View>
{/* */}
<Text
style={{
textTransform: 'uppercase',
fontSize: 12,
lineHeight: 22,
color: 'white',
}}>
Please note the maximum date range available is 6 months. For older
transactions, contact customer service on 406-528-3926.
</Text>
<SizedBox height={20} />
<View>
<BButton
title="Show"
onPress={() => {
refetchTransactions();
}}
mode="primary"
/>
</View>
{/* */}
{transactionsIsLoading && (
<View
style={{
...GS.centered,
flex: 1,
paddingVertical: 15,
paddingHorizontal: 10,
}}>
<ActivityIndicator size={45} color={'white'} />
</View>
)}
{!transactionsIsLoading &&
transactions?.response?.response &&
transactions?.response?.response.length > 0 && (
<React.Fragment>
<BSeparator spaceless />
<View style={{ zIndex: 10, position: 'relative', flex: 1 }}>
<BDropdown
label="Sort by"
value={sortBy}
onPress={(entry) => {
setCurrentPage(1);
setSortBy(entry.value);
}}
values={[
{ label: 'Latest first', value: 'timestamp_DESC' },
{ label: 'Latest last', value: 'timestamp_ASC' },
{
label: 'Activity descending',
value: 'transactionTypeName_DESC',
},
{
label: 'Activity ascending',
value: 'transactionTypeName_ASC',
},
{ label: 'Winnings ascending', value: 'amount_ASC' },
{
label: 'Winnings descending',
value: 'amount_DESC',
},
]}
fullWidth={true}
/>
</View>
<SizedBox height={30} />
<Text
style={{
flexDirection: 'row',
alignItems: 'center',
color: 'white',
}}>
<Text
style={{
textTransform: 'uppercase',
fontWeight: 'bold',
fontSize: CS.FONT_SIZE_MD,
color: 'white',
}}>
Viewing {transactions?.response?.response?.length}{' '}
transactions in the past
</Text>
<SizedBox width={5} />
<Text
style={{
textTransform: 'uppercase',
fontWeight: 'bold',
fontSize: CS.FONT_SIZE_MD,
color: CC.primary,
}}>
{dateResult}
</Text>
</Text>
<SizedBox height={15} />
</React.Fragment>
)}
{/* */}
{!transactionsIsLoading &&
transactions?.response?.response &&
transactions?.response?.response?.length === 0 && (
<View style={{ marginTop: 40, marginBottom: 5 }}>
<Text style={[GS.txtWhite, GS.txtCenter, GS.txtH3]}>
No transactions available.
</Text>
</View>
)}
{!transactionsIsLoading &&
transactions?.response?.response &&
transactions?.response?.response?.length > 0 &&
transactions?.response?.response?.map((transaction, index) => (
<TransactionDetail transaction={transaction} key={index} />
))}
{transactions?.response &&
transactions?.response?.args?.pagination?.totalItems >
transactions?.response?.response?.length && (
<View>
<View
style={[
GS.row,
GS.alignCenter,
GS.justifyBetween,
GS.mt4,
{ width: '100%' },
]}>
<Text
style={[GS.fontItalic, GS.fontBold, GS.txtWhite]}>{`Showing ${(transactions?.response?.args?.pagination?.pageNumber - 1) *
transactions?.response?.args?.pagination?.itemsPerPage +
1
} to ${transactions?.response?.args?.pagination?.pageNumber *
transactions?.response?.args?.pagination?.itemsPerPage >
transactions?.response?.args?.pagination?.totalItems
? transactions?.response?.args?.pagination?.totalItems
: transactions?.response?.args?.pagination?.pageNumber *
transactions?.response?.args?.pagination?.itemsPerPage
} of ${transactions?.response?.args?.pagination?.totalItems
} entries`}</Text>
</View>
<View
style={[
GS.row,
GS.alignCenter,
GS.justifyBetween,
GS.mt4,
{ width: '100%' },
]}>
<View
style={{
width: '60%',
display: 'flex',
flexDirection: 'row',
}}>
<BButton
mode="primary"
title="Load more"
disabled={
parseInt(
transactions?.response?.args?.pagination?.totalPages,
) <=
parseInt(
transactions?.response?.args?.pagination?.pageNumber,
)
}
onPress={() => {
setItemsPerPage(itemsPerPage + 10);
}}
/>
</View>
<View
style={[
GS.row,
GS.alignCenter,
GS.justifyEnd,
{ width: '40%' },
]}>
<Text style={[GS.txtWhite, GS.txtUpper, GS.mr2]}>Page</Text>
<View style={{ zIndex: 10, position: 'relative', width: 75 }}>
<BDropdown
placeholder="1"
value={currentPage}
onPress={(entry) => setCurrentPage(entry.value)}
values={Array(
transactions?.response?.args?.pagination?.totalPages,
)
.fill('0')
.map((v, i) => ({
label: String(i + 1),
value: i + 1,
}))}
fullWidth={true}
/>
</View>
</View>
</View>
</View>
)}
{/* */}
<DateTimePickerModal
isVisible={isDatePickerVisible}
display="spinner"
date={pressedButton === 'from' ? startDateFilter : endDateFilter}
minimumDate={
pressedButton === 'from' ? undefined : startDateFilter || undefined
}
mode="date"
onConfirm={handleConfirm}
onCancel={() => setDatePickerVisibility(false)}
/>
</View>
</AccountLayout>
);
};
export default TransactionHistoryScreen;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment