Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ import Cable from './screens/cable';
import Support from './screens/support';
import requestInAppReview from './utils/requestInAppReview';

// TODO: add autocomplete prop to all text inputs
// TODO: add autofocus, keyboardAvoidingView and onSubmitediting prop to all forms
// TODO: install why did you render to monitor avoidable re-renders
// TODO: remove orange cellular icon from splashscreen or redesign it

/**
* Create Stack navigator
Expand Down
Binary file modified android/app/src/main/res/drawable/splashscreen_bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions components/CarrierAndPhoneNumberField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ const CarrierAndPhoneNumberField = ({
textContentType="telephoneNumber"
value={phoneNumber}
onChangeText={value => setPhoneNumber(value)}
autoComplete={"tel"}
autoFocus
/>
<View style={tw`mt-6 mb-4`}>
<CarrierSelector selected={carrier} />
Expand Down
68 changes: 68 additions & 0 deletions components/FaultyTxModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//import libraries
import React, {useState} from 'react';
import Text from '~components/Text';
import tw from '../lib/tailwind';
import BottomSheet, {BOTTOMSHEETHEIGHT} from './BottomSheet';
import Clipboard from '@react-native-clipboard/clipboard';
import {NavigationProp, useNavigation} from '@react-navigation/native';
import {StackParamList} from '../navigation/screenParams';

interface FaultyTxModalProps {
/**
* The transaction ref to display.
* This determines the visibility of the component
*/
txRef?: string;

/**
* Function to be called when modal is dismissed
*/
onDismiss: () => void;
}

const FAULTY_TX_MSG = `Payment was successful but top-up failed due to slow internet connection. Copy below transaction id, then you'll redirected to contact our customer care and complete top-up. Please keep the copied transaction id safe`;

/**
* Displays modal for faulty transactions i.e transactions where payment
* was successful but top-up completion failed for some reason.
* It shows the `transaction ref` to user, so user can copy it and resolve issue
* with customer care
*/
const FaultyTxModal = ({txRef, onDismiss}: FaultyTxModalProps) => {
const [txRefCopied, setTxRefCopied] = useState(false);
const {navigate} = useNavigation<NavigationProp<StackParamList>>();

const handleCopyId = () => {
Clipboard.setString(txRef!);
setTxRefCopied(true);
setTimeout(() => navigate('Support'), 1000);
};

const noop = () => null;

return (
<BottomSheet
height={BOTTOMSHEETHEIGHT.THREE_QUATER}
visible={!!txRef}
onDismiss={txRefCopied ? onDismiss : noop}
title={"An error occurred, top-up couldn't complete"}>
<Text style={tw`text-center`}>{FAULTY_TX_MSG}</Text>
<Text
onPress={handleCopyId}
type="small"
style={tw`mt-4 bg-gray5 text-center p-3 rounded-md`}>
{txRef}
</Text>
<Text
onPress={handleCopyId}
style={tw.style(
`mx-auto p-2 px-6 rounded-md text-white mt-4`,
txRefCopied ? 'bg-green-500' : 'bg-primary',
)}>
{txRefCopied ? 'TRANSACTION ID COPIED' : 'COPY'}
</Text>
</BottomSheet>
);
};

export default FaultyTxModal;
19 changes: 15 additions & 4 deletions components/PaymentBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import PaymentMethodButton, {PAYMENT_METHODS} from './PaymentMethodButton';
import {FlutterwaveInitOptions} from 'flutterwave-react-native/dist/FlutterwaveInit';
import constants from '../utils/constants';
import {AppServices} from '../global';
import {decrypt, encrypt} from '../utils/crypto';

interface PaymentBottomSheetProps {
/**
Expand All @@ -26,6 +27,14 @@ interface PaymentBottomSheetProps {
*/
amount: number;

/**
* The unencrypted transaction ref to use for flutterwave.
* We delegate tx ref generation to housing component because
* we want tx ref to house all top-up details to aid in faulty tx handling.
* This component will handle encryption of tx_ref
*/
flutterwaveTxRef: string;

/**
* Indicates the service being paid for
*/
Expand Down Expand Up @@ -62,9 +71,13 @@ const PaymentBottomSheet = ({
onFlutterwaveInit,
service = 'airtime',
visible = false,
flutterwaveTxRef,
}: PaymentBottomSheetProps) => {
const balance = useAppStore(state => state.profile?.wallet_balance);
const profile = useAppStore(state => state.profile);
const txRef = useMemo(() => encrypt(
flutterwaveTxRef || `service=${service};amt=${amount};dt=${Date.now()}`,
),[flutterwaveTxRef, amount]);

// flutterwave options
const flutterwaveOptions = useMemo<
Expand All @@ -73,9 +86,7 @@ const PaymentBottomSheet = ({
() => ({
...constants.INCOMPLETE_STATIC_FLUTTERWAVE_PAYMENT_OPTIONS,
amount: amount,
tx_ref: `${amount}-${service}-top-up-${
Date.now() + Math.floor(Math.random() * 100_000).toString(16)
}`,
tx_ref: txRef || `service=${service};amt=${amount};dt=${Date.now()}`,
customer:
profile?.email && profile?.username
? {
Expand All @@ -93,7 +104,7 @@ const PaymentBottomSheet = ({
} Payment`,
},
}),
[amount, profile?.email, profile?.username],
[amount, profile?.email, profile?.username, txRef],
);

return (
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 43 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
},
"dependencies": {
"@hookform/resolvers": "^2.9.8",
"@react-native-clipboard/clipboard": "^1.11.1",
"@react-navigation/bottom-tabs": "^6.4.0",
"@react-navigation/native": "^6.0.13",
"@react-navigation/native-stack": "^6.9.0",
"@types/crypto-js": "^4.1.1",
"axios": "^1.0.0",
"crypto-js": "^3.1.9-1",
"flutterwave-react-native": "^1.0.2",
"lottie-react-native": "^5.1.4",
"react": "18.1.0",
Expand Down
1 change: 1 addition & 0 deletions react-app-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ declare module '@env' {
// CHORE: When new env var are added in .env file,
// export the key as const like below
export const FLUTTERWAVE_MERCHANT_API_KEY: S;
export const ENCRYPTION_KEY: S;
}
6 changes: 0 additions & 6 deletions screens/airtime/airtime.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,3 @@ export enum Carrier {
Glo = 'glo',
Etisalat = 'etisalat',
}

export type IncompleteTopUp = {
phone: string;
amount: number;
carrier: Carrier;
};
Loading